[x86] fix assert with horizontal math + broadcast of vector (PR43402)
[llvm-core.git] / lib / Analysis / DDG.cpp
blob29778b3e0d645ec700b3c9c109bb02d794c16f8d
1 //===- DDG.cpp - Data Dependence Graph -------------------------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // The implementation for the data dependence graph.
10 //===----------------------------------------------------------------------===//
11 #include "llvm/Analysis/DDG.h"
12 #include "llvm/Analysis/LoopInfo.h"
14 using namespace llvm;
16 #define DEBUG_TYPE "ddg"
18 template class llvm::DGEdge<DDGNode, DDGEdge>;
19 template class llvm::DGNode<DDGNode, DDGEdge>;
20 template class llvm::DirectedGraph<DDGNode, DDGEdge>;
22 //===--------------------------------------------------------------------===//
23 // DDGNode implementation
24 //===--------------------------------------------------------------------===//
25 DDGNode::~DDGNode() {}
27 bool DDGNode::collectInstructions(
28 llvm::function_ref<bool(Instruction *)> const &Pred,
29 InstructionListType &IList) const {
30 assert(IList.empty() && "Expected the IList to be empty on entry.");
31 if (isa<SimpleDDGNode>(this)) {
32 for (auto *I : cast<const SimpleDDGNode>(this)->getInstructions())
33 if (Pred(I))
34 IList.push_back(I);
35 } else
36 llvm_unreachable("unimplemented type of node");
37 return !IList.empty();
40 raw_ostream &llvm::operator<<(raw_ostream &OS, const DDGNode::NodeKind K) {
41 const char *Out;
42 switch (K) {
43 case DDGNode::NodeKind::SingleInstruction:
44 Out = "single-instruction";
45 break;
46 case DDGNode::NodeKind::MultiInstruction:
47 Out = "multi-instruction";
48 break;
49 case DDGNode::NodeKind::Unknown:
50 Out = "??";
51 break;
53 OS << Out;
54 return OS;
57 raw_ostream &llvm::operator<<(raw_ostream &OS, const DDGNode &N) {
58 OS << "Node Address:" << &N << ":" << N.getKind() << "\n";
59 if (isa<SimpleDDGNode>(N)) {
60 OS << " Instructions:\n";
61 for (auto *I : cast<const SimpleDDGNode>(N).getInstructions())
62 OS.indent(2) << *I << "\n";
63 } else
64 llvm_unreachable("unimplemented type of node");
66 OS << (N.getEdges().empty() ? " Edges:none!\n" : " Edges:\n");
67 for (auto &E : N.getEdges())
68 OS.indent(2) << *E;
69 return OS;
72 //===--------------------------------------------------------------------===//
73 // SimpleDDGNode implementation
74 //===--------------------------------------------------------------------===//
76 SimpleDDGNode::SimpleDDGNode(Instruction &I)
77 : DDGNode(NodeKind::SingleInstruction), InstList() {
78 assert(InstList.empty() && "Expected empty list.");
79 InstList.push_back(&I);
82 SimpleDDGNode::SimpleDDGNode(const SimpleDDGNode &N)
83 : DDGNode(N), InstList(N.InstList) {
84 assert(((getKind() == NodeKind::SingleInstruction && InstList.size() == 1) ||
85 (getKind() == NodeKind::MultiInstruction && InstList.size() > 1)) &&
86 "constructing from invalid simple node.");
89 SimpleDDGNode::SimpleDDGNode(SimpleDDGNode &&N)
90 : DDGNode(std::move(N)), InstList(std::move(N.InstList)) {
91 assert(((getKind() == NodeKind::SingleInstruction && InstList.size() == 1) ||
92 (getKind() == NodeKind::MultiInstruction && InstList.size() > 1)) &&
93 "constructing from invalid simple node.");
96 SimpleDDGNode::~SimpleDDGNode() { InstList.clear(); }
98 //===--------------------------------------------------------------------===//
99 // DDGEdge implementation
100 //===--------------------------------------------------------------------===//
102 raw_ostream &llvm::operator<<(raw_ostream &OS, const DDGEdge::EdgeKind K) {
103 const char *Out;
104 switch (K) {
105 case DDGEdge::EdgeKind::RegisterDefUse:
106 Out = "def-use";
107 break;
108 case DDGEdge::EdgeKind::MemoryDependence:
109 Out = "memory";
110 break;
111 case DDGEdge::EdgeKind::Unknown:
112 Out = "??";
113 break;
115 OS << Out;
116 return OS;
119 raw_ostream &llvm::operator<<(raw_ostream &OS, const DDGEdge &E) {
120 OS << "[" << E.getKind() << "] to " << &E.getTargetNode() << "\n";
121 return OS;
124 //===--------------------------------------------------------------------===//
125 // DataDependenceGraph implementation
126 //===--------------------------------------------------------------------===//
127 using BasicBlockListType = SmallVector<BasicBlock *, 8>;
129 DataDependenceGraph::DataDependenceGraph(Function &F, DependenceInfo &D)
130 : DependenceGraphInfo(F.getName().str(), D) {
131 BasicBlockListType BBList;
132 for (auto &BB : F.getBasicBlockList())
133 BBList.push_back(&BB);
134 DDGBuilder(*this, D, BBList).populate();
137 DataDependenceGraph::DataDependenceGraph(const Loop &L, DependenceInfo &D)
138 : DependenceGraphInfo(Twine(L.getHeader()->getParent()->getName() + "." +
139 L.getHeader()->getName())
140 .str(),
141 D) {
142 BasicBlockListType BBList;
143 for (BasicBlock *BB : L.blocks())
144 BBList.push_back(BB);
145 DDGBuilder(*this, D, BBList).populate();
148 DataDependenceGraph::~DataDependenceGraph() {
149 for (auto *N : Nodes) {
150 for (auto *E : *N)
151 delete E;
152 delete N;
156 raw_ostream &llvm::operator<<(raw_ostream &OS, const DataDependenceGraph &G) {
157 for (auto *Node : G)
158 OS << *Node << "\n";
159 return OS;
162 //===--------------------------------------------------------------------===//
163 // DDG Analysis Passes
164 //===--------------------------------------------------------------------===//
166 /// DDG as a loop pass.
167 DDGAnalysis::Result DDGAnalysis::run(Loop &L, LoopAnalysisManager &AM,
168 LoopStandardAnalysisResults &AR) {
169 Function *F = L.getHeader()->getParent();
170 DependenceInfo DI(F, &AR.AA, &AR.SE, &AR.LI);
171 return std::make_unique<DataDependenceGraph>(L, DI);
173 AnalysisKey DDGAnalysis::Key;
175 PreservedAnalyses DDGAnalysisPrinterPass::run(Loop &L, LoopAnalysisManager &AM,
176 LoopStandardAnalysisResults &AR,
177 LPMUpdater &U) {
178 OS << "'DDG' for loop '" << L.getHeader()->getName() << "':\n";
179 OS << *AM.getResult<DDGAnalysis>(L, AR);
180 return PreservedAnalyses::all();