Fix some bugs, straighten stuff out, more work needs to be done.
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index 9679a2b6aabc2b3d59fdfbce759b05107b43be71..385c07004d4e7d304f2e7634d81edea69c2d7956 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Transforms/Scalar/InstructionCombining.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/ConstantHandling.h"
 #include "llvm/iMemory.h"
 #include "llvm/iOther.h"
+#include "llvm/iPHINode.h"
 #include "llvm/iOperators.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/InstVisitor.h"
-#include "../TransformInternals.h"
 
 
 namespace {
@@ -57,7 +58,7 @@ namespace {
     //     I          - Change was made, I is still valid
     //   otherwise    - Change was made, replace I with returned instruction
     //   
-
+    Instruction *visitNot(UnaryOperator *I);
     Instruction *visitAdd(BinaryOperator *I);
     Instruction *visitSub(BinaryOperator *I);
     Instruction *visitMul(BinaryOperator *I);
@@ -69,6 +70,7 @@ namespace {
     Instruction *visitSetCondInst(BinaryOperator *I);
     Instruction *visitShiftInst(Instruction *I);
     Instruction *visitCastInst(CastInst *CI);
+    Instruction *visitPHINode(PHINode *PN);
     Instruction *visitGetElementPtrInst(GetElementPtrInst *GEP);
     Instruction *visitMemAccessInst(MemAccessInst *MAI);
 
@@ -78,6 +80,19 @@ namespace {
 }
 
 
+Instruction *InstCombiner::visitNot(UnaryOperator *I) {
+  if (I->use_empty()) return 0;       // Don't fix dead instructions...
+
+  // not (not X) = X
+  if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(0)))
+    if (Op->getOpcode() == Instruction::Not) {
+      AddUsesToWorkList(I);         // Add all modified instrs to worklist
+      I->replaceAllUsesWith(Op->getOperand(0));
+      return I;
+    }
+  return 0;
+}
+
 
 // Make sure that this instruction has a constant on the right hand side if it
 // has any constant arguments.  If not, fix it an return true.
@@ -113,13 +128,13 @@ Instruction *InstCombiner::visitAdd(BinaryOperator *I) {
     return I;
   }
 
-  // -B + A  -->  A - B
+  // -A + B  -->  B - A
   if (Value *V = dyn_castNegInst(LHS))
-    return BinaryOperator::create(Instruction::Sub, RHS, LHS);
+    return BinaryOperator::create(Instruction::Sub, RHS, V);
 
   // A + -B  -->  A - B
   if (Value *V = dyn_castNegInst(RHS))
-    return BinaryOperator::create(Instruction::Sub, LHS, RHS);
+    return BinaryOperator::create(Instruction::Sub, LHS, V);
 
   // Simplify add instructions with a constant RHS...
   if (Constant *Op2 = dyn_cast<Constant>(RHS)) {
@@ -161,14 +176,23 @@ Instruction *InstCombiner::visitSub(BinaryOperator *I) {
     if (Constant *RHS = *Constant::getNullValue(I->getType()) - *Op2) // 0 - RHS
       return BinaryOperator::create(Instruction::Add, Op0, RHS, I->getName());
 
-  // If this is a 'C = -B', check to see if 'B = -A', so that C = A...
-  if (Op0 == Constant::getNullValue(I->getType())) 
-    if (Value *V = dyn_castNegInst(Op1)) {
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(V);
-      return I;
-    }
+  // If this is a 'C = x-B', check to see if 'B = -A', so that C = x+A...
+  if (Value *V = dyn_castNegInst(Op1))
+    return BinaryOperator::create(Instruction::Add, Op0, V);
 
+  // Replace (x - (y - z)) with (x + (z - y)) if the (y - z) subexpression is
+  // not used by anyone else...
+  //
+  if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1))
+    if (Op1I->use_size() == 1) {
+      // Swap the two operands of the subexpr...
+      Value *IIOp0 = Op1I->getOperand(0), *IIOp1 = Op1I->getOperand(1);
+      Op1I->setOperand(0, IIOp1);
+      Op1I->setOperand(1, IIOp0);
+
+      // Create the new top level add instruction...
+      return BinaryOperator::create(Instruction::Add, Op0, Op1);
+    }
   return 0;
 }
 
