015618d0572ed92fa82c8a8696c6c25069075e13
[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 #include "Support/hash_map"
45
46 class Module;
47 class Function;
48 class CallSite;
49 class Instruction;
50 class CallInst;
51 class InvokeInst;
52 class DSNode;
53 class DSGraph;
54 class DSNodeHandle;
55 class ModRefInfo;               // Result of IP Mod/Ref for one entity
56 class FunctionModRefInfo;       // ModRefInfo for a func and all calls in it
57 class IPModRef;                 // Pass that computes IP Mod/Ref info
58
59 //---------------------------------------------------------------------------
60 // class ModRefInfo 
61 // 
62 // Purpose:
63 //   Representation of Mod/Ref information for a single function or callsite.
64 //   This is represented as a pair of bit vectors, one each for Mod and Ref.
65 //   Each bit vector is indexed by the node id of the DS graph node index.
66 //---------------------------------------------------------------------------
67
68 class ModRefInfo {
69   BitSetVector   modNodeSet;            // set of modified nodes
70   BitSetVector   refNodeSet;            // set of referenced nodes
71   
72 public:
73   // 
74   // Methods to construct ModRefInfo objects.
75   // 
76   ModRefInfo(unsigned int numNodes)
77     : modNodeSet(numNodes),
78       refNodeSet(numNodes) { }
79
80   unsigned getSize() const {
81     assert(modNodeSet.size() == refNodeSet.size() &&
82            "Mod & Ref different size?");
83     return modNodeSet.size();
84   }
85
86   void setNodeIsMod (unsigned nodeId)   { modNodeSet[nodeId] = true; }
87   void setNodeIsRef (unsigned nodeId)   { refNodeSet[nodeId] = true; }
88
89   //
90   // Methods to query the mod/ref info
91   // 
92   bool nodeIsMod (unsigned nodeId) const  { return modNodeSet.test(nodeId); }
93   bool nodeIsRef (unsigned nodeId) const  { return refNodeSet.test(nodeId); }
94   bool nodeIsKill(unsigned nodeId) const  { return false; }
95
96   const BitSetVector&  getModSet() const  { return modNodeSet; }
97         BitSetVector&  getModSet()        { return modNodeSet; }
98
99   const BitSetVector&  getRefSet() const  { return refNodeSet; }
100         BitSetVector&  getRefSet()        { return refNodeSet; }
101
102   // Debugging support methods
103   void print(std::ostream &O, const std::string& prefix=std::string("")) const;
104   void dump() const;
105 };
106
107
108 //----------------------------------------------------------------------------
109 // class FunctionModRefInfo
110 // 
111 // Representation of the results of IP Mod/Ref analysis for a function
112 // and for each of the call sites within the function.
113 // Each of these are represented as bit vectors of size = the number of
114 // nodes in the top-dwon DS graph of the function.  Nodes are identified by
115 // their nodeId, in the range [0 .. funcTDGraph.size()-1].
116 //----------------------------------------------------------------------------
117
118 class FunctionModRefInfo {
119   const Function&       F;                  // The function
120   IPModRef&             IPModRefObj;        // The IPModRef Object owning this
121   DSGraph*              funcTDGraph;        // Top-down DS graph for function
122   ModRefInfo            funcModRefInfo;     // ModRefInfo for the function body
123   std::map<const Instruction*, ModRefInfo*>
124                         callSiteModRefInfo; // ModRefInfo for each callsite
125   std::map<const DSNode*, unsigned> NodeIds;
126
127   friend class IPModRef;
128
129   void          computeModRef   (const Function &func);
130   void          computeModRef   (CallSite call);
131   DSGraph *ResolveCallSiteModRefInfo(CallSite CS,
132                                 hash_map<const DSNode*, DSNodeHandle> &NodeMap);
133
134 public:
135   /* ctor */    FunctionModRefInfo      (const Function& func,
136                                          IPModRef&       IPModRefObj,
137                                          DSGraph*        tdgClone);
138   /* dtor */    ~FunctionModRefInfo     ();
139
140   // Identify the function and its relevant DS graph
141   // 
142   const Function& getFunction() const   { return F; }
143   const DSGraph&  getFuncGraph() const  { return *funcTDGraph; }
144
145   // Retrieve Mod/Ref results for a single call site and for the function body
146   // 
147   const ModRefInfo*     getModRefInfo  (const Function& func) const {
148     return &funcModRefInfo;
149   }
150   const ModRefInfo*     getModRefInfo  (const CallInst& callInst) const {
151     std::map<const Instruction*, ModRefInfo*>::const_iterator I = 
152       callSiteModRefInfo.find((Instruction*)&callInst);
153     return (I == callSiteModRefInfo.end()) ? NULL : I->second;
154   }
155   const ModRefInfo*     getModRefInfo  (const InvokeInst& II) const {
156     std::map<const Instruction*, ModRefInfo*>::const_iterator I = 
157       callSiteModRefInfo.find((Instruction*)&II);
158     return (I == callSiteModRefInfo.end()) ? NULL : I->second;
159   }
160
161   // Get the nodeIds used to index all Mod/Ref information for current function
162   //
163   unsigned              getNodeId       (const DSNode* node) const {
164     std::map<const DSNode*, unsigned>::const_iterator iter = NodeIds.find(node);
165     assert(iter != NodeIds.end() && iter->second < funcModRefInfo.getSize());
166     return iter->second;
167   }
168
169   unsigned              getNodeId       (const Value* value) const;
170
171   // Debugging support methods
172   void print(std::ostream &O) const;
173   void dump() const;
174 };
175
176
177 //----------------------------------------------------------------------------
178 // class IPModRef
179 // 
180 // Purpose:
181 // An interprocedural pass that computes IP Mod/Ref info for functions and
182 // for individual call sites.
183 // 
184 // Given the DSGraph of a function, this class can be queried for
185 // a ModRefInfo object describing all the nodes in the DSGraph that are
186 // (a) modified, and (b) referenced during an execution of the function
187 // from an arbitrary callsite, or during an execution of a single call-site
188 // within the function.
189 //----------------------------------------------------------------------------
190
191 class IPModRef : public Pass {
192   std::map<const Function*, FunctionModRefInfo*> funcToModRefInfoMap;
193   Module* M;
194
195   FunctionModRefInfo& getFuncInfo(const Function& func,
196                                   bool computeIfMissing = false);
197 public:
198   IPModRef() : M(NULL)  { }
199   ~IPModRef()           { }
200
201   // Driver function to run IP Mod/Ref on a Module.
202   // This initializes the module reference, and then computes IPModRef
203   // results immediately if demand-driven analysis was *not* specified.
204   // 
205   virtual bool run(Module &M);
206
207   // Retrieve the Mod/Ref information for a single function
208   // 
209   const FunctionModRefInfo& getFunctionModRefInfo(const Function& func) {
210     return getFuncInfo(func);
211   }
212
213   /// getBUDSGraph - This method returns the BU data structure graph for F
214   /// through the use of the BUDataStructures object.
215   ///
216   const DSGraph &getBUDSGraph(const Function &F);
217
218   // Debugging support methods
219   // 
220   void print(std::ostream &O) const;
221   void dump() const;
222
223   // Release memory held by this pass when the pass pipeline is done
224   // 
225   virtual void releaseMemory();
226
227   // getAnalysisUsage - This pass requires top-down data structure graphs.
228   // It modifies nothing.
229   // 
230   virtual void getAnalysisUsage(AnalysisUsage &AU) const;
231 };
232
233 //===----------------------------------------------------------------------===//
234
235 #endif