From 12d9e4e26925559a73ed082ce47b32659f445668 Mon Sep 17 00:00:00 2001 From: Bardia Mahjour Date: Wed, 18 Sep 2019 17:43:45 +0000 Subject: [PATCH] Data Dependence Graph Basics Summary: This is the first patch in a series of patches that will implement data dependence graph in LLVM. Many of the ideas used in this implementation are based on the following paper: D. J. Kuck, R. H. Kuhn, D. A. Padua, B. Leasure, and M. Wolfe (1981). DEPENDENCE GRAPHS AND COMPILER OPTIMIZATIONS. This patch contains support for a basic DDGs containing only atomic nodes (one node for each instruction). The edges are two fold: def-use edges and memory-dependence edges. The implementation takes a list of basic-blocks and only considers dependencies among instructions in those basic blocks. Any dependencies coming into or going out of instructions that do not belong to those basic blocks are ignored. The algorithm for building the graph involves the following steps in order: 1. For each instruction in the range of basic blocks to consider, create an atomic node in the resulting graph. 2. For each node in the graph establish def-use edges to/from other nodes in the graph. 3. For each pair of nodes containing memory instruction(s) create memory edges between them. This part of the algorithm goes through the instructions in lexicographical order and creates edges in reverse order if the sink of the dependence occurs before the source of it. Authored By: bmahjour Reviewer: Meinersbur, fhahn, myhsu, xtian, dmgreen, kbarton, jdoerfert Reviewed By: Meinersbur, fhahn, myhsu Subscribers: ychen, arphaman, simoll, a.elovikov, mgorny, hiraditya, jfb, wuzish, llvm-commits, jsji, Whitney, etiotto Tag: #llvm Differential Revision: https://reviews.llvm.org/D65350 llvm-svn: 372238 --- docs/DependenceGraphs/cycle.png | Bin 0 -> 46831 bytes docs/DependenceGraphs/cycle_pi.png | Bin 0 -> 47148 bytes docs/DependenceGraphs/index.rst | 140 ++++++ docs/DependenceGraphs/uml_builder_pattern.png | Bin 0 -> 77125 bytes docs/DependenceGraphs/uml_nodes_and_edges.png | Bin 0 -> 51501 bytes docs/SubsystemDocumentation.rst | 7 +- include/llvm/Analysis/DDG.h | 372 +++++++++++++++ .../llvm/Analysis/DependenceGraphBuilder.h | 108 +++++ lib/Analysis/CMakeLists.txt | 2 + lib/Analysis/DDG.cpp | 181 ++++++++ lib/Analysis/DependenceGraphBuilder.cpp | 200 ++++++++ lib/Passes/PassBuilder.cpp | 1 + lib/Passes/PassRegistry.def | 2 + test/Analysis/DDG/basic-a.ll | 189 ++++++++ test/Analysis/DDG/basic-b.ll | 216 +++++++++ test/Analysis/DDG/basic-loopnest.ll | 434 ++++++++++++++++++ 16 files changed, 1851 insertions(+), 1 deletion(-) create mode 100644 docs/DependenceGraphs/cycle.png create mode 100644 docs/DependenceGraphs/cycle_pi.png create mode 100644 docs/DependenceGraphs/index.rst create mode 100644 docs/DependenceGraphs/uml_builder_pattern.png create mode 100644 docs/DependenceGraphs/uml_nodes_and_edges.png create mode 100644 include/llvm/Analysis/DDG.h create mode 100644 include/llvm/Analysis/DependenceGraphBuilder.h create mode 100644 lib/Analysis/DDG.cpp create mode 100644 lib/Analysis/DependenceGraphBuilder.cpp create mode 100644 test/Analysis/DDG/basic-a.ll create mode 100644 test/Analysis/DDG/basic-b.ll create mode 100644 test/Analysis/DDG/basic-loopnest.ll diff --git a/docs/DependenceGraphs/cycle.png b/docs/DependenceGraphs/cycle.png new file mode 100644 index 0000000000000000000000000000000000000000..8099c4166544db1feb39508cb66f8f35bcddb89f GIT binary patch literal 46831 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