@@ -234,16 +258,15 @@ static Constant *getMaxValue(const Type *Ty) {
   if (Ty == Type::BoolTy)
     return ConstantBool::True;
 
-  // Calculate -1 casted to the right type...
-  unsigned TypeBits = Ty->getPrimitiveSize()*8;
-  uint64_t Val = (uint64_t)-1LL;       // All ones
-  Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
-
   if (Ty->isSigned())
-    return ConstantSInt::get(Ty, (int64_t)Val);
-  else if (Ty->isUnsigned())
+    return ConstantSInt::get(Ty, -1);
+  else if (Ty->isUnsigned()) {
+    // Calculate -1 casted to the right type...
+    unsigned TypeBits = Ty->getPrimitiveSize()*8;
+    uint64_t Val = (uint64_t)-1LL;       // All ones
+    Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
     return ConstantUInt::get(Ty, Val);
-
+  }
   return 0;
 }
 
@@ -320,17 +343,31 @@ Instruction *InstCombiner::visitXor(BinaryOperator *I) {
   return Changed ? I : 0;
 }
 
+// isTrueWhenEqual - Return true if the specified setcondinst instruction is
+// true when both operands are equal...
+//
+static bool isTrueWhenEqual(Instruction *I) {
+  return I->getOpcode() == Instruction::SetEQ ||
+         I->getOpcode() == Instruction::SetGE ||
+         I->getOpcode() == Instruction::SetLE;
+}
+
 Instruction *InstCombiner::visitSetCondInst(BinaryOperator *I) {
   if (I->use_empty()) return 0;       // Don't fix dead instructions...
   bool Changed = SimplifyBinOp(I);
 
   // setcc X, X
   if (I->getOperand(0) == I->getOperand(1)) {
-    bool NewVal = I->getOpcode() == Instruction::SetEQ ||
-                  I->getOpcode() == Instruction::SetGE ||
-                  I->getOpcode() == Instruction::SetLE;
     AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(ConstantBool::get(NewVal));
+    I->replaceAllUsesWith(ConstantBool::get(isTrueWhenEqual(I)));
+    return I;
+  }
+
+  // setcc <global*>, 0 - Global value addresses are never null!
+  if (isa<GlobalValue>(I->getOperand(0)) &&
+      isa<ConstantPointerNull>(I->getOperand(1))) {
+    AddUsesToWorkList(I);         // Add all modified instrs to worklist
+    I->replaceAllUsesWith(ConstantBool::get(!isTrueWhenEqual(I)));
     return I;
   }
 
@@ -399,6 +436,8 @@ static inline bool isEliminableCastOfCast(const CastInst *CI,
 // CastInst simplification
 //
 Instruction *InstCombiner::visitCastInst(CastInst *CI) {
+  if (CI->use_empty()) return 0;       // Don't fix dead instructions...
+
   // If the user is casting a value to the same type, eliminate this cast
   // instruction...
   if (CI->getType() == CI->getOperand(0)->getType() && !CI->use_empty()) {
@@ -423,6 +462,21 @@ Instruction *InstCombiner::visitCastInst(CastInst *CI) {
 }
 
 
+// PHINode simplification
+//
+Instruction *InstCombiner::visitPHINode(PHINode *PN) {
+  if (PN->use_empty()) return 0;       // Don't fix dead instructions...
+
+  // If the PHI node only has one incoming value, eliminate the PHI node...
+  if (PN->getNumIncomingValues() == 1) {
+    AddUsesToWorkList(PN);         // Add all modified instrs to worklist
+    PN->replaceAllUsesWith(PN->getIncomingValue(0));
+    return PN;
+  }
+
+  return 0;
+}
+
 
 Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst *GEP) {
   // Is it getelementptr %P, uint 0