mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 20:34:38 +00:00
simplify CanEvaluateZExtd now that we don't care about the number of
bits known clear in the result and don't care about the # casts eliminated. TD is also dead but keeping it for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93098 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5324d80283
commit
9e390ddf91
@ -575,122 +575,60 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, Instruction &CI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GetLeadingZeros - Compute the number of known-zero leading bits.
|
|
||||||
static unsigned GetLeadingZeros(Value *V, const TargetData *TD) {
|
|
||||||
unsigned Bits = V->getType()->getScalarSizeInBits();
|
|
||||||
APInt KnownZero(Bits, 0), KnownOne(Bits, 0);
|
|
||||||
ComputeMaskedBits(V, APInt::getAllOnesValue(Bits), KnownZero, KnownOne, TD);
|
|
||||||
return KnownZero.countLeadingOnes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// CanEvaluateZExtd - Determine if the specified value can be computed in the
|
/// CanEvaluateZExtd - Determine if the specified value can be computed in the
|
||||||
/// specified wider type and produce the same low bits. If not, return -1. If
|
/// specified wider type and produce the same low bits. If not, return -1. If
|
||||||
/// it is possible, return the number of high bits that are known to be zero in
|
/// it is possible, return the number of high bits that are known to be zero in
|
||||||
/// the promoted value.
|
/// the promoted value.
|
||||||
static int CanEvaluateZExtd(Value *V, const Type *Ty,unsigned &NumCastsRemoved,
|
static bool CanEvaluateZExtd(Value *V, const Type *Ty, const TargetData *TD) {
|
||||||
const TargetData *TD) {
|
if (isa<Constant>(V))
|
||||||
const Type *OrigTy = V->getType();
|
return true;
|
||||||
|
|
||||||
if (isa<Constant>(V)) {
|
|
||||||
unsigned Extended = Ty->getScalarSizeInBits()-OrigTy->getScalarSizeInBits();
|
|
||||||
|
|
||||||
// Constants can always be zero ext'd, even if it requires a ConstantExpr.
|
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
|
|
||||||
return Extended + CI->getValue().countLeadingZeros();
|
|
||||||
return Extended;
|
|
||||||
}
|
|
||||||
|
|
||||||
Instruction *I = dyn_cast<Instruction>(V);
|
Instruction *I = dyn_cast<Instruction>(V);
|
||||||
if (!I) return -1;
|
if (!I) return false;
|
||||||
|
|
||||||
// If the input is a truncate from the destination type, we can trivially
|
// If the input is a truncate from the destination type, we can trivially
|
||||||
// eliminate it, and this will remove a cast overall.
|
// eliminate it.
|
||||||
if (isa<TruncInst>(I) && I->getOperand(0)->getType() == Ty) {
|
if (isa<TruncInst>(I) && I->getOperand(0)->getType() == Ty)
|
||||||
// If the first operand is itself a cast, and is eliminable, do not count
|
return true;
|
||||||
// this as an eliminable cast. We would prefer to eliminate those two
|
|
||||||
// casts first.
|
|
||||||
if (!isa<CastInst>(I->getOperand(0)) && I->hasOneUse())
|
|
||||||
++NumCastsRemoved;
|
|
||||||
|
|
||||||
// Figure out the number of known-zero bits coming in.
|
|
||||||
return GetLeadingZeros(I->getOperand(0), TD);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can't extend or shrink something that has multiple uses: doing so would
|
// We can't extend or shrink something that has multiple uses: doing so would
|
||||||
// require duplicating the instruction in general, which isn't profitable.
|
// require duplicating the instruction in general, which isn't profitable.
|
||||||
if (!I->hasOneUse()) return -1;
|
if (!I->hasOneUse()) return false;
|
||||||
|
|
||||||
int Tmp1, Tmp2;
|
|
||||||
unsigned Opc = I->getOpcode();
|
unsigned Opc = I->getOpcode();
|
||||||
switch (Opc) {
|
switch (Opc) {
|
||||||
case Instruction::And:
|
case Instruction::And:
|
||||||
Tmp1 = CanEvaluateZExtd(I->getOperand(0), Ty, NumCastsRemoved, TD);
|
|
||||||
if (Tmp1 == -1) return -1;
|
|
||||||
Tmp2 = CanEvaluateZExtd(I->getOperand(1), Ty, NumCastsRemoved, TD);
|
|
||||||
if (Tmp2 == -1) return -1;
|
|
||||||
return std::max(Tmp1, Tmp2);
|
|
||||||
case Instruction::Or:
|
case Instruction::Or:
|
||||||
case Instruction::Xor:
|
case Instruction::Xor:
|
||||||
Tmp1 = CanEvaluateZExtd(I->getOperand(0), Ty, NumCastsRemoved, TD);
|
|
||||||
if (Tmp1 == -1) return -1;
|
|
||||||
Tmp2 = CanEvaluateZExtd(I->getOperand(1), Ty, NumCastsRemoved, TD);
|
|
||||||
return std::min(Tmp1, Tmp2);
|
|
||||||
|
|
||||||
case Instruction::Add:
|
case Instruction::Add:
|
||||||
case Instruction::Sub:
|
case Instruction::Sub:
|
||||||
case Instruction::Mul:
|
case Instruction::Mul:
|
||||||
Tmp1 = CanEvaluateZExtd(I->getOperand(0), Ty, NumCastsRemoved, TD);
|
|
||||||
if (Tmp1 == -1) return -1;
|
|
||||||
Tmp2 = CanEvaluateZExtd(I->getOperand(1), Ty, NumCastsRemoved, TD);
|
|
||||||
if (Tmp2 == -1) return -1;
|
|
||||||
return 0; // TODO: Could be improved.
|
|
||||||
|
|
||||||
case Instruction::Shl:
|
case Instruction::Shl:
|
||||||
Tmp1 = CanEvaluateZExtd(I->getOperand(0), Ty, NumCastsRemoved, TD);
|
return CanEvaluateZExtd(I->getOperand(0), Ty, TD) &&
|
||||||
if (Tmp1 == -1) return -1;
|
CanEvaluateZExtd(I->getOperand(1), Ty, TD);
|
||||||
|
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1)))
|
|
||||||
return Tmp1 - CI->getZExtValue();
|
|
||||||
|
|
||||||
// Variable shift, no known zext bits.
|
|
||||||
Tmp2 = CanEvaluateZExtd(I->getOperand(1), Ty, NumCastsRemoved, TD);
|
|
||||||
if (Tmp2 == -1) return -1;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
//case Instruction::LShr:
|
//case Instruction::LShr:
|
||||||
case Instruction::ZExt:
|
case Instruction::ZExt: // zext(zext(x)) -> zext(x).
|
||||||
// zext(zext(x)) -> zext(x). Since we're replacing it, it isn't eliminated.
|
case Instruction::SExt: // zext(sext(x)) -> sext(x).
|
||||||
Tmp1 = Ty->getScalarSizeInBits()-OrigTy->getScalarSizeInBits();
|
return true;
|
||||||
return GetLeadingZeros(I, TD)+Tmp1;
|
|
||||||
|
|
||||||
case Instruction::SExt:
|
|
||||||
// zext(sext(x)) -> sext(x) with no upper bits known.
|
|
||||||
return 0;
|
|
||||||
//case Instruction::Trunc: -> Could turn into AND.
|
|
||||||
|
|
||||||
case Instruction::Select:
|
case Instruction::Select:
|
||||||
Tmp1 = CanEvaluateZExtd(I->getOperand(1), Ty, NumCastsRemoved, TD);
|
return CanEvaluateZExtd(I->getOperand(1), Ty, TD) &&
|
||||||
if (Tmp1 == -1) return -1;
|
CanEvaluateZExtd(I->getOperand(2), Ty, TD);
|
||||||
Tmp2 = CanEvaluateZExtd(I->getOperand(2), Ty, NumCastsRemoved, TD);
|
|
||||||
return std::min(Tmp1, Tmp2);
|
|
||||||
|
|
||||||
case Instruction::PHI: {
|
case Instruction::PHI: {
|
||||||
// We can change a phi if we can change all operands. Note that we never
|
// We can change a phi if we can change all operands. Note that we never
|
||||||
// get into trouble with cyclic PHIs here because we only consider
|
// get into trouble with cyclic PHIs here because we only consider
|
||||||
// instructions with a single use.
|
// instructions with a single use.
|
||||||
PHINode *PN = cast<PHINode>(I);
|
PHINode *PN = cast<PHINode>(I);
|
||||||
int Result = CanEvaluateZExtd(PN->getIncomingValue(0), Ty,
|
if (!CanEvaluateZExtd(PN->getIncomingValue(0), Ty, TD)) return false;
|
||||||
NumCastsRemoved, TD);
|
for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
|
||||||
for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) {
|
if (!CanEvaluateZExtd(PN->getIncomingValue(0), Ty, TD)) return false;
|
||||||
if (Result == -1) return -1;
|
return true;
|
||||||
Tmp1 = CanEvaluateZExtd(PN->getIncomingValue(i), Ty, NumCastsRemoved, TD);
|
|
||||||
Result = std::min(Result, Tmp1);
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// TODO: Can handle more cases here.
|
// TODO: Can handle more cases here.
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,11 +654,8 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
|
|||||||
// type. Only do this if the dest type is a simple type, don't convert the
|
// type. Only do this if the dest type is a simple type, don't convert the
|
||||||
// expression tree to something weird like i93 unless the source is also
|
// expression tree to something weird like i93 unless the source is also
|
||||||
// strange.
|
// strange.
|
||||||
if (isa<VectorType>(DestTy) || ShouldChangeType(SrcTy, DestTy)) {
|
if ((isa<VectorType>(DestTy) || ShouldChangeType(SrcTy, DestTy)) &&
|
||||||
unsigned NumCastsRemoved = 0;
|
CanEvaluateZExtd(Src, DestTy, TD)) {
|
||||||
int BitsZExt = CanEvaluateZExtd(Src, DestTy, NumCastsRemoved, TD);
|
|
||||||
if (BitsZExt == -1) return 0;
|
|
||||||
|
|
||||||
// Okay, we can transform this! Insert the new expression now.
|
// Okay, we can transform this! Insert the new expression now.
|
||||||
DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
|
DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
|
||||||
" to avoid zero extend: " << CI);
|
" to avoid zero extend: " << CI);
|
||||||
@ -731,8 +666,7 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
|
|||||||
// cast with the result.
|
// cast with the result.
|
||||||
uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
|
uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||||
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
|
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
|
||||||
if (unsigned(BitsZExt) >= DestBitSize-SrcBitSize ||
|
if (MaskedValueIsZero(Res, APInt::getHighBitsSet(DestBitSize,
|
||||||
MaskedValueIsZero(Res, APInt::getHighBitsSet(DestBitSize,
|
|
||||||
DestBitSize-SrcBitSize)))
|
DestBitSize-SrcBitSize)))
|
||||||
return ReplaceInstUsesWith(CI, Res);
|
return ReplaceInstUsesWith(CI, Res);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user