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