Polly 22.0.0git
ScopGraphPrinter.cpp
Go to the documentation of this file.
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.
10//
11// For each function a dot file is created that shows the control flow graph of
12// the function and highlights the detected Scops.
13//
14//===----------------------------------------------------------------------===//
15
17#include "polly/ScopDetection.h"
18#include "llvm/Support/CommandLine.h"
19
20using namespace polly;
21using namespace llvm;
22
23namespace polly {
24std::string ViewFilter;
26} // namespace polly
27
28static cl::opt<std::string, true>
29 XViewFilter("polly-view-only",
30 cl::desc("Only view functions that match this pattern"),
31 cl::location(ViewFilter), cl::Hidden, cl::init(""));
32
33static cl::opt<bool, true>
34 XViewAll("polly-view-all",
35 cl::desc("Also show functions without any scops"),
36 cl::location(ViewAll), cl::Hidden, cl::init(false));
37
38namespace llvm {
39
42 ScopDetection *SD) {
43 RegionNode *destNode = *CI;
44
45 if (srcNode->isSubRegion() || destNode->isSubRegion())
46 return "";
47
48 // In case of a backedge, do not use it to define the layout of the nodes.
49 BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
50 BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
51
52 RegionInfo *RI = SD->getRI();
53 Region *R = RI->getRegionFor(destBB);
54
55 while (R && R->getParent())
56 if (R->getParent()->getEntry() == destBB)
57 R = R->getParent();
58 else
59 break;
60
61 if (R && R->getEntry() == destBB && R->contains(srcBB))
62 return "constraint=false";
63
64 return "";
65}
66
67std::string
68DOTGraphTraits<ScopDetection *>::escapeString(llvm::StringRef String) {
69 std::string Escaped;
70
71 for (const auto &C : String) {
72 if (C == '"')
73 Escaped += '\\';
74
75 Escaped += C;
76 }
77 return Escaped;
78}
79
80void DOTGraphTraits<ScopDetection *>::printRegionCluster(ScopDetection *SD,
81 const Region *R,
82 raw_ostream &O,
83 unsigned depth) {
84 O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void *>(R)
85 << " {\n";
86 unsigned LineBegin, LineEnd;
87 std::string FileName;
88
89 getDebugLocation(R, LineBegin, LineEnd, FileName);
90
91 std::string Location;
92 if (LineBegin != (unsigned)-1) {
93 Location = escapeString(FileName + ":" + std::to_string(LineBegin) + "-" +
94 std::to_string(LineEnd) + "\n");
95 }
96
97 std::string ErrorMessage = SD->regionIsInvalidBecause(R);
98 ErrorMessage = escapeString(ErrorMessage);
99 O.indent(2 * (depth + 1))
100 << "label = \"" << Location << ErrorMessage << "\";\n";
101
102 if (SD->isMaxRegionInScop(*R)) {
103 O.indent(2 * (depth + 1)) << "style = filled;\n";
104
105 // Set color to green.
106 O.indent(2 * (depth + 1)) << "color = 3";
107 } else {
108 O.indent(2 * (depth + 1)) << "style = solid;\n";
109
110 int color = (R->getDepth() * 2 % 12) + 1;
111
112 // We do not want green again.
113 if (color == 3)
114 color = 6;
115
116 O.indent(2 * (depth + 1)) << "color = " << color << "\n";
117 }
118
119 for (const auto &SubRegion : *R)
120 printRegionCluster(SD, SubRegion.get(), O, depth + 1);
121
122 RegionInfo *RI = R->getRegionInfo();
123
124 for (BasicBlock *BB : R->blocks())
125 if (RI->getRegionFor(BB) == R)
126 O.indent(2 * (depth + 1))
127 << "Node"
128 << static_cast<void *>(RI->getTopLevelRegion()->getBBNode(BB))
129 << ";\n";
130
131 O.indent(2 * depth) << "}\n";
132}
133
134void DOTGraphTraits<ScopDetection *>::addCustomGraphFeatures(
135 ScopDetection *SD, GraphWriter<ScopDetection *> &GW) {
136 raw_ostream &O = GW.getOStream();
137 O << "\tcolorscheme = \"paired12\"\n";
138 printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4);
139}
140
141} // namespace llvm
142
143bool ScopViewer::processFunction(Function &F, const ScopDetection &SD) {
144 if (ViewFilter != "" && !F.getName().count(ViewFilter))
145 return false;
146
147 if (ViewAll)
148 return true;
149
150 // Check that at least one scop was detected.
151 return std::distance(SD.begin(), SD.end()) > 0;
152}
static cl::opt< std::string, true > XViewFilter("polly-view-only", cl::desc("Only view functions that match this pattern"), cl::location(ViewFilter), cl::Hidden, cl::init(""))
static cl::opt< bool, true > XViewAll("polly-view-all", cl::desc("Also show functions without any scops"), cl::location(ViewAll), cl::Hidden, cl::init(false))
Pass to detect the maximal static control parts (Scops) of a function.
RegionInfo * getRI() const
Get the RegionInfo stored in this pass.
std::string regionIsInvalidBecause(const Region *R) const
Get a message why a region is invalid.
bool isMaxRegionInScop(const Region &R, bool Verify=true)
Is the region is the maximum region of a Scop?
#define C(FN,...)
Definition isl_test2.cc:197
void getDebugLocation(const llvm::Region *R, unsigned &LineBegin, unsigned &LineEnd, std::string &FileName)
Get the location of a region from the debug info.
std::string ViewFilter
bool processFunction(Function &F, const ScopDetection &SD) override