Coverage Report

Created: 2017-03-27 23:01

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/lib/Analysis/ScopGraphPrinter.cpp
Line
Count
Source (jump to first uncovered line)
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 "polly/Support/ScopLocation.h"
20
#include "llvm/Analysis/DOTGraphTraitsPass.h"
21
#include "llvm/Analysis/RegionInfo.h"
22
#include "llvm/Analysis/RegionIterator.h"
23
#include "llvm/Support/CommandLine.h"
24
25
using namespace polly;
26
using namespace llvm;
27
static cl::opt<std::string>
28
    ViewFilter("polly-view-only",
29
               cl::desc("Only view functions that match this pattern"),
30
               cl::Hidden, cl::init(""), cl::ZeroOrMore);
31
32
static cl::opt<bool> ViewAll("polly-view-all",
33
                             cl::desc("Also show functions without any scops"),
34
                             cl::Hidden, cl::init(false), cl::ZeroOrMore);
35
36
namespace llvm {
37
template <>
38
struct GraphTraits<ScopDetection *> : public GraphTraits<RegionInfo *> {
39
2
  static NodeRef getEntryNode(ScopDetection *SD) {
40
2
    return GraphTraits<RegionInfo *>::getEntryNode(SD->getRI());
41
2
  }
42
1
  static nodes_iterator nodes_begin(ScopDetection *SD) {
43
1
    return nodes_iterator::begin(getEntryNode(SD));
44
1
  }
45
1
  static nodes_iterator nodes_end(ScopDetection *SD) {
46
1
    return nodes_iterator::end(getEntryNode(SD));
47
1
  }
48
};
49
50
template <> struct DOTGraphTraits<RegionNode *> : public DefaultDOTGraphTraits {
51
  DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
52
53
  std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
54
    if (!Node->isSubRegion()) {
55
      BasicBlock *BB = Node->getNodeAs<BasicBlock>();
56
57
      if (isSimple())
58
        return DOTGraphTraits<const Function *>::getSimpleNodeLabel(
59
            BB, BB->getParent());
60
      else
61
        return DOTGraphTraits<const Function *>::getCompleteNodeLabel(
62
            BB, BB->getParent());
63
    }
64
65
    return "Not implemented";
66
  }
67
};
68
69
template <>
70
struct DOTGraphTraits<ScopDetection *> : public DOTGraphTraits<RegionNode *> {
71
  DOTGraphTraits(bool isSimple = false)
72
2
      : DOTGraphTraits<RegionNode *>(isSimple) {}
73
2
  static std::string getGraphName(ScopDetection *SD) { return "Scop Graph"; }
74
75
  std::string getEdgeAttributes(RegionNode *srcNode,
76
                                GraphTraits<RegionInfo *>::ChildIteratorType CI,
77
10
                                ScopDetection *SD) {
78
10
    RegionNode *destNode = *CI;
79
10
80
10
    if (
srcNode->isSubRegion() || 10
destNode->isSubRegion()10
)
81
0
      return "";
82
10
83
10
    // In case of a backedge, do not use it to define the layout of the nodes.
84
10
    BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
85
10
    BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
86
10
87
10
    RegionInfo *RI = SD->getRI();
88
10
    Region *R = RI->getRegionFor(destBB);
89
10
90
12
    while (
R && 12
R->getParent()12
)
91
11
      
if (11
R->getParent()->getEntry() == destBB11
)
92
2
        R = R->getParent();
93
11
      else
94
9
        break;
95
10
96
10
    if (
R && 10
R->getEntry() == destBB10
&&
R->contains(srcBB)4
)
97
2
      return "constraint=false";
98
10
99
8
    return "";
100
10
  }
101
102
9
  std::string getNodeLabel(RegionNode *Node, ScopDetection *SD) {
103
9
    return DOTGraphTraits<RegionNode *>::getNodeLabel(
104
9
        Node, reinterpret_cast<RegionNode *>(SD->getRI()->getTopLevelRegion()));
105
9
  }
106
107
4
  static std::string escapeString(std::string String) {
108
4
    std::string Escaped;
109
4
110
0
    for (const auto &C : String) {
111
0
      if (C == '"')
112
0
        Escaped += '\\';
113
0
114
0
      Escaped += C;
115
0
    }
116
4
    return Escaped;
117
4
  }
118
119
  // Print the cluster of the subregions. This groups the single basic blocks
120
  // and adds a different background color for each group.
121
  static void printRegionCluster(const ScopDetection *SD, const Region *R,
122
4
                                 raw_ostream &O, unsigned depth = 0) {
123
4
    O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void *>(R)
124
4
                        << " {\n";
125
4
    unsigned LineBegin, LineEnd;
126
4
    std::string FileName;
127
4
128
4
    getDebugLocation(R, LineBegin, LineEnd, FileName);
129
4
130
4
    std::string Location;
131
4
    if (
LineBegin != (unsigned)-14
)
{0
132
0
      Location = escapeString(FileName + ":" + std::to_string(LineBegin) + "-" +
133
0
                              std::to_string(LineEnd) + "\n");
134
0
    }
135
4
136
4
    std::string ErrorMessage = SD->regionIsInvalidBecause(R);
137
4
    ErrorMessage = escapeString(ErrorMessage);
138
4
    O.indent(2 * (depth + 1))
139
4
        << "label = \"" << Location << ErrorMessage << "\";\n";
140
4
141
4
    if (
SD->isMaxRegionInScop(*R)4
)
{1
142
1
      O.indent(2 * (depth + 1)) << "style = filled;\n";
143
1
144
1
      // Set color to green.
145
1
      O.indent(2 * (depth + 1)) << "color = 3";
146
3
    } else {
147
3
      O.indent(2 * (depth + 1)) << "style = solid;\n";
148
3
149
3
      int color = (R->getDepth() * 2 % 12) + 1;
150
3
151
3
      // We do not want green again.
152
3
      if (color == 3)
153
0
        color = 6;
154
3
155
3
      O.indent(2 * (depth + 1)) << "color = " << color << "\n";
156
3
    }
157
4
158
4
    for (const auto &SubRegion : *R)
159
3
      printRegionCluster(SD, SubRegion.get(), O, depth + 1);
160
4
161
4
    RegionInfo *RI = R->getRegionInfo();
162
4
163
4
    for (const auto &BB : R->blocks())
164
25
      
if (25
RI->getRegionFor(BB) == R25
)
165
9
        O.indent(2 * (depth + 1))
166
9
            << "Node"
167
9
            << static_cast<void *>(RI->getTopLevelRegion()->getBBNode(BB))
168
9
            << ";\n";
169
4
170
4
    O.indent(2 * depth) << "}\n";
171
4
  }
172
  static void addCustomGraphFeatures(const ScopDetection *SD,
173
1
                                     GraphWriter<ScopDetection *> &GW) {
174
1
    raw_ostream &O = GW.getOStream();
175
1
    O << "\tcolorscheme = \"paired12\"\n";
176
1
    printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4);
177
1
  }
