Bug Summary

File:polly/lib/Analysis/ScopGraphPrinter.cpp
Location:line 86, column 9
Description:Called C++ object pointer is null

Annotated Source Code

1//===- GraphPrinter.cpp - Create a DOT output describing the Scop. --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Create a DOT output describing the Scop.
11//
12// For each function a dot file is created that shows the control flow graph of
13// the function and highlights the detected Scops.
14//
15//===----------------------------------------------------------------------===//
16
17#include "polly/LinkAllPasses.h"
18#include "polly/ScopDetection.h"
19#include "llvm/Analysis/DOTGraphTraitsPass.h"
20#include "llvm/Analysis/RegionInfo.h"
21#include "llvm/Analysis/RegionIterator.h"
22
23using namespace polly;
24using namespace llvm;
25
26namespace llvm {
27template <>
28struct GraphTraits<ScopDetection *> : public GraphTraits<RegionInfo *> {
29 static NodeType *getEntryNode(ScopDetection *SD) {
30 return GraphTraits<RegionInfo *>::getEntryNode(SD->getRI());
31 }
32 static nodes_iterator nodes_begin(ScopDetection *SD) {
33 return nodes_iterator::begin(getEntryNode(SD));
34 }
35 static nodes_iterator nodes_end(ScopDetection *SD) {
36 return nodes_iterator::end(getEntryNode(SD));
37 }
38};
39
40template <> struct DOTGraphTraits<RegionNode *> : public DefaultDOTGraphTraits {
41 DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
42
43 std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
44 if (!Node->isSubRegion()) {
45 BasicBlock *BB = Node->getNodeAs<BasicBlock>();
46
47 if (isSimple())
48 return DOTGraphTraits<const Function *>::getSimpleNodeLabel(
49 BB, BB->getParent());
50 else
51 return DOTGraphTraits<const Function *>::getCompleteNodeLabel(
52 BB, BB->getParent());
53 }
54
55 return "Not implemented";
56 }
57};
58
59template <>
60struct DOTGraphTraits<ScopDetection *> : public DOTGraphTraits<RegionNode *> {
61 DOTGraphTraits(bool isSimple = false)
62 : DOTGraphTraits<RegionNode *>(isSimple) {}
63 static std::string getGraphName(ScopDetection *SD) { return "Scop Graph"; }
64
65 std::string getEdgeAttributes(RegionNode *srcNode,
66 GraphTraits<RegionInfo *>::ChildIteratorType CI,
67 ScopDetection *SD) {
68 RegionNode *destNode = *CI;
69
70 if (srcNode->isSubRegion() || destNode->isSubRegion())
1
Taking false branch
71 return "";
72
73 // In case of a backedge, do not use it to define the layout of the nodes.
74 BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
75 BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
76
77 RegionInfo *RI = SD->getRI();
78 Region *R = RI->getRegionFor(destBB);
2
'R' initialized here
79
80 while (R && R->getParent())
3
Assuming pointer value is null
81 if (R->getParent()->getEntry() == destBB)
82 R = R->getParent();
83 else
84 break;
85
86 if (R->getEntry() == destBB && R->contains(srcBB))
4
Called C++ object pointer is null
87 return "constraint=false";
88
89 return "";
90 }
91
92 std::string getNodeLabel(RegionNode *Node, ScopDetection *SD) {
93 return DOTGraphTraits<RegionNode *>::getNodeLabel(
94 Node, reinterpret_cast<RegionNode *>(SD->getRI()->getTopLevelRegion()));
95 }
96
97 static std::string escapeString(std::string String) {
98 std::string Escaped;
99
100 for (const auto &C : String) {
101 if (C == '"')
102 Escaped += '\\';
103
104 Escaped += C;
105 }
106 return Escaped;
107 }
108
109 // Print the cluster of the subregions. This groups the single basic blocks
110 // and adds a different background color for each group.
111 static void printRegionCluster(const ScopDetection *SD, const Region *R,
112 raw_ostream &O, unsigned depth = 0) {
113 O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void *>(R)
114 << " {\n";
115 std::string ErrorMessage = SD->regionIsInvalidBecause(R);
116 ErrorMessage = escapeString(ErrorMessage);
117 O.indent(2 * (depth + 1)) << "label = \"" << ErrorMessage << "\";\n";
118
119 if (SD->isMaxRegionInScop(*R)) {
120 O.indent(2 * (depth + 1)) << "style = filled;\n";
121
122 // Set color to green.
123 O.indent(2 * (depth + 1)) << "color = 3";
124 } else {
125 O.indent(2 * (depth + 1)) << "style = solid;\n";
126
127 int color = (R->getDepth() * 2 % 12) + 1;
128
129 // We do not want green again.
130 if (color == 3)
131 color = 6;
132
133 O.indent(2 * (depth + 1)) << "color = " << color << "\n";
134 }
135
136 for (const auto &SubRegion : *R)
137 printRegionCluster(SD, SubRegion.get(), O, depth + 1);
138
139 RegionInfo *RI = R->getRegionInfo();
140
141 for (const auto &BB : R->blocks())
142 if (RI->getRegionFor(BB) == R)
143 O.indent(2 * (depth + 1))
144 << "Node"
145 << static_cast<void *>(RI->getTopLevelRegion()->getBBNode(BB))
146 << ";\n";
147
148 O.indent(2 * depth) << "}\n";
149 }
150 static void addCustomGraphFeatures(const ScopDetection *SD,
151 GraphWriter<ScopDetection *> &GW) {
152 raw_ostream &O = GW.getOStream();
153 O << "\tcolorscheme = \"paired12\"\n";
154 printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4);
155 }
156};
157
158} // end namespace llvm
159
160struct ScopViewer : public DOTGraphTraitsViewer<ScopDetection, false> {
161 static char ID;
162 ScopViewer() : DOTGraphTraitsViewer<ScopDetection, false>("scops", ID) {}
163};
164char ScopViewer::ID = 0;
165
166struct ScopOnlyViewer : public DOTGraphTraitsViewer<ScopDetection, true> {
167 static char ID;
168 ScopOnlyViewer()
169 : DOTGraphTraitsViewer<ScopDetection, true>("scopsonly", ID) {}
170};
171char ScopOnlyViewer::ID = 0;
172
173struct ScopPrinter : public DOTGraphTraitsPrinter<ScopDetection, false> {
174 static char ID;
175 ScopPrinter() : DOTGraphTraitsPrinter<ScopDetection, false>("scops", ID) {}
176};
177char ScopPrinter::ID = 0;
178
179struct ScopOnlyPrinter : public DOTGraphTraitsPrinter<ScopDetection, true> {
180 static char ID;
181 ScopOnlyPrinter()
182 : DOTGraphTraitsPrinter<ScopDetection, true>("scopsonly", ID) {}
183};
184char ScopOnlyPrinter::ID = 0;
185
186static RegisterPass<ScopViewer> X("view-scops",
187 "Polly - View Scops of function");
188
189static RegisterPass<ScopOnlyViewer>
190 Y("view-scops-only",
191 "Polly - View Scops of function (with no function bodies)");
192
193static RegisterPass<ScopPrinter> M("dot-scops",
194 "Polly - Print Scops of function");
195
196static RegisterPass<ScopOnlyPrinter>
197 N("dot-scops-only",
198 "Polly - Print Scops of function (with no function bodies)");
199
200Pass *polly::createDOTViewerPass() { return new ScopViewer(); }
201
202Pass *polly::createDOTOnlyViewerPass() { return new ScopOnlyViewer(); }
203
204Pass *polly::createDOTPrinterPass() { return new ScopPrinter(); }
205
206Pass *polly::createDOTOnlyPrinterPass() { return new ScopOnlyPrinter(); }