move header
[oota-llvm.git] / include / llvm / Analysis / DataStructure / DataStructure.h
1 //===- DataStructure.h - Build data structure graphs ------------*- 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 // Implement the LLVM data structure analysis library.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ANALYSIS_DATA_STRUCTURE_H
15 #define LLVM_ANALYSIS_DATA_STRUCTURE_H
16
17 #include "llvm/Pass.h"
18 #include "llvm/Target/TargetData.h"
19 #include "llvm/ADT/hash_map"
20 #include "llvm/ADT/hash_set"
21 #include "llvm/ADT/EquivalenceClasses.h"
22
23 namespace llvm {
24
25 class Type;
26 class Instruction;
27 class GlobalValue;
28 class CallSite;
29 class DSGraph;
30 class DSCallSite;
31 class DSNode;
32 class DSNodeHandle;
33
34 FunctionPass *createDataStructureStatsPass();
35 FunctionPass *createDataStructureGraphCheckerPass();
36
37
38 // FIXME: move this stuff to a private header
39 namespace DataStructureAnalysis {
40   /// isPointerType - Return true if this first class type is big enough to hold
41   /// a pointer.
42   ///
43   bool isPointerType(const Type *Ty);
44 }
45
46
47 // LocalDataStructures - The analysis that computes the local data structure
48 // graphs for all of the functions in the program.
49 //
50 // FIXME: This should be a Function pass that can be USED by a Pass, and would
51 // be automatically preserved.  Until we can do that, this is a Pass.
52 //
53 class LocalDataStructures : public ModulePass {
54   // DSInfo, one graph for each function
55   hash_map<Function*, DSGraph*> DSInfo;
56   DSGraph *GlobalsGraph;
57
58   /// GlobalECs - The equivalence classes for each global value that is merged
59   /// with other global values in the DSGraphs.
60   EquivalenceClasses<GlobalValue*> GlobalECs;
61 public:
62   ~LocalDataStructures() { releaseMemory(); }
63
64   virtual bool runOnModule(Module &M);
65
66   bool hasGraph(const Function &F) const {
67     return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
68   }
69
70   /// getDSGraph - Return the data structure graph for the specified function.
71   ///
72   DSGraph &getDSGraph(const Function &F) const {
73     hash_map<Function*, DSGraph*>::const_iterator I =
74       DSInfo.find(const_cast<Function*>(&F));
75     assert(I != DSInfo.end() && "Function not in module!");
76     return *I->second;
77   }
78
79   DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
80
81   EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
82
83   /// print - Print out the analysis results...
84   ///
85   void print(std::ostream &O, const Module *M) const;
86
87   /// releaseMemory - if the pass pipeline is done with this pass, we can
88   /// release our memory...
89   ///
90   virtual void releaseMemory();
91
92   /// getAnalysisUsage - This obviously provides a data structure graph.
93   ///
94   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
95     AU.setPreservesAll();
96     AU.addRequired<TargetData>();
97   }
98 };
99
100
101 /// BUDataStructures - The analysis that computes the interprocedurally closed
102 /// data structure graphs for all of the functions in the program.  This pass
103 /// only performs a "Bottom Up" propagation (hence the name).
104 ///
105 class BUDataStructures : public ModulePass {
106 protected:
107   // DSInfo, one graph for each function
108   hash_map<Function*, DSGraph*> DSInfo;
109   DSGraph *GlobalsGraph;
110   std::set<std::pair<Instruction*, Function*> > ActualCallees;
111
112   // This map is only maintained during construction of BU Graphs
113   std::map<std::vector<Function*>,
114            std::pair<DSGraph*, std::vector<DSNodeHandle> > > *IndCallGraphMap;
115
116   /// GlobalECs - The equivalence classes for each global value that is merged
117   /// with other global values in the DSGraphs.
118   EquivalenceClasses<GlobalValue*> GlobalECs;
119 public:
120   ~BUDataStructures() { releaseMyMemory(); }
121
122   virtual bool runOnModule(Module &M);
123
124   bool hasGraph(const Function &F) const {
125     return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
126   }
127
128   /// getDSGraph - Return the data structure graph for the specified function.
129   ///
130   DSGraph &getDSGraph(const Function &F) const {
131     hash_map<Function*, DSGraph*>::const_iterator I =
132       DSInfo.find(const_cast<Function*>(&F));
133     if (I != DSInfo.end())
134       return *I->second;
135     return const_cast<BUDataStructures*>(this)->
136                    CreateGraphForExternalFunction(F);
137   }
138
139   DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
140
141   EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
142
143   DSGraph &CreateGraphForExternalFunction(const Function &F);
144
145   /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
146   /// These correspond to the interfaces defined in the AliasAnalysis class.
147   void deleteValue(Value *V);
148   void copyValue(Value *From, Value *To);
149
150   /// print - Print out the analysis results...
151   ///
152   void print(std::ostream &O, const Module *M) const;
153
154   // FIXME: Once the pass manager is straightened out, rename this to
155   // releaseMemory.
156   void releaseMyMemory();
157
158   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
159     AU.setPreservesAll();
160     AU.addRequired<LocalDataStructures>();
161   }
162
163   typedef std::set<std::pair<Instruction*, Function*> > ActualCalleesTy;
164   const ActualCalleesTy &getActualCallees() const {
165     return ActualCallees;
166   }
167
168   typedef ActualCalleesTy::const_iterator callee_iterator;
169   callee_iterator callee_begin(Instruction *I) const {
170     return ActualCallees.lower_bound(std::pair<Instruction*,Function*>(I, 0));
171   }
172
173   callee_iterator callee_end(Instruction *I) const {
174     I = (Instruction*)((char*)I + 1);
175     return ActualCallees.lower_bound(std::pair<Instruction*,Function*>(I, 0));
176   }
177
178 private:
179   void calculateGraph(DSGraph &G);
180
181   DSGraph &getOrCreateGraph(Function *F);
182
183   unsigned calculateGraphs(Function *F, std::vector<Function*> &Stack,
184                            unsigned &NextID,
185                            hash_map<Function*, unsigned> &ValMap);
186 };
187
188
189 /// TDDataStructures - Analysis that computes new data structure graphs
190 /// for each function using the closed graphs for the callers computed
191 /// by the bottom-up pass.
192 ///
193 class TDDataStructures : public ModulePass {
194   // DSInfo, one graph for each function
195   hash_map<Function*, DSGraph*> DSInfo;
196   hash_set<Function*> ArgsRemainIncomplete;
197   DSGraph *GlobalsGraph;
198   BUDataStructures *BUInfo;
199
200   /// GlobalECs - The equivalence classes for each global value that is merged
201   /// with other global values in the DSGraphs.
202   EquivalenceClasses<GlobalValue*> GlobalECs;
203
204   /// CallerCallEdges - For a particular graph, we keep a list of these records
205   /// which indicates which graphs call this function and from where.
206   struct CallerCallEdge {
207     DSGraph *CallerGraph;        // The graph of the caller function.
208     const DSCallSite *CS;        // The actual call site.
209     Function *CalledFunction;    // The actual function being called.
210
211     CallerCallEdge(DSGraph *G, const DSCallSite *cs, Function *CF)
212       : CallerGraph(G), CS(cs), CalledFunction(CF) {}
213
214     bool operator<(const CallerCallEdge &RHS) const {
215       return CallerGraph < RHS.CallerGraph ||
216             (CallerGraph == RHS.CallerGraph && CS < RHS.CS);
217     }
218   };
219
220   std::map<DSGraph*, std::vector<CallerCallEdge> > CallerEdges;
221
222
223   // IndCallMap - We memoize the results of indirect call inlining operations
224   // that have multiple targets here to avoid N*M inlining.  The key to the map
225   // is a sorted set of callee functions, the value is the DSGraph that holds
226   // all of the caller graphs merged together, and the DSCallSite to merge with
227   // the arguments for each function.
228   std::map<std::vector<Function*>, DSGraph*> IndCallMap;
229
230 public:
231   ~TDDataStructures() { releaseMyMemory(); }
232
233   virtual bool runOnModule(Module &M);
234
235   bool hasGraph(const Function &F) const {
236     return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
237   }
238
239   /// getDSGraph - Return the data structure graph for the specified function.
240   ///
241   DSGraph &getDSGraph(const Function &F) const {
242     hash_map<Function*, DSGraph*>::const_iterator I =
243       DSInfo.find(const_cast<Function*>(&F));
244     if (I != DSInfo.end()) return *I->second;
245     return const_cast<TDDataStructures*>(this)->
246         getOrCreateDSGraph(const_cast<Function&>(F));
247   }
248
249   DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
250   EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
251
252
253   /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
254   /// These correspond to the interfaces defined in the AliasAnalysis class.
255   void deleteValue(Value *V);
256   void copyValue(Value *From, Value *To);
257
258   /// print - Print out the analysis results...
259   ///
260   void print(std::ostream &O, const Module *M) const;
261
262   /// If the pass pipeline is done with this pass, we can release our memory...
263   ///
264   virtual void releaseMyMemory();
265
266   /// getAnalysisUsage - This obviously provides a data structure graph.
267   ///
268   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
269     AU.setPreservesAll();
270     AU.addRequired<BUDataStructures>();
271   }
272
273 private:
274   void markReachableFunctionsExternallyAccessible(DSNode *N,
275                                                   hash_set<DSNode*> &Visited);
276
277   void InlineCallersIntoGraph(DSGraph &G);
278   DSGraph &getOrCreateDSGraph(Function &F);
279   void ComputePostOrder(Function &F, hash_set<DSGraph*> &Visited,
280                         std::vector<DSGraph*> &PostOrder);
281 };
282
283
284 /// CompleteBUDataStructures - This is the exact same as the bottom-up graphs,
285 /// but we use take a completed call graph and inline all indirect callees into
286 /// their callers graphs, making the result more useful for things like pool
287 /// allocation.
288 ///
289 struct CompleteBUDataStructures : public BUDataStructures {
290   virtual bool runOnModule(Module &M);
291
292   bool hasGraph(const Function &F) const {
293     return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
294   }
295
296   /// getDSGraph - Return the data structure graph for the specified function.
297   ///
298   DSGraph &getDSGraph(const Function &F) const {
299     hash_map<Function*, DSGraph*>::const_iterator I =
300       DSInfo.find(const_cast<Function*>(&F));
301     assert(I != DSInfo.end() && "Function not in module!");
302     return *I->second;
303   }
304
305   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
306     AU.setPreservesAll();
307     AU.addRequired<BUDataStructures>();
308
309     // FIXME: TEMPORARY (remove once finalization of indirect call sites in the
310     // globals graph has been implemented in the BU pass)
311     AU.addRequired<TDDataStructures>();
312   }
313
314   /// print - Print out the analysis results...
315   ///
316   void print(std::ostream &O, const Module *M) const;
317
318 private:
319   unsigned calculateSCCGraphs(DSGraph &FG, std::vector<DSGraph*> &Stack,
320                               unsigned &NextID,
321                               hash_map<DSGraph*, unsigned> &ValMap);
322   DSGraph &getOrCreateGraph(Function &F);
323   void processGraph(DSGraph &G);
324 };
325
326
327 /// EquivClassGraphs - This is the same as the complete bottom-up graphs, but
328 /// with functions partitioned into equivalence classes and a single merged
329 /// DS graph for all functions in an equivalence class.  After this merging,
330 /// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
331 ///
332 struct EquivClassGraphs : public ModulePass {
333   CompleteBUDataStructures *CBU;
334
335   DSGraph *GlobalsGraph;
336
337   // DSInfo - one graph for each function.
338   hash_map<const Function*, DSGraph*> DSInfo;
339
340   /// ActualCallees - The actual functions callable from indirect call sites.
341   ///
342   std::set<std::pair<Instruction*, Function*> > ActualCallees;
343
344   // Equivalence class where functions that can potentially be called via the
345   // same function pointer are in the same class.
346   EquivalenceClasses<Function*> FuncECs;
347
348   /// OneCalledFunction - For each indirect call, we keep track of one
349   /// target of the call.  This is used to find equivalence class called by
350   /// a call site.
351   std::map<DSNode*, Function *> OneCalledFunction;
352
353   /// GlobalECs - The equivalence classes for each global value that is merged
354   /// with other global values in the DSGraphs.
355   EquivalenceClasses<GlobalValue*> GlobalECs;
356
357 public:
358   /// EquivClassGraphs - Computes the equivalence classes and then the
359   /// folded DS graphs for each class.
360   ///
361   virtual bool runOnModule(Module &M);
362
363   /// print - Print out the analysis results...
364   ///
365   void print(std::ostream &O, const Module *M) const;
366
367   EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
368
369   /// getDSGraph - Return the data structure graph for the specified function.
370   /// This returns the folded graph.  The folded graph is the same as the CBU
371   /// graph iff the function is in a singleton equivalence class AND all its
372   /// callees also have the same folded graph as the CBU graph.
373   ///
374   DSGraph &getDSGraph(const Function &F) const {
375     hash_map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
376     assert(I != DSInfo.end() && "No graph computed for that function!");
377     return *I->second;
378   }
379
380   bool hasGraph(const Function &F) const {
381     return DSInfo.find(&F) != DSInfo.end();
382   }
383
384   /// ContainsDSGraphFor - Return true if we have a graph for the specified
385   /// function.
386   bool ContainsDSGraphFor(const Function &F) const {
387     return DSInfo.find(&F) != DSInfo.end();
388   }
389
390   /// getSomeCalleeForCallSite - Return any one callee function at
391   /// a call site.
392   ///
393   Function *getSomeCalleeForCallSite(const CallSite &CS) const;
394
395   DSGraph &getGlobalsGraph() const {
396     return *GlobalsGraph;
397   }
398
399   typedef std::set<std::pair<Instruction*, Function*> > ActualCalleesTy;
400   const ActualCalleesTy &getActualCallees() const {
401     return ActualCallees;
402   }
403
404   typedef ActualCalleesTy::const_iterator callee_iterator;
405   callee_iterator callee_begin(Instruction *I) const {
406     return ActualCallees.lower_bound(std::pair<Instruction*,Function*>(I, 0));
407   }
408
409   callee_iterator callee_end(Instruction *I) const {
410     I = (Instruction*)((char*)I + 1);
411     return ActualCallees.lower_bound(std::pair<Instruction*,Function*>(I, 0));
412   }
413
414   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
415     AU.setPreservesAll();
416     AU.addRequired<CompleteBUDataStructures>();
417   }
418
419 private:
420   void buildIndirectFunctionSets(Module &M);
421
422   unsigned processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack,
423                       unsigned &NextID,
424                       std::map<DSGraph*, unsigned> &ValMap);
425   void processGraph(DSGraph &FG);
426
427   DSGraph &getOrCreateGraph(Function &F);
428 };
429
430 } // End llvm namespace
431
432 #endif