[llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp

Owen Anderson resistor at mac.com
Sat Jun 9 11:36:03 PDT 2007



Changes in directory llvm/lib/Transforms/Scalar:

GVNPRE.cpp updated: 1.27 -> 1.28
---
Log message:

Perform PRE of comparison operators.


---
Diffs of the changes:  (+155 -24)

 GVNPRE.cpp |  179 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 155 insertions(+), 24 deletions(-)


Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp
diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.27 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.28
--- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.27	Fri Jun  8 17:02:36 2007
+++ llvm/lib/Transforms/Scalar/GVNPRE.cpp	Sat Jun  9 13:35:31 2007
@@ -39,20 +39,43 @@
 
 struct ExprLT {
   bool operator()(Value* left, Value* right) {
-    if (!isa<BinaryOperator>(left) || !isa<BinaryOperator>(right))
+    if (BinaryOperator* leftBO = dyn_cast<BinaryOperator>(left)) {
+      if (BinaryOperator* rightBO = dyn_cast<BinaryOperator>(right))
+        return cmpBinaryOperator(leftBO, rightBO);
+      else
+        return left < right;
+    } else if (CmpInst* leftCmp = dyn_cast<CmpInst>(left)) {
+      if (CmpInst* rightCmp = dyn_cast<CmpInst>(right))
+        return cmpComparison(leftCmp, rightCmp);
+      else
+        return left < right;
+    } else {
       return left < right;
-    
-    BinaryOperator* BO1 = cast<BinaryOperator>(left);
-    BinaryOperator* BO2 = cast<BinaryOperator>(right);
-    
-    if (BO1->getOpcode() != BO2->getOpcode())
-      return BO1->getOpcode() < BO2->getOpcode();
-    else if ((*this)(BO1->getOperand(0), BO2->getOperand(0)))
+    }
+  }
+  
+  bool cmpBinaryOperator(BinaryOperator* left, BinaryOperator* right) {
+    if (left->getOpcode() != right->getOpcode())
+      return left->getOpcode() < right->getOpcode();
+    else if ((*this)(left->getOperand(0), right->getOperand(0)))
+      return true;
+    else if ((*this)(right->getOperand(0), left->getOperand(0)))
+      return false;
+    else
+      return (*this)(left->getOperand(1), right->getOperand(1));
+  }
+  
+  bool cmpComparison(CmpInst* left, CmpInst* right) {
+    if (left->getOpcode() != right->getOpcode())
+      return left->getOpcode() < right->getOpcode();
+    else if (left->getPredicate() != right->getPredicate())
+      return left->getPredicate() < right->getPredicate();
+    else if ((*this)(left->getOperand(0), right->getOperand(0)))
       return true;
-    else if ((*this)(BO2->getOperand(0), BO1->getOperand(0)))
+    else if ((*this)(right->getOperand(0), left->getOperand(0)))
       return false;
     else
-      return (*this)(BO1->getOperand(1), BO2->getOperand(1));
+      return (*this)(left->getOperand(1), right->getOperand(1));
   }
 };
 
@@ -62,7 +85,7 @@
     bool runOnFunction(Function &F);
   public:
     static char ID; // Pass identification, replacement for typeid
-    GVNPRE() : FunctionPass((intptr_t)&ID) { nextValueNumber = 0; }
+    GVNPRE() : FunctionPass((intptr_t)&ID) { nextValueNumber = 1; }
 
   private:
     uint32_t nextValueNumber;
@@ -121,7 +144,7 @@
 
 bool GVNPRE::add(Value* V, uint32_t number) {
   std::pair<ValueTable::iterator, bool> ret = VN.insert(std::make_pair(V, number));
-  if (isa<BinaryOperator>(V) || isa<PHINode>(V))
+  if (isa<BinaryOperator>(V) || isa<PHINode>(V) || isa<CmpInst>(V))
     MS.insert(V);
   return ret.second;
 }
@@ -187,6 +210,48 @@
   } else if (PHINode* P = dyn_cast<PHINode>(V)) {
     if (P->getParent() == pred->getTerminator()->getSuccessor(0))
       return P->getIncomingValueForBlock(pred);
+  } else if (CmpInst* C = dyn_cast<CmpInst>(V)) {
+    Value* newOp1 = isa<Instruction>(C->getOperand(0))
+                                ? phi_translate(set,
+                                  find_leader(set, C->getOperand(0)),
+                                  pred)
+                                : C->getOperand(0);
+    if (newOp1 == 0)
+      return 0;
+    
+    Value* newOp2 = isa<Instruction>(C->getOperand(1))
+                                ? phi_translate(set,
+                                  find_leader(set, C->getOperand(1)),
+                                  pred)
+                                : C->getOperand(1);
+    if (newOp2 == 0)
+      return 0;
+    
+    if (newOp1 != C->getOperand(0) || newOp2 != C->getOperand(1)) {
+      Instruction* newVal = CmpInst::create(C->getOpcode(),
+                                            C->getPredicate(),
+                                             newOp1, newOp2,
+                                             C->getName()+".gvnpre");
+      
+      if (add(newVal, nextValueNumber))
+        nextValueNumber++;
+      if (!find_leader(set, newVal)) {
+        DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n";
+        createdExpressions.insert(newVal);
+        return newVal;
+      } else {
+        ValueTable::iterator I = VN.find(newVal);
+        if (I->first == newVal)
+          VN.erase(newVal);
+        
+        std::set<Value*, ExprLT>::iterator F = MS.find(newVal);
+        if (*F == newVal)
+          MS.erase(newVal);
+        
+        delete newVal;
+        return 0;
+      }
+    }
   }
   
   return V;
@@ -231,6 +296,27 @@
       
       if (!lhsValid || !rhsValid)
         set.erase(BO);
