blob: 8fa331c92d1773330aa405efc0540f4a05daced8 [file] [log] [blame]
Chris Lattner55c10582002-10-03 20:38:41 +00001//===- BottomUpClosure.cpp - Compute bottom-up interprocedural closure ----===//
Chris Lattner0d9bab82002-07-18 00:12:30 +00002//
3// This file implements the BUDataStructures class, which represents the
4// Bottom-Up Interprocedural closure of the data structure graph over the
5// program. This is useful for applications like pool allocation, but **not**
Chris Lattner55c10582002-10-03 20:38:41 +00006// applications like alias analysis.
Chris Lattner0d9bab82002-07-18 00:12:30 +00007//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Analysis/DataStructure.h"
Chris Lattner55c10582002-10-03 20:38:41 +000011#include "llvm/Analysis/DSGraph.h"
Chris Lattner0d9bab82002-07-18 00:12:30 +000012#include "llvm/Module.h"
Chris Lattnerfccd06f2002-10-01 22:33:50 +000013#include "Support/Statistic.h"
Chris Lattner41c04f72003-02-01 04:52:08 +000014#include "Support/hash_map"
Chris Lattner0d9bab82002-07-18 00:12:30 +000015
Chris Lattnerae5f6032002-11-17 22:16:28 +000016namespace {
17 Statistic<> MaxSCC("budatastructure", "Maximum SCC Size in Call Graph");
18
19 RegisterAnalysis<BUDataStructures>
20 X("budatastructure", "Bottom-up Data Structure Analysis Closure");
21}
Chris Lattner0d9bab82002-07-18 00:12:30 +000022
Chris Lattnerb1060432002-11-07 05:20:53 +000023using namespace DS;
Chris Lattner55c10582002-10-03 20:38:41 +000024
Chris Lattnera9c9c022002-11-11 21:35:13 +000025// isCompleteNode - Return true if we know all of the targets of this node, and
26// if the call sites are not external.
27//
28static inline bool isCompleteNode(DSNode *N) {
29 if (N->NodeType & DSNode::Incomplete) return false;
30 const std::vector<GlobalValue*> &Callees = N->getGlobals();
31 for (unsigned i = 0, e = Callees.size(); i != e; ++i)
32 if (Callees[i]->isExternal()) {
33 GlobalValue &FI = cast<Function>(*Callees[i]);
34 if (FI.getName() != "printf" && FI.getName() != "sscanf" &&
35 FI.getName() != "fprintf" && FI.getName() != "open" &&
Chris Lattner11d71ed2003-01-31 23:57:10 +000036 FI.getName() != "sprintf" && FI.getName() != "fputs" &&
37 FI.getName() != "fscanf")
Chris Lattnera9c9c022002-11-11 21:35:13 +000038 return false; // External function found...
39 }
40 return true; // otherwise ok
41}
42
43struct CallSiteIterator {
44 // FCs are the edges out of the current node are the call site targets...
45 std::vector<DSCallSite> *FCs;
46 unsigned CallSite;
47 unsigned CallSiteEntry;
48
49 CallSiteIterator(std::vector<DSCallSite> &CS) : FCs(&CS) {
50 CallSite = 0; CallSiteEntry = 0;
51 advanceToNextValid();
52 }
53
54 // End iterator ctor...
55 CallSiteIterator(std::vector<DSCallSite> &CS, bool) : FCs(&CS) {
56 CallSite = FCs->size(); CallSiteEntry = 0;
57 }
58
59 void advanceToNextValid() {
60 while (CallSite < FCs->size()) {
61 if (DSNode *CalleeNode = (*FCs)[CallSite].getCallee().getNode()) {
62 if (CallSiteEntry || isCompleteNode(CalleeNode)) {
63 const std::vector<GlobalValue*> &Callees = CalleeNode->getGlobals();
64
65 if (CallSiteEntry < Callees.size())
66 return;
67 }
68 CallSiteEntry = 0;
69 ++CallSite;
70 }
71 }
72 }
73public:
74 static CallSiteIterator begin(DSGraph &G) { return G.getAuxFunctionCalls(); }
75 static CallSiteIterator end(DSGraph &G) {
76 return CallSiteIterator(G.getAuxFunctionCalls(), true);
77 }
78 static CallSiteIterator begin(std::vector<DSCallSite> &CSs) { return CSs; }
79 static CallSiteIterator end(std::vector<DSCallSite> &CSs) {
80 return CallSiteIterator(CSs, true);
81 }
82 bool operator==(const CallSiteIterator &CSI) const {
83 return CallSite == CSI.CallSite && CallSiteEntry == CSI.CallSiteEntry;
84 }
85 bool operator!=(const CallSiteIterator &CSI) const { return !operator==(CSI);}
86
87 unsigned getCallSiteIdx() const { return CallSite; }
88 DSCallSite &getCallSite() const { return (*FCs)[CallSite]; }
89
90 Function* operator*() const {
91 DSNode *Node = (*FCs)[CallSite].getCallee().getNode();
92 return cast<Function>(Node->getGlobals()[CallSiteEntry]);
93 }
94
95 CallSiteIterator& operator++() { // Preincrement
96 ++CallSiteEntry;
97 advanceToNextValid();
98 return *this;
99 }
100 CallSiteIterator operator++(int) { // Postincrement
101 CallSiteIterator tmp = *this; ++*this; return tmp;
102 }
103};
104
105
106
Chris Lattneraa0b4682002-11-09 21:12:07 +0000107// run - Calculate the bottom up data structure graphs for each function in the
108// program.
109//
110bool BUDataStructures::run(Module &M) {
111 GlobalsGraph = new DSGraph();
112
Chris Lattnera9c9c022002-11-11 21:35:13 +0000113 Function *MainFunc = M.getMainFunction();
114 if (MainFunc)
115 calculateReachableGraphs(MainFunc);
116
117 // Calculate the graphs for any functions that are unreachable from main...
Chris Lattneraa0b4682002-11-09 21:12:07 +0000118 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Chris Lattnera9c9c022002-11-11 21:35:13 +0000119 if (!I->isExternal() && DSInfo.find(I) == DSInfo.end()) {
Chris Lattnerae5f6032002-11-17 22:16:28 +0000120#ifndef NDEBUG
Chris Lattnera9c9c022002-11-11 21:35:13 +0000121 if (MainFunc)
122 std::cerr << "*** Function unreachable from main: "
123 << I->getName() << "\n";
Chris Lattnerae5f6032002-11-17 22:16:28 +0000124#endif
Chris Lattnera9c9c022002-11-11 21:35:13 +0000125 calculateReachableGraphs(I); // Calculate all graphs...
126 }
Chris Lattneraa0b4682002-11-09 21:12:07 +0000127 return false;
128}
Chris Lattner55c10582002-10-03 20:38:41 +0000129
Chris Lattnera9c9c022002-11-11 21:35:13 +0000130void BUDataStructures::calculateReachableGraphs(Function *F) {
131 std::vector<Function*> Stack;
Chris Lattner41c04f72003-02-01 04:52:08 +0000132 hash_map<Function*, unsigned> ValMap;
Chris Lattnera9c9c022002-11-11 21:35:13 +0000133 unsigned NextID = 1;
134 calculateGraphs(F, Stack, NextID, ValMap);
135}
136
137DSGraph &BUDataStructures::getOrCreateGraph(Function *F) {
138 // Has the graph already been created?
139 DSGraph *&Graph = DSInfo[F];
140 if (Graph) return *Graph;
141
142 // Copy the local version into DSInfo...
143 Graph = new DSGraph(getAnalysis<LocalDataStructures>().getDSGraph(*F));
144
145 Graph->setGlobalsGraph(GlobalsGraph);
146 Graph->setPrintAuxCalls();
147
148 // Start with a copy of the original call sites...
149 Graph->getAuxFunctionCalls() = Graph->getFunctionCalls();
150 return *Graph;
151}
152
153unsigned BUDataStructures::calculateGraphs(Function *F,
154 std::vector<Function*> &Stack,
155 unsigned &NextID,
Chris Lattner41c04f72003-02-01 04:52:08 +0000156 hash_map<Function*, unsigned> &ValMap) {
Chris Lattnera9c9c022002-11-11 21:35:13 +0000157 assert(ValMap.find(F) == ValMap.end() && "Shouldn't revisit functions!");
158 unsigned Min = NextID++, MyID = Min;
159 ValMap[F] = Min;
160 Stack.push_back(F);
161
162 if (F->isExternal()) { // sprintf, fprintf, sscanf, etc...
163 // No callees!
164 Stack.pop_back();
165 ValMap[F] = ~0;
166 return Min;
167 }
168
169 DSGraph &Graph = getOrCreateGraph(F);
170
171 // The edges out of the current node are the call site targets...
172 for (CallSiteIterator I = CallSiteIterator::begin(Graph),
173 E = CallSiteIterator::end(Graph); I != E; ++I) {
174 Function *Callee = *I;
175 unsigned M;
176 // Have we visited the destination function yet?
Chris Lattner41c04f72003-02-01 04:52:08 +0000177 hash_map<Function*, unsigned>::iterator It = ValMap.find(Callee);
Chris Lattnera9c9c022002-11-11 21:35:13 +0000178 if (It == ValMap.end()) // No, visit it now.
179 M = calculateGraphs(Callee, Stack, NextID, ValMap);
180 else // Yes, get it's number.
181 M = It->second;
182 if (M < Min) Min = M;
183 }
184
185 assert(ValMap[F] == MyID && "SCC construction assumption wrong!");
186 if (Min != MyID)
187 return Min; // This is part of a larger SCC!
188
189 // If this is a new SCC, process it now.
190 if (Stack.back() == F) { // Special case the single "SCC" case here.
191 DEBUG(std::cerr << "Visiting single node SCC #: " << MyID << " fn: "
192 << F->getName() << "\n");
193 Stack.pop_back();
194 DSGraph &G = calculateGraph(*F);
195
Chris Lattnerae5f6032002-11-17 22:16:28 +0000196 if (MaxSCC < 1) MaxSCC = 1;
197
Chris Lattnera9c9c022002-11-11 21:35:13 +0000198 // Should we revisit the graph?
199 if (CallSiteIterator::begin(G) != CallSiteIterator::end(G)) {
200 ValMap.erase(F);
201 return calculateGraphs(F, Stack, NextID, ValMap);
202 } else {
203 ValMap[F] = ~0U;
204 }
205 return MyID;
206
207 } else {
208 // SCCFunctions - Keep track of the functions in the current SCC
209 //
Chris Lattner41c04f72003-02-01 04:52:08 +0000210 hash_set<Function*> SCCFunctions;
Chris Lattnera9c9c022002-11-11 21:35:13 +0000211
212 Function *NF;
213 std::vector<Function*>::iterator FirstInSCC = Stack.end();
214 do {
215 NF = *--FirstInSCC;
216 ValMap[NF] = ~0U;
217 SCCFunctions.insert(NF);
218 } while (NF != F);
219
220 std::cerr << "Identified SCC #: " << MyID << " of size: "
221 << (Stack.end()-FirstInSCC) << "\n";
222
Chris Lattnerae5f6032002-11-17 22:16:28 +0000223 // Compute the Max SCC Size...
224 if (MaxSCC < unsigned(Stack.end()-FirstInSCC))
225 MaxSCC = Stack.end()-FirstInSCC;
226
Chris Lattnera9c9c022002-11-11 21:35:13 +0000227 std::vector<Function*>::iterator I = Stack.end();
228 do {
229 --I;
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000230#ifndef NDEBUG
Chris Lattnera9c9c022002-11-11 21:35:13 +0000231 /*DEBUG*/(std::cerr << " Fn #" << (Stack.end()-I) << "/"
232 << (Stack.end()-FirstInSCC) << " in SCC: "
233 << (*I)->getName());
234 DSGraph &G = getDSGraph(**I);
235 std::cerr << " [" << G.getGraphSize() << "+"
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000236 << G.getAuxFunctionCalls().size() << "] ";
237#endif
Chris Lattnera9c9c022002-11-11 21:35:13 +0000238
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000239 // Eliminate all call sites in the SCC that are not to functions that are
240 // in the SCC.
241 inlineNonSCCGraphs(**I, SCCFunctions);
242
243#ifndef NDEBUG
244 std::cerr << "after Non-SCC's [" << G.getGraphSize() << "+"
245 << G.getAuxFunctionCalls().size() << "]\n";
246#endif
247 } while (I != FirstInSCC);
248
249 I = Stack.end();
250 do {
251 --I;
252#ifndef NDEBUG
253 /*DEBUG*/(std::cerr << " Fn #" << (Stack.end()-I) << "/"
254 << (Stack.end()-FirstInSCC) << " in SCC: "
255 << (*I)->getName());
256 DSGraph &G = getDSGraph(**I);
257 std::cerr << " [" << G.getGraphSize() << "+"
258 << G.getAuxFunctionCalls().size() << "] ";
259#endif
260 // Inline all graphs into the SCC nodes...
Chris Lattnera9c9c022002-11-11 21:35:13 +0000261 calculateSCCGraph(**I, SCCFunctions);
262
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000263#ifndef NDEBUG
Chris Lattnera9c9c022002-11-11 21:35:13 +0000264 std::cerr << "after [" << G.getGraphSize() << "+"
265 << G.getAuxFunctionCalls().size() << "]\n";
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000266#endif
Chris Lattnera9c9c022002-11-11 21:35:13 +0000267 } while (I != FirstInSCC);
268
269
270 std::cerr << "DONE with SCC #: " << MyID << "\n";
271
272 // We never have to revisit "SCC" processed functions...
273
274 // Drop the stuff we don't need from the end of the stack
275 Stack.erase(FirstInSCC, Stack.end());
276 return MyID;
277 }
278
279 return MyID; // == Min
280}
281
282
Chris Lattner0d9bab82002-07-18 00:12:30 +0000283// releaseMemory - If the pass pipeline is done with this pass, we can release
284// our memory... here...
285//
286void BUDataStructures::releaseMemory() {
Chris Lattner41c04f72003-02-01 04:52:08 +0000287 for (hash_map<const Function*, DSGraph*>::iterator I = DSInfo.begin(),
Chris Lattner0d9bab82002-07-18 00:12:30 +0000288 E = DSInfo.end(); I != E; ++I)
289 delete I->second;
290
291 // Empty map so next time memory is released, data structures are not
292 // re-deleted.
293 DSInfo.clear();
Chris Lattneraa0b4682002-11-09 21:12:07 +0000294 delete GlobalsGraph;
295 GlobalsGraph = 0;
Chris Lattner0d9bab82002-07-18 00:12:30 +0000296}
297
Chris Lattnera9c9c022002-11-11 21:35:13 +0000298DSGraph &BUDataStructures::calculateGraph(Function &F) {
299 DSGraph &Graph = getDSGraph(F);
300 DEBUG(std::cerr << " [BU] Calculating graph for: " << F.getName() << "\n");
Chris Lattner8a5db462002-11-11 00:01:34 +0000301
Chris Lattnera9c9c022002-11-11 21:35:13 +0000302 // Move our call site list into TempFCs so that inline call sites go into the
303 // new call site list and doesn't invalidate our iterators!
304 std::vector<DSCallSite> TempFCs;
305 std::vector<DSCallSite> &AuxCallsList = Graph.getAuxFunctionCalls();
306 TempFCs.swap(AuxCallsList);
Chris Lattner8a5db462002-11-11 00:01:34 +0000307
Chris Lattnera9c9c022002-11-11 21:35:13 +0000308 // Loop over all of the resolvable call sites
309 unsigned LastCallSiteIdx = ~0U;
310 for (CallSiteIterator I = CallSiteIterator::begin(TempFCs),
311 E = CallSiteIterator::end(TempFCs); I != E; ++I) {
312 // If we skipped over any call sites, they must be unresolvable, copy them
313 // to the real call site list.
314 LastCallSiteIdx++;
315 for (; LastCallSiteIdx < I.getCallSiteIdx(); ++LastCallSiteIdx)
316 AuxCallsList.push_back(TempFCs[LastCallSiteIdx]);
317 LastCallSiteIdx = I.getCallSiteIdx();
Chris Lattnera1079052002-11-10 06:52:47 +0000318
Chris Lattnera9c9c022002-11-11 21:35:13 +0000319 // Resolve the current call...
320 Function *Callee = *I;
321 DSCallSite &CS = I.getCallSite();
Chris Lattner0d9bab82002-07-18 00:12:30 +0000322
Chris Lattnera9c9c022002-11-11 21:35:13 +0000323 if (Callee->isExternal()) {
324 // Ignore this case, simple varargs functions we cannot stub out!
325 } else if (Callee == &F) {
326 // Self recursion... simply link up the formal arguments with the
327 // actual arguments...
328 DEBUG(std::cerr << " Self Inlining: " << F.getName() << "\n");
329
330 // Handle self recursion by resolving the arguments and return value
331 Graph.mergeInGraph(CS, Graph, 0);
332
333 } else {
334 // Get the data structure graph for the called function.
335 //
336 DSGraph &GI = getDSGraph(*Callee); // Graph to inline
337
338 DEBUG(std::cerr << " Inlining graph for " << Callee->getName()
339 << " in: " << F.getName() << "[" << GI.getGraphSize() << "+"
340 << GI.getAuxFunctionCalls().size() << "]\n");
Chris Lattnerae5f6032002-11-17 22:16:28 +0000341
342#if 0
343 Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_before_" +
344 Callee->getName());
345#endif
Chris Lattnera9c9c022002-11-11 21:35:13 +0000346
347 // Handle self recursion by resolving the arguments and return value
Vikram S. Adve61ff0292002-11-27 17:41:13 +0000348 Graph.mergeInGraph(CS, GI,
349 DSGraph::KeepModRefBits |
350 DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes);
Chris Lattnerae5f6032002-11-17 22:16:28 +0000351
352#if 0
353 Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_after_" +
354 Callee->getName());
355#endif
Chris Lattnera9c9c022002-11-11 21:35:13 +0000356 }
357 }
358
359 // Make sure to catch any leftover unresolvable calls...
360 for (++LastCallSiteIdx; LastCallSiteIdx < TempFCs.size(); ++LastCallSiteIdx)
361 AuxCallsList.push_back(TempFCs[LastCallSiteIdx]);
362
363 TempFCs.clear();
364
365 // Recompute the Incomplete markers. If there are any function calls left
366 // now that are complete, we must loop!
367 Graph.maskIncompleteMarkers();
Chris Lattner394471f2003-01-23 22:05:33 +0000368 Graph.markIncompleteNodes(DSGraph::MarkFormalArgs);
369 Graph.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
Chris Lattnera9c9c022002-11-11 21:35:13 +0000370
371 DEBUG(std::cerr << " [BU] Done inlining: " << F.getName() << " ["
Chris Lattner8a5db462002-11-11 00:01:34 +0000372 << Graph.getGraphSize() << "+" << Graph.getAuxFunctionCalls().size()
Chris Lattner221c9792002-08-07 21:41:11 +0000373 << "]\n");
Vikram S. Adve355e2ca2002-07-30 22:05:22 +0000374
Chris Lattnera9c9c022002-11-11 21:35:13 +0000375 //Graph.writeGraphToFile(std::cerr, "bu_" + F.getName());
376
377 return Graph;
378}
379
380
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000381// inlineNonSCCGraphs - This method is almost like the other two calculate graph
382// methods. This one is used to inline function graphs (from functions outside
383// of the SCC) into functions in the SCC. It is not supposed to touch functions
384// IN the SCC at all.
385//
386DSGraph &BUDataStructures::inlineNonSCCGraphs(Function &F,
Chris Lattner41c04f72003-02-01 04:52:08 +0000387 hash_set<Function*> &SCCFunctions){
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000388 DSGraph &Graph = getDSGraph(F);
389 DEBUG(std::cerr << " [BU] Inlining Non-SCC graphs for: "
390 << F.getName() << "\n");
391
392 // Move our call site list into TempFCs so that inline call sites go into the
393 // new call site list and doesn't invalidate our iterators!
394 std::vector<DSCallSite> TempFCs;
395 std::vector<DSCallSite> &AuxCallsList = Graph.getAuxFunctionCalls();
396 TempFCs.swap(AuxCallsList);
397
398 // Loop over all of the resolvable call sites
399 unsigned LastCallSiteIdx = ~0U;
400 for (CallSiteIterator I = CallSiteIterator::begin(TempFCs),
401 E = CallSiteIterator::end(TempFCs); I != E; ++I) {
402 // If we skipped over any call sites, they must be unresolvable, copy them
403 // to the real call site list.
404 LastCallSiteIdx++;
405 for (; LastCallSiteIdx < I.getCallSiteIdx(); ++LastCallSiteIdx)
406 AuxCallsList.push_back(TempFCs[LastCallSiteIdx]);
407 LastCallSiteIdx = I.getCallSiteIdx();
408
409 // Resolve the current call...
410 Function *Callee = *I;
411 DSCallSite &CS = I.getCallSite();
412
413 if (Callee->isExternal()) {
414 // Ignore this case, simple varargs functions we cannot stub out!
415 } else if (SCCFunctions.count(Callee)) {
416 // Calling a function in the SCC, ignore it for now!
417 DEBUG(std::cerr << " SCC CallSite for: " << Callee->getName() << "\n");
418 AuxCallsList.push_back(CS);
419 } else {
420 // Get the data structure graph for the called function.
421 //
422 DSGraph &GI = getDSGraph(*Callee); // Graph to inline
423
424 DEBUG(std::cerr << " Inlining graph for " << Callee->getName()
425 << " in: " << F.getName() << "[" << GI.getGraphSize() << "+"
426 << GI.getAuxFunctionCalls().size() << "]\n");
Chris Lattnerae5f6032002-11-17 22:16:28 +0000427
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000428 // Handle self recursion by resolving the arguments and return value
Vikram S. Adve61ff0292002-11-27 17:41:13 +0000429 Graph.mergeInGraph(CS, GI,
430 DSGraph::KeepModRefBits | DSGraph::StripAllocaBit |
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000431 DSGraph::DontCloneCallNodes);
432 }
433 }
434
435 // Make sure to catch any leftover unresolvable calls...
436 for (++LastCallSiteIdx; LastCallSiteIdx < TempFCs.size(); ++LastCallSiteIdx)
437 AuxCallsList.push_back(TempFCs[LastCallSiteIdx]);
438
439 TempFCs.clear();
440
441 // Recompute the Incomplete markers. If there are any function calls left
442 // now that are complete, we must loop!
443 Graph.maskIncompleteMarkers();
Chris Lattner394471f2003-01-23 22:05:33 +0000444 Graph.markIncompleteNodes(DSGraph::MarkFormalArgs);
445 Graph.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000446
447 DEBUG(std::cerr << " [BU] Done Non-SCC inlining: " << F.getName() << " ["
448 << Graph.getGraphSize() << "+" << Graph.getAuxFunctionCalls().size()
449 << "]\n");
450
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000451 return Graph;
452}
453
454
Chris Lattnera9c9c022002-11-11 21:35:13 +0000455DSGraph &BUDataStructures::calculateSCCGraph(Function &F,
Chris Lattner41c04f72003-02-01 04:52:08 +0000456 hash_set<Function*> &SCCFunctions){
Chris Lattnera9c9c022002-11-11 21:35:13 +0000457 DSGraph &Graph = getDSGraph(F);
458 DEBUG(std::cerr << " [BU] Calculating SCC graph for: " << F.getName()<<"\n");
459
460 std::vector<DSCallSite> UnresolvableCalls;
Chris Lattner41c04f72003-02-01 04:52:08 +0000461 hash_map<Function*, DSCallSite> SCCCallSiteMap;
Chris Lattnera9c9c022002-11-11 21:35:13 +0000462 std::vector<DSCallSite> &AuxCallsList = Graph.getAuxFunctionCalls();
463
464 while (1) { // Loop until we run out of resolvable call sites!
465 // Move our call site list into TempFCs so that inline call sites go into
466 // the new call site list and doesn't invalidate our iterators!
467 std::vector<DSCallSite> TempFCs;
468 TempFCs.swap(AuxCallsList);
469
470 // Loop over all of the resolvable call sites
471 unsigned LastCallSiteIdx = ~0U;
472 CallSiteIterator I = CallSiteIterator::begin(TempFCs),
473 E = CallSiteIterator::end(TempFCs);
474 if (I == E) {
475 TempFCs.swap(AuxCallsList);
476 break; // Done when no resolvable call sites exist
477 }
478
479 for (; I != E; ++I) {
480 // If we skipped over any call sites, they must be unresolvable, copy them
481 // to the unresolvable site list.
482 LastCallSiteIdx++;
483 for (; LastCallSiteIdx < I.getCallSiteIdx(); ++LastCallSiteIdx)
484 UnresolvableCalls.push_back(TempFCs[LastCallSiteIdx]);
485 LastCallSiteIdx = I.getCallSiteIdx();
486
487 // Resolve the current call...
488 Function *Callee = *I;
489 DSCallSite &CS = I.getCallSite();
490
491 if (Callee->isExternal()) {
492 // Ignore this case, simple varargs functions we cannot stub out!
493 } else if (Callee == &F) {
494 // Self recursion... simply link up the formal arguments with the
495 // actual arguments...
496 DEBUG(std::cerr << " Self Inlining: " << F.getName() << "\n");
497
498 // Handle self recursion by resolving the arguments and return value
499 Graph.mergeInGraph(CS, Graph, 0);
500 } else if (SCCCallSiteMap.count(Callee)) {
501 // We have already seen a call site in the SCC for this function, just
502 // merge the two call sites together and we are done.
503 SCCCallSiteMap.find(Callee)->second.mergeWith(CS);
504 } else {
505 // Get the data structure graph for the called function.
506 //
507 DSGraph &GI = getDSGraph(*Callee); // Graph to inline
508
509 DEBUG(std::cerr << " Inlining graph for " << Callee->getName()
510 << " in: " << F.getName() << "[" << GI.getGraphSize() << "+"
511 << GI.getAuxFunctionCalls().size() << "]\n");
512
513 // Handle self recursion by resolving the arguments and return value
Vikram S. Adve61ff0292002-11-27 17:41:13 +0000514 Graph.mergeInGraph(CS, GI,
515 DSGraph::KeepModRefBits | DSGraph::StripAllocaBit |
Chris Lattnera9c9c022002-11-11 21:35:13 +0000516 DSGraph::DontCloneCallNodes);
517
Chris Lattner5f1f2c62002-11-12 15:58:08 +0000518 if (SCCFunctions.count(Callee))
Chris Lattnera9c9c022002-11-11 21:35:13 +0000519 SCCCallSiteMap.insert(std::make_pair(Callee, CS));
520 }
521 }
522
523 // Make sure to catch any leftover unresolvable calls...
524 for (++LastCallSiteIdx; LastCallSiteIdx < TempFCs.size(); ++LastCallSiteIdx)
525 UnresolvableCalls.push_back(TempFCs[LastCallSiteIdx]);
526 }
527
528 // Reset the SCCCallSiteMap...
529 SCCCallSiteMap.clear();
530
531 AuxCallsList.insert(AuxCallsList.end(), UnresolvableCalls.begin(),
532 UnresolvableCalls.end());
533 UnresolvableCalls.clear();
534
535
536 // Recompute the Incomplete markers. If there are any function calls left
537 // now that are complete, we must loop!
538 Graph.maskIncompleteMarkers();
Chris Lattner394471f2003-01-23 22:05:33 +0000539 Graph.markIncompleteNodes(DSGraph::MarkFormalArgs);
540 Graph.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
Chris Lattnera9c9c022002-11-11 21:35:13 +0000541
542 DEBUG(std::cerr << " [BU] Done inlining: " << F.getName() << " ["
543 << Graph.getGraphSize() << "+" << Graph.getAuxFunctionCalls().size()
544 << "]\n");
Chris Lattnera9c9c022002-11-11 21:35:13 +0000545 //Graph.writeGraphToFile(std::cerr, "bu_" + F.getName());
Chris Lattnera1079052002-11-10 06:52:47 +0000546
Chris Lattner8a5db462002-11-11 00:01:34 +0000547 return Graph;
Chris Lattner0d9bab82002-07-18 00:12:30 +0000548}