1 //===- DataStructure.h - Build data structure graphs ------------*- C++ -*-===//
3 // Implement the LLVM data structure analysis library.
5 //===----------------------------------------------------------------------===//
7 #ifndef LLVM_ANALYSIS_DATA_STRUCTURE_H
8 #define LLVM_ANALYSIS_DATA_STRUCTURE_H
10 #include "llvm/Pass.h"
18 // FIXME: move this stuff to a private header
19 namespace DataStructureAnalysis {
20 // isPointerType - Return true if this first class type is big enough to hold
23 bool isPointerType(const Type *Ty);
27 // LocalDataStructures - The analysis that computes the local data structure
28 // graphs for all of the functions in the program.
30 // FIXME: This should be a Function pass that can be USED by a Pass, and would
31 // be automatically preserved. Until we can do that, this is a Pass.
33 class LocalDataStructures : public Pass {
34 // DSInfo, one graph for each function
35 std::map<const Function*, DSGraph*> DSInfo;
36 DSGraph *GlobalsGraph;
38 ~LocalDataStructures() { releaseMemory(); }
40 virtual bool run(Module &M);
42 bool hasGraph(const Function &F) const {
43 return DSInfo.find(&F) != DSInfo.end();
46 // getDSGraph - Return the data structure graph for the specified function.
47 DSGraph &getDSGraph(const Function &F) const {
48 std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
49 assert(I != DSInfo.end() && "Function not in module!");
53 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
55 // print - Print out the analysis results...
56 void print(std::ostream &O, const Module *M) const;
58 // If the pass pipeline is done with this pass, we can release our memory...
59 virtual void releaseMemory();
61 // getAnalysisUsage - This obviously provides a data structure graph.
62 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
68 // BUDataStructures - The analysis that computes the interprocedurally closed
69 // data structure graphs for all of the functions in the program. This pass
70 // only performs a "Bottom Up" propagation (hence the name).
72 class BUDataStructures : public Pass {
73 // DSInfo, one graph for each function
74 std::map<const Function*, DSGraph*> DSInfo;
75 DSGraph *GlobalsGraph;
77 ~BUDataStructures() { releaseMemory(); }
79 virtual bool run(Module &M);
81 bool hasGraph(const Function &F) const {
82 return DSInfo.find(&F) != DSInfo.end();
85 // getDSGraph - Return the data structure graph for the specified function.
86 DSGraph &getDSGraph(const Function &F) const {
87 std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
88 assert(I != DSInfo.end() && "Function not in module!");
92 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
94 // print - Print out the analysis results...
95 void print(std::ostream &O, const Module *M) const;
97 // If the pass pipeline is done with this pass, we can release our memory...
98 virtual void releaseMemory();
100 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
101 AU.setPreservesAll();
102 AU.addRequired<LocalDataStructures>();
105 DSGraph &calculateGraph(Function &F);
106 DSGraph &calculateSCCGraph(Function &F,
107 std::set<Function*> &InlinedSCCFunctions);
108 void calculateReachableGraphs(Function *F);
111 DSGraph &getOrCreateGraph(Function *F);
113 unsigned calculateGraphs(Function *F, std::vector<Function*> &Stack,
115 std::map<Function*, unsigned> &ValMap);
119 bool ResolveFunctionCalls(DSGraph &G, unsigned &FirstResolvableCall,
120 std::map<Function*, DSCallSite> &InProcess,
126 // TDDataStructures - Analysis that computes new data structure graphs
127 // for each function using the closed graphs for the callers computed
128 // by the bottom-up pass.
130 class TDDataStructures : public Pass {
131 // DSInfo, one graph for each function
132 std::map<const Function*, DSGraph*> DSInfo;
133 std::set<const Function*> GraphDone;
134 DSGraph *GlobalsGraph;
136 ~TDDataStructures() { releaseMemory(); }
138 virtual bool run(Module &M);
140 bool hasGraph(const Function &F) const {
141 return DSInfo.find(&F) != DSInfo.end();
144 // getDSGraph - Return the data structure graph for the specified function.
145 DSGraph &getDSGraph(const Function &F) const {
146 std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
147 assert(I != DSInfo.end() && "Function not in module!");
151 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
153 // print - Print out the analysis results...
154 void print(std::ostream &O, const Module *M) const;
156 // If the pass pipeline is done with this pass, we can release our memory...
157 virtual void releaseMemory();
159 // getAnalysisUsage - This obviously provides a data structure graph.
160 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
161 AU.setPreservesAll();
162 AU.addRequired<BUDataStructures>();
165 void calculateGraph(Function &F);
166 DSGraph &getOrCreateDSGraph(Function &F);
168 void ResolveCallSite(DSGraph &Graph, const DSCallSite &CallSite);