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

Chris Lattner lattner at cs.uiuc.edu
Mon Feb 6 22:56:46 PST 2006



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.418 -> 1.419
---
Log message:

Implement the beginnings of a facility for simplifying expressions based on
'demanded bits', inspired by Nate's work in the dag combiner.  This isn't
complete, but needs to unrelated instcombiner changes to continue.


---
Diffs of the changes:  (+145 -3)

 InstructionCombining.cpp |  148 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 145 insertions(+), 3 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.418 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.419
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.418	Sun Feb  5 01:54:04 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Tue Feb  7 00:56:34 2006
@@ -72,7 +72,7 @@
     /// the instruction to the work lists because they might get more simplified
     /// now.
     ///
-    void AddUsersToWorkList(Instruction &I) {
+    void AddUsersToWorkList(Value &I) {
       for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
            UI != UE; ++UI)
         WorkList.push_back(cast<Instruction>(*UI));
@@ -188,6 +188,21 @@
       }
     }
 
+    // UpdateValueUsesWith - This method is to be used when an value is
+    // found to be replacable with another preexisting expression or was
+    // updated.  Here we add all uses of I to the worklist, replace all uses of
+    // I with the new value (unless the instruction was just updated), then
+    // return true, so that the inst combiner will know that I was modified.
+    //
+    bool UpdateValueUsesWith(Value *Old, Value *New) {
+      AddUsersToWorkList(*Old);         // Add all modified instrs to worklist
+      if (Old != New)
+        Old->replaceAllUsesWith(New);
+      if (Instruction *I = dyn_cast<Instruction>(Old))
+        WorkList.push_back(I);
+      return true;
+    }
+    
     // EraseInstFromFunction - When dealing with an instruction that has side
     // effects or produces a void value, we can't rely on DCE to delete the
     // instruction.  Instead, visit methods should return the value returned by
@@ -200,7 +215,6 @@
       return 0;  // Don't do anything with FI
     }
 
-
   private:
     /// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
     /// InsertBefore instruction.  This is specialized a bit to avoid inserting
@@ -213,6 +227,7 @@
     // operators.
     bool SimplifyCommutative(BinaryOperator &I);
 
+    bool SimplifyDemandedBits(Value *V, uint64_t Mask, unsigned Depth = 0);
 
     // FoldOpIntoPhi - Given a binary operator or cast instruction which has a
     // PHI node as operand #0, see if we can fold the instruction into the PHI
@@ -476,6 +491,122 @@
   return false;
 }
 
