1 | //===- GraphPrinter.h - 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 | |
16 | #ifndef POLLY_SCOP_GRAPH_PRINTER_H |
17 | #define POLLY_SCOP_GRAPH_PRINTER_H |
18 | |
19 | #include "polly/ScopDetection.h" |
20 | #include "polly/Support/ScopLocation.h" |
21 | #include "llvm/Analysis/DOTGraphTraitsPass.h" |
22 | #include "llvm/Analysis/RegionInfo.h" |
23 | #include "llvm/Analysis/RegionIterator.h" |
24 | #include "llvm/Analysis/RegionPrinter.h" |
25 | #include "llvm/IR/PassManager.h" |
26 | |
27 | namespace llvm { |
28 | |
29 | template <> |
30 | struct GraphTraits<polly::ScopDetection *> : GraphTraits<RegionInfo *> { |
31 | static NodeRef getEntryNode(polly::ScopDetection *SD) { |
32 | return GraphTraits<RegionInfo *>::getEntryNode(RI: SD->getRI()); |
33 | } |
34 | static nodes_iterator nodes_begin(polly::ScopDetection *SD) { |
35 | return nodes_iterator::begin(G: getEntryNode(SD)); |
36 | } |
37 | static nodes_iterator nodes_end(polly::ScopDetection *SD) { |
38 | return nodes_iterator::end(G: getEntryNode(SD)); |
39 | } |
40 | }; |
41 | |
42 | template <> |
43 | struct DOTGraphTraits<polly::ScopDetection *> : DOTGraphTraits<RegionNode *> { |
44 | DOTGraphTraits(bool isSimple = false) |
45 | : DOTGraphTraits<RegionNode *>(isSimple) {} |
46 | static std::string getGraphName(polly::ScopDetection *SD) { |
47 | return "Scop Graph" ; |
48 | } |
49 | |
50 | std::string getEdgeAttributes(RegionNode *srcNode, |
51 | GraphTraits<RegionInfo *>::ChildIteratorType CI, |
52 | polly::ScopDetection *SD); |
53 | |
54 | std::string getNodeLabel(RegionNode *Node, polly::ScopDetection *SD) { |
55 | return DOTGraphTraits<RegionNode *>::getNodeLabel( |
56 | Node, Graph: reinterpret_cast<RegionNode *>(SD->getRI()->getTopLevelRegion())); |
57 | } |
58 | |
59 | static std::string escapeString(llvm::StringRef String); |
60 | |
61 | /// Print the cluster of the subregions. This groups the single basic blocks |
62 | /// and adds a different background color for each group. |
63 | static void printRegionCluster(polly::ScopDetection *SD, const Region *R, |
64 | raw_ostream &O, unsigned depth = 0); |
65 | |
66 | static void addCustomGraphFeatures(polly::ScopDetection *SD, |
67 | GraphWriter<polly::ScopDetection *> &GW); |
68 | }; |
69 | } // end namespace llvm |
70 | |
71 | namespace polly { |
72 | |
73 | struct ScopViewer final : llvm::DOTGraphTraitsViewer<ScopAnalysis, false> { |
74 | ScopViewer() : llvm::DOTGraphTraitsViewer<ScopAnalysis, false>("scops" ) {} |
75 | |
76 | bool processFunction(Function &F, const ScopDetection &SD) override; |
77 | }; |
78 | |
79 | struct ScopOnlyViewer final : llvm::DOTGraphTraitsViewer<ScopAnalysis, false> { |
80 | ScopOnlyViewer() |
81 | : llvm::DOTGraphTraitsViewer<ScopAnalysis, false>("scops-only" ) {} |
82 | }; |
83 | |
84 | struct ScopPrinter final : llvm::DOTGraphTraitsPrinter<ScopAnalysis, false> { |
85 | ScopPrinter() : llvm::DOTGraphTraitsPrinter<ScopAnalysis, false>("scops" ) {} |
86 | }; |
87 | |
88 | struct ScopOnlyPrinter final : llvm::DOTGraphTraitsPrinter<ScopAnalysis, true> { |
89 | ScopOnlyPrinter() |
90 | : llvm::DOTGraphTraitsPrinter<ScopAnalysis, true>("scopsonly" ) {} |
91 | }; |
92 | |
93 | } // end namespace polly |
94 | |
95 | #endif /* POLLY_SCOP_GRAPH_PRINTER_H */ |
96 | |