[clang-repl] [codegen] Reduce the state in TBAA. NFC for static compilation. (#98138)
[llvm-project.git] / polly / lib / Analysis / ScopGraphPrinter.cpp
blobeb6c995f0bb91ac043435421568a6aa7bb1b7b63
1 //===- GraphPrinter.cpp - Create a DOT output describing the Scop. --------===//
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 // Create a DOT output describing the Scop.
11 // For each function a dot file is created that shows the control flow graph of
12 // the function and highlights the detected Scops.
14 //===----------------------------------------------------------------------===//
16 #include "polly/ScopGraphPrinter.h"
17 #include "polly/LinkAllPasses.h"
18 #include "polly/ScopDetection.h"
19 #include "llvm/Support/CommandLine.h"
21 using namespace polly;
22 using namespace llvm;
23 static cl::opt<std::string>
24 ViewFilter("polly-view-only",
25 cl::desc("Only view functions that match this pattern"),
26 cl::Hidden, cl::init(""));
28 static cl::opt<bool> ViewAll("polly-view-all",
29 cl::desc("Also show functions without any scops"),
30 cl::Hidden, cl::init(false));
32 namespace llvm {
34 std::string DOTGraphTraits<ScopDetection *>::getEdgeAttributes(
35 RegionNode *srcNode, GraphTraits<RegionInfo *>::ChildIteratorType CI,
36 ScopDetection *SD) {
37 RegionNode *destNode = *CI;
39 if (srcNode->isSubRegion() || destNode->isSubRegion())
40 return "";
42 // In case of a backedge, do not use it to define the layout of the nodes.
43 BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
44 BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
46 RegionInfo *RI = SD->getRI();
47 Region *R = RI->getRegionFor(destBB);
49 while (R && R->getParent())
50 if (R->getParent()->getEntry() == destBB)
51 R = R->getParent();
52 else
53 break;
55 if (R && R->getEntry() == destBB && R->contains(srcBB))
56 return "constraint=false";
58 return "";
61 std::string
62 DOTGraphTraits<ScopDetection *>::escapeString(llvm::StringRef String) {
63 std::string Escaped;
65 for (const auto &C : String) {
66 if (C == '"')
67 Escaped += '\\';
69 Escaped += C;
71 return Escaped;
74 void DOTGraphTraits<ScopDetection *>::printRegionCluster(ScopDetection *SD,
75 const Region *R,
76 raw_ostream &O,
77 unsigned depth) {
78 O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void *>(R)
79 << " {\n";
80 unsigned LineBegin, LineEnd;
81 std::string FileName;
83 getDebugLocation(R, LineBegin, LineEnd, FileName);
85 std::string Location;
86 if (LineBegin != (unsigned)-1) {
87 Location = escapeString(FileName + ":" + std::to_string(LineBegin) + "-" +
88 std::to_string(LineEnd) + "\n");
91 std::string ErrorMessage = SD->regionIsInvalidBecause(R);
92 ErrorMessage = escapeString(ErrorMessage);
93 O.indent(2 * (depth + 1))
94 << "label = \"" << Location << ErrorMessage << "\";\n";
96 if (SD->isMaxRegionInScop(*R)) {
97 O.indent(2 * (depth + 1)) << "style = filled;\n";
99 // Set color to green.
100 O.indent(2 * (depth + 1)) << "color = 3";
101 } else {
102 O.indent(2 * (depth + 1)) << "style = solid;\n";
104 int color = (R->getDepth() * 2 % 12) + 1;
106 // We do not want green again.
107 if (color == 3)
108 color = 6;
110 O.indent(2 * (depth + 1)) << "color = " << color << "\n";
113 for (const auto &SubRegion : *R)
114 printRegionCluster(SD, SubRegion.get(), O, depth + 1);
116 RegionInfo *RI = R->getRegionInfo();
118 for (BasicBlock *BB : R->blocks())
119 if (RI->getRegionFor(BB) == R)
120 O.indent(2 * (depth + 1))
121 << "Node"
122 << static_cast<void *>(RI->getTopLevelRegion()->getBBNode(BB))
123 << ";\n";
125 O.indent(2 * depth) << "}\n";
128 void DOTGraphTraits<ScopDetection *>::addCustomGraphFeatures(
129 ScopDetection *SD, GraphWriter<ScopDetection *> &GW) {
130 raw_ostream &O = GW.getOStream();
131 O << "\tcolorscheme = \"paired12\"\n";
132 printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4);
135 } // namespace llvm
137 struct ScopDetectionAnalysisGraphTraits {
138 static ScopDetection *getGraph(ScopDetectionWrapperPass *Analysis) {
139 return &Analysis->getSD();
143 struct ScopViewerWrapperPass
144 : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
145 ScopDetection *,
146 ScopDetectionAnalysisGraphTraits> {
147 static char ID;
148 ScopViewerWrapperPass()
149 : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
150 ScopDetection *,
151 ScopDetectionAnalysisGraphTraits>(
152 "scops", ID) {}
153 bool processFunction(Function &F, ScopDetectionWrapperPass &SD) override {
154 if (ViewFilter != "" && !F.getName().count(ViewFilter))
155 return false;
157 if (ViewAll)
158 return true;
160 // Check that at least one scop was detected.
161 return std::distance(SD.getSD().begin(), SD.getSD().end()) > 0;
164 char ScopViewerWrapperPass::ID = 0;
166 struct ScopOnlyViewerWrapperPass
167 : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
168 ScopDetection *,
169 ScopDetectionAnalysisGraphTraits> {
170 static char ID;
171 ScopOnlyViewerWrapperPass()
172 : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
173 ScopDetection *,
174 ScopDetectionAnalysisGraphTraits>(
175 "scopsonly", ID) {}
177 char ScopOnlyViewerWrapperPass::ID = 0;
179 struct ScopPrinterWrapperPass
180 : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
181 ScopDetection *,
182 ScopDetectionAnalysisGraphTraits> {
183 static char ID;
184 ScopPrinterWrapperPass()
185 : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
186 ScopDetection *,
187 ScopDetectionAnalysisGraphTraits>(
188 "scops", ID) {}
190 char ScopPrinterWrapperPass::ID = 0;
192 struct ScopOnlyPrinterWrapperPass
193 : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
194 ScopDetection *,
195 ScopDetectionAnalysisGraphTraits> {
196 static char ID;
197 ScopOnlyPrinterWrapperPass()
198 : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
199 ScopDetection *,
200 ScopDetectionAnalysisGraphTraits>(
201 "scopsonly", ID) {}
203 char ScopOnlyPrinterWrapperPass::ID = 0;
205 static RegisterPass<ScopViewerWrapperPass> X("view-scops",
206 "Polly - View Scops of function");
208 static RegisterPass<ScopOnlyViewerWrapperPass>
209 Y("view-scops-only",
210 "Polly - View Scops of function (with no function bodies)");
212 static RegisterPass<ScopPrinterWrapperPass>
213 M("dot-scops", "Polly - Print Scops of function");
215 static RegisterPass<ScopOnlyPrinterWrapperPass>
216 N("dot-scops-only",
217 "Polly - Print Scops of function (with no function bodies)");
219 Pass *polly::createDOTViewerWrapperPass() {
220 return new ScopViewerWrapperPass();
223 Pass *polly::createDOTOnlyViewerWrapperPass() {
224 return new ScopOnlyViewerWrapperPass();
227 Pass *polly::createDOTPrinterWrapperPass() {
228 return new ScopPrinterWrapperPass();
231 Pass *polly::createDOTOnlyPrinterWrapperPass() {
232 return new ScopOnlyPrinterWrapperPass();
235 bool ScopViewer::processFunction(Function &F, const ScopDetection &SD) {
236 if (ViewFilter != "" && !F.getName().count(ViewFilter))
237 return false;
239 if (ViewAll)
240 return true;
242 // Check that at least one scop was detected.
243 return std::distance(SD.begin(), SD.end()) > 0;