+    } else if (CmpInst* C = dyn_cast<CmpInst>(v)) {
+      bool lhsValid = !isa<Instruction>(C->getOperand(0));
+      if (!lhsValid)
+        for (std::set<Value*, ExprLT>::iterator I = set.begin(), E = set.end();
+             I != E; ++I)
+          if (VN[*I] == VN[C->getOperand(0)]) {
+            lhsValid = true;
+            break;
+          }
+  
+      bool rhsValid = !isa<Instruction>(C->getOperand(1));
+      if (!rhsValid)
+      for (std::set<Value*, ExprLT>::iterator I = set.begin(), E = set.end();
+           I != E; ++I)
+        if (VN[*I] == VN[C->getOperand(1)]) {
+          rhsValid = true;
+          break;
+        }
+    
+      if (!lhsValid || !rhsValid)
+        set.erase(C);
     }
   }
 }
@@ -246,7 +332,14 @@
             VN[BO->getOperand(1)] == VN[*SI]) {
           toErase.insert(*SI);
         }
-    }
+      }
+    else if (CmpInst* C = dyn_cast<CmpInst>(*I))
+      for (std::set<Value*, ExprLT>::iterator SI = set.begin(); SI != E; ++SI) {
+        if (VN[C->getOperand(0)] == VN[*SI] ||
+            VN[C->getOperand(1)] == VN[*SI]) {
+          toErase.insert(*SI);
+        }
+      }
   }
   
   std::vector<Value*> Q;
@@ -275,6 +368,21 @@
         visited.insert(e);
         Q.pop_back();
       }
+    } else if (CmpInst* C = dyn_cast<CmpInst>(e)) {
+      Value* l = find_leader(set, C->getOperand(0));
+      Value* r = find_leader(set, C->getOperand(1));
+      
+      if (l != 0 && isa<Instruction>(l) &&
+          visited.find(l) == visited.end())
+        Q.push_back(l);
+      else if (r != 0 && isa<Instruction>(r) &&
+               visited.find(r) == visited.end())
+        Q.push_back(r);
+      else {
+        vec.push_back(e);
+        visited.insert(e);
+        Q.pop_back();
+      }
     } else {
       visited.insert(e);
       vec.push_back(e);
@@ -340,6 +448,20 @@
         currExps.insert(rightValue);
       currExps.insert(BO);
       
+    // Handle cmp ops...
+    } else if (CmpInst* C = dyn_cast<CmpInst>(BI)) {
+      Value* leftValue = C->getOperand(0);
+      Value* rightValue = C->getOperand(1);
+      
+      if (add(C, nextValueNumber))
+        nextValueNumber++;
+      
+      if (isa<Instruction>(leftValue))
+        currExps.insert(leftValue);
+      if (isa<Instruction>(rightValue))
+        currExps.insert(rightValue);
+      currExps.insert(C);
+      
     // Handle unsupported ops
     } else if (!BI->isTerminator()){
       if (add(BI, nextValueNumber))
@@ -549,7 +671,7 @@
           Value* e = workList.back();
           workList.pop_back();
           
-          if (isa<BinaryOperator>(e)) {
+          if (isa<BinaryOperator>(e) || isa<CmpInst>(e)) {
             if (find_leader(availableOut[DI->getIDom()->getBlock()], e) != 0)
               continue;
             
@@ -588,25 +710,34 @@
                    PI != PE; ++PI) {
                 Value* e2 = avail[*PI];
                 if (!find_leader(availableOut[*PI], e2)) {
-                  BinaryOperator* BO = cast<BinaryOperator>(e2);
+                  User* U = cast<User>(e2);
                 
                   Value* s1 = 0;
-                  if (isa<Instruction>(BO->getOperand(0)))
-                    s1 = find_leader(availableOut[*PI], BO->getOperand(0));
+                  if (isa<Instruction>(U->getOperand(0)))
+                    s1 = find_leader(availableOut[*PI], U->getOperand(0));
                   else
-                    s1 = BO->getOperand(0);
+                    s1 = U->getOperand(0);
                   
                   Value* s2 = 0;
-                  if (isa<Instruction>(BO->getOperand(1)))
-                    s2 = find_leader(availableOut[*PI], BO->getOperand(1));
+                  if (isa<Instruction>(U->getOperand(1)))
+                    s2 = find_leader(availableOut[*PI], U->getOperand(1));
                   else
-                    s2 = BO->getOperand(1);
+                    s2 = U->getOperand(1);
                   
-                  Value* newVal = BinaryOperator::create(BO->getOpcode(),
+                  Value* newVal = 0;
+                  if (BinaryOperator* BO = dyn_cast<BinaryOperator>(U))
+                    newVal = BinaryOperator::create(BO->getOpcode(),
                                              s1, s2,
                                              BO->getName()+".gvnpre",
                                              (*PI)->getTerminator());
-                  add(newVal, VN[BO]);
+                  else if (CmpInst* C = dyn_cast<CmpInst>(U))
+                    newVal = CmpInst::create(C->getOpcode(),
+                                             C->getPredicate(),
+                                             s1, s2,
+                                             C->getName()+".gvnpre",
+                                             (*PI)->getTerminator());
+                  
+                  add(newVal, VN[U]);
                   
                   std::set<Value*, ExprLT>& predAvail = availableOut[*PI];
                   Value* val = find_leader(predAvail, newVal);
@@ -688,7 +819,7 @@
     for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
          BI != BE; ++BI) {
 
-      if (isa<BinaryOperator>(BI)) {
+      if (isa<BinaryOperator>(BI) || isa<CmpInst>(BI)) {
          Value *leader = find_leader(availableOut[BB], BI);
   
         if (leader != 0)






More information about the llvm-commits mailing list