1 //===- DataStructure.h - Build data structure graphs ------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // Implement the LLVM data structure analysis library.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_ANALYSIS_DATA_STRUCTURE_H
15 #define LLVM_ANALYSIS_DATA_STRUCTURE_H
17 #include "llvm/Pass.h"
18 #include "llvm/Target/TargetData.h"
19 #include "llvm/ADT/hash_map"
20 #include "llvm/ADT/hash_set"
29 // FIXME: move this stuff to a private header
30 namespace DataStructureAnalysis {
31 /// isPointerType - Return true if this first class type is big enough to hold
34 bool isPointerType(const Type *Ty);
38 // LocalDataStructures - The analysis that computes the local data structure
39 // graphs for all of the functions in the program.
41 // FIXME: This should be a Function pass that can be USED by a Pass, and would
42 // be automatically preserved. Until we can do that, this is a Pass.
44 class LocalDataStructures : public ModulePass {
45 // DSInfo, one graph for each function
46 hash_map<Function*, DSGraph*> DSInfo;
47 DSGraph *GlobalsGraph;
49 ~LocalDataStructures() { releaseMemory(); }
51 virtual bool runOnModule(Module &M);
53 bool hasGraph(const Function &F) const {
54 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
57 /// getDSGraph - Return the data structure graph for the specified function.
59 DSGraph &getDSGraph(const Function &F) const {
60 hash_map<Function*, DSGraph*>::const_iterator I =
61 DSInfo.find(const_cast<Function*>(&F));
62 assert(I != DSInfo.end() && "Function not in module!");
66 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
68 /// print - Print out the analysis results...
70 void print(std::ostream &O, const Module *M) const;
72 /// releaseMemory - if the pass pipeline is done with this pass, we can
73 /// release our memory...
75 virtual void releaseMemory();
77 /// getAnalysisUsage - This obviously provides a data structure graph.
79 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
81 AU.addRequired<TargetData>();
86 /// BUDataStructures - The analysis that computes the interprocedurally closed
87 /// data structure graphs for all of the functions in the program. This pass
88 /// only performs a "Bottom Up" propagation (hence the name).
90 class BUDataStructures : public ModulePass {
92 // DSInfo, one graph for each function
93 hash_map<Function*, DSGraph*> DSInfo;
94 DSGraph *GlobalsGraph;
95 hash_multimap<Instruction*, Function*> ActualCallees;
97 ~BUDataStructures() { releaseMemory(); }
99 virtual bool runOnModule(Module &M);
101 bool hasGraph(const Function &F) const {
102 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
105 /// getDSGraph - Return the data structure graph for the specified function.
107 DSGraph &getDSGraph(const Function &F) const {
108 hash_map<Function*, DSGraph*>::const_iterator I =
109 DSInfo.find(const_cast<Function*>(&F));
110 assert(I != DSInfo.end() && "Function not in module!");
114 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
116 /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
117 /// These correspond to the interfaces defined in the AliasAnalysis class.
118 void deleteValue(Value *V);
119 void copyValue(Value *From, Value *To);
121 /// print - Print out the analysis results...
123 void print(std::ostream &O, const Module *M) const;
125 /// releaseMemory - if the pass pipeline is done with this pass, we can
126 /// release our memory...
128 virtual void releaseMemory();
130 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
131 AU.setPreservesAll();
132 AU.addRequired<LocalDataStructures>();
135 typedef hash_multimap<Instruction*, Function*> ActualCalleesTy;
136 const ActualCalleesTy &getActualCallees() const {
137 return ActualCallees;
141 void calculateGraph(DSGraph &G);
143 void calculateReachableGraphs(Function *F);
146 DSGraph &getOrCreateGraph(Function *F);
148 unsigned calculateGraphs(Function *F, std::vector<Function*> &Stack,
150 hash_map<Function*, unsigned> &ValMap);
154 /// TDDataStructures - Analysis that computes new data structure graphs
155 /// for each function using the closed graphs for the callers computed
156 /// by the bottom-up pass.
158 class TDDataStructures : public ModulePass {
159 // DSInfo, one graph for each function
160 hash_map<Function*, DSGraph*> DSInfo;
161 hash_set<Function*> ArgsRemainIncomplete;
162 DSGraph *GlobalsGraph;
164 ~TDDataStructures() { releaseMyMemory(); }
166 virtual bool runOnModule(Module &M);
168 bool hasGraph(const Function &F) const {
169 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
172 /// getDSGraph - Return the data structure graph for the specified function.
174 DSGraph &getDSGraph(const Function &F) const {
175 hash_map<Function*, DSGraph*>::const_iterator I =
176 DSInfo.find(const_cast<Function*>(&F));
177 assert(I != DSInfo.end() && "Function not in module!");
181 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
183 /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
184 /// These correspond to the interfaces defined in the AliasAnalysis class.
185 void deleteValue(Value *V);
186 void copyValue(Value *From, Value *To);
188 /// print - Print out the analysis results...
190 void print(std::ostream &O, const Module *M) const;
192 /// If the pass pipeline is done with this pass, we can release our memory...
194 virtual void releaseMyMemory();
196 /// getAnalysisUsage - This obviously provides a data structure graph.
198 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
199 AU.setPreservesAll();
200 AU.addRequired<BUDataStructures>();
204 void markReachableFunctionsExternallyAccessible(DSNode *N,
205 hash_set<DSNode*> &Visited);
207 void inlineGraphIntoCallees(DSGraph &G);
208 DSGraph &getOrCreateDSGraph(Function &F);
209 void ComputePostOrder(Function &F, hash_set<DSGraph*> &Visited,
210 std::vector<DSGraph*> &PostOrder,
211 const BUDataStructures::ActualCalleesTy &ActualCallees);
215 /// CompleteBUDataStructures - This is the exact same as the bottom-up graphs,
216 /// but we use take a completed call graph and inline all indirect callees into
217 /// their callers graphs, making the result more useful for things like pool
220 struct CompleteBUDataStructures : public BUDataStructures {
221 virtual bool runOnModule(Module &M);
223 bool hasGraph(const Function &F) const {
224 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
227 /// getDSGraph - Return the data structure graph for the specified function.
229 DSGraph &getDSGraph(const Function &F) const {
230 hash_map<Function*, DSGraph*>::const_iterator I =
231 DSInfo.find(const_cast<Function*>(&F));
232 assert(I != DSInfo.end() && "Function not in module!");
236 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
237 AU.setPreservesAll();
238 AU.addRequired<BUDataStructures>();
240 // FIXME: TEMPORARY (remove once finalization of indirect call sites in the
241 // globals graph has been implemented in the BU pass)
242 AU.addRequired<TDDataStructures>();
245 /// print - Print out the analysis results...
247 void print(std::ostream &O, const Module *M) const;
250 unsigned calculateSCCGraphs(DSGraph &FG, std::vector<DSGraph*> &Stack,
252 hash_map<DSGraph*, unsigned> &ValMap);
253 DSGraph &getOrCreateGraph(Function &F);
254 void processGraph(DSGraph &G);
257 } // End llvm namespace