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(SD->getRI());
33   }
34   static nodes_iterator nodes_begin(polly::ScopDetection *SD) {
35     return nodes_iterator::begin(getEntryNode(SD));
36   }
37   static nodes_iterator nodes_end(polly::ScopDetection *SD) {
38     return nodes_iterator::end(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, 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