Iterator that enumerates the ProgramDependenceGraph (PDG) for a function,
[oota-llvm.git] / include / llvm / Analysis / IPModRef.h
1 //===- IPModRef.h - Compute IP Mod/Ref information --------------*- C++ -*-===//
2 //
3 // class IPModRef:
4 // 
5 // class IPModRef is an interprocedural analysis pass that computes
6 // flow-insensitive IP Mod and Ref information for every function
7 // (the GMOD and GREF problems) and for every call site (MOD and REF).
8 // 
9 // In practice, this needs to do NO real interprocedural work because
10 // all that is needed is done by the data structure analysis.
11 // This uses the top-down DS graph for a function and the bottom-up DS graph
12 // for each callee (including the Mod/Ref flags in the bottom-up graph)
13 // to compute the set of nodes that are Mod and Ref for the function and
14 // for each of its call sites.
15 //
16 // 
17 // class FunctionModRefInfo:
18 // 
19 // The results of IPModRef are encapsulated in the class FunctionModRefInfo.
20 // The results are stored as bit vectors: bit i represents node i
21 // in the TD DSGraph for the current function.  (This node numbering is
22 // implemented by class FunctionModRefInfo.)  Each FunctionModRefInfo
23 // includes:
24 // -- 2 bit vectors for the function (GMOD and GREF), and
25 // -- 2 bit vectors for each call site (MOD and REF).
26 //
27 // 
28 // IPModRef vs. Alias Analysis for Clients:
29 // 
30 // The IPModRef pass does not provide simpler query interfaces for specific
31 // LLVM values, instructions, or pointers because those results should be
32 // obtained through alias analysis (e.g., class DSAliasAnalysis).
33 // class IPModRef is primarily meant for other analysis passes that need to
34 // use Mod/Ref information efficiently for more complicated purposes;
35 // the bit-vector representations make propagation very efficient.
36 //
37 //===----------------------------------------------------------------------===//
38
39 #ifndef LLVM_ANALYSIS_IPMODREF_H
40 #define LLVM_ANALYSIS_IPMODREF_H
41
42 #include "llvm/Pass.h"
43 #include "Support/BitSetVector.h"
44
45 class Module;
46 class Function;
47 class CallInst;
48 class DSNode;
49 class DSGraph;
50 class DSNodeHandle;
51 class ModRefInfo;               // Result of IP Mod/Ref for one entity
52 class FunctionModRefInfo;       // ModRefInfo for a func and all calls in it
53 class IPModRef;                 // Pass that computes IP Mod/Ref info
54
55 //---------------------------------------------------------------------------
56 // class ModRefInfo 
57 // 
58 // Purpose:
59 //   Representation of Mod/Ref information for a single function or callsite.
60 //   This is represented as a pair of bit vectors, one each for Mod and Ref.
61 //   Each bit vector is indexed by the node id of the DS graph node index.
62 //---------------------------------------------------------------------------
63
64 class ModRefInfo {
65   BitSetVector   modNodeSet;            // set of modified nodes
66   BitSetVector   refNodeSet;            // set of referenced nodes
67   
68 public:
69   // 
70   // Methods to construct ModRefInfo objects.
71   // 
72   ModRefInfo(unsigned int numNodes)
73     : modNodeSet(numNodes),
74       refNodeSet(numNodes) { }
75
76   unsigned getSize() const {
77     assert(modNodeSet.size() == refNodeSet.size() &&
78            "Mod & Ref different size?");
79     return modNodeSet.size();
80   }
81
82   void setNodeIsMod (unsigned nodeId)   { modNodeSet[nodeId] = true; }
83   void setNodeIsRef (unsigned nodeId)   { refNodeSet[nodeId] = true; }
84
85   //
86   // Methods to query the mod/ref info
87   // 
88   bool nodeIsMod (unsigned nodeId) const  { return modNodeSet.test(nodeId); }
89   bool nodeIsRef (unsigned nodeId) const  { return refNodeSet.test(nodeId); }
90   bool nodeIsKill(unsigned nodeId) const  { return false; }
91
92   const BitSetVector&  getModSet() const  { return modNodeSet; }
93         BitSetVector&  getModSet()        { return modNodeSet; }
94
95   const BitSetVector&  getRefSet() const  { return refNodeSet; }
96         BitSetVector&  getRefSet()        { return refNodeSet; }
97
98   // Debugging support methods
99   void print(std::ostream &O, const std::string& prefix=std::string("")) const;
100   void dump() const;
101 };
102
103
104 //----------------------------------------------------------------------------
105 // class FunctionModRefInfo
106 // 
107 // Representation of the results of IP Mod/Ref analysis for a function
108 // and for each of the call sites within the function.
109 // Each of these are represented as bit vectors of size = the number of
110 // nodes in the top-dwon DS graph of the function.  Nodes are identified by
111 // their nodeId, in the range [0 .. funcTDGraph.size()-1].
112 //----------------------------------------------------------------------------
113
114 class FunctionModRefInfo {
115   const Function&       F;                  // The function
116   IPModRef&             IPModRefObj;        // The IPModRef Object owning this
117   DSGraph*              funcTDGraph;        // Top-down DS graph for function
118   ModRefInfo            funcModRefInfo;     // ModRefInfo for the function body
119   std::map<const CallInst*, ModRefInfo*>
120                         callSiteModRefInfo; // ModRefInfo for each callsite
121   std::map<const DSNode*, unsigned> NodeIds;
122
123   friend class IPModRef;
124
125   void          computeModRef   (const Function &func);
126   void          computeModRef   (const CallInst& callInst);
127   DSGraph *ResolveCallSiteModRefInfo(CallInst &CI,
128                                 std::map<const DSNode*, DSNodeHandle> &NodeMap);
129
130 public:
131   /* ctor */    FunctionModRefInfo      (const Function& func,
132                                          IPModRef&       IPModRefObj,
133                                          DSGraph*        tdgClone);
134   /* dtor */    ~FunctionModRefInfo     ();
135
136   // Identify the function and its relevant DS graph
137   // 
138   const Function& getFunction() const   { return F; }
139   const DSGraph&  getFuncGraph() const  { return *funcTDGraph; }
140
141   // Retrieve Mod/Ref results for a single call site and for the function body
142   // 
143   const ModRefInfo*     getModRefInfo  (const Function& func) const {
144     return &funcModRefInfo;
145   }
146   const ModRefInfo*     getModRefInfo  (const CallInst& callInst) const {
147     std::map<const CallInst*, ModRefInfo*>::const_iterator I = 
148       callSiteModRefInfo.find(&callInst);
149     return (I == callSiteModRefInfo.end())? NULL : I->second;
150   }
151
152   // Get the nodeIds used to index all Mod/Ref information for current function
153   //
154   unsigned              getNodeId       (const DSNode* node) const {
155     std::map<const DSNode*, unsigned>::const_iterator iter = NodeIds.find(node);
156     assert(iter != NodeIds.end() && iter->second < funcModRefInfo.getSize());
157     return iter->second;
158   }
159
160   unsigned              getNodeId       (const Value* value) const;
161
162   // Debugging support methods
163   void print(std::ostream &O) const;
164   void dump() const;
165 };
166
167
168 //----------------------------------------------------------------------------
169 // class IPModRef
170 // 
171 // Purpose:
172 // An interprocedural pass that computes IP Mod/Ref info for functions and
173 // for individual call sites.
174 // 
175 // Given the DSGraph of a function, this class can be queried for
176 // a ModRefInfo object describing all the nodes in the DSGraph that are
177 // (a) modified, and (b) referenced during an execution of the function
178 // from an arbitrary callsite, or during an execution of a single call-site
179 // within the function.
180 //----------------------------------------------------------------------------
181
182 class IPModRef : public Pass {
183   std::map<const Function*, FunctionModRefInfo*> funcToModRefInfoMap;
184   Module* M;
185
186   FunctionModRefInfo& getFuncInfo(const Function& func,
187                                   bool computeIfMissing = false);
188 public:
189   IPModRef() : M(NULL)  { }
190   ~IPModRef()           { }
191
192   // Driver function to run IP Mod/Ref on a Module.
193   // This initializes the module reference, and then computes IPModRef
194   // results immediately if demand-driven analysis was *not* specified.
195   // 
196   virtual bool run(Module &M);
197
198   // Retrieve the Mod/Ref information for a single function
199   // 
200   const FunctionModRefInfo& getFunctionModRefInfo(const Function& func) {
201     return getFuncInfo(func);
202   }
203
204   /// getBUDSGraph - This method returns the BU data structure graph for F
205   /// through the use of the BUDataStructures object.
206   ///
207   const DSGraph &getBUDSGraph(const Function &F);
208
209   // Debugging support methods
210   // 
211   void print(std::ostream &O) const;
212   void dump() const;
213
214   // Release memory held by this pass when the pass pipeline is done
215   // 
216   virtual void releaseMemory();
217
218   // getAnalysisUsage - This pass requires top-down data structure graphs.
219   // It modifies nothing.
220   // 
221   virtual void getAnalysisUsage(AnalysisUsage &AU) const;
222 };
223
224 //===----------------------------------------------------------------------===//
225
226 #endif