| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 1 | //===- BottomUpClosure.cpp - Compute bottom-up interprocedural closure ----===// | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 2 | // | 
 | 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 Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 6 | // applications like alias analysis. | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 |  | 
 | 10 | #include "llvm/Analysis/DataStructure.h" | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 11 | #include "llvm/Analysis/DSGraph.h" | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 12 | #include "llvm/Module.h" | 
| Chris Lattner | fccd06f | 2002-10-01 22:33:50 +0000 | [diff] [blame] | 13 | #include "Support/Statistic.h" | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 14 | using std::map; | 
 | 15 |  | 
| Chris Lattner | 1e43516 | 2002-07-26 21:12:44 +0000 | [diff] [blame] | 16 | static RegisterAnalysis<BUDataStructures> | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 17 | X("budatastructure", "Bottom-up Data Structure Analysis Closure"); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 18 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 19 | // TODO: FIXME | 
 | 20 | namespace DataStructureAnalysis { | 
 | 21 |   // isPointerType - Return true if this first class type is big enough to hold | 
 | 22 |   // a pointer. | 
 | 23 |   // | 
 | 24 |   bool isPointerType(const Type *Ty); | 
 | 25 | } | 
 | 26 | using namespace DataStructureAnalysis; | 
 | 27 |  | 
 | 28 |  | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 29 | // releaseMemory - If the pass pipeline is done with this pass, we can release | 
 | 30 | // our memory... here... | 
 | 31 | // | 
 | 32 | void BUDataStructures::releaseMemory() { | 
| Chris Lattner | 613692c | 2002-10-17 04:24:08 +0000 | [diff] [blame^] | 33 |   // Delete all call site information | 
 | 34 |   CallSites.clear(); | 
 | 35 |  | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 36 |   for (map<const Function*, DSGraph*>::iterator I = DSInfo.begin(), | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 37 |          E = DSInfo.end(); I != E; ++I) | 
 | 38 |     delete I->second; | 
 | 39 |  | 
 | 40 |   // Empty map so next time memory is released, data structures are not | 
 | 41 |   // re-deleted. | 
 | 42 |   DSInfo.clear(); | 
 | 43 | } | 
 | 44 |  | 
 | 45 | // run - Calculate the bottom up data structure graphs for each function in the | 
 | 46 | // program. | 
 | 47 | // | 
 | 48 | bool BUDataStructures::run(Module &M) { | 
 | 49 |   // Simply calculate the graphs for each function... | 
 | 50 |   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) | 
 | 51 |     if (!I->isExternal()) | 
 | 52 |       calculateGraph(*I); | 
 | 53 |   return false; | 
 | 54 | } | 
 | 55 |  | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 56 | // ResolveArguments - Resolve the formal and actual arguments for a function | 
 | 57 | // call. | 
 | 58 | // | 
 | 59 | static void ResolveArguments(std::vector<DSNodeHandle> &Call, Function &F, | 
 | 60 |                              map<Value*, DSNodeHandle> &ValueMap) { | 
 | 61 |   // Resolve all of the function arguments... | 
 | 62 |   Function::aiterator AI = F.abegin(); | 
 | 63 |   for (unsigned i = 2, e = Call.size(); i != e; ++i) { | 
 | 64 |     // Advance the argument iterator to the first pointer argument... | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 65 |     while (!isPointerType(AI->getType())) ++AI; | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 66 |      | 
 | 67 |     // Add the link from the argument scalar to the provided value | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 68 |     DSNodeHandle &NN = ValueMap[AI]; | 
 | 69 |     NN.addEdgeTo(Call[i]); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 70 |     ++AI; | 
 | 71 |   } | 
 | 72 | } | 
 | 73 |  | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 74 | // MergeGlobalNodes - Merge all existing global nodes with globals | 
 | 75 | // inlined from the callee or with globals from the GlobalsGraph. | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 76 | // | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 77 | static void MergeGlobalNodes(DSGraph &Graph, | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 78 |                              map<Value*, DSNodeHandle> &OldValMap) { | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 79 |   map<Value*, DSNodeHandle> &ValMap = Graph.getValueMap(); | 
 | 80 |   for (map<Value*, DSNodeHandle>::iterator I = ValMap.begin(), E = ValMap.end(); | 
 | 81 |        I != E; ++I) | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 82 |     if (GlobalValue *GV = dyn_cast<GlobalValue>(I->first)) { | 
 | 83 |       map<Value*, DSNodeHandle>::iterator NHI = OldValMap.find(GV); | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 84 |       if (NHI != OldValMap.end())       // was it inlined from the callee? | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 85 |         I->second.mergeWith(NHI->second); | 
 | 86 | #if 0 | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 87 |       else                              // get it from the GlobalsGraph | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 88 |         I->second.mergeWith(Graph.cloneGlobalInto(GV)); | 
 | 89 | #endif | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 90 |     } | 
 | 91 |  | 
 | 92 |   // Add unused inlined global nodes into the value map | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 93 |   for (map<Value*, DSNodeHandle>::iterator I = OldValMap.begin(), | 
 | 94 |          E = OldValMap.end(); I != E; ++I) | 
 | 95 |     if (isa<GlobalValue>(I->first)) { | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 96 |       DSNodeHandle &NH = ValMap[I->first];  // If global is not in ValMap... | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 97 |       if (NH.getNode() == 0) | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 98 |         NH = I->second;                     // Add the one just inlined. | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 99 |     } | 
 | 100 |  | 
 | 101 | } | 
 | 102 |  | 
 | 103 | DSGraph &BUDataStructures::calculateGraph(Function &F) { | 
 | 104 |   // Make sure this graph has not already been calculated, or that we don't get | 
 | 105 |   // into an infinite loop with mutually recursive functions. | 
 | 106 |   // | 
 | 107 |   DSGraph *&Graph = DSInfo[&F]; | 
 | 108 |   if (Graph) return *Graph; | 
 | 109 |  | 
 | 110 |   // Copy the local version into DSInfo... | 
 | 111 |   Graph = new DSGraph(getAnalysis<LocalDataStructures>().getDSGraph(F)); | 
 | 112 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 113 | #if 0 | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 114 |   // Populate the GlobalsGraph with globals from this one. | 
 | 115 |   Graph->GlobalsGraph->cloneGlobals(*Graph, /*cloneCalls*/ false); | 
 | 116 |  | 
| Vikram S. Adve | c44e9bf | 2002-07-18 16:13:52 +0000 | [diff] [blame] | 117 |   // Save a copy of the original call nodes for the top-down pass | 
 | 118 |   Graph->saveOrigFunctionCalls(); | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 119 | #endif | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 120 |  | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 121 |   // Start resolving calls... | 
 | 122 |   std::vector<std::vector<DSNodeHandle> > &FCs = Graph->getFunctionCalls(); | 
 | 123 |  | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 124 |   DEBUG(std::cerr << "  [BU] Inlining: " << F.getName() << "\n"); | 
 | 125 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 126 | #if 0 | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 127 |   // Add F to the PendingCallers list of each direct callee for use in the | 
 | 128 |   // top-down pass so we don't have to compute this again.  We don't want | 
 | 129 |   // to do it for indirect callees inlined later, so remember which calls | 
 | 130 |   // are in the original FCs set. | 
 | 131 |   std::set<const DSNode*> directCallees; | 
 | 132 |   for (unsigned i = 0; i < FCs.size(); ++i) | 
 | 133 |     directCallees.insert(FCs[i][1]); // ptr to function node | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 134 | #endif | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 135 |  | 
 | 136 |   bool Inlined; | 
 | 137 |   do { | 
 | 138 |     Inlined = false; | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 139 |  | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 140 |     for (unsigned i = 0; i != FCs.size(); ++i) { | 
 | 141 |       // Copy the call, because inlining graphs may invalidate the FCs vector. | 
 | 142 |       std::vector<DSNodeHandle> Call = FCs[i]; | 
 | 143 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 144 |       // If the function list is complete... | 
 | 145 |       if ((Call[1].getNode()->NodeType & DSNode::Incomplete) == 0) { | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 146 |         // Start inlining all of the functions we can... some may not be | 
 | 147 |         // inlinable if they are external... | 
 | 148 |         // | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 149 |         std::vector<GlobalValue*> Callees(Call[1].getNode()->getGlobals()); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 150 |  | 
 | 151 |         // Loop over the functions, inlining whatever we can... | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 152 |         for (unsigned c = 0; c != Callees.size(); ++c) { | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 153 |           // Must be a function type, so this cast MUST succeed. | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 154 |           Function &FI = cast<Function>(*Callees[c]); | 
| Chris Lattner | 613692c | 2002-10-17 04:24:08 +0000 | [diff] [blame^] | 155 |  | 
 | 156 |           // Record that this is a call site of FI. | 
 | 157 |           CallSites[&FI].push_back(CallSite(F, Call)); | 
 | 158 |  | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 159 |           if (&FI == &F) { | 
 | 160 |             // Self recursion... simply link up the formal arguments with the | 
 | 161 |             // actual arguments... | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 162 |  | 
 | 163 |             DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n"); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 164 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 165 |             if (Call[0].getNode()) // Handle the return value if present... | 
 | 166 |               Graph->getRetNode().mergeWith(Call[0]); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 167 |  | 
 | 168 |             // Resolve the arguments in the call to the actual values... | 
 | 169 |             ResolveArguments(Call, F, Graph->getValueMap()); | 
 | 170 |  | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 171 |             // Erase the entry in the callees vector | 
 | 172 |             Callees.erase(Callees.begin()+c--); | 
| Chris Lattner | 613692c | 2002-10-17 04:24:08 +0000 | [diff] [blame^] | 173 |  | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 174 |           } else if (!FI.isExternal()) { | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 175 |             DEBUG(std::cerr << "\t[BU] In " << F.getName() << " inlining: " | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 176 |                   << FI.getName() << "\n"); | 
| Vikram S. Adve | c44e9bf | 2002-07-18 16:13:52 +0000 | [diff] [blame] | 177 |              | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 178 |             // Get the data structure graph for the called function, closing it | 
 | 179 |             // if possible (which is only impossible in the case of mutual | 
 | 180 |             // recursion... | 
 | 181 |             // | 
 | 182 |             DSGraph &GI = calculateGraph(FI);  // Graph to inline | 
 | 183 |  | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 184 |             DEBUG(std::cerr << "\t\t[BU] Got graph for " << FI.getName() | 
 | 185 |                   << " in: " << F.getName() << "\n"); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 186 |  | 
| Vikram S. Adve | c44e9bf | 2002-07-18 16:13:52 +0000 | [diff] [blame] | 187 |             // Clone the callee's graph into the current graph, keeping | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 188 |             // track of where scalars in the old graph _used_ to point, | 
 | 189 |             // and of the new nodes matching nodes of the old graph. | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 190 |             map<Value*, DSNodeHandle> OldValMap; | 
 | 191 |             map<const DSNode*, DSNode*> OldNodeMap; | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 192 |  | 
 | 193 |             // The clone call may invalidate any of the vectors in the data | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 194 |             // structure graph.  Strip locals and don't copy the list of callers | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 195 |             DSNodeHandle RetVal = Graph->cloneInto(GI, OldValMap, OldNodeMap, | 
 | 196 |                                                    /*StripScalars*/   true, | 
 | 197 |                                                    /*StripAllocas*/   true, | 
 | 198 |                                                    /*CopyCallers*/    false, | 
 | 199 |                                                    /*CopyOrigCalls*/  false); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 200 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 201 |             // Resolve the arguments in the call to the actual values... | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 202 |             ResolveArguments(Call, FI, OldValMap); | 
 | 203 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 204 |             if (Call[0].getNode())  // Handle the return value if present | 
 | 205 |               RetVal.mergeWith(Call[0]); | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 206 |  | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 207 |             // Merge global value nodes in the inlined graph with the global | 
 | 208 |             // value nodes in the current graph if there are duplicates. | 
 | 209 |             // | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 210 |             MergeGlobalNodes(*Graph, OldValMap); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 211 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 212 | #if 0 | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 213 |             // If this was an original call, add F to the PendingCallers list | 
 | 214 |             if (directCallees.find(Call[1]) != directCallees.end()) | 
 | 215 |               GI.addCaller(F); | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 216 | #endif | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 217 |  | 
 | 218 |             // Erase the entry in the Callees vector | 
 | 219 |             Callees.erase(Callees.begin()+c--); | 
 | 220 |  | 
| Chris Lattner | 9eee58d | 2002-07-19 18:11:43 +0000 | [diff] [blame] | 221 |           } else if (FI.getName() == "printf" || FI.getName() == "sscanf" || | 
 | 222 |                      FI.getName() == "fprintf" || FI.getName() == "open" || | 
 | 223 |                      FI.getName() == "sprintf") { | 
 | 224 |  | 
 | 225 |             // Erase the entry in the globals vector | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 226 |             Callees.erase(Callees.begin()+c--); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 227 |           } | 
 | 228 |         } | 
 | 229 |  | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 230 |         if (Callees.empty()) {         // Inlined all of the function calls? | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 231 |           // Erase the call if it is resolvable... | 
 | 232 |           FCs.erase(FCs.begin()+i--);  // Don't skip a the next call... | 
 | 233 |           Inlined = true; | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 234 |         } else if (Callees.size() != Call[1].getNode()->getGlobals().size()) { | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 235 |           // Was able to inline SOME, but not all of the functions.  Construct a | 
 | 236 |           // new global node here. | 
 | 237 |           // | 
 | 238 |           assert(0 && "Unimpl!"); | 
 | 239 |           Inlined = true; | 
 | 240 |         } | 
 | 241 |       } | 
 | 242 |     } | 
 | 243 |  | 
 | 244 |     // Recompute the Incomplete markers.  If there are any function calls left | 
 | 245 |     // now that are complete, we must loop! | 
 | 246 |     if (Inlined) { | 
 | 247 |       Graph->maskIncompleteMarkers(); | 
 | 248 |       Graph->markIncompleteNodes(); | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 249 |       Graph->removeDeadNodes(/*KeepAllGlobals*/ true, /*KeepCalls*/ true); | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 250 |     } | 
 | 251 |   } while (Inlined && !FCs.empty()); | 
 | 252 |  | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 253 | #if 0 | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 254 |   // Copy any unresolved call nodes into the Globals graph and | 
 | 255 |   // filter out unresolved call nodes inlined from the callee. | 
 | 256 |   if (!FCs.empty()) | 
 | 257 |     Graph->GlobalsGraph->cloneCalls(*Graph); | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 258 | #endif | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 259 |  | 
 | 260 |   Graph->maskIncompleteMarkers(); | 
 | 261 |   Graph->markIncompleteNodes(); | 
| Chris Lattner | a00397e | 2002-10-03 21:55:28 +0000 | [diff] [blame] | 262 |   Graph->removeTriviallyDeadNodes(false); | 
| Chris Lattner | 55c1058 | 2002-10-03 20:38:41 +0000 | [diff] [blame] | 263 |   Graph->removeDeadNodes(/*KeepAllGlobals*/ true, /*KeepCalls*/ true); | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 264 |  | 
| Chris Lattner | 221c979 | 2002-08-07 21:41:11 +0000 | [diff] [blame] | 265 |   DEBUG(std::cerr << "  [BU] Done inlining: " << F.getName() << " [" | 
 | 266 |         << Graph->getGraphSize() << "+" << Graph->getFunctionCalls().size() | 
 | 267 |         << "]\n"); | 
| Vikram S. Adve | 355e2ca | 2002-07-30 22:05:22 +0000 | [diff] [blame] | 268 |  | 
| Chris Lattner | 0d9bab8 | 2002-07-18 00:12:30 +0000 | [diff] [blame] | 269 |   return *Graph; | 
 | 270 | } |