Minor efficiency tweak, suggested by Patrick Meredith
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index 6b7f20a73cf0dcec496e5556e164c5e05b08f37d..2266a70b6e616d4c70d7eac8aa6b0e11ee925980 100644 (file)
 // simplification happens.
 //
 // This pass combines things like:
-//    %Y = add int 1, %X
-//    %Z = add int 1, %Y
+//    %Y = add int %X, 1
+//    %Z = add int %Y, 1
 // into:
-//    %Z = add int 2, %X
+//    %Z = add int %X, 2
 //
 // This is a simple worklist driven algorithm.
 //
@@ -849,11 +849,15 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
 }
 
 Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
-  // div X, 1 == X
   if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1))) {
+    // div X, 1 == X
     if (RHS->equalsInt(1))
       return ReplaceInstUsesWith(I, I.getOperand(0));
 
+    // div X, -1 == -X
+    if (RHS->isAllOnesValue())
+      return BinaryOperator::createNeg(I.getOperand(0));
+
     // Check to see if this is an unsigned division with an exact power of 2,
     // if so, convert to a right shift.
     if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
@@ -883,7 +887,7 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) {
     // if so, convert to a bitwise and.
     if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
       if (uint64_t Val = C->getValue())    // Don't break X % 0 (divide by zero)
-        if (Log2(Val))
+        if (!(Val & Val-1))                // Power of 2
           return BinaryOperator::create(Instruction::And, I.getOperand(0),
                                         ConstantUInt::get(I.getType(), Val-1));
   }
@@ -2031,7 +2035,7 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
             New = new MallocInst(CastElTy, Amt, Name);
           else
             New = new AllocaInst(CastElTy, Amt, Name);
-          InsertNewInstBefore(New, CI);
+          InsertNewInstBefore(New, *AI);
           return ReplaceInstUsesWith(CI, New);
         }
       }
@@ -2580,7 +2584,10 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
       // obvious.
       Value *Op = GEP.getOperand(i);
       if (Op->getType()->getPrimitiveSize() > TD->getPointerSize())
-        if (!isa<Constant>(Op)) {
+        if (Constant *C = dyn_cast<Constant>(Op)) {
+          GEP.setOperand(i, ConstantExpr::getCast(C, TD->getIntPtrType()));
+          MadeChange = true;
+        } else {
           Op = InsertNewInstBefore(new CastInst(Op, TD->getIntPtrType(),
                                                 Op->getName()), GEP);
           GEP.setOperand(i, Op);
@@ -2927,7 +2934,9 @@ bool InstCombiner::runOnFunction(Function &F) {
   bool Changed = false;
   TD = &getAnalysis<TargetData>();
 
-  WorkList.insert(WorkList.end(), inst_begin(F), inst_end(F));
+  for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i)
+    WorkList.push_back(&*i);
+
 
   while (!WorkList.empty()) {
     Instruction *I = WorkList.back();  // Get an instruction from the worklist
@@ -2988,6 +2997,12 @@ bool InstCombiner::runOnFunction(Function &F) {
         BasicBlock *InstParent = I->getParent();
         InstParent->getInstList().insert(I, Result);
 
+        // Make sure that we reprocess all operands now that we reduced their
+        // use counts.
+        for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+          if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(i)))
+            WorkList.push_back(OpI);
+
         // Everything uses the new instruction now...
         I->replaceAllUsesWith(Result);
 
@@ -2996,14 +3011,19 @@ bool InstCombiner::runOnFunction(Function &F) {
       } else {
         DEBUG(std::cerr << "IC: MOD = " << *I);
 
-        BasicBlock::iterator II = I;
-
         // If the instruction was modified, it's possible that it is now dead.
         // if so, remove it.
-        if (dceInstruction(II)) {
-          // Instructions may end up in the worklist more than once.  Erase them
-          // all.
+        if (isInstructionTriviallyDead(I)) {
+          // Make sure we process all operands now that we are reducing their
+          // use counts.
+          for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+            if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(i)))
+              WorkList.push_back(OpI);
+          
+          // Instructions may end up in the worklist more than once.  Erase all
+          // occurrances of this instruction.
           removeFromWorkList(I);
+          I->getParent()->getInstList().erase(I);
           Result = 0;
         }
       }