+/// SimplifyDemandedBits - Look at V.  At this point, we know that only the Mask
+/// bits of the result of V are ever used downstream.  If we can use this
+/// information to simplify V, return V and set NewVal to the new value we
+/// should use in V's place.
+bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t Mask,
+                                        unsigned Depth) {
+  if (!V->hasOneUse()) {    // Other users may use these bits.
+    if (Depth != 0)         // Not at the root.
+      return false;
+    // If this is the root being simplified, allow it to have multiple uses,
+    // just set the Mask to all bits.
+    Mask = V->getType()->getIntegralTypeMask();
+  } else if (Mask == 0) {   // Not demanding any bits from V.
+    return UpdateValueUsesWith(V, UndefValue::get(V->getType()));
+  } else if (Depth == 6) {        // Limit search depth.
+    return false;
+  }
+  
+  Instruction *I = dyn_cast<Instruction>(V);
+  if (!I) return false;        // Only analyze instructions.
+
+  switch (I->getOpcode()) {
+  default: break;
+  case Instruction::And:
+    if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
+      // Only demanding an intersection of the bits.
+      if (SimplifyDemandedBits(I->getOperand(0), RHS->getRawValue() & Mask,
+                               Depth+1))
+        return true;
+      if (~Mask & RHS->getRawValue()) {
+        // If this is producing any bits that are not needed, simplify the RHS.
+        if (I->getType()->isSigned()) {
+          int64_t Val = Mask & cast<ConstantSInt>(RHS)->getValue();
+          I->setOperand(1, ConstantSInt::get(I->getType(), Val));
+        } else {
+          uint64_t Val = Mask & cast<ConstantUInt>(RHS)->getValue();
+          I->setOperand(1, ConstantUInt::get(I->getType(), Val));
+        }
+        return UpdateValueUsesWith(I, I);
+      }
+    }
+    // Walk the LHS and the RHS.
+    return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1) ||
+           SimplifyDemandedBits(I->getOperand(1), Mask, Depth+1);
+  case Instruction::Or:
+  case Instruction::Xor:
+    if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
+      // If none of the [x]or'd in bits are demanded, don't both with the [x]or.
+      if ((Mask & RHS->getRawValue()) == 0)
+        return UpdateValueUsesWith(I, I->getOperand(0));
+      
+      // Otherwise, for an OR, we only demand those bits not set by the OR.
+      if (I->getOpcode() == Instruction::Or)
+        Mask &= ~RHS->getRawValue();
+      return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1);
+    }
+    // Walk the LHS and the RHS.
+    return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1) ||
+           SimplifyDemandedBits(I->getOperand(1), Mask, Depth+1);
+  case Instruction::Cast: {
+    const Type *SrcTy = I->getOperand(0)->getType();
+    if (SrcTy == Type::BoolTy)
+      return SimplifyDemandedBits(I->getOperand(0), Mask&1, Depth+1);
+    
+    if (!SrcTy->isInteger()) return false;
+
+    unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
+    // If this is a sign-extend, treat specially.
+    if (SrcTy->isSigned() &&
+        SrcBits < I->getType()->getPrimitiveSizeInBits()) {
+      // If none of the top bits are demanded, convert this into an unsigned
+      // extend instead of a sign extend.
+      if ((Mask & ((1ULL << SrcBits)-1)) == 0) {
+        // Convert to unsigned first.
+        Value *NewVal;
+        NewVal = new CastInst(I->getOperand(0), SrcTy->getUnsignedVersion(),
+                              I->getOperand(0)->getName(), I);
+        NewVal = new CastInst(I->getOperand(0), I->getType(), I->getName());
+        return UpdateValueUsesWith(I, NewVal);
+      }
+
+      // Otherwise, the high-bits *are* demanded.  This means that the code
+      // implicitly demands computation of the sign bit of the input, make sure
+      // we explicitly include it in Mask.
+      Mask |= 1ULL << (SrcBits-1);
+    }
+    
+    // If this is an extension, the top bits are ignored.
+    Mask &= SrcTy->getIntegralTypeMask();
+    return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1);
+  }
+  case Instruction::Select:
+    // Simplify the T and F values if they are not demanded.
+    return SimplifyDemandedBits(I->getOperand(2), Mask, Depth+1) ||
+           SimplifyDemandedBits(I->getOperand(1), Mask, Depth+1);
+  case Instruction::Shl:
+    // We only demand the low bits of the input.
+    if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
+      return SimplifyDemandedBits(I->getOperand(0), Mask >> SA->getValue(), 
+                                  Depth+1);
+    break;
+  case Instruction::Shr:
+    // We only demand the high bits of the input.
+    if (I->getType()->isUnsigned())
+      if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) {
+        Mask <<= SA->getValue();
+        Mask &= I->getType()->getIntegralTypeMask();
+        return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1);
+      }
+    // FIXME: handle signed shr, demanding the appropriate bits.  If the top
+    // bits aren't demanded, strength reduce to a logical SHR instead.
+    break;
+  }
+  return false;
+}  
+
 // isTrueWhenEqual - Return true if the specified setcondinst instruction is
 // true when both operands are equal...
 //
@@ -1824,6 +1955,11 @@
     if (MaskedValueIsZero(Op0, NotAndRHS))
       return ReplaceInstUsesWith(I, Op0);
 
+    // See if we can simplify any instructions used by the LHS whose sole 
+    // purpose is to compute bits we don't care about.
+    if (SimplifyDemandedBits(Op0, AndRHS->getRawValue()))
+      return &I;
+    
     // Optimize a variety of ((val OP C1) & C2) combinations...
     if (isa<BinaryOperator>(Op0) || isa<ShiftInst>(Op0)) {
       Instruction *Op0I = cast<Instruction>(Op0);
@@ -4122,12 +4258,18 @@
       return And;
     }
   }
-
+  
   // If this is a cast to bool, turn it into the appropriate setne instruction.
   if (CI.getType() == Type::BoolTy)
     return BinaryOperator::createSetNE(CI.getOperand(0),
                        Constant::getNullValue(CI.getOperand(0)->getType()));
 
+  // See if we can simplify any instructions used by the LHS whose sole 
+  // purpose is to compute bits we don't care about.
+  if (CI.getType()->isInteger() && CI.getOperand(0)->getType()->isIntegral() &&
+      SimplifyDemandedBits(&CI, CI.getType()->getIntegralTypeMask()))
+    return &CI;
+  
   // If casting the result of a getelementptr instruction with no offset, turn
   // this into a cast of the original pointer!
   //






More information about the llvm-commits mailing list