Add a topological sort function.
authorOwen Anderson <resistor@mac.com>
Thu, 31 May 2007 22:44:11 +0000 (22:44 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 31 May 2007 22:44:11 +0000 (22:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37376 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/GVNPRE.cpp

index f672cbbbfa72a8876f1f25621a603cd26fcdc316..287b845f69f94cefabf5d6a3a8299789378be68a 100644 (file)
@@ -30,7 +30,9 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
 #include <algorithm>
+#include <deque>
 #include <map>
+#include <vector>
 #include <set>
 using namespace llvm;
 
@@ -113,6 +115,9 @@ namespace {
                        std::set<Expression>& anticIn, BasicBlock* B,
                        std::set<Expression>& out);
     
+    void topo_sort(ValueTable& VN, std::set<Expression>& set,
+                   std::vector<Expression>& vec);
+    
     // For a given block, calculate the generated expressions, temporaries,
     // and the AVAIL_OUT set
     void CalculateAvailOut(ValueTable& VN, std::set<Expression>& MS,
@@ -332,11 +337,60 @@ void GVNPRE::clean(GVNPRE::ValueTable VN, std::set<GVNPRE::Expression>& set) {
   }
 }
 
+void GVNPRE::topo_sort(GVNPRE::ValueTable& VN,
+                       std::set<GVNPRE::Expression>& set,
+                       std::vector<GVNPRE::Expression>& vec) {
+  std::set<Expression> toErase;               
+  for (std::set<Expression>::iterator I = set.begin(), E = set.end();
+       I != E; ++I) {
+    for (std::set<Expression>::iterator SI = set.begin(); SI != E; ++SI) {
+      if (I->lhs == VN[*SI] || I->rhs == VN[*SI]) {
+        toErase.insert(*SI);
+      }
+    }
+  }
+  
+  std::vector<Expression> Q;
+  std::insert_iterator<std::vector<Expression> > q_ins(Q, Q.begin());
+  std::set_difference(set.begin(), set.end(),
+                     toErase.begin(), toErase.end(),
+                     q_ins);
+  
+  std::set<Expression> visited;
+  while (!Q.empty()) {
+    Expression e = Q.back();
+    
+    if (e.opcode == 0) {
+      visited.insert(e);
+      vec.push_back(e);
+      Q.pop_back();
+      continue;
+    }
+    
+    std::set<Expression>::iterator l = find_leader(VN, set, e.lhs);
+    std::set<Expression>::iterator r = find_leader(VN, set, e.rhs);
+    
+    if (l != set.end() && visited.find(*l) == visited.end())
+      Q.push_back(*l);
+    else if (r != set.end() && visited.find(*r) == visited.end())
+      Q.push_back(*r);
+    else {
+      vec.push_back(e);
+      visited.insert(e);
+      Q.pop_back();
+    }
+  }
+}
+
 void GVNPRE::dump(GVNPRE::ValueTable& VN, std::set<GVNPRE::Expression>& s) {
+  std::vector<Expression> sorted;
+  topo_sort(VN, s, sorted);
   DOUT << "{ ";
-  for (std::set<Expression>::iterator I = s.begin(), E = s.end(); I != E; ++I) {
+  for (std::vector<Expression>::iterator I = sorted.begin(), E = sorted.end();
+       I != E; ++I) {
+    DOUT << VN[*I] << ": ";
     DOUT << "( ";
-    DOUT << I->opcode+48;
+    DOUT << (char)(I->opcode+48);
     DOUT << ", "
          << (I->value == 0 ? "0" : I->value->getName().c_str())
          << ", value." << I->lhs << ", value." << I->rhs << " ) ";