[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
clattner at apple.com
Fri Mar 23 23:30:11 PDT 2007
ComputeMaskedBits had several iterations, here's a review of the one
in CVS now. Comments preceeded by ***.
static void ComputeMaskedBits(Value *V, APInt Mask, APInt& KnownZero,
APInt& KnownOne, unsigned Depth = 0) {
assert(V && "No Value?");
assert(Depth <= 6 && "Limit Search Depth");
uint32_t BitWidth = Mask.getBitWidth();
const IntegerType *VTy = cast<IntegerType>(V->getType());
assert(VTy->getBitWidth() == BitWidth &&
*** VTy is only used in the assertion, please change this to:
assert(cast<IntegerType>(V->getType())->getBitWidth() == BitWidth &&
..
KnownZero.clear(); KnownOne.clear(); // Don't know anything.
APInt KnownZero2(KnownZero), KnownOne2(KnownOne);
Mask &= APInt::getAllOnesValue(BitWidth);
*** This &= is useless.
switch (I->getOpcode()) {
...
case Instruction::Trunc: {
// All these have integer operands
uint32_t SrcBitWidth =
cast<IntegerType>(I->getOperand(0)->getType())->getBitWidth();
ComputeMaskedBits(I->getOperand(0), Mask.zext(SrcBitWidth),
KnownZero.zext(SrcBitWidth), KnownOne.zext(SrcBitWidth), Depth
+1);
*** Please move the nested ZExt's out of line to make this simpler.
KnownZero.trunc(BitWidth);
KnownOne.trunc(BitWidth);
return;
}
case Instruction::ZExt: {
// Compute the bits in the result that are not present in the
input.
const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)-
>getType());
APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy-
>getBitWidth()));
*** NewBits should use SrcBitWidth and should be moved closer/inlined
into its only use.
uint32_t SrcBitWidth = SrcTy->getBitWidth();
ComputeMaskedBits(I->getOperand(0), Mask.trunc(SrcBitWidth),
KnownZero.trunc(SrcBitWidth), KnownOne.trunc(SrcBitWidth),
Depth+1);
*** Likewise out of line the trunc's.
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND
zero?");
// The top bits are known to be zero.
KnownZero.zext(BitWidth);
KnownOne.zext(BitWidth);
KnownZero |= NewBits;
return;
}
case Instruction::SExt: {
// Compute the bits in the result that are not present in the
input.
const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)-
>getType());
APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy-
>getBitWidth()));
*** Likewise, move NewBits down plz, use SrcBitWidth.
uint32_t SrcBitWidth = SrcTy->getBitWidth();
ComputeMaskedBits(I->getOperand(0), Mask.trunc(SrcBitWidth),
KnownZero.trunc(SrcBitWidth), KnownOne.trunc(SrcBitWidth),
Depth+1);
*** Out of line the truncs plz.
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND
zero?");
KnownZero.zext(BitWidth);
KnownOne.zext(BitWidth);
// If the sign bit of the input is known set or clear, then we
know the
// top bits of the result.
APInt InSignBit(APInt::getSignBit(SrcTy->getBitWidth()));
*** Use SrcBitWidth.
InSignBit.zext(BitWidth);
*** This zext is dead.
if ((KnownZero & InSignBit) != 0) { // Input sign bit
known zero
KnownZero |= NewBits;
KnownOne &= ~NewBits;
*** This &= is dead.
} else if ((KnownOne & InSignBit) != 0) { // Input sign bit
known set
KnownOne |= NewBits;
KnownZero &= ~NewBits;
*** This &= is dead.
} else { // Input sign bit unknown
KnownZero &= ~NewBits;
*** This &= is dead.
KnownOne &= ~NewBits;
*** This &= is dead.
}
return;
}
case Instruction::LShr:
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
// Compute the new bits that are at the top now.
uint64_t ShiftAmt = SA->getZExtValue();
APInt HighBits(APInt::getAllOnesValue(BitWidth).shl(BitWidth-
ShiftAmt));
*** Sink HighBits down to its only use.
// Unsigned shift right.
Mask <<= ShiftAmt;
ComputeMaskedBits(I->getOperand(0), Mask,
KnownZero,KnownOne,Depth+1);
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND
zero?");
KnownZero = APIntOps::lshr(KnownZero, ShiftAmt);
KnownOne = APIntOps::lshr(KnownOne, ShiftAmt);
KnownZero |= HighBits; // high bits known zero.
return;
}
break;
case Instruction::AShr:
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
*** ushr -> ashr in comment.
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
// Compute the new bits that are at the top now.
uint64_t ShiftAmt = SA->getZExtValue();
APInt HighBits(APInt::getAllOnesValue(BitWidth).shl(BitWidth-
ShiftAmt));
*** Sink HighBits.
// Signed shift right.
Mask <<= ShiftAmt;
ComputeMaskedBits(I->getOperand(0), Mask,
KnownZero,KnownOne,Depth+1);
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND
zero?");
KnownZero = APIntOps::lshr(KnownZero, ShiftAmt);
KnownOne = APIntOps::lshr(KnownOne, ShiftAmt);
// Handle the sign bits and adjust to where it is now in the
mask.
APInt SignBit(APInt::getSignBit(BitWidth).lshr(ShiftAmt));
if ((KnownZero & SignBit) != 0) { // New bits are known
zero.
KnownZero |= HighBits;
} else if ((KnownOne & SignBit) != 0) { // New bits are known
one.
KnownOne |= HighBits;
}
return;
}
break;
}
}
-Chris
More information about the llvm-commits
mailing list