diff options
-rw-r--r-- | lib/Analysis/DataStructure/BottomUpClosure.cpp | 11 | ||||
-rw-r--r-- | lib/Analysis/DataStructure/CompleteBottomUp.cpp | 4 | ||||
-rw-r--r-- | lib/Analysis/DataStructure/DataStructure.cpp | 42 | ||||
-rw-r--r-- | lib/Analysis/DataStructure/EquivClassGraphs.cpp | 5 | ||||
-rw-r--r-- | lib/Analysis/DataStructure/Local.cpp | 43 | ||||
-rw-r--r-- | lib/Analysis/DataStructure/Steensgaard.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/DataStructure/TopDownClosure.cpp | 7 |
7 files changed, 72 insertions, 48 deletions
diff --git a/lib/Analysis/DataStructure/BottomUpClosure.cpp b/lib/Analysis/DataStructure/BottomUpClosure.cpp index 7ab7d80..1903008 100644 --- a/lib/Analysis/DataStructure/BottomUpClosure.cpp +++ b/lib/Analysis/DataStructure/BottomUpClosure.cpp @@ -37,7 +37,9 @@ using namespace DS; // bool BUDataStructures::runOnModule(Module &M) { LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>(); - GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph()); + GlobalECs = LocalDSA.getGlobalECs(); + + GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph(), GlobalECs); GlobalsGraph->setPrintAuxCalls(); IndCallGraphMap = new std::map<std::vector<Function*>, @@ -112,7 +114,8 @@ DSGraph &BUDataStructures::getOrCreateGraph(Function *F) { if (Graph) return *Graph; // Copy the local version into DSInfo... - Graph = new DSGraph(getAnalysis<LocalDataStructures>().getDSGraph(*F)); + Graph = new DSGraph(getAnalysis<LocalDataStructures>().getDSGraph(*F), + GlobalECs); Graph->setGlobalsGraph(GlobalsGraph); Graph->setPrintAuxCalls(); @@ -379,7 +382,7 @@ void BUDataStructures::calculateGraph(DSGraph &Graph) { E = CalledFuncs.end(); // Start with a copy of the first graph. - GI = IndCallGraph.first = new DSGraph(getDSGraph(**I)); + GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs); GI->setGlobalsGraph(Graph.getGlobalsGraph()); std::vector<DSNodeHandle> &Args = IndCallGraph.second; @@ -498,7 +501,7 @@ void BUDataStructures::copyValue(Value *From, Value *To) { if (Function *FromF = dyn_cast<Function>(From)) { Function *ToF = cast<Function>(To); assert(!DSInfo.count(ToF) && "New Function already exists!"); - DSGraph *NG = new DSGraph(getDSGraph(*FromF)); + DSGraph *NG = new DSGraph(getDSGraph(*FromF), GlobalECs); DSInfo[ToF] = NG; assert(NG->getReturnNodes().size() == 1 && "Cannot copy SCC's yet!"); diff --git a/lib/Analysis/DataStructure/CompleteBottomUp.cpp b/lib/Analysis/DataStructure/CompleteBottomUp.cpp index a70080a..16ea438 100644 --- a/lib/Analysis/DataStructure/CompleteBottomUp.cpp +++ b/lib/Analysis/DataStructure/CompleteBottomUp.cpp @@ -34,7 +34,7 @@ namespace { // bool CompleteBUDataStructures::runOnModule(Module &M) { BUDataStructures &BU = getAnalysis<BUDataStructures>(); - GlobalsGraph = new DSGraph(BU.getGlobalsGraph()); + GlobalsGraph = new DSGraph(BU.getGlobalsGraph(), GlobalECs); GlobalsGraph->setPrintAuxCalls(); #if 1 // REMOVE ME EVENTUALLY @@ -121,7 +121,7 @@ DSGraph &CompleteBUDataStructures::getOrCreateGraph(Function &F) { if (Graph) return *Graph; // Copy the BU graph... - Graph = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F)); + Graph = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F), GlobalECs); Graph->setGlobalsGraph(GlobalsGraph); Graph->setPrintAuxCalls(); diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp index 43170fd..5f8b3bf 100644 --- a/lib/Analysis/DataStructure/DataStructure.cpp +++ b/lib/Analysis/DataStructure/DataStructure.cpp @@ -115,7 +115,7 @@ void DSNode::assertOK() const { assert(ParentGraph && "Node has no parent?"); const DSScalarMap &SM = ParentGraph->getScalarMap(); for (unsigned i = 0, e = Globals.size(); i != e; ++i) { - assert(SM.count(Globals[i])); + assert(SM.global_count(Globals[i])); assert(SM.find(Globals[i])->second.getNode() == this); } } @@ -143,6 +143,10 @@ void DSNode::forwardNode(DSNode *To, unsigned Offset) { // marks the node with the 'G' flag if it does not already have it. // void DSNode::addGlobal(GlobalValue *GV) { + // First, check to make sure this is the leader if the global is in an + // equivalence class. + GV = getParentGraph()->getScalarMap().getLeaderForGlobal(GV); + // Keep the list sorted. std::vector<GlobalValue*>::iterator I = std::lower_bound(Globals.begin(), Globals.end(), GV); @@ -1091,14 +1095,16 @@ std::string DSGraph::getFunctionNames() const { } -DSGraph::DSGraph(const DSGraph &G) : GlobalsGraph(0), TD(G.TD) { +DSGraph::DSGraph(const DSGraph &G, EquivalenceClasses<GlobalValue*> &ECs) + : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { PrintAuxCalls = false; NodeMapTy NodeMap; cloneInto(G, ScalarMap, ReturnNodes, NodeMap); } -DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap) - : GlobalsGraph(0), TD(G.TD) { +DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap, + EquivalenceClasses<GlobalValue*> &ECs) + : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { PrintAuxCalls = false; cloneInto(G, ScalarMap, ReturnNodes, NodeMap); } @@ -1865,8 +1871,9 @@ void DSGraph::removeDeadNodes(unsigned Flags) { DSGraph::StripIncompleteBit); // Mark all nodes reachable by (non-global) scalar nodes as alive... - { TIME_REGION(Y, "removeDeadNodes:scalarscan"); - for (DSScalarMap::iterator I = ScalarMap.begin(), E = ScalarMap.end(); I !=E;) +{ TIME_REGION(Y, "removeDeadNodes:scalarscan"); + for (DSScalarMap::iterator I = ScalarMap.begin(), E = ScalarMap.end(); + I != E; ++I) if (isa<GlobalValue>(I->first)) { // Keep track of global nodes assert(!I->second.isNull() && "Null global node?"); assert(I->second.getNode()->isGlobalNode() && "Should be a global node!"); @@ -1881,29 +1888,10 @@ void DSGraph::removeDeadNodes(unsigned Flags) { else GGCloner.getClonedNH(I->second); } - ++I; } else { - DSNode *N = I->second.getNode(); -#if 0 - // Check to see if this is a worthless node generated for non-pointer - // values, such as integers. Consider an addition of long types: A+B. - // Assuming we can track all uses of the value in this context, and it is - // NOT used as a pointer, we can delete the node. We will be able to - // detect this situation if the node pointed to ONLY has Unknown bit set - // in the node. In this case, the node is not incomplete, does not point - // to any other nodes (no mod/ref bits set), and is therefore - // uninteresting for data structure analysis. If we run across one of - // these, prune the scalar pointing to it. - // - if (N->getNodeFlags() == DSNode::UnknownNode && !isa<Argument>(I->first)) - ScalarMap.erase(I++); - else { -#endif - N->markReachableNodes(Alive); - ++I; - //} + I->second.getNode()->markReachableNodes(Alive); } - } +} // The return values are alive as well. for (ReturnNodesTy::iterator I = ReturnNodes.begin(), E = ReturnNodes.end(); diff --git a/lib/Analysis/DataStructure/EquivClassGraphs.cpp b/lib/Analysis/DataStructure/EquivClassGraphs.cpp index 02b7fb7..447b36d 100644 --- a/lib/Analysis/DataStructure/EquivClassGraphs.cpp +++ b/lib/Analysis/DataStructure/EquivClassGraphs.cpp @@ -72,9 +72,10 @@ Function *EquivClassGraphs::getSomeCalleeForCallSite(const CallSite &CS) const{ // bool EquivClassGraphs::runOnModule(Module &M) { CBU = &getAnalysis<CompleteBUDataStructures>(); + GlobalECs = CBU->getGlobalECs(); DEBUG(CheckAllGraphs(&M, *CBU)); - GlobalsGraph = new DSGraph(CBU->getGlobalsGraph()); + GlobalsGraph = new DSGraph(CBU->getGlobalsGraph(), GlobalECs); GlobalsGraph->setPrintAuxCalls(); ActualCallees = CBU->getActualCallees(); @@ -305,7 +306,7 @@ DSGraph &EquivClassGraphs::getOrCreateGraph(Function &F) { DSGraph &CBUGraph = CBU->getDSGraph(F); // Copy the CBU graph... - Graph = new DSGraph(CBUGraph); // updates the map via reference + Graph = new DSGraph(CBUGraph, GlobalECs); // updates the map via reference Graph->setGlobalsGraph(&getGlobalsGraph()); Graph->setPrintAuxCalls(); diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp index 9cb899c..02b5b16 100644 --- a/lib/Analysis/DataStructure/Local.cpp +++ b/lib/Analysis/DataStructure/Local.cpp @@ -164,8 +164,9 @@ using namespace DS; //===----------------------------------------------------------------------===// // DSGraph constructor - Simply use the GraphBuilder to construct the local // graph. -DSGraph::DSGraph(const TargetData &td, Function &F, DSGraph *GG) - : GlobalsGraph(GG), TD(td) { +DSGraph::DSGraph(EquivalenceClasses<GlobalValue*> &ECs, const TargetData &td, + Function &F, DSGraph *GG) + : GlobalsGraph(GG), ScalarMap(ECs), TD(td) { PrintAuxCalls = false; DEBUG(std::cerr << " [Loc] Calculating graph for: " << F.getName() << "\n"); @@ -1071,21 +1072,49 @@ void GraphBuilder::mergeInGlobalInitializer(GlobalVariable *GV) { bool LocalDataStructures::runOnModule(Module &M) { const TargetData &TD = getAnalysis<TargetData>(); - GlobalsGraph = new DSGraph(TD); - + // First step, build the globals graph. + GlobalsGraph = new DSGraph(GlobalECs, TD); { GraphBuilder GGB(*GlobalsGraph); - // Add initializers for all of the globals to the globals graph... - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) + // Add initializers for all of the globals to the globals graph. + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) if (!I->isExternal()) GGB.mergeInGlobalInitializer(I); } + // Next step, iterate through the nodes in the globals graph, unioning + // together the globals into equivalence classes. + for (DSGraph::node_iterator I = GlobalsGraph->node_begin(), + E = GlobalsGraph->node_end(); I != E; ++I) + if (I->getGlobals().size() > 1) { + // First, build up the equivalence set for this block of globals. + const std::vector<GlobalValue*> &GVs = I->getGlobals(); + GlobalValue *First = GVs[0]; + for (unsigned i = 1, e = GVs.size(); i != e; ++i) + GlobalECs.unionSets(First, GVs[i]); + + // Next, get the leader element. + First = GlobalECs.getLeaderValue(First); + + // Next, remove all globals from the scalar map that are not the leader. + DSScalarMap &SM = GlobalsGraph->getScalarMap(); + for (unsigned i = 0, e = GVs.size(); i != e; ++i) + if (GVs[i] != First) + SM.erase(SM.find(GVs[i])); + + // Finally, change the global node to only contain the leader. + I->clearGlobals(); + I->addGlobal(First); + } + DEBUG(GlobalsGraph->AssertGraphOK()); + // Calculate all of the graphs... for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) - DSInfo.insert(std::make_pair(I, new DSGraph(TD, *I, GlobalsGraph))); + DSInfo.insert(std::make_pair(I, new DSGraph(GlobalECs, TD, *I, + GlobalsGraph))); GlobalsGraph->removeTriviallyDeadNodes(); GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs); diff --git a/lib/Analysis/DataStructure/Steensgaard.cpp b/lib/Analysis/DataStructure/Steensgaard.cpp index dd07ee6..9ed65bb 100644 --- a/lib/Analysis/DataStructure/Steensgaard.cpp +++ b/lib/Analysis/DataStructure/Steensgaard.cpp @@ -26,6 +26,8 @@ namespace { class Steens : public ModulePass, public AliasAnalysis { DSGraph *ResultGraph; DSGraph *GlobalsGraph; // FIXME: Eliminate globals graph stuff from DNE + + EquivalenceClasses<GlobalValue*> GlobalECs; // Always empty public: Steens() : ResultGraph(0), GlobalsGraph(0) {} ~Steens() { @@ -112,8 +114,8 @@ bool Steens::runOnModule(Module &M) { LocalDataStructures &LDS = getAnalysis<LocalDataStructures>(); // Create a new, empty, graph... - ResultGraph = new DSGraph(getTargetData()); - GlobalsGraph = new DSGraph(getTargetData()); + ResultGraph = new DSGraph(GlobalECs, getTargetData()); + GlobalsGraph = new DSGraph(GlobalECs, getTargetData()); ResultGraph->setGlobalsGraph(GlobalsGraph); ResultGraph->setPrintAuxCalls(); @@ -128,7 +130,7 @@ bool Steens::runOnModule(Module &M) { unsigned Count = 0; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) { - DSGraph::ScalarMapTy ValMap; + DSGraph::ScalarMapTy ValMap(GlobalECs); { // Scope to free NodeMap memory ASAP DSGraph::NodeMapTy NodeMap; const DSGraph &FDSG = LDS.getDSGraph(*I); diff --git a/lib/Analysis/DataStructure/TopDownClosure.cpp b/lib/Analysis/DataStructure/TopDownClosure.cpp index 580f228..9a661e2 100644 --- a/lib/Analysis/DataStructure/TopDownClosure.cpp +++ b/lib/Analysis/DataStructure/TopDownClosure.cpp @@ -53,7 +53,8 @@ void TDDataStructures::markReachableFunctionsExternallyAccessible(DSNode *N, // bool TDDataStructures::runOnModule(Module &M) { BUDataStructures &BU = getAnalysis<BUDataStructures>(); - GlobalsGraph = new DSGraph(BU.getGlobalsGraph()); + GlobalECs = BU.getGlobalECs(); + GlobalsGraph = new DSGraph(BU.getGlobalsGraph(), GlobalECs); GlobalsGraph->setPrintAuxCalls(); // Figure out which functions must not mark their arguments complete because @@ -115,7 +116,7 @@ bool TDDataStructures::runOnModule(Module &M) { DSGraph &TDDataStructures::getOrCreateDSGraph(Function &F) { DSGraph *&G = DSInfo[&F]; if (G == 0) { // Not created yet? Clone BU graph... - G = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F)); + G = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F), GlobalECs); G->getAuxFunctionCalls().clear(); G->setPrintAuxCalls(); G->setGlobalsGraph(GlobalsGraph); @@ -324,7 +325,7 @@ void TDDataStructures::copyValue(Value *From, Value *To) { if (Function *FromF = dyn_cast<Function>(From)) { Function *ToF = cast<Function>(To); assert(!DSInfo.count(ToF) && "New Function already exists!"); - DSGraph *NG = new DSGraph(getDSGraph(*FromF)); + DSGraph *NG = new DSGraph(getDSGraph(*FromF), GlobalECs); DSInfo[ToF] = NG; assert(NG->getReturnNodes().size() == 1 && "Cannot copy SCC's yet!"); |