]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / Analysis / DOTGraphTraitsPass.h
1 //===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
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 // Templates to create dotty viewer and printer passes for GraphTraits graphs.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
14 #define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
15
16 #include "llvm/Analysis/CFGPrinter.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Support/FileSystem.h"
19
20 namespace llvm {
21
22 /// Default traits class for extracting a graph from an analysis pass.
23 ///
24 /// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
25 template <typename AnalysisT, typename GraphT = AnalysisT *>
26 struct DefaultAnalysisGraphTraits {
27   static GraphT getGraph(AnalysisT *A) { return A; }
28 };
29
30 template <
31     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
32     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT, GraphT> >
33 class DOTGraphTraitsViewer : public FunctionPass {
34 public:
35   DOTGraphTraitsViewer(StringRef GraphName, char &ID)
36       : FunctionPass(ID), Name(GraphName) {}
37
38   /// Return true if this function should be processed.
39   ///
40   /// An implementation of this class my override this function to indicate that
41   /// only certain functions should be viewed.
42   ///
43   /// @param Analysis The current analysis result for this function.
44   virtual bool processFunction(Function &F, AnalysisT &Analysis) {
45     return true;
46   }
47
48   bool runOnFunction(Function &F) override {
49     auto &Analysis = getAnalysis<AnalysisT>();
50
51     if (!processFunction(F, Analysis))
52       return false;
53
54     GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis);
55     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
56     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
57
58     ViewGraph(Graph, Name, IsSimple, Title);
59
60     return false;
61   }
62
63   void getAnalysisUsage(AnalysisUsage &AU) const override {
64     AU.setPreservesAll();
65     AU.addRequired<AnalysisT>();
66   }
67
68 private:
69   std::string Name;
70 };
71
72 template <
73     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
74     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT, GraphT> >
75 class DOTGraphTraitsPrinter : public FunctionPass {
76 public:
77   DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
78       : FunctionPass(ID), Name(GraphName) {}
79
80   /// Return true if this function should be processed.
81   ///
82   /// An implementation of this class my override this function to indicate that
83   /// only certain functions should be printed.
84   ///
85   /// @param Analysis The current analysis result for this function.
86   virtual bool processFunction(Function &F, AnalysisT &Analysis) {
87     return true;
88   }
89
90   bool runOnFunction(Function &F) override {
91     auto &Analysis = getAnalysis<AnalysisT>();
92
93     if (!processFunction(F, Analysis))
94       return false;
95
96     GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis);
97     std::string Filename = Name + "." + F.getName().str() + ".dot";
98     std::error_code EC;
99
100     errs() << "Writing '" << Filename << "'...";
101
102     raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
103     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
104     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
105
106     if (!EC)
107       WriteGraph(File, Graph, IsSimple, Title);
108     else
109       errs() << "  error opening file for writing!";
110     errs() << "\n";
111
112     return false;
113   }
114
115   void getAnalysisUsage(AnalysisUsage &AU) const override {
116     AU.setPreservesAll();
117     AU.addRequired<AnalysisT>();
118   }
119
120 private:
121   std::string Name;
122 };
123
124 template <
125     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
126     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT, GraphT> >
127 class DOTGraphTraitsModuleViewer : public ModulePass {
128 public:
129   DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
130       : ModulePass(ID), Name(GraphName) {}
131
132   bool runOnModule(Module &M) override {
133     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
134     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
135
136     ViewGraph(Graph, Name, IsSimple, Title);
137
138     return false;
139   }
140
141   void getAnalysisUsage(AnalysisUsage &AU) const override {
142     AU.setPreservesAll();
143     AU.addRequired<AnalysisT>();
144   }
145
146 private:
147   std::string Name;
148 };
149
150 template <
151     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
152     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT, GraphT> >
153 class DOTGraphTraitsModulePrinter : public ModulePass {
154 public:
155   DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
156       : ModulePass(ID), Name(GraphName) {}
157
158   bool runOnModule(Module &M) override {
159     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
160     std::string Filename = Name + ".dot";
161     std::error_code EC;
162
163     errs() << "Writing '" << Filename << "'...";
164
165     raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
166     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
167
168     if (!EC)
169       WriteGraph(File, Graph, IsSimple, Title);
170     else
171       errs() << "  error opening file for writing!";
172     errs() << "\n";
173
174     return false;
175   }
176
177   void getAnalysisUsage(AnalysisUsage &AU) const override {
178     AU.setPreservesAll();
179     AU.addRequired<AnalysisT>();
180   }
181
182 private:
183   std::string Name;
184 };
185
186 } // end namespace llvm
187
188 #endif