[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
clattner at apple.com
Sat Mar 24 00:04:27 PDT 2007
>
> Add an APInt version of SimplifyDemandedBits.
>
> Patch by Zhou Sheng.
Commenting on the version from mainline, comments preceeded with ***'s:
static void ComputeMaskedBits(Value *V, APInt Mask, APInt& KnownZero,
*** Mask should be passed by const&.
bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
*** Plz pass APInt's by const&, not by-value.
APInt& KnownZero, APInt&
KnownOne,
unsigned Depth) {
...
Instruction *I = dyn_cast<Instruction>(V);
if (!I) return false; // Only analyze instructions.
DemandedMask &= APInt::getAllOnesValue(BitWidth);
*** This &= is dead.
APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne;
*** What is the point of the RHSKnownZero/RHSKnownOne references, plz
drop them.
switch (I->getOpcode()) {
...
case Instruction::Trunc: {
uint32_t truncBf =
cast<IntegerType>(I->getOperand(0)->getType())->getBitWidth();
if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.zext
(truncBf),
RHSKnownZero.zext(truncBf), RHSKnownOne.zext(truncBf), Depth
+1))
*** Plz move the calls to zext out of line.
return true;
DemandedMask.trunc(BitWidth);
RHSKnownZero.trunc(BitWidth);
RHSKnownOne.trunc(BitWidth);
assert((RHSKnownZero & RHSKnownOne) == 0 &&
"Bits known to be one AND zero?");
break;
}
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()));
*** This idiom occurs in many places, it should be a new
APInt::getHighBitsSet(width,numbits) method.
DemandedMask &= SrcTy->getMask().zext(BitWidth);
*** This should truncate DemandedMask then 'and' it.
uint32_t zextBf = SrcTy->getBitWidth();
if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.trunc
(zextBf),
RHSKnownZero.trunc(zextBf), RHSKnownOne.trunc(zextBf),
Depth+1))
*** Truncs out of line plz.
return true;
}
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()));
*** Should use APInt::getHighBitsSet.
// Get the sign bit for the source type
APInt InSignBit(APInt::getSignBit(SrcTy->getPrimitiveSizeInBits
()));
InSignBit.zext(BitWidth);
APInt InputDemandedBits = DemandedMask &
SrcTy->getMask().zext(BitWidth);
*** The getMask().zext stuff should get 'APInt::getLowBitsSet(...)'.
..
uint32_t sextBf = SrcTy->getBitWidth();
if (SimplifyDemandedBits(I->getOperand(0),
InputDemandedBits.trunc(sextBf),
RHSKnownZero.trunc(sextBf), RHSKnownOne.trunc(sextBf),
Depth+1))
*** Plz don't nest the trunc calls.
return true;
case Instruction::Add: {
...
// If the top bit of the output is demanded, demand everything
from the
// input. Otherwise, we demand all the input bits except NLZ
top bits.
APInt InDemandedBits(APInt::getAllOnesValue(BitWidth).lshr(NLZ));
*** Should be APInt::getLowBitsSet.
...
bool CarryIn = false;
APInt CarryBits(BitWidth, 0);
const uint64_t *LHSKnownZeroRawVal = LHSKnownZero.getRawData(),
*RHSRawVal = RHSVal.getRawData();
for (uint32_t i = 0; i != RHSVal.getNumWords(); ++i) {
uint64_t AddVal = ~LHSKnownZeroRawVal[i] + RHSRawVal[i],
XorVal = ~LHSKnownZeroRawVal[i] ^ RHSRawVal[i];
uint64_t WordCarryBits = AddVal ^ XorVal + CarryIn;
if (AddVal < RHSRawVal[i])
CarryIn = true;
else
CarryIn = false;
CarryBits.setWordToValue(i, WordCarryBits);
}
*** Why aren't you doing this in terms of APInt operations?
...
// If the high-bits of this ADD are not demanded, then it does
not demand
// the high bits of its LHS or RHS.
if ((DemandedMask & APInt::getSignBit(BitWidth)) == 0) {
*** This seems like it should be: "if (DemandedMask[BitWidth-1] == 0)
{". Likewise in other places, grep for getSignBit to find them.
// Right fill the mask of bits for this ADD to demand the most
// significant bit and all those below it.
APInt DemandedFromOps = APInt::getAllOnesValue(BitWidth).lshr
(NLZ);
*** Use APInt::getLowBitsSet.
...
case Instruction::Sub:
// If the high-bits of this SUB are not demanded, then it does
not demand
// the high bits of its LHS or RHS.
if ((DemandedMask & APInt::getSignBit(BitWidth)) == 0) {
*** Use operator[]
// Right fill the mask of bits for this SUB to demand the most
// significant bit and all those below it.
unsigned NLZ = DemandedMask.countLeadingZeros();
APInt DemandedFromOps(APInt::getAllOnesValue(BitWidth).lshr
(NLZ));
*** Use getLowBitsSet.
case Instruction::Shl:
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
uint64_t ShiftAmt = SA->getZExtValue();
if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.lshr
(ShiftAmt),
*** Don't nest the lshr call, it makes it VERY easy to miss.
RHSKnownZero, RHSKnownOne, Depth+1))
return true;
...
// low bits known zero.
if (ShiftAmt)
RHSKnownZero |= APInt::getAllOnesValue(ShiftAmt).zextOrCopy
(BitWidth);
*** getLowBitsSet. If this is the only use of zextOrCopy, remove it.
case Instruction::LShr:
// For a logical shift right
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
unsigned ShiftAmt = SA->getZExtValue();
APInt TypeMask(APInt::getAllOnesValue(BitWidth));
// Unsigned shift right.
if (SimplifyDemandedBits(I->getOperand(0),
(DemandedMask.shl(ShiftAmt)) & TypeMask,
*** The & is dead, move the shl out of line plz.
RHSKnownZero, RHSKnownOne, Depth+1))
return true;
assert((RHSKnownZero & RHSKnownOne) == 0 &&
"Bits known to be one AND zero?");
RHSKnownZero &= TypeMask;
RHSKnownOne &= TypeMask;
*** These &='s are dead.
RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt);
RHSKnownOne = APIntOps::lshr(RHSKnownOne, ShiftAmt);
if (ShiftAmt) {
// Compute the new bits that are at the top now.
APInt HighBits(APInt::getAllOnesValue(BitWidth).shl(
BitWidth - ShiftAmt));
*** Should use APInt::getHighBitsSet.
...
case Instruction::AShr:
*** Many of the same comments about LShr apply here.
...
// Handle the sign bits.
APInt SignBit(APInt::getSignBit(BitWidth));
// Adjust to where it is now in the mask.
SignBit = APIntOps::lshr(SignBit, ShiftAmt);
// If the input sign bit is known to be zero, or if none of
the top bits
// are demanded, turn this into an unsigned shift right.
if ((RHSKnownZero & SignBit) != 0 ||
*** All this logic playing with Sign bit should be eliminated and
replace with use of RHSKnownZero[] and RHSKnownOne[] (down below).
static void ComputeUnsignedMinMaxValuesFromKnownBits(const Type *Ty,
const APInt&
KnownZero,
const APInt&
KnownOne,
APInt& Min,
APInt& Max) {
uint32_t BitWidth = cast<IntegerType>(Ty)->getBitWidth();
assert(KnownZero.getBitWidth() == BitWidth &&
KnownOne.getBitWidth() == BitWidth &&
Min.getBitWidth() == BitWidth && Max.getBitWidth() &&
"Ty, KnownZero, KnownOne and Min, Max must have equal
bitwidth.");
APInt TypeBits(APInt::getAllOnesValue(BitWidth));
APInt UnknownBits = ~(KnownZero|KnownOne) & TypeBits;
*** TypeBits and the & are dead.
// The minimum value is when the unknown bits are all zeros.
Min = KnownOne;
// The maximum value is when the unknown bits are all ones.
Max = KnownOne|UnknownBits;
}
static void ComputeSignedMinMaxValuesFromKnownBits(const Type *Ty,
const APInt&
KnownZero,
const APInt&
KnownOne,
APInt& Min,
APInt& Max) {
uint32_t BitWidth = cast<IntegerType>(Ty)->getBitWidth();
assert(KnownZero.getBitWidth() == BitWidth &&
KnownOne.getBitWidth() == BitWidth &&
Min.getBitWidth() == BitWidth && Max.getBitWidth() ==
BitWidth &&
"Ty, KnownZero, KnownOne and Min, Max must have equal
bitwidth.");
APInt TypeBits(APInt::getAllOnesValue(BitWidth));
APInt UnknownBits = ~(KnownZero|KnownOne) & TypeBits;
*** TypeBits and the & are dead.
APInt SignBit(APInt::getSignBit(BitWidth));
*** Eliminate SignBit (and its uses) in favor of using UnknownBIts
[BitWidth-1] and Min[BitWidth-1] = 1, etc.
// The minimum value is when all unknown bits are zeros, EXCEPT
for the sign
// bit if it is unknown.
Min = KnownOne;
Max = KnownOne|UnknownBits;
if ((SignBit & UnknownBits) != 0) { // Sign bit is unknown
Min |= SignBit;
Max &= ~SignBit;
}
}
static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo,
APInt Demanded) {
*** Pass Demanded by const&.
assert(I && "No instruction?");
assert(OpNo < I->getNumOperands() && "Operand index too large");
// If the operand is not a constant integer, nothing to do.
ConstantInt *OpC = dyn_cast<ConstantInt>(I->getOperand(OpNo));
if (!OpC) return false;
// If there are no bits set that aren't demanded, nothing to do.
Demanded.zextOrTrunc(OpC->getValue().getBitWidth());
*** This zextOrTrunc is dead.
if ((~Demanded & OpC->getValue()) == 0)
return false;
// This instruction is producing bits that are not demanded.
Shrink the RHS.
Demanded &= OpC->getValue();
I->setOperand(OpNo, ConstantInt::get(Demanded));
return true;
}
Overall, nice job,
-Chris
More information about the llvm-commits
mailing list