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