Break part of Pass.h out into PassAnalysisSupport.h
[oota-llvm.git] / include / llvm / PassAnalysisSupport.h
1 //===- llvm/PassAnalysisSupport.h - Analysis Pass Support code ---*- C++ -*-==//
2 //
3 // This file defines stuff that is used to define and "use" Analysis Passes.
4 // This file is automatically #included by Pass.h, so:
5 //
6 //           NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
7 //
8 // Instead, #include Pass.h
9 //
10 //===----------------------------------------------------------------------===//
11
12 #ifndef LLVM_PASS_ANALYSIS_SUPPORT_H
13 #define LLVM_PASS_ANALYSIS_SUPPORT_H
14
15 // No need to include Pass.h, we are being included by it!
16
17
18 // CreatePass - Helper template to invoke the constructor for the AnalysisID
19 // class. Note that this should be a template internal to AnalysisID, but
20 // GCC 2.95.3 crashes if we do that, doh.
21 //
22 template<class AnalysisType>
23 static Pass *CreatePass(AnalysisID ID) { return new AnalysisType(ID); }
24
25 //===----------------------------------------------------------------------===//
26 // AnalysisID - This class is used to uniquely identify an analysis pass that
27 //              is referenced by a transformation.
28 //
29 class AnalysisID {
30   static unsigned NextID;               // Next ID # to deal out...
31   unsigned ID;                          // Unique ID for this analysis
32   Pass *(*Constructor)(AnalysisID);     // Constructor to return the Analysis
33
34   AnalysisID();                         // Disable default ctor
35   AnalysisID(unsigned id, Pass *(*Ct)(AnalysisID)) : ID(id), Constructor(Ct) {}
36 public:
37   // create - the only way to define a new AnalysisID.  This static method is
38   // supposed to be used to define the class static AnalysisID's that are
39   // provided by analysis passes.  In the implementation (.cpp) file for the
40   // class, there should be a line that looks like this (using CallGraph as an
41   // example):
42   //
43   //  AnalysisID CallGraph::ID(AnalysisID::create<CallGraph>());
44   //
45   template<class AnalysisType>
46   static AnalysisID create() {
47     return AnalysisID(NextID++, CreatePass<AnalysisType>);
48   }
49
50   // Special Copy Constructor - This is how analysis passes declare that they
51   // only depend on the CFG of the function they are working on, so they are not
52   // invalidated by other passes that do not modify the CFG.  This should be
53   // used like this:
54   // AnalysisID DominatorSet::ID(AnalysisID::create<DominatorSet>(), true);
55   //
56   AnalysisID(const AnalysisID &AID, bool DependsOnlyOnCFG = false);
57
58
59   inline Pass *createPass() const { return Constructor(*this); }
60
61   inline bool operator==(const AnalysisID &A) const {
62     return A.ID == ID;
63   }
64   inline bool operator!=(const AnalysisID &A) const {
65     return A.ID != ID;
66   }
67   inline bool operator<(const AnalysisID &A) const {
68     return ID < A.ID;
69   }
70 };
71
72 //===----------------------------------------------------------------------===//
73 // AnalysisUsage - Represent the analysis usage information of a pass.  This
74 // tracks analyses that the pass REQUIRES (must available when the pass runs),
75 // and analyses that the pass PRESERVES (the pass does not invalidate the
76 // results of these analyses).  This information is provided by a pass to the
77 // Pass infrastructure through the getAnalysisUsage virtual function.
78 //
79 class AnalysisUsage {
80   // Sets of analyses required and preserved by a pass
81   std::vector<AnalysisID> Required, Preserved, Provided;
82   bool PreservesAll;
83 public:
84   AnalysisUsage() : PreservesAll(false) {}
85   
86   // addRequires - Add the specified ID to the required set of the usage info
87   // for a pass.
88   //
89   AnalysisUsage &addRequired(AnalysisID ID) {
90     Required.push_back(ID);
91     return *this;
92   }
93
94   // addPreserves - Add the specified ID to the set of analyses preserved by
95   // this pass
96   //
97   AnalysisUsage &addPreserved(AnalysisID ID) {
98     Preserved.push_back(ID);
99     return *this;
100   }
101
102   void addProvided(AnalysisID ID) {
103     Provided.push_back(ID);
104   }
105
106   // PreservesAll - Set by analyses that do not transform their input at all
107   void setPreservesAll() { PreservesAll = true; }
108   bool preservesAll() const { return PreservesAll; }
109
110   // preservesCFG - This function should be called to by the pass, iff they do
111   // not:
112   //
113   //  1. Add or remove basic blocks from the function
114   //  2. Modify terminator instructions in any way.
115   //
116   // This function annotates the AnalysisUsage info object to say that analyses
117   // that only depend on the CFG are preserved by this pass.
118   //
119   void preservesCFG();
120
121   const std::vector<AnalysisID> &getRequiredSet() const { return Required; }
122   const std::vector<AnalysisID> &getPreservedSet() const { return Preserved; }
123   const std::vector<AnalysisID> &getProvidedSet() const { return Provided; }
124 };
125
126
127
128 //===----------------------------------------------------------------------===//
129 // AnalysisResolver - Simple interface implemented by PassManagers objects that
130 // is used to pull analysis information out of them.
131 //
132 struct AnalysisResolver {
133   virtual Pass *getAnalysisOrNullUp(AnalysisID ID) const = 0;
134   virtual Pass *getAnalysisOrNullDown(AnalysisID ID) const = 0;
135   Pass *getAnalysis(AnalysisID ID) {
136     Pass *Result = getAnalysisOrNullUp(ID);
137     assert(Result && "Pass has an incorrect analysis uses set!");
138     return Result;
139   }
140
141   // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
142   Pass *getAnalysisToUpdate(AnalysisID ID) {
143     Pass *Result = getAnalysisOrNullUp(ID);
144     return Result;
145   }
146
147   virtual unsigned getDepth() const = 0;
148
149   virtual void markPassUsed(AnalysisID P, Pass *User) = 0;
150
151   void startPass(Pass *P) {}
152   void endPass(Pass *P) {}
153 protected:
154   void setAnalysisResolver(Pass *P, AnalysisResolver *AR);
155 };
156
157 #endif