178
};
179
180
} // end namespace llvm
181
182
struct ScopViewer : public DOTGraphTraitsViewer<ScopDetection, false> {
183
  static char ID;
184
0
  ScopViewer() : DOTGraphTraitsViewer<ScopDetection, false>("scops", ID) {}
185
0
  bool processFunction(Function &F, ScopDetection &SD) override {
186
0
    if (
ViewFilter != "" && 0
!F.getName().count(ViewFilter)0
)
187
0
      return false;
188
0
189
0
    
if (0
ViewAll0
)
190
0
      return true;
191
0
192
0
    // Check that at least one scop was detected.
193
0
    return std::distance(SD.begin(), SD.end()) > 0;
194
0
  }
195
};
196
char ScopViewer::ID = 0;
197
198
struct ScopOnlyViewer : public DOTGraphTraitsViewer<ScopDetection, true> {
199
  static char ID;
200
  ScopOnlyViewer()
201
0
      : DOTGraphTraitsViewer<ScopDetection, true>("scopsonly", ID) {}
202
};
203
char ScopOnlyViewer::ID = 0;
204
205
struct ScopPrinter : public DOTGraphTraitsPrinter<ScopDetection, false> {
206
  static char ID;
207
1
  ScopPrinter() : DOTGraphTraitsPrinter<ScopDetection, false>("scops", ID) {}
208
};
209
char ScopPrinter::ID = 0;
210
211
struct ScopOnlyPrinter : public DOTGraphTraitsPrinter<ScopDetection, true> {
212
  static char ID;
213
  ScopOnlyPrinter()
214
0
      : DOTGraphTraitsPrinter<ScopDetection, true>("scopsonly", ID) {}
215
};
216
char ScopOnlyPrinter::ID = 0;
217
218
static RegisterPass<ScopViewer> X("view-scops",
219
                                  "Polly - View Scops of function");
220
221
static RegisterPass<ScopOnlyViewer>
222
    Y("view-scops-only",
223
      "Polly - View Scops of function (with no function bodies)");
224
225
static RegisterPass<ScopPrinter> M("dot-scops",
226
                                   "Polly - Print Scops of function");
227
228
static RegisterPass<ScopOnlyPrinter>
229
    N("dot-scops-only",
230
      "Polly - Print Scops of function (with no function bodies)");
231
232
0
Pass *polly::createDOTViewerPass() { return new ScopViewer(); }
233
234
0
Pass *polly::createDOTOnlyViewerPass() { return new ScopOnlyViewer(); }
235
236
0
Pass *polly::createDOTPrinterPass() { return new ScopPrinter(); }
237
238
0
Pass *polly::createDOTOnlyPrinterPass() { return new ScopOnlyPrinter(); }