In APInt version ComputeMaskedBits():

1. Ensure VTy, KnownOne and KnownZero have same bitwidth.
  2. Make code more efficient.

llvm-svn: 35078
This commit is contained in:
Zhou Sheng 2007-03-13 02:23:10 +00:00
parent 818242bbaf
commit af4341d441
1 changed files with 28 additions and 15 deletions

View File

@ -582,29 +582,30 @@ static ConstantInt *SubOne(ConstantInt *C) {
/// this won't lose us code quality. /// this won't lose us code quality.
static void ComputeMaskedBits(Value *V, APInt Mask, APInt& KnownZero, static void ComputeMaskedBits(Value *V, APInt Mask, APInt& KnownZero,
APInt& KnownOne, unsigned Depth = 0) { APInt& KnownOne, unsigned Depth = 0) {
assert(V && "No Value?");
assert(Depth <= 6 && "Limit Search Depth");
uint32_t BitWidth = Mask.getBitWidth(); uint32_t BitWidth = Mask.getBitWidth();
assert(KnownZero.getBitWidth() == BitWidth && const IntegerType *VTy = cast<IntegerType>(V->getType());
assert(VTy->getBitWidth() == BitWidth &&
KnownZero.getBitWidth() == BitWidth &&
KnownOne.getBitWidth() == BitWidth && KnownOne.getBitWidth() == BitWidth &&
"Mask, KnownOne and KnownZero should have same BitWidth"); "VTy, Mask, KnownOne and KnownZero should have same BitWidth");
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
// We know all of the bits for a constant! // We know all of the bits for a constant!
APInt Tmp(CI->getValue()); KnownOne = CI->getValue() & Mask;
Tmp.zextOrTrunc(BitWidth);
KnownOne = Tmp & Mask;
KnownZero = ~KnownOne & Mask; KnownZero = ~KnownOne & Mask;
return; return;
} }
KnownZero.clear(); KnownOne.clear(); // Don't know anything.
if (Depth == 6 || Mask == 0) if (Depth == 6 || Mask == 0)
return; // Limit search depth. return; // Limit search depth.
Instruction *I = dyn_cast<Instruction>(V); Instruction *I = dyn_cast<Instruction>(V);
if (!I) return; if (!I) return;
KnownZero.clear(); KnownOne.clear(); // Don't know anything.
APInt KnownZero2(KnownZero), KnownOne2(KnownOne); APInt KnownZero2(KnownZero), KnownOne2(KnownOne);
Mask &= APInt::getAllOnesValue( Mask &= APInt::getAllOnesValue(BitWidth);
cast<IntegerType>(V->getType())->getBitWidth()).zextOrTrunc(BitWidth);
switch (I->getOpcode()) { switch (I->getOpcode()) {
case Instruction::And: case Instruction::And:
@ -664,10 +665,16 @@ static void ComputeMaskedBits(Value *V, APInt Mask, APInt& KnownZero,
case Instruction::UIToFP: case Instruction::UIToFP:
case Instruction::IntToPtr: case Instruction::IntToPtr:
return; // Can't work with floating point or pointers return; // Can't work with floating point or pointers
case Instruction::Trunc: case Instruction::Trunc: {
// All these have integer operands // All these have integer operands
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); 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);
KnownZero.trunc(BitWidth);
KnownOne.trunc(BitWidth);
return; return;
}
case Instruction::BitCast: { case Instruction::BitCast: {
const Type *SrcTy = I->getOperand(0)->getType(); const Type *SrcTy = I->getOperand(0)->getType();
if (SrcTy->isInteger()) { if (SrcTy->isInteger()) {
@ -681,10 +688,13 @@ static void ComputeMaskedBits(Value *V, APInt Mask, APInt& KnownZero,
const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType()); const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy->getBitWidth())); APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy->getBitWidth()));
Mask &= SrcTy->getMask().zextOrTrunc(BitWidth); uint32_t SrcBitWidth = SrcTy->getBitWidth();
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); ComputeMaskedBits(I->getOperand(0), Mask.trunc(SrcBitWidth),
KnownZero.trunc(SrcBitWidth), KnownOne.trunc(SrcBitWidth), Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
// The top bits are known to be zero. // The top bits are known to be zero.
KnownZero.zext(BitWidth);
KnownOne.zext(BitWidth);
KnownZero |= NewBits; KnownZero |= NewBits;
return; return;
} }
@ -693,14 +703,17 @@ static void ComputeMaskedBits(Value *V, APInt Mask, APInt& KnownZero,
const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType()); const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy->getBitWidth())); APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy->getBitWidth()));
Mask &= SrcTy->getMask().zextOrTrunc(BitWidth); uint32_t SrcBitWidth = SrcTy->getBitWidth();
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); ComputeMaskedBits(I->getOperand(0), Mask.trunc(SrcBitWidth),
KnownZero.trunc(SrcBitWidth), KnownOne.trunc(SrcBitWidth), Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); 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 // If the sign bit of the input is known set or clear, then we know the
// top bits of the result. // top bits of the result.
APInt InSignBit(APInt::getSignBit(SrcTy->getBitWidth())); APInt InSignBit(APInt::getSignBit(SrcTy->getBitWidth()));
InSignBit.zextOrTrunc(BitWidth); InSignBit.zext(BitWidth);
if ((KnownZero & InSignBit) != 0) { // Input sign bit known zero if ((KnownZero & InSignBit) != 0) { // Input sign bit known zero
KnownZero |= NewBits; KnownZero |= NewBits;
KnownOne &= ~NewBits; KnownOne &= ~NewBits;