[llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp

Chris Lattner lattner at cs.uiuc.edu
Sat Mar 19 19:32:48 PST 2005



Changes in directory llvm/lib/Analysis/DataStructure:

Local.cpp updated: 1.130 -> 1.131
---
Log message:

Build EC's for globals twice.  The first is after constructing the initial
Globals Graph for the local pass, the second is after all of the locals 
graphs have been constructed.  This allows for many additional global EC's
to be recognized that weren't before.  This speeds up analysis of programs 
like 177.mesa, where it changes DSA from taking 0.712s to 0.4018s.



---
Diffs of the changes:  (+99 -23)

 Local.cpp |  122 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 99 insertions(+), 23 deletions(-)


Index: llvm/lib/Analysis/DataStructure/Local.cpp
diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.130 llvm/lib/Analysis/DataStructure/Local.cpp:1.131
--- llvm/lib/Analysis/DataStructure/Local.cpp:1.130	Sat Mar 19 20:40:04 2005
+++ llvm/lib/Analysis/DataStructure/Local.cpp	Sat Mar 19 21:32:35 2005
@@ -1069,6 +1069,88 @@
 }
 
 
+/// BuildGlobalECs - Look at all of the nodes in the globals graph.  If any node
+/// contains multiple globals, DSA will never, ever, be able to tell the globals
+/// apart.  Instead of maintaining this information in all of the graphs
+/// throughout the entire program, store only a single global (the "leader") in
+/// the graphs, and build equivalence classes for the rest of the globals.
+static void BuildGlobalECs(DSGraph &GG, std::set<GlobalValue*> &ECGlobals) {
+  DSScalarMap &SM = GG.getScalarMap();
+  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
+  for (DSGraph::node_iterator I = GG.node_begin(), E = GG.node_end();
+       I != E; ++I) {
+    if (I->getGlobalsList().size() <= 1) continue;
+
+    // First, build up the equivalence set for this block of globals.
+    const std::vector<GlobalValue*> &GVs = I->getGlobalsList();
+    GlobalValue *First = GVs[0];
+    for (unsigned i = 1, e = GVs.size(); i != e; ++i)
+      GlobalECs.unionSets(First, GVs[i]);
+    
+    // Next, get the leader element.
+    assert(First == GlobalECs.getLeaderValue(First) &&
+           "First did not end up being the leader?");
+    
+    // Next, remove all globals from the scalar map that are not the leader.
+    assert(GVs[0] == First && "First had to be at the front!");
+    for (unsigned i = 1, e = GVs.size(); i != e; ++i) {
+      ECGlobals.insert(GVs[i]);
+      SM.erase(SM.find(GVs[i]));
+    }
+    
+    // Finally, change the global node to only contain the leader.
+    I->clearGlobals();
+    I->addGlobal(First);
+  }
+  
+  DEBUG(GG.AssertGraphOK());
+}
+
+/// EliminateUsesOfECGlobals - Once we have determined that some globals are in
+/// really just equivalent to some other globals, remove the globals from the
+/// specified DSGraph (if present), and merge any nodes with their leader nodes.
+static void EliminateUsesOfECGlobals(DSGraph &G,
+                                     const std::set<GlobalValue*> &ECGlobals) {
+  DSScalarMap &SM = G.getScalarMap();
+  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
+
+  bool MadeChange = false;
+  for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
+       GI != E; ) {
+    GlobalValue *GV = *GI++;
+    if (!ECGlobals.count(GV)) continue;
+
+    const DSNodeHandle &GVNH = SM[GV];
+    assert(!GVNH.isNull() && "Global has null NH!?");
+
+    // Okay, this global is in some equivalence class.  Start by finding the
+    // leader of the class.
+    GlobalValue *Leader = GlobalECs.getLeaderValue(GV);
+
+    // If the leader isn't already in the graph, insert it into the node
+    // corresponding to GV.
+    if (!SM.global_count(Leader)) {
+      GVNH.getNode()->addGlobal(Leader);
+      SM[Leader] = GVNH;
+    } else {
+      // Otherwise, the leader is in the graph, make sure the nodes are the
+      // merged in the specified graph.
+      const DSNodeHandle &LNH = SM[Leader];
+      if (LNH.getNode() != GVNH.getNode())
+        LNH.mergeWith(GVNH);
+    }
+
+    // Next step, remove the global from the DSNode.
+    GVNH.getNode()->removeGlobal(GV);
+
+    // Finally, remove the global from the ScalarMap.
+    SM.erase(GV);
+    MadeChange = true;
+  }
+
+  DEBUG(if(MadeChange) G.AssertGraphOK());
+}
+
 bool LocalDataStructures::runOnModule(Module &M) {
   const TargetData &TD = getAnalysis<TargetData>();
 
@@ -1086,29 +1168,10 @@
 
   // 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->getGlobalsList().size() > 1) {
-      // First, build up the equivalence set for this block of globals.
-      const std::vector<GlobalValue*> &GVs = I->getGlobalsList();
-      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());
+  std::set<GlobalValue*> ECGlobals;
+  BuildGlobalECs(*GlobalsGraph, ECGlobals);
+  DEBUG(std::cerr << "Eliminating " << ECGlobals.size() << " EC Globals!\n");
+  ECGlobals.clear();
 
   // Calculate all of the graphs...
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
@@ -1118,6 +1181,19 @@
 
   GlobalsGraph->removeTriviallyDeadNodes();
   GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
+
+  // Now that we've computed all of the graphs, and merged all of the info into
+  // the globals graph, see if we have further constrained the globals in the
+  // program if so, update GlobalECs and remove the extraneous globals from the
+  // program.
+  BuildGlobalECs(*GlobalsGraph, ECGlobals);
+  if (!ECGlobals.empty()) {
+    DEBUG(std::cerr << "Eliminating " << ECGlobals.size() << " EC Globals!\n");
+    for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
+           E = DSInfo.end(); I != E; ++I)
+      EliminateUsesOfECGlobals(*I->second, ECGlobals);
+  }
+
   return false;
 }
 






More information about the llvm-commits mailing list