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

Chris Lattner lattner at cs.uiuc.edu
Thu May 11 10:12:04 PDT 2006



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.478 -> 1.479
---
Log message:

Refactor some code, making it simpler.
When doing the initial pass of constant folding, if we get a constantexpr,
simplify the constant expr like we would do if the constant is folded in the
normal loop.

This fixes the missed-optimization regression in 
Transforms/InstCombine/getelementptr.ll last night.


---
Diffs of the changes:  (+43 -31)

 InstructionCombining.cpp |   74 +++++++++++++++++++++++++++--------------------
 1 files changed, 43 insertions(+), 31 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.478 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.479
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.478	Wed May 10 14:00:36 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Thu May 11 12:11:52 2006
@@ -7317,6 +7317,33 @@
   return true;
 }
 
+/// OptimizeConstantExpr - Given a constant expression and target data layout
+/// information, symbolically evaluation the constant expr to something simpler
+/// if possible.
+static Constant *OptimizeConstantExpr(ConstantExpr *CE, const TargetData *TD) {
+  if (!TD) return CE;
+  
+  Constant *Ptr = CE->getOperand(0);
+  if (CE->getOpcode() == Instruction::GetElementPtr && Ptr->isNullValue() &&
+      cast<PointerType>(Ptr->getType())->getElementType()->isSized()) {
+    // If this is a constant expr gep that is effectively computing an
+    // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12'
+    bool isFoldableGEP = true;
+    for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
+      if (!isa<ConstantInt>(CE->getOperand(i)))
+        isFoldableGEP = false;
+    if (isFoldableGEP) {
+      std::vector<Value*> Ops(CE->op_begin()+1, CE->op_end());
+      uint64_t Offset = TD->getIndexedOffset(Ptr->getType(), Ops);
+      Constant *C = ConstantUInt::get(Type::ULongTy, Offset);
+      C = ConstantExpr::getCast(C, TD->getIntPtrType());
+      return ConstantExpr::getCast(C, CE->getType());
+    }
+  }
+  
+  return CE;
+}
+
 
 /// AddReachableCodeToWorklist - Walk the function in depth-first order, adding
 /// all reachable code to the worklist.
@@ -7329,7 +7356,8 @@
 ///
 static void AddReachableCodeToWorklist(BasicBlock *BB, 
                                        std::set<BasicBlock*> &Visited,
-                                       std::vector<Instruction*> &WorkList) {
+                                       std::vector<Instruction*> &WorkList,
+                                       const TargetData *TD) {
   // We have now visited this block!  If we've already been here, bail out.
   if (!Visited.insert(BB).second) return;
     
@@ -7346,6 +7374,8 @@
     
     // ConstantProp instruction if trivially constant.
     if (Constant *C = ConstantFoldInstruction(Inst)) {
+      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+        C = OptimizeConstantExpr(CE, TD);
       DEBUG(std::cerr << "IC: ConstFold to: " << *C << " from: " << *Inst);
       Inst->replaceAllUsesWith(C);
       ++NumConstProp;
@@ -7362,7 +7392,8 @@
   if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
     if (BI->isConditional() && isa<ConstantBool>(BI->getCondition())) {
       bool CondVal = cast<ConstantBool>(BI->getCondition())->getValue();
-      AddReachableCodeToWorklist(BI->getSuccessor(!CondVal), Visited, WorkList);
+      AddReachableCodeToWorklist(BI->getSuccessor(!CondVal), Visited, WorkList,
+                                 TD);
       return;
     }
   } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
@@ -7370,18 +7401,18 @@
       // See if this is an explicit destination.
       for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i)
         if (SI->getCaseValue(i) == Cond) {
-          AddReachableCodeToWorklist(SI->getSuccessor(i), Visited, WorkList);
+          AddReachableCodeToWorklist(SI->getSuccessor(i), Visited, WorkList,TD);
           return;
         }
       
       // Otherwise it is the default destination.
-      AddReachableCodeToWorklist(SI->getSuccessor(0), Visited, WorkList);
+      AddReachableCodeToWorklist(SI->getSuccessor(0), Visited, WorkList, TD);
       return;
     }
   }
   
   for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
-    AddReachableCodeToWorklist(TI->getSuccessor(i), Visited, WorkList);
+    AddReachableCodeToWorklist(TI->getSuccessor(i), Visited, WorkList, TD);
 }
 
 bool InstCombiner::runOnFunction(Function &F) {
@@ -7393,7 +7424,7 @@
     // the reachable instructions.  Ignore blocks that are not reachable.  Keep
     // track of which blocks we visit.
     std::set<BasicBlock*> Visited;
-    AddReachableCodeToWorklist(F.begin(), Visited, WorkList);
+    AddReachableCodeToWorklist(F.begin(), Visited, WorkList, TD);
 
     // Do a quick scan over the function.  If we find any blocks that are
     // unreachable, remove any instructions inside of them.  This prevents
@@ -7418,10 +7449,9 @@
     Instruction *I = WorkList.back();  // Get an instruction from the worklist
     WorkList.pop_back();
 
-    // Check to see if we can DCE or ConstantPropagate the instruction...
-    // Check to see if we can DIE the instruction...
+    // Check to see if we can DCE the instruction.
     if (isInstructionTriviallyDead(I)) {
-      // Add operands to the worklist...
+      // Add operands to the worklist.
       if (I->getNumOperands() < 4)
         AddUsesToWorkList(*I);
       ++NumDeadInst;
@@ -7433,31 +7463,13 @@
       continue;
     }
 
-    // Instruction isn't dead, see if we can constant propagate it...
+    // Instruction isn't dead, see if we can constant propagate it.
     if (Constant *C = ConstantFoldInstruction(I)) {
-      Value* Ptr = I->getOperand(0);
-      if (isa<GetElementPtrInst>(I) &&
-          cast<Constant>(Ptr)->isNullValue() &&
-          !isa<ConstantPointerNull>(C) &&
-          cast<PointerType>(Ptr->getType())->getElementType()->isSized()) {
-        // If this is a constant expr gep that is effectively computing an
-        // "offsetof", fold it into 'cast int X to T*' instead of 'gep 0, 0, 12'
-        bool isFoldableGEP = true;
-        for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i)
-          if (!isa<ConstantInt>(I->getOperand(i)))
-            isFoldableGEP = false;
-        if (isFoldableGEP) {
-          uint64_t Offset = TD->getIndexedOffset(Ptr->getType(),
-                             std::vector<Value*>(I->op_begin()+1, I->op_end()));
-          C = ConstantUInt::get(Type::ULongTy, Offset);
-          C = ConstantExpr::getCast(C, TD->getIntPtrType());
-          C = ConstantExpr::getCast(C, I->getType());
-        }
-      }
-
+      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+        C = OptimizeConstantExpr(CE, TD);
       DEBUG(std::cerr << "IC: ConstFold to: " << *C << " from: " << *I);
 
-      // Add operands to the worklist...
+      // Add operands to the worklist.
       AddUsesToWorkList(*I);
       ReplaceInstUsesWith(*I, C);
 






More information about the llvm-commits mailing list