From 55c1058135def83aa57e06d12984bc4a378fd757 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 3 Oct 2002 20:38:41 +0000 Subject: [PATCH] Reimplement/port the Bottom Up Closure pass git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4031 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../DataStructure/BottomUpClosure.cpp | 86 +++++++++++-------- lib/Analysis/DataStructure/Printer.cpp | 13 ++- 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/lib/Analysis/DataStructure/BottomUpClosure.cpp b/lib/Analysis/DataStructure/BottomUpClosure.cpp index c3d19d4bc22..11ee6065d19 100644 --- a/lib/Analysis/DataStructure/BottomUpClosure.cpp +++ b/lib/Analysis/DataStructure/BottomUpClosure.cpp @@ -1,24 +1,33 @@ -//===- BottomUpClosure.cpp - Compute the bottom up interprocedure closure -===// +//===- BottomUpClosure.cpp - Compute bottom-up interprocedural closure ----===// // // This file implements the BUDataStructures class, which represents the // Bottom-Up Interprocedural closure of the data structure graph over the // program. This is useful for applications like pool allocation, but **not** -// applications like pointer analysis. +// applications like alias analysis. // //===----------------------------------------------------------------------===// #include "llvm/Analysis/DataStructure.h" +#include "llvm/Analysis/DSGraph.h" #include "llvm/Module.h" -#include "llvm/DerivedTypes.h" +//#include "llvm/DerivedTypes.h" #include "Support/Statistic.h" -#include +//#include using std::map; -#if 0 - static RegisterAnalysis X("budatastructure", "Bottom-up Data Structure Analysis Closure"); +// TODO: FIXME +namespace DataStructureAnalysis { + // isPointerType - Return true if this first class type is big enough to hold + // a pointer. + // + bool isPointerType(const Type *Ty); +} +using namespace DataStructureAnalysis; + + // releaseMemory - If the pass pipeline is done with this pass, we can release // our memory... here... // @@ -43,7 +52,6 @@ bool BUDataStructures::run(Module &M) { return false; } - // ResolveArguments - Resolve the formal and actual arguments for a function // call. // @@ -53,11 +61,11 @@ static void ResolveArguments(std::vector &Call, Function &F, Function::aiterator AI = F.abegin(); for (unsigned i = 2, e = Call.size(); i != e; ++i) { // Advance the argument iterator to the first pointer argument... - while (!isa(AI->getType())) ++AI; + while (!isPointerType(AI->getType())) ++AI; // Add the link from the argument scalar to the provided value - DSNode *NN = ValueMap[AI]; - NN->addEdgeTo(Call[i]); + DSNodeHandle &NN = ValueMap[AI]; + NN.addEdgeTo(Call[i]); ++AI; } } @@ -65,17 +73,19 @@ static void ResolveArguments(std::vector &Call, Function &F, // MergeGlobalNodes - Merge all existing global nodes with globals // inlined from the callee or with globals from the GlobalsGraph. // -static void MergeGlobalNodes(DSGraph& Graph, +static void MergeGlobalNodes(DSGraph &Graph, map &OldValMap) { map &ValMap = Graph.getValueMap(); for (map::iterator I = ValMap.begin(), E = ValMap.end(); I != E; ++I) - if (GlobalValue* GV = dyn_cast(I->first)) { - map:: iterator NHI = OldValMap.find(GV); + if (GlobalValue *GV = dyn_cast(I->first)) { + map::iterator NHI = OldValMap.find(GV); if (NHI != OldValMap.end()) // was it inlined from the callee? - I->second->mergeWith(NHI->second); + I->second.mergeWith(NHI->second); +#if 0 else // get it from the GlobalsGraph - I->second->mergeWith(Graph.cloneGlobalInto(GV)); + I->second.mergeWith(Graph.cloneGlobalInto(GV)); +#endif } // Add unused inlined global nodes into the value map @@ -83,7 +93,7 @@ static void MergeGlobalNodes(DSGraph& Graph, E = OldValMap.end(); I != E; ++I) if (isa(I->first)) { DSNodeHandle &NH = ValMap[I->first]; // If global is not in ValMap... - if (NH == 0) + if (NH.getNode() == 0) NH = I->second; // Add the one just inlined. } @@ -99,17 +109,20 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { // Copy the local version into DSInfo... Graph = new DSGraph(getAnalysis().getDSGraph(F)); +#if 0 // Populate the GlobalsGraph with globals from this one. Graph->GlobalsGraph->cloneGlobals(*Graph, /*cloneCalls*/ false); // Save a copy of the original call nodes for the top-down pass Graph->saveOrigFunctionCalls(); +#endif // Start resolving calls... std::vector > &FCs = Graph->getFunctionCalls(); DEBUG(std::cerr << " [BU] Inlining: " << F.getName() << "\n"); +#if 0 // Add F to the PendingCallers list of each direct callee for use in the // top-down pass so we don't have to compute this again. We don't want // to do it for indirect callees inlined later, so remember which calls @@ -117,6 +130,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { std::set directCallees; for (unsigned i = 0; i < FCs.size(); ++i) directCallees.insert(FCs[i][1]); // ptr to function node +#endif bool Inlined; do { @@ -126,12 +140,12 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { // Copy the call, because inlining graphs may invalidate the FCs vector. std::vector Call = FCs[i]; - // If the function list is not incomplete... - if ((Call[1]->NodeType & DSNode::Incomplete) == 0) { + // If the function list is complete... + if ((Call[1].getNode()->NodeType & DSNode::Incomplete) == 0) { // Start inlining all of the functions we can... some may not be // inlinable if they are external... // - std::vector Callees(Call[1]->getGlobals()); + std::vector Callees(Call[1].getNode()->getGlobals()); // Loop over the functions, inlining whatever we can... for (unsigned c = 0; c != Callees.size(); ++c) { @@ -143,8 +157,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n"); - if (Call[0]) // Handle the return value if present... - Graph->RetNode->mergeWith(Call[0]); + if (Call[0].getNode()) // Handle the return value if present... + Graph->getRetNode().mergeWith(Call[0]); // Resolve the arguments in the call to the actual values... ResolveArguments(Call, F, Graph->getValueMap()); @@ -167,30 +181,33 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { // Clone the callee's graph into the current graph, keeping // track of where scalars in the old graph _used_ to point, // and of the new nodes matching nodes of the old graph. - std::map OldValMap; - std::map OldNodeMap; + map OldValMap; + map OldNodeMap; // The clone call may invalidate any of the vectors in the data // structure graph. Strip locals and don't copy the list of callers - DSNode *RetVal = Graph->cloneInto(GI, OldValMap, OldNodeMap, - /*StripScalars*/ true, - /*StripAllocas*/ true, - /*CopyCallers*/ false, - /*CopyOrigCalls*/ false); + DSNodeHandle RetVal = Graph->cloneInto(GI, OldValMap, OldNodeMap, + /*StripScalars*/ true, + /*StripAllocas*/ true, + /*CopyCallers*/ false, + /*CopyOrigCalls*/ false); + // Resolve the arguments in the call to the actual values... ResolveArguments(Call, FI, OldValMap); - if (Call[0]) // Handle the return value if present - RetVal->mergeWith(Call[0]); + if (Call[0].getNode()) // Handle the return value if present + RetVal.mergeWith(Call[0]); // Merge global value nodes in the inlined graph with the global // value nodes in the current graph if there are duplicates. // MergeGlobalNodes(*Graph, OldValMap); +#if 0 // If this was an original call, add F to the PendingCallers list if (directCallees.find(Call[1]) != directCallees.end()) GI.addCaller(F); +#endif // Erase the entry in the Callees vector Callees.erase(Callees.begin()+c--); @@ -208,7 +225,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { // Erase the call if it is resolvable... FCs.erase(FCs.begin()+i--); // Don't skip a the next call... Inlined = true; - } else if (Callees.size() != Call[1]->getGlobals().size()) { + } else if (Callees.size() != Call[1].getNode()->getGlobals().size()) { // Was able to inline SOME, but not all of the functions. Construct a // new global node here. // @@ -223,18 +240,20 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { if (Inlined) { Graph->maskIncompleteMarkers(); Graph->markIncompleteNodes(); - Graph->removeDeadNodes(/*KeepAllGlobals*/ false, /*KeepCalls*/ true); + Graph->removeDeadNodes(/*KeepAllGlobals*/ true, /*KeepCalls*/ true); } } while (Inlined && !FCs.empty()); +#if 0 // Copy any unresolved call nodes into the Globals graph and // filter out unresolved call nodes inlined from the callee. if (!FCs.empty()) Graph->GlobalsGraph->cloneCalls(*Graph); +#endif Graph->maskIncompleteMarkers(); Graph->markIncompleteNodes(); - Graph->removeDeadNodes(/*KeepAllGlobals*/ false, /*KeepCalls*/ false); + Graph->removeDeadNodes(/*KeepAllGlobals*/ true, /*KeepCalls*/ true); DEBUG(std::cerr << " [BU] Done inlining: " << F.getName() << " [" << Graph->getGraphSize() << "+" << Graph->getFunctionCalls().size() @@ -242,4 +261,3 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { return *Graph; } -#endif diff --git a/lib/Analysis/DataStructure/Printer.cpp b/lib/Analysis/DataStructure/Printer.cpp index 82aa0055027..b78861c1347 100644 --- a/lib/Analysis/DataStructure/Printer.cpp +++ b/lib/Analysis/DataStructure/Printer.cpp @@ -13,6 +13,12 @@ #include using std::string; +// OnlyPrintMain - The DataStructure printer exposes this option to allow +// printing of only the graph for "main". +// +static cl::opt OnlyPrintMain("only-print-main-ds", cl::ReallyHidden); + + void DSNode::dump() const { print(std::cerr, 0); } static string getCaption(const DSNode *N, const DSGraph *G) { @@ -168,8 +174,6 @@ void DSGraph::writeGraphToFile(std::ostream &O, const string &GraphName) { } } -static cl::opt OnlyPrintMain("only-print-main-ds", cl::ReallyHidden); - template static void printCollection(const Collection &C, std::ostream &O, const Module *M, const string &Prefix) { @@ -189,17 +193,18 @@ void LocalDataStructures::print(std::ostream &O, const Module *M) const { printCollection(*this, O, M, "ds."); } -#if 0 void BUDataStructures::print(std::ostream &O, const Module *M) const { printCollection(*this, O, M, "bu."); - +#if 0 for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) if (!I->isExternal()) { (*getDSGraph(*I).GlobalsGraph)->writeGraphToFile(O, "gg.program"); break; } +#endif } +#if 0 void TDDataStructures::print(std::ostream &O, const Module *M) const { printCollection(*this, O, M, "td.");