>*#+5?VYAWblNp~4=El}xOu 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�%MIIO#oZoWZ^6b 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 Ll0>l literal 0 HcmV?d00001 diff --git a/docs/DependenceGraphs/cycle_pi.png b/docs/DependenceGraphs/cycle_pi.png new file mode 100644 index 0000000000000000000000000000000000000000..ce69fd36a079922e5718e857918dc63e44cb55b7 GIT binary patch literal 47148 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ⅈ6tF{rVDW! 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 literal 0 HcmV?d00001 diff --git a/docs/DependenceGraphs/index.rst b/docs/DependenceGraphs/index.rst new file mode 100644 index 00000000000..c53ee9051d5 --- /dev/null +++ b/docs/DependenceGraphs/index.rst @@ -0,0 +1,140 @@ +========================= +Dependence Graphs in LLVM +========================= + +.. contents:: + :local: + +Introduction +============ +Dependence graphs are useful tools in compilers for analyzing relationships +between various program elements to help guide optimizations. The ideas +behind these graphs are described in papers [1]_ and [2]_. + +The implementation of these ideas in LLVM may be slightly different than +what is mentioned in the papers. These differences are documented in +the `implementation details `_. + +.. _DataDependenceGraph: + +Data Dependence Graph +===================== +In its simplest form the Data Dependence Graph (or DDG) represents data +dependencies between individual instructions. Each node in such a graph +represents a single instruction and is referred to as an "atomic" node. +It is also possible to combine some atomic nodes that have a simple +def-use dependency between them into larger nodes that contain multiple- +instructions. + +As described in [1]_ the DDG uses graph abstraction to group nodes +that are part of a strongly connected component of the graph +into special nodes called pi-blocks. pi-blocks represent cycles of data +dependency that prevent reordering transformations. Since any strongly +connected component of the graph is a maximal subgraph of all the nodes +that form a cycle, pi-blocks are at most one level deep. In other words, +no pi-blocks are nested inside another pi-block, resulting in a +hierarchical representation that is at most one level deep. + + +For example, consider the following: + +.. code-block:: c++ + + for (int i = 1; i < n; i++) { + b[i] = c[i] + b[i-1]; + } + +This code contains a statement that has a loop carried dependence on +itself creating a cycle in the DDG. The figure bellow illustrates +how the cycle of dependency is carried through multiple def-use relations +and a memory access dependency. + +.. image:: cycle.png + +The DDG corresponding to this example would have a pi-block that contains +all the nodes participating in the cycle, as shown bellow: + +.. image:: cycle_pi.png + +Program Dependence Graph +======================== + +The Program Dependence Graph (or PDG) has a similar structure as the +DDG, but it is capable of representing both data dependencies and +control-flow dependencies between program elements such as +instructions, groups of instructions, basic blocks or groups of +basic blocks. + +High-Level Design +================= + +The DDG and the PDG are both directed graphs and they extend the +``DirectedGraph`` class. Each implementation extends its corresponding +node and edge types resulting in the inheritance relationship depicted +in the UML diagram bellow: + +.. image:: uml_nodes_and_edges.png + +Graph Construction +------------------ + +The graph build algorithm considers dependencies between elements of +a given set of instructions or basic blocks. Any dependencies coming +into or going out of instructions that do not belong to that range +are ignored. The steps in the build algorithm for the DDG are very +similar to the steps in the build algorithm for the PDG. As such, +one of the design goals is to reuse the build algorithm code to +allow creation of both DDG and PDG representations while allowing +the two implementations to define their own distinct and independent +node and edge types. This is achieved by using the well-known builder +design pattern to isolate the construction of the dependence graph +from its concrete representation. + +The following UML diagram depicts the overall structure of the design +pattern as it applies to the dependence graph implementation. + +.. image:: uml_builder_pattern.png + +Notice that the common code for building the two types of graphs are +provided in the ``DependenceGraphBuilder`` class, while the ``DDGBuilder`` +and ``PDGBuilder`` control some aspects of how the graph is constructed +by the way of overriding virtual methods defined in ``DependenceGraphBuilder``. + +Note also that the steps and the names used in this diagram are for +illustrative purposes and may be different from those in the actual +implementation. + +Design Trade-offs +----------------- + +Advantages: +^^^^^^^^^^^ + - Builder allows graph construction code to be reused for DDG and PDG. + - Builder allows us to create DDG and PDG as separate graphs. + - DDG nodes and edges are completely disjoint from PDG nodes and edges allowing them to change easily and independently. + +Disadvantages: +^^^^^^^^^^^^^^ + - Builder may be perceived as over-engineering at first. + - There are some similarities between DDG nodes and edges compared to PDG nodes and edges, but there is little reuse of the class definitions. + + - This is tolerable given that the node and edge types are fairly simple and there is little code reuse opportunity anyway. + + +.. _implementation-details: + +Implementation Details +====================== + +The current implementation of DDG differs slightly from the dependence +graph described in [1]_ in the following ways: + + 1. The graph nodes in the paper represent three main program components, namely *assignment statements*, *for loop headers* and *while loop headers*. In this implementation, DDG nodes naturally represent LLVM IR instructions. An assignment statement in this implementation typically involves a node representing the ``store`` instruction along with a number of individual nodes computing the right-hand-side of the assignment that connect to the ``store`` node via a def-use edge. The loop header instructions are not represented as special nodes in this implementation because they have limited uses and can be easily identified, for example, through ``LoopAnalysis``. + 2. The paper describes five types of dependency edges between nodes namely *loop dependency*, *flow-*, *anti-*, *output-*, and *input-* dependencies. In this implementation *memory* edges represent the *flow-*, *anti-*, *output-*, and *input-* dependencies. However, *loop dependencies* are not made explicit, because they mainly represent association between a loop structure and the program elements inside the loop and this association is fairly obvious in LLVM IR itself. + 3. The paper describes two types of pi-blocks; *recurrences* whose bodies are SCCs and *IN* nodes whose bodies are not part of any SCC. In this impelmentation, pi-blocks are only created for *recurrences*. *IN* nodes remain as simple DDG nodes in the graph. + + +References +---------- +.. [1] "D. J. Kuck, R. H. Kuhn, D. A. Padua, B. Leasure, and M. Wolfe (1981). DEPENDENCE GRAPHS AND COMPILER OPTIMIZATIONS." +.. [2] "J. FERRANTE (IBM), K. J. OTTENSTEIN (Michigan Technological University) and JOE D. WARREN (Rice University), 1987. The Program Dependence Graph and Its Use in Optimization." diff --git a/docs/DependenceGraphs/uml_builder_pattern.png b/docs/DependenceGraphs/uml_builder_pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..1651f9141de5146d418c26b8c48c935beb487c18 GIT binary patch literal 77125 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 L`njxgN@xNAxEl<) literal 0 HcmV?d00001 diff --git a/docs/DependenceGraphs/uml_nodes_and_edges.png b/docs/DependenceGraphs/uml_nodes_and_edges.png new file mode 100644 index 0000000000000000000000000000000000000000..c0ffacafca70960dd8c3257c4dd790a565d71b37 GIT binary patch literal 51501 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 + A description of the design of the various dependence graphs such as + the DDG (Data Dependence Graph). diff --git a/include/llvm/Analysis/DDG.h b/include/llvm/Analysis/DDG.h new file mode 100644 index 00000000000..9f28c3178fc --- /dev/null +++ b/include/llvm/Analysis/DDG.h @@ -0,0 +1,372 @@ +//===- llvm/Analysis/DDG.h --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the Data-Dependence Graph (DDG). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_DDG_H +#define LLVM_ANALYSIS_DDG_H + +#include "llvm/ADT/DirectedGraph.h" +#include "llvm/Analysis/DependenceAnalysis.h" +#include "llvm/Analysis/DependenceGraphBuilder.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/IR/Instructions.h" +#include "llvm/Transforms/Scalar/LoopPassManager.h" +#include + +namespace llvm { +class DDGNode; +class DDGEdge; +using DDGNodeBase = DGNode; +using DDGEdgeBase = DGEdge; +using DDGBase = DirectedGraph; + +/// Data Dependence Graph Node +/// The graph can represent the following types of nodes: +/// 1. Single instruction node containing just one instruction. +/// 2. Multiple instruction node where two or more instructions from +/// the same basic block are merged into one node. +class DDGNode : public DDGNodeBase { +public: + using InstructionListType = SmallVectorImpl; + + enum class NodeKind { + Unknown, + SingleInstruction, + MultiInstruction, + }; + + DDGNode() = delete; + DDGNode(const NodeKind K) : DDGNodeBase(), Kind(K) {} + DDGNode(const DDGNode &N) : DDGNodeBase(N), Kind(N.Kind) {} + DDGNode(DDGNode &&N) : DDGNodeBase(std::move(N)), Kind(N.Kind) {} + virtual ~DDGNode() = 0; + + DDGNode &operator=(const DDGNode &N) { + DGNode::operator=(N); + Kind = N.Kind; + return *this; + } + + DDGNode &operator=(DDGNode &&N) { + DGNode::operator=(std::move(N)); + Kind = N.Kind; + return *this; + } + + /// Getter for the kind of this node. + NodeKind getKind() const { return Kind; } + + /// Collect a list of instructions, in \p IList, for which predicate \p Pred + /// evaluates to true when iterating over instructions of this node. Return + /// true if at least one instruction was collected, and false otherwise. + bool collectInstructions(llvm::function_ref const &Pred, + InstructionListType &IList) const; + +protected: + /// Setter for the kind of this node. + void setKind(NodeKind K) { Kind = K; } + +private: + NodeKind Kind; +}; + +/// Subclass of DDGNode representing single or multi-instruction nodes. +class SimpleDDGNode : public DDGNode { +public: + SimpleDDGNode() = delete; + SimpleDDGNode(Instruction &I); + SimpleDDGNode(const SimpleDDGNode &N); + SimpleDDGNode(SimpleDDGNode &&N); + ~SimpleDDGNode(); + + SimpleDDGNode &operator=(const SimpleDDGNode &N) { + DDGNode::operator=(N); + InstList = N.InstList; + return *this; + } + + SimpleDDGNode &operator=(SimpleDDGNode &&N) { + DDGNode::operator=(std::move(N)); + InstList = std::move(N.InstList); + return *this; + } + + /// Get the list of instructions in this node. + const InstructionListType &getInstructions() const { + assert(!InstList.empty() && "Instruction List is empty."); + return InstList; + } + InstructionListType &getInstructions() { + return const_cast( + static_cast(this)->getInstructions()); + } + + /// Get the first/last instruction in the node. + Instruction *getFirstInstruction() const { return getInstructions().front(); } + Instruction *getLastInstruction() const { return getInstructions().back(); } + + /// Define classof to be able to use isa<>, cast<>, dyn_cast<>, etc. + static bool classof(const DDGNode *N) { + return N->getKind() == NodeKind::SingleInstruction || + N->getKind() == NodeKind::MultiInstruction; + } + static bool classof(const SimpleDDGNode *N) { return true; } + +private: + /// Append the list of instructions in \p Input to this node. + void appendInstructions(const InstructionListType &Input) { + setKind((InstList.size() == 0 && Input.size() == 1) + ? NodeKind::SingleInstruction + : NodeKind::MultiInstruction); + InstList.insert(InstList.end(), Input.begin(), Input.end()); + } + void appendInstructions(const SimpleDDGNode &Input) { + appendInstructions(Input.getInstructions()); + } + + /// List of instructions associated with a single or multi-instruction node. + SmallVector InstList; +}; + +/// Data Dependency Graph Edge. +/// An edge in the DDG can represent a def-use relationship or +/// a memory dependence based on the result of DependenceAnalysis. +class DDGEdge : public DDGEdgeBase { +public: + /// The kind of edge in the DDG + enum class EdgeKind { Unknown, RegisterDefUse, MemoryDependence }; + + explicit DDGEdge(DDGNode &N) = delete; + DDGEdge(DDGNode &N, EdgeKind K) : DDGEdgeBase(N), Kind(K) {} + DDGEdge(const DDGEdge &E) : DDGEdgeBase(E), Kind(E.getKind()) {} + DDGEdge(DDGEdge &&E) : DDGEdgeBase(std::move(E)), Kind(E.Kind) {} + DDGEdge &operator=(const DDGEdge &E) { + DDGEdgeBase::operator=(E); + Kind = E.Kind; + return *this; + } + + DDGEdge &operator=(DDGEdge &&E) { + DDGEdgeBase::operator=(std::move(E)); + Kind = E.Kind; + return *this; + } + + /// Get the edge kind + EdgeKind getKind() const { return Kind; }; + + /// Return true if this is a def-use edge, and false otherwise. + bool isDefUse() const { return Kind == EdgeKind::RegisterDefUse; } + + /// Return true if this is a memory dependence edge, and false otherwise. + bool isMemoryDependence() const { return Kind == EdgeKind::MemoryDependence; } + +private: + EdgeKind Kind; +}; + +/// Encapsulate some common data and functionality needed for different +/// variations of data dependence graphs. +template class DependenceGraphInfo { +public: + using DependenceList = SmallVector, 1>; + + DependenceGraphInfo() = delete; + DependenceGraphInfo(const DependenceGraphInfo &G) = delete; + DependenceGraphInfo(const std::string &N, const DependenceInfo &DepInfo) + : Name(N), DI(DepInfo) {} + DependenceGraphInfo(DependenceGraphInfo &&G) + : Name(std::move(G.Name)), DI(std::move(G.DI)) {} + virtual ~DependenceGraphInfo() {} + + /// Return the label that is used to name this graph. + const StringRef getName() const { return Name; } + +protected: + // Name of the graph. + std::string Name; + + // Store a copy of DependenceInfo in the graph, so that individual memory + // dependencies don't need to be stored. Instead when the dependence is + // queried it is recomputed using @DI. + const DependenceInfo DI; +}; + +using DDGInfo = DependenceGraphInfo; + +/// Data Dependency Graph +class DataDependenceGraph : public DDGBase, public DDGInfo { + friend class DDGBuilder; + +public: + using NodeType = DDGNode; + using EdgeType = DDGEdge; + + DataDependenceGraph() = delete; + DataDependenceGraph(const DataDependenceGraph &G) = delete; + DataDependenceGraph(DataDependenceGraph &&G) + : DDGBase(std::move(G)), DDGInfo(std::move(G)) {} + DataDependenceGraph(Function &F, DependenceInfo &DI); + DataDependenceGraph(const Loop &L, DependenceInfo &DI); + ~DataDependenceGraph(); +}; + +/// Concrete implementation of a pure data dependence graph builder. This class +/// provides custom implementation for the pure-virtual functions used in the +/// generic dependence graph build algorithm. +/// +/// For information about time complexity of the build algorithm see the +/// comments near the declaration of AbstractDependenceGraphBuilder. +class DDGBuilder : public AbstractDependenceGraphBuilder { +public: + DDGBuilder(DataDependenceGraph &G, DependenceInfo &D, + const BasicBlockListType &BBs) + : AbstractDependenceGraphBuilder(G, D, BBs) {} + DDGNode &createFineGrainedNode(Instruction &I) final override { + auto *SN = new SimpleDDGNode(I); + assert(SN && "Failed to allocate memory for simple DDG node."); + Graph.addNode(*SN); + return *SN; + } + DDGEdge &createDefUseEdge(DDGNode &Src, DDGNode &Tgt) final override { + auto *E = new DDGEdge(Tgt, DDGEdge::EdgeKind::RegisterDefUse); + assert(E && "Failed to allocate memory for edge"); + Graph.connect(Src, Tgt, *E); + return *E; + } + DDGEdge &createMemoryEdge(DDGNode &Src, DDGNode &Tgt) final override { + auto *E = new DDGEdge(Tgt, DDGEdge::EdgeKind::MemoryDependence); + assert(E && "Failed to allocate memory for edge"); + Graph.connect(Src, Tgt, *E); + return *E; + } +}; + +raw_ostream &operator<<(raw_ostream &OS, const DDGNode &N); +raw_ostream &operator<<(raw_ostream &OS, const DDGNode::NodeKind K); +raw_ostream &operator<<(raw_ostream &OS, const DDGEdge &E); +raw_ostream &operator<<(raw_ostream &OS, const DDGEdge::EdgeKind K); +raw_ostream &operator<<(raw_ostream &OS, const DataDependenceGraph &G); + +//===--------------------------------------------------------------------===// +// DDG Analysis Passes +//===--------------------------------------------------------------------===// + +/// Analysis pass that builds the DDG for a loop. +class DDGAnalysis : public AnalysisInfoMixin { +public: + using Result = std::unique_ptr; + Result run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR); + +private: + friend AnalysisInfoMixin; + static AnalysisKey Key; +}; + +/// Textual printer pass for the DDG of a loop. +class DDGAnalysisPrinterPass : public PassInfoMixin { +public: + explicit DDGAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {} + PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, LPMUpdater &U); + +private: + raw_ostream &OS; +}; + +//===--------------------------------------------------------------------===// +// GraphTraits specializations for the DDG +//===--------------------------------------------------------------------===// + +/// non-const versions of the grapth trait specializations for DDG +template <> struct GraphTraits { + using NodeRef = DDGNode *; + + static DDGNode *DDGGetTargetNode(DGEdge *P) { + return &P->getTargetNode(); + } + + // Provide a mapped iterator so that the GraphTrait-based implementations can + // find the target nodes without having to explicitly go through the edges. + using ChildIteratorType = + mapped_iterator; + using ChildEdgeIteratorType = DDGNode::iterator; + + static NodeRef getEntryNode(NodeRef N) { return N; } + static ChildIteratorType child_begin(NodeRef N) { + return ChildIteratorType(N->begin(), &DDGGetTargetNode); + } + static ChildIteratorType child_end(NodeRef N) { + return ChildIteratorType(N->end(), &DDGGetTargetNode); + } + + static ChildEdgeIteratorType child_edge_begin(NodeRef N) { + return N->begin(); + } + static ChildEdgeIteratorType child_edge_end(NodeRef N) { return N->end(); } +}; + +template <> +struct GraphTraits : public GraphTraits { + using nodes_iterator = DataDependenceGraph::iterator; + static NodeRef getEntryNode(DataDependenceGraph *DG) { return *DG->begin(); } + static nodes_iterator nodes_begin(DataDependenceGraph *DG) { + return DG->begin(); + } + static nodes_iterator nodes_end(DataDependenceGraph *DG) { return DG->end(); } +}; + +/// const versions of the grapth trait specializations for DDG +template <> struct GraphTraits { + using NodeRef = const DDGNode *; + + static const DDGNode *DDGGetTargetNode(const DGEdge *P) { + return &P->getTargetNode(); + } + + // Provide a mapped iterator so that the GraphTrait-based implementations can + // find the target nodes without having to explicitly go through the edges. + using ChildIteratorType = + mapped_iterator; + using ChildEdgeIteratorType = DDGNode::const_iterator; + + static NodeRef getEntryNode(NodeRef N) { return N; } + static ChildIteratorType child_begin(NodeRef N) { + return ChildIteratorType(N->begin(), &DDGGetTargetNode); + } + static ChildIteratorType child_end(NodeRef N) { + return ChildIteratorType(N->end(), &DDGGetTargetNode); + } + + static ChildEdgeIteratorType child_edge_begin(NodeRef N) { + return N->begin(); + } + static ChildEdgeIteratorType child_edge_end(NodeRef N) { return N->end(); } +}; + +template <> +struct GraphTraits + : public GraphTraits { + using nodes_iterator = DataDependenceGraph::const_iterator; + static NodeRef getEntryNode(const DataDependenceGraph *DG) { + return *DG->begin(); + } + static nodes_iterator nodes_begin(const DataDependenceGraph *DG) { + return DG->begin(); + } + static nodes_iterator nodes_end(const DataDependenceGraph *DG) { + return DG->end(); + } +}; + +} // namespace llvm + +#endif // LLVM_ANALYSIS_DDG_H diff --git a/include/llvm/Analysis/DependenceGraphBuilder.h b/include/llvm/Analysis/DependenceGraphBuilder.h new file mode 100644 index 00000000000..b61aeb645a5 --- /dev/null +++ b/include/llvm/Analysis/DependenceGraphBuilder.h @@ -0,0 +1,108 @@ +//===- llvm/Analysis/DependenceGraphBuilder.h -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines a builder interface that can be used to populate dependence +// graphs such as DDG and PDG. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_DEPENDENCE_GRAPH_BUILDER_H +#define LLVM_ANALYSIS_DEPENDENCE_GRAPH_BUILDER_H + +#include "llvm/ADT/EquivalenceClasses.h" +#include "llvm/Analysis/DependenceAnalysis.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Instructions.h" + +namespace llvm { + +/// This abstract builder class defines a set of high-level steps for creating +/// DDG-like graphs. The client code is expected to inherit from this class and +/// define concrete implementation for each of the pure virtual functions used +/// in the high-level algorithm. +template class AbstractDependenceGraphBuilder { +protected: + using BasicBlockListType = SmallVectorImpl; + +private: + using NodeType = typename GraphType::NodeType; + using EdgeType = typename GraphType::EdgeType; + +public: + using ClassesType = EquivalenceClasses; + using NodeListType = SmallVector; + + AbstractDependenceGraphBuilder(GraphType &G, DependenceInfo &D, + const BasicBlockListType &BBs) + : Graph(G), DI(D), BBList(BBs) {} + virtual ~AbstractDependenceGraphBuilder() {} + + /// The main entry to the graph construction algorithm. It starts by + /// creating nodes in increasing order of granularity and then + /// adds def-use and memory edges. + /// + /// The algorithmic complexity of this implementation is O(V^2 * I^2), where V + /// is the number of vertecies (nodes) and I is the number of instructions in + /// each node. The total number of instructions, N, is equal to V * I, + /// therefore the worst-case time complexity is O(N^2). The average time + /// complexity is O((N^2)/2). + void populate() { + createFineGrainedNodes(); + createDefUseEdges(); + createMemoryDependencyEdges(); + } + + /// Create fine grained nodes. These are typically atomic nodes that + /// consist of a single instruction. + void createFineGrainedNodes(); + + /// Analyze the def-use chains and create edges from the nodes containing + /// definitions to the nodes containing the uses. + void createDefUseEdges(); + + /// Analyze data dependencies that exist between memory loads or stores, + /// in the graph nodes and create edges between them. + void createMemoryDependencyEdges(); + +protected: + /// Create an atomic node in the graph given a single instruction. + virtual NodeType &createFineGrainedNode(Instruction &I) = 0; + + /// Create a def-use edge going from \p Src to \p Tgt. + virtual EdgeType &createDefUseEdge(NodeType &Src, NodeType &Tgt) = 0; + + /// Create a memory dependence edge going from \p Src to \p Tgt. + virtual EdgeType &createMemoryEdge(NodeType &Src, NodeType &Tgt) = 0; + + /// Deallocate memory of edge \p E. + virtual void destroyEdge(EdgeType &E) { delete &E; } + + /// Deallocate memory of node \p N. + virtual void destroyNode(NodeType &N) { delete &N; } + + /// Map types to map instructions to nodes used when populating the graph. + using InstToNodeMap = DenseMap; + + /// Reference to the graph that gets built by a concrete implementation of + /// this builder. + GraphType &Graph; + + /// Dependence information used to create memory dependence edges in the + /// graph. + DependenceInfo &DI; + + /// The list of basic blocks to consider when building the graph. + const BasicBlockListType &BBList; + + /// A mapping from instructions to the corresponding nodes in the graph. + InstToNodeMap IMap; +}; + +} // namespace llvm + +#endif // LLVM_ANALYSIS_DEPENDENCE_GRAPH_BUILDER_H diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt index 1dc9544120e..3d4920e5ead 100644 --- a/lib/Analysis/CMakeLists.txt +++ b/lib/Analysis/CMakeLists.txt @@ -22,9 +22,11 @@ add_llvm_library(LLVMAnalysis CostModel.cpp CodeMetrics.cpp ConstantFolding.cpp + DDG.cpp Delinearization.cpp DemandedBits.cpp DependenceAnalysis.cpp + DependenceGraphBuilder.cpp DivergenceAnalysis.cpp DomPrinter.cpp DomTreeUpdater.cpp diff --git a/lib/Analysis/DDG.cpp b/lib/Analysis/DDG.cpp new file mode 100644 index 00000000000..29778b3e0d6 --- /dev/null +++ b/lib/Analysis/DDG.cpp @@ -0,0 +1,181 @@ +//===- DDG.cpp - Data Dependence Graph -------------------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// The implementation for the data dependence graph. +//===----------------------------------------------------------------------===// +#include "llvm/Analysis/DDG.h" +#include "llvm/Analysis/LoopInfo.h" + +using namespace llvm; + +#define DEBUG_TYPE "ddg" + +template class llvm::DGEdge; +template class llvm::DGNode; +template class llvm::DirectedGraph; + +//===--------------------------------------------------------------------===// +// DDGNode implementation +//===--------------------------------------------------------------------===// +DDGNode::~DDGNode() {} + +bool DDGNode::collectInstructions( + llvm::function_ref const &Pred, + InstructionListType &IList) const { + assert(IList.empty() && "Expected the IList to be empty on entry."); + if (isa(this)) { + for (auto *I : cast(this)->getInstructions()) + if (Pred(I)) + IList.push_back(I); + } else + llvm_unreachable("unimplemented type of node"); + return !IList.empty(); +} + +raw_ostream &llvm::operator<<(raw_ostream &OS, const DDGNode::NodeKind K) { + const char *Out; + switch (K) { + case DDGNode::NodeKind::SingleInstruction: + Out = "single-instruction"; + break; + case DDGNode::NodeKind::MultiInstruction: + Out = "multi-instruction"; + break; + case DDGNode::NodeKind::Unknown: + Out = "??"; + break; + } + OS << Out; + return OS; +} + +raw_ostream &llvm::operator<<(raw_ostream &OS, const DDGNode &N) { + OS << "Node Address:" << &N << ":" << N.getKind() << "\n"; + if (isa(N)) { + OS << " Instructions:\n"; + for (auto *I : cast(N).getInstructions()) + OS.indent(2) << *I << "\n"; + } else + llvm_unreachable("unimplemented type of node"); + + OS << (N.getEdges().empty() ? " Edges:none!\n" : " Edges:\n"); + for (auto &E : N.getEdges()) + OS.indent(2) << *E; + return OS; +} + +//===--------------------------------------------------------------------===// +// SimpleDDGNode implementation +//===--------------------------------------------------------------------===// + +SimpleDDGNode::SimpleDDGNode(Instruction &I) + : DDGNode(NodeKind::SingleInstruction), InstList() { + assert(InstList.empty() && "Expected empty list."); + InstList.push_back(&I); +} + +SimpleDDGNode::SimpleDDGNode(const SimpleDDGNode &N) + : DDGNode(N), InstList(N.InstList) { + assert(((getKind() == NodeKind::SingleInstruction && InstList.size() == 1) || + (getKind() == NodeKind::MultiInstruction && InstList.size() > 1)) && + "constructing from invalid simple node."); +} + +SimpleDDGNode::SimpleDDGNode(SimpleDDGNode &&N) + : DDGNode(std::move(N)), InstList(std::move(N.InstList)) { + assert(((getKind() == NodeKind::SingleInstruction && InstList.size() == 1) || + (getKind() == NodeKind::MultiInstruction && InstList.size() > 1)) && + "constructing from invalid simple node."); +} + +SimpleDDGNode::~SimpleDDGNode() { InstList.clear(); } + +//===--------------------------------------------------------------------===// +// DDGEdge implementation +//===--------------------------------------------------------------------===// + +raw_ostream &llvm::operator<<(raw_ostream &OS, const DDGEdge::EdgeKind K) { + const char *Out; + switch (K) { + case DDGEdge::EdgeKind::RegisterDefUse: + Out = "def-use"; + break; + case DDGEdge::EdgeKind::MemoryDependence: + Out = "memory"; + break; + case DDGEdge::EdgeKind::Unknown: + Out = "??"; + break; + } + OS << Out; + return OS; +} + +raw_ostream &llvm::operator<<(raw_ostream &OS, const DDGEdge &E) { + OS << "[" << E.getKind() << "] to " << &E.getTargetNode() << "\n"; + return OS; +} + +//===--------------------------------------------------------------------===// +// DataDependenceGraph implementation +//===--------------------------------------------------------------------===// +using BasicBlockListType = SmallVector; + +DataDependenceGraph::DataDependenceGraph(Function &F, DependenceInfo &D) + : DependenceGraphInfo(F.getName().str(), D) { + BasicBlockListType BBList; + for (auto &BB : F.getBasicBlockList()) + BBList.push_back(&BB); + DDGBuilder(*this, D, BBList).populate(); +} + +DataDependenceGraph::DataDependenceGraph(const Loop &L, DependenceInfo &D) + : DependenceGraphInfo(Twine(L.getHeader()->getParent()->getName() + "." + + L.getHeader()->getName()) + .str(), + D) { + BasicBlockListType BBList; + for (BasicBlock *BB : L.blocks()) + BBList.push_back(BB); + DDGBuilder(*this, D, BBList).populate(); +} + +DataDependenceGraph::~DataDependenceGraph() { + for (auto *N : Nodes) { + for (auto *E : *N) + delete E; + delete N; + } +} + +raw_ostream &llvm::operator<<(raw_ostream &OS, const DataDependenceGraph &G) { + for (auto *Node : G) + OS << *Node << "\n"; + return OS; +} + +//===--------------------------------------------------------------------===// +// DDG Analysis Passes +//===--------------------------------------------------------------------===// + +/// DDG as a loop pass. +DDGAnalysis::Result DDGAnalysis::run(Loop &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR) { + Function *F = L.getHeader()->getParent(); + DependenceInfo DI(F, &AR.AA, &AR.SE, &AR.LI); + return std::make_unique(L, DI); +} +AnalysisKey DDGAnalysis::Key; + +PreservedAnalyses DDGAnalysisPrinterPass::run(Loop &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, + LPMUpdater &U) { + OS << "'DDG' for loop '" << L.getHeader()->getName() << "':\n"; + OS << *AM.getResult(L, AR); + return PreservedAnalyses::all(); +} diff --git a/lib/Analysis/DependenceGraphBuilder.cpp b/lib/Analysis/DependenceGraphBuilder.cpp new file mode 100644 index 00000000000..ed21cc7134f --- /dev/null +++ b/lib/Analysis/DependenceGraphBuilder.cpp @@ -0,0 +1,200 @@ +//===- DependenceGraphBuilder.cpp ------------------------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// This file implements common steps of the build algorithm for construction +// of dependence graphs such as DDG and PDG. +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/DependenceGraphBuilder.h" +#include "llvm/ADT/SCCIterator.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/DDG.h" + +using namespace llvm; + +#define DEBUG_TYPE "dgb" + +STATISTIC(TotalGraphs, "Number of dependence graphs created."); +STATISTIC(TotalDefUseEdges, "Number of def-use edges created."); +STATISTIC(TotalMemoryEdges, "Number of memory dependence edges created."); +STATISTIC(TotalFineGrainedNodes, "Number of fine-grained nodes created."); +STATISTIC(TotalConfusedEdges, + "Number of confused memory dependencies between two nodes."); +STATISTIC(TotalEdgeReversals, + "Number of times the source and sink of dependence was reversed to " + "expose cycles in the graph."); + +using InstructionListType = SmallVector; + +//===--------------------------------------------------------------------===// +// AbstractDependenceGraphBuilder implementation +//===--------------------------------------------------------------------===// + +template +void AbstractDependenceGraphBuilder::createFineGrainedNodes() { + ++TotalGraphs; + assert(IMap.empty() && "Expected empty instruction map at start"); + for (BasicBlock *BB : BBList) + for (Instruction &I : *BB) { + auto &NewNode = createFineGrainedNode(I); + IMap.insert(std::make_pair(&I, &NewNode)); + ++TotalFineGrainedNodes; + } +} + +template void AbstractDependenceGraphBuilder::createDefUseEdges() { + for (NodeType *N : Graph) { + InstructionListType SrcIList; + N->collectInstructions([](const Instruction *I) { return true; }, SrcIList); + + // Use a set to mark the targets that we link to N, so we don't add + // duplicate def-use edges when more than one instruction in a target node + // use results of instructions that are contained in N. + SmallPtrSet VisitedTargets; + + for (Instruction *II : SrcIList) { + for (User *U : II->users()) { + Instruction *UI = dyn_cast(U); + if (!UI) + continue; + NodeType *DstNode = nullptr; + if (IMap.find(UI) != IMap.end()) + DstNode = IMap.find(UI)->second; + + // In the case of loops, the scope of the subgraph is all the + // basic blocks (and instructions within them) belonging to the loop. We + // simply ignore all the edges coming from (or going into) instructions + // or basic blocks outside of this range. + if (!DstNode) { + LLVM_DEBUG( + dbgs() + << "skipped def-use edge since the sink" << *UI + << " is outside the range of instructions being considered.\n"); + continue; + } + + // Self dependencies are ignored because they are redundant and + // uninteresting. + if (DstNode == N) { + LLVM_DEBUG(dbgs() + << "skipped def-use edge since the sink and the source (" + << N << ") are the same.\n"); + continue; + } + + if (VisitedTargets.insert(DstNode).second) { + createDefUseEdge(*N, *DstNode); + ++TotalDefUseEdges; + } + } + } + } +} + +template +void AbstractDependenceGraphBuilder::createMemoryDependencyEdges() { + using DGIterator = typename G::iterator; + auto isMemoryAccess = [](const Instruction *I) { + return I->mayReadOrWriteMemory(); + }; + for (DGIterator SrcIt = Graph.begin(), E = Graph.end(); SrcIt != E; ++SrcIt) { + InstructionListType SrcIList; + (*SrcIt)->collectInstructions(isMemoryAccess, SrcIList); + if (SrcIList.empty()) + continue; + + for (DGIterator DstIt = SrcIt; DstIt != E; ++DstIt) { + if (**SrcIt == **DstIt) + continue; + InstructionListType DstIList; + (*DstIt)->collectInstructions(isMemoryAccess, DstIList); + if (DstIList.empty()) + continue; + bool ForwardEdgeCreated = false; + bool BackwardEdgeCreated = false; + for (Instruction *ISrc : SrcIList) { + for (Instruction *IDst : DstIList) { + auto D = DI.depends(ISrc, IDst, true); + if (!D) + continue; + + // If we have a dependence with its left-most non-'=' direction + // being '>' we need to reverse the direction of the edge, because + // the source of the dependence cannot occur after the sink. For + // confused dependencies, we will create edges in both directions to + // represent the possibility of a cycle. + + auto createConfusedEdges = [&](NodeType &Src, NodeType &Dst) { + if (!ForwardEdgeCreated) { + createMemoryEdge(Src, Dst); + ++TotalMemoryEdges; + } + if (!BackwardEdgeCreated) { + createMemoryEdge(Dst, Src); + ++TotalMemoryEdges; + } + ForwardEdgeCreated = BackwardEdgeCreated = true; + ++TotalConfusedEdges; + }; + + auto createForwardEdge = [&](NodeType &Src, NodeType &Dst) { + if (!ForwardEdgeCreated) { + createMemoryEdge(Src, Dst); + ++TotalMemoryEdges; + } + ForwardEdgeCreated = true; + }; + + auto createBackwardEdge = [&](NodeType &Src, NodeType &Dst) { + if (!BackwardEdgeCreated) { + createMemoryEdge(Dst, Src); + ++TotalMemoryEdges; + } + BackwardEdgeCreated = true; + }; + + if (D->isConfused()) + createConfusedEdges(**SrcIt, **DstIt); + else if (D->isOrdered() && !D->isLoopIndependent()) { + bool ReversedEdge = false; + for (unsigned Level = 1; Level <= D->getLevels(); ++Level) { + if (D->getDirection(Level) == Dependence::DVEntry::EQ) + continue; + else if (D->getDirection(Level) == Dependence::DVEntry::GT) { + createBackwardEdge(**SrcIt, **DstIt); + ReversedEdge = true; + ++TotalEdgeReversals; + break; + } else if (D->getDirection(Level) == Dependence::DVEntry::LT) + break; + else { + createConfusedEdges(**SrcIt, **DstIt); + break; + } + } + if (!ReversedEdge) + createForwardEdge(**SrcIt, **DstIt); + } else + createForwardEdge(**SrcIt, **DstIt); + + // Avoid creating duplicate edges. + if (ForwardEdgeCreated && BackwardEdgeCreated) + break; + } + + // If we've created edges in both directions, there is no more + // unique edge that we can create between these two nodes, so we + // can exit early. + if (ForwardEdgeCreated && BackwardEdgeCreated) + break; + } + } + } +} + +template class llvm::AbstractDependenceGraphBuilder; +template class llvm::DependenceGraphInfo; diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index 460992207e6..12c4dcb86ce 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -27,6 +27,7 @@ #include "llvm/Analysis/CFLSteensAliasAnalysis.h" #include "llvm/Analysis/CGSCCPassManager.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/DDG.h" #include "llvm/Analysis/DemandedBits.h" #include "llvm/Analysis/DependenceAnalysis.h" #include "llvm/Analysis/DominanceFrontier.h" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index b943e9c75ed..4cd05ee11f6 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -281,6 +281,7 @@ FUNCTION_PASS_WITH_PARAMS("mldst-motion", #endif LOOP_ANALYSIS("no-op-loop", NoOpLoopAnalysis()) LOOP_ANALYSIS("access-info", LoopAccessAnalysis()) +LOOP_ANALYSIS("ddg", DDGAnalysis()) LOOP_ANALYSIS("ivusers", IVUsersAnalysis()) LOOP_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC)) #undef LOOP_ANALYSIS @@ -303,6 +304,7 @@ LOOP_PASS("irce", IRCEPass()) LOOP_PASS("unroll-and-jam", LoopUnrollAndJamPass()) LOOP_PASS("unroll-full", LoopFullUnrollPass()) LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs())) +LOOP_PASS("print", DDGAnalysisPrinterPass(dbgs())) LOOP_PASS("print", IVUsersPrinterPass(dbgs())) LOOP_PASS("print", LoopCachePrinterPass(dbgs())) LOOP_PASS("loop-predication", LoopPredicationPass()) diff --git a/test/Analysis/DDG/basic-a.ll b/test/Analysis/DDG/basic-a.ll new file mode 100644 index 00000000000..4c05259a886 --- /dev/null +++ b/test/Analysis/DDG/basic-a.ll @@ -0,0 +1,189 @@ +; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s + +; CHECK-LABEL: 'DDG' for loop 'test1.for.body': +; CHECK: Node Address:[[N1:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %i.02 = phi i64 [ %inc, %test1.for.body ], [ 0, %test1.for.body.preheader ] +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N2:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N3:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N4:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N4]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N5:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N5]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %0 = load float, float* %arrayidx, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N6:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N7:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %conv = uitofp i64 %n to float +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N6]] + +; CHECK: Node Address:[[N6]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %add = fadd float %0, %conv +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N8:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N3]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx1 = getelementptr inbounds float, float* %a, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N8]] + +; CHECK: Node Address:[[N8]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: store float %add, float* %arrayidx1, align 4 +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N2]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %inc = add i64 %i.02, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N9:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N1]] + +; CHECK: Node Address:[[N9]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %exitcond = icmp ne i64 %inc, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N10:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N10]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %exitcond, label %test1.for.body, label %for.end.loopexit +; CHECK-NEXT: Edges:none! + +;; No memory dependencies. +;; void test1(unsigned long n, float * restrict a, float * restrict b) { +;; for (unsigned long i = 0; i < n; i++) +;; a[i] = b[i] + n; +;; } + +define void @test1(i64 %n, float* noalias %a, float* noalias %b) { +entry: + %exitcond1 = icmp ne i64 0, %n + br i1 %exitcond1, label %test1.for.body, label %for.end + +test1.for.body: ; preds = %entry, %test1.for.body + %i.02 = phi i64 [ %inc, %test1.for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02 + %0 = load float, float* %arrayidx, align 4 + %conv = uitofp i64 %n to float + %add = fadd float %0, %conv + %arrayidx1 = getelementptr inbounds float, float* %a, i64 %i.02 + store float %add, float* %arrayidx1, align 4 + %inc = add i64 %i.02, 1 + %exitcond = icmp ne i64 %inc, %n + br i1 %exitcond, label %test1.for.body, label %for.end + +for.end: ; preds = %test1.for.body, %entry + ret void +} + + +; CHECK-LABEL: 'DDG' for loop 'test2.for.body': +; CHECK: Node Address:[[N1:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %i.02 = phi i64 [ %inc, %test2.for.body ], [ 0, %test2.for.body.preheader ] +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N2:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N3:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N4:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N5:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N5]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N6:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N6]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %0 = load float, float* %arrayidx, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N4]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx1 = getelementptr inbounds float, float* %a, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N8:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N8]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %1 = load float, float* %arrayidx1, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7]] +; CHECK-NEXT: [memory] to [[N9:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N7]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %add = fadd float %0, %1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N9]] + +; CHECK: Node Address:[[N3]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx2 = getelementptr inbounds float, float* %a, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N9]] + +; CHECK: Node Address:[[N9]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: store float %add, float* %arrayidx2, align 4 +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N2]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %inc = add i64 %i.02, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N10:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N1]] + +; CHECK: Node Address:[[N10]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %exitcond = icmp ne i64 %inc, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N11:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N11]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %exitcond, label %test2.for.body, label %for.end.loopexit +; CHECK-NEXT: Edges:none! + +;; Loop-independent memory dependencies. +;; void test2(unsigned long n, float * restrict a, float * restrict b) { +;; for (unsigned long i = 0; i < n; i++) +;; a[i] = b[i] + a[i]; +;; } + +define void @test2(i64 %n, float* noalias %a, float* noalias %b) { +entry: + %exitcond1 = icmp ne i64 0, %n + br i1 %exitcond1, label %test2.for.body, label %for.end + +test2.for.body: ; preds = %entry, %test2.for.body + %i.02 = phi i64 [ %inc, %test2.for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02 + %0 = load float, float* %arrayidx, align 4 + %arrayidx1 = getelementptr inbounds float, float* %a, i64 %i.02 + %1 = load float, float* %arrayidx1, align 4 + %add = fadd float %0, %1 + %arrayidx2 = getelementptr inbounds float, float* %a, i64 %i.02 + store float %add, float* %arrayidx2, align 4 + %inc = add i64 %i.02, 1 + %exitcond = icmp ne i64 %inc, %n + br i1 %exitcond, label %test2.for.body, label %for.end + +for.end: ; preds = %test2.for.body, %entry + ret void +} \ No newline at end of file diff --git a/test/Analysis/DDG/basic-b.ll b/test/Analysis/DDG/basic-b.ll new file mode 100644 index 00000000000..2a90d028a6f --- /dev/null +++ b/test/Analysis/DDG/basic-b.ll @@ -0,0 +1,216 @@ +; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s + +; CHECK-LABEL: 'DDG' for loop 'test1.for.body': +; CHECK: Node Address:[[N1:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %i.02 = phi i64 [ %inc, %test1.for.body ], [ 1, %test1.for.body.preheader ] +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N2:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N3:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N4:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N5:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N5]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N6:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N6]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %0 = load float, float* %arrayidx, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N4]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %sub1 = add i64 %i.02, -1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N8:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N8]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx2 = getelementptr inbounds float, float* %a, i64 %sub1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N9:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N9]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %1 = load float, float* %arrayidx2, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7]] + +; CHECK: Node Address:[[N7]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %add = fadd float %0, %1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N10:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N3]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, float* %a, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N10]] + +; CHECK: Node Address:[[N10]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: store float %add, float* %arrayidx3, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [memory] to [[N9]] + +; CHECK: Node Address:[[N2]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %inc = add i64 %i.02, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N11:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N1]] + +; CHECK: Node Address:[[N11]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %cmp = icmp ult i64 %inc, %sub +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N12:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N12]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %cmp, label %test1.for.body, label %for.end.loopexit +; CHECK-NEXT: Edges:none! + +;; Loop-carried dependence requiring edge-reversal to expose a cycle +;; in the graph. +;; void test(unsigned long n, float * restrict a, float * restrict b) { +;; for (unsigned long i = 1; i < n-1; i++) +;; a[i] = b[i] + a[i-1]; +;; } + +define void @test1(i64 %n, float* noalias %a, float* noalias %b) { +entry: + %sub = add i64 %n, -1 + %cmp1 = icmp ult i64 1, %sub + br i1 %cmp1, label %test1.for.body, label %for.end + +test1.for.body: ; preds = %entry, %test1.for.body + %i.02 = phi i64 [ %inc, %test1.for.body ], [ 1, %entry ] + %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02 + %0 = load float, float* %arrayidx, align 4 + %sub1 = add i64 %i.02, -1 + %arrayidx2 = getelementptr inbounds float, float* %a, i64 %sub1 + %1 = load float, float* %arrayidx2, align 4 + %add = fadd float %0, %1 + %arrayidx3 = getelementptr inbounds float, float* %a, i64 %i.02 + store float %add, float* %arrayidx3, align 4 + %inc = add i64 %i.02, 1 + %cmp = icmp ult i64 %inc, %sub + br i1 %cmp, label %test1.for.body, label %for.end + +for.end: ; preds = %test1.for.body, %entry + ret void +} + + +; CHECK-LABEL: 'DDG' for loop 'test2.for.body': +; CHECK: Node Address:[[N1:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %i.02 = phi i64 [ %inc, %test2.for.body ], [ 1, %test2.for.body.preheader ] +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N2:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N3:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N4:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N5:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N5]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N6:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N6]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %0 = load float, float* %arrayidx, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N4]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %add1 = add i64 %i.02, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N8:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N8]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx2 = getelementptr inbounds float, float* %a, i64 %add1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N9:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N9]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %1 = load float, float* %arrayidx2, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7]] +; CHECK-NEXT: [memory] to [[N10:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N7]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %add = fadd float %0, %1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N10]] + +; CHECK: Node Address:[[N3]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, float* %a, i64 %i.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N10]] + +; CHECK: Node Address:[[N10]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: store float %add, float* %arrayidx3, align 4 +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N2]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %inc = add i64 %i.02, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N11:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N1]] + +; CHECK: Node Address:[[N11]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %cmp = icmp ult i64 %inc, %sub +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N12:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N12]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %cmp, label %test2.for.body, label %for.end.loopexit +; CHECK-NEXT: Edges:none! + + +;; Forward loop-carried dependence *not* causing a cycle. +;; void test2(unsigned long n, float * restrict a, float * restrict b) { +;; for (unsigned long i = 1; i < n-1; i++) +;; a[i] = b[i] + a[i+1]; +;; } + +define void @test2(i64 %n, float* noalias %a, float* noalias %b) { +entry: + %sub = add i64 %n, -1 + %cmp1 = icmp ult i64 1, %sub + br i1 %cmp1, label %test2.for.body, label %for.end + +test2.for.body: ; preds = %entry, %test2.for.body + %i.02 = phi i64 [ %inc, %test2.for.body ], [ 1, %entry ] + %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02 + %0 = load float, float* %arrayidx, align 4 + %add1 = add i64 %i.02, 1 + %arrayidx2 = getelementptr inbounds float, float* %a, i64 %add1 + %1 = load float, float* %arrayidx2, align 4 + %add = fadd float %0, %1 + %arrayidx3 = getelementptr inbounds float, float* %a, i64 %i.02 + store float %add, float* %arrayidx3, align 4 + %inc = add i64 %i.02, 1 + %cmp = icmp ult i64 %inc, %sub + br i1 %cmp, label %test2.for.body, label %for.end + +for.end: ; preds = %test2.for.body, %entry + ret void +} diff --git a/test/Analysis/DDG/basic-loopnest.ll b/test/Analysis/DDG/basic-loopnest.ll new file mode 100644 index 00000000000..a2abbf8c09b --- /dev/null +++ b/test/Analysis/DDG/basic-loopnest.ll @@ -0,0 +1,434 @@ +; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s + + +; CHECK-LABEL: 'DDG' for loop 'test1.for.cond1.preheader': +; CHECK: Node Address:[[N1:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %i.04 = phi i64 [ %inc13, %for.inc12 ], [ 0, %test1.for.cond1.preheader.preheader ] +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N2:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N3:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N4:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N5:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N6:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %sub = add i64 %n, -1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N8:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N8]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %cmp21 = icmp ult i64 1, %sub +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N9:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N9]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %cmp21, label %for.body4.preheader, label %for.inc12 +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N10:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %j.02 = phi i64 [ %inc, %for.body4 ], [ 1, %for.body4.preheader ] +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N11:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N12:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N13:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N14:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N5]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %0 = mul nsw i64 %i.04, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N15:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N15]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx = getelementptr inbounds float, float* %b, i64 %0 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N14]] + +; CHECK: Node Address:[[N14]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, float* %arrayidx, i64 %j.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N16:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N16]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %1 = load float, float* %arrayidx5, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N17:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N4]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %2 = mul nsw i64 %i.04, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N18:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N18]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx6 = getelementptr inbounds float, float* %a, i64 %2 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N19:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N13]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %sub7 = add i64 %j.02, -1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N19]] + +; CHECK: Node Address:[[N19]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx8 = getelementptr inbounds float, float* %arrayidx6, i64 %sub7 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N20:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N20]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %3 = load float, float* %arrayidx8, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N17]] + +; CHECK: Node Address:[[N17]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %add = fadd float %1, %3 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N26:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N3]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %4 = mul nsw i64 %i.04, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N27:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N27]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx10 = getelementptr inbounds float, float* %a, i64 %4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N12]] + +; CHECK: Node Address:[[N12]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx11 = getelementptr inbounds float, float* %arrayidx10, i64 %j.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N26]] + +; CHECK: Node Address:[[N26]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: store float %add, float* %arrayidx11, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [memory] to [[N20]] + +; CHECK: Node Address:[[N11]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %inc = add i64 %j.02, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7]] +; CHECK-NEXT: [def-use] to [[N10]] + +; CHECK: Node Address:[[N7]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %cmp2 = icmp ult i64 %inc, %sub +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N21:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N21]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %cmp2, label %for.body4, label %for.inc12.loopexit +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N2]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %inc13 = add i64 %i.04, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N22:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N1]] + +; CHECK: Node Address:[[N22]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %exitcond = icmp ne i64 %inc13, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N23:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N23]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %exitcond, label %test1.for.cond1.preheader, label %for.end14.loopexit +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N24:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br label %for.body4 +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N25:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br label %for.inc12 +; CHECK-NEXT: Edges:none! + + + +;; This test has a cycle. +;; void test1(unsigned long n, float a[][n], float b[][n]) { +;; for (unsigned long i = 0; i < n; i++) +;; for (unsigned long j = 1; j < n-1; j++) +;; a[i][j] = b[i][j] + a[i][j-1]; +;; } + +define void @test1(i64 %n, float* noalias %a, float* noalias %b) { +entry: + %exitcond3 = icmp ne i64 0, %n + br i1 %exitcond3, label %test1.for.cond1.preheader, label %for.end14 + +test1.for.cond1.preheader: ; preds = %entry, %for.inc12 + %i.04 = phi i64 [ %inc13, %for.inc12 ], [ 0, %entry ] + %sub = add i64 %n, -1 + %cmp21 = icmp ult i64 1, %sub + br i1 %cmp21, label %for.body4, label %for.inc12 + +for.body4: ; preds = %test1.for.cond1.preheader, %for.body4 + %j.02 = phi i64 [ %inc, %for.body4 ], [ 1, %test1.for.cond1.preheader ] + %0 = mul nsw i64 %i.04, %n + %arrayidx = getelementptr inbounds float, float* %b, i64 %0 + %arrayidx5 = getelementptr inbounds float, float* %arrayidx, i64 %j.02 + %1 = load float, float* %arrayidx5, align 4 + %2 = mul nsw i64 %i.04, %n + %arrayidx6 = getelementptr inbounds float, float* %a, i64 %2 + %sub7 = add i64 %j.02, -1 + %arrayidx8 = getelementptr inbounds float, float* %arrayidx6, i64 %sub7 + %3 = load float, float* %arrayidx8, align 4 + %add = fadd float %1, %3 + %4 = mul nsw i64 %i.04, %n + %arrayidx10 = getelementptr inbounds float, float* %a, i64 %4 + %arrayidx11 = getelementptr inbounds float, float* %arrayidx10, i64 %j.02 + store float %add, float* %arrayidx11, align 4 + %inc = add i64 %j.02, 1 + %cmp2 = icmp ult i64 %inc, %sub + br i1 %cmp2, label %for.body4, label %for.inc12 + +for.inc12: ; preds = %for.body4, %test1.for.cond1.preheader + %inc13 = add i64 %i.04, 1 + %exitcond = icmp ne i64 %inc13, %n + br i1 %exitcond, label %test1.for.cond1.preheader, label %for.end14 + +for.end14: ; preds = %for.inc12, %entry + ret void +} + + + +; CHECK-LABEL: 'DDG' for loop 'test2.for.cond1.preheader': +; CHECK: Node Address:[[N1:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %i.04 = phi i64 [ %inc13, %for.inc12 ], [ 0, %test2.for.cond1.preheader.preheader ] +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N2:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N3:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N4:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N5:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N6:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %sub = add i64 %n, -1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N8:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N8]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %cmp21 = icmp ult i64 1, %sub +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N9:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N9]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %cmp21, label %for.body4.preheader, label %for.inc12 +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N10:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %j.02 = phi i64 [ %inc, %for.body4 ], [ 1, %for.body4.preheader ] +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N11:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N12:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N13:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N14:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N5]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %0 = mul nsw i64 %i.04, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N15:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N15]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx = getelementptr inbounds float, float* %b, i64 %0 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N14]] + +; CHECK: Node Address:[[N14]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, float* %arrayidx, i64 %j.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N16:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N16]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %1 = load float, float* %arrayidx5, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N17:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N4]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %2 = mul nsw i64 %i.04, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N18:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N18]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx6 = getelementptr inbounds float, float* %a, i64 %2 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N19:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N13]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %add7 = add i64 %j.02, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N19]] + +; CHECK: Node Address:[[N19]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx8 = getelementptr inbounds float, float* %arrayidx6, i64 %add7 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N20:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N20]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %3 = load float, float* %arrayidx8, align 4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N17]] +; CHECK-NEXT: [memory] to [[N26:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N17]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %add = fadd float %1, %3 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N26]] + +; CHECK: Node Address:[[N3]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %4 = mul nsw i64 %i.04, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N27:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N27]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx10 = getelementptr inbounds float, float* %a, i64 %4 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N12]] + +; CHECK: Node Address:[[N12]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %arrayidx11 = getelementptr inbounds float, float* %arrayidx10, i64 %j.02 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N26]] + +; CHECK: Node Address:[[N26]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: store float %add, float* %arrayidx11, align 4 +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N11]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %inc = add i64 %j.02, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N7]] +; CHECK-NEXT: [def-use] to [[N10]] + +; CHECK: Node Address:[[N7]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %cmp2 = icmp ult i64 %inc, %sub +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N21:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N21]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %cmp2, label %for.body4, label %for.inc12.loopexit +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N2]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %inc13 = add i64 %i.04, 1 +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N22:0x[0-9a-f]*]] +; CHECK-NEXT: [def-use] to [[N1]] + +; CHECK: Node Address:[[N22]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: %exitcond = icmp ne i64 %inc13, %n +; CHECK-NEXT: Edges: +; CHECK-NEXT: [def-use] to [[N23:0x[0-9a-f]*]] + +; CHECK: Node Address:[[N23]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br i1 %exitcond, label %test2.for.cond1.preheader, label %for.end14.loopexit +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N24:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br label %for.body4 +; CHECK-NEXT: Edges:none! + +; CHECK: Node Address:[[N25:0x[0-9a-f]*]]:single-instruction +; CHECK-NEXT: Instructions: +; CHECK-NEXT: br label %for.inc12 +; CHECK-NEXT: Edges:none! + +;; This test has no cycles. +;; void test2(unsigned long n, float a[][n], float b[][n]) { +;; for (unsigned long i = 0; i < n; i++) +;; for (unsigned long j = 1; j < n-1; j++) +;; a[i][j] = b[i][j] + a[i][j+1]; +;; } + +define void @test2(i64 %n, float* noalias %a, float* noalias %b) { +entry: + %exitcond3 = icmp ne i64 0, %n + br i1 %exitcond3, label %test2.for.cond1.preheader, label %for.end14 + +test2.for.cond1.preheader: ; preds = %entry, %for.inc12 + %i.04 = phi i64 [ %inc13, %for.inc12 ], [ 0, %entry ] + %sub = add i64 %n, -1 + %cmp21 = icmp ult i64 1, %sub + br i1 %cmp21, label %for.body4, label %for.inc12 + +for.body4: ; preds = %test2.for.cond1.preheader, %for.body4 + %j.02 = phi i64 [ %inc, %for.body4 ], [ 1, %test2.for.cond1.preheader ] + %0 = mul nsw i64 %i.04, %n + %arrayidx = getelementptr inbounds float, float* %b, i64 %0 + %arrayidx5 = getelementptr inbounds float, float* %arrayidx, i64 %j.02 + %1 = load float, float* %arrayidx5, align 4 + %2 = mul nsw i64 %i.04, %n + %arrayidx6 = getelementptr inbounds float, float* %a, i64 %2 + %add7 = add i64 %j.02, 1 + %arrayidx8 = getelementptr inbounds float, float* %arrayidx6, i64 %add7 + %3 = load float, float* %arrayidx8, align 4 + %add = fadd float %1, %3 + %4 = mul nsw i64 %i.04, %n + %arrayidx10 = getelementptr inbounds float, float* %a, i64 %4 + %arrayidx11 = getelementptr inbounds float, float* %arrayidx10, i64 %j.02 + store float %add, float* %arrayidx11, align 4 + %inc = add i64 %j.02, 1 + %cmp2 = icmp ult i64 %inc, %sub + br i1 %cmp2, label %for.body4, label %for.inc12 + +for.inc12: ; preds = %for.body4, %test2.for.cond1.preheader + %inc13 = add i64 %i.04, 1 + %exitcond = icmp ne i64 %inc13, %n + br i1 %exitcond, label %test2.for.cond1.preheader, label %for.end14 + +for.end14: ; preds = %for.inc12, %entry + ret void +} \ No newline at end of file