mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-14 15:28:20 +00:00
rename CanEvaluateInDifferentType -> CanEvaluateTruncated and
simplify it now that it is only used for truncates. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93021 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -147,29 +147,16 @@ Instruction *InstCombiner::PromoteCastOfAllocation(BitCastInst &CI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// CanEvaluateInDifferentType - Return true if we can take the specified value
|
/// CanEvaluateTruncated - Return true if we can evaluate the specified
|
||||||
/// and return it as type Ty without inserting any new casts and without
|
/// expression tree as type Ty instead of its larger type, and arrive with the
|
||||||
/// changing the computed value. This is used by code that tries to decide
|
/// same value. This is used by code that tries to eliminate truncates.
|
||||||
/// whether promoting or shrinking integer operations to wider or smaller types
|
|
||||||
/// will allow us to eliminate a truncate or extend.
|
|
||||||
///
|
///
|
||||||
/// This is a truncation operation if Ty is smaller than V->getType(), or a zero
|
/// Ty will always be a type smaller than V. We should return true if trunc(V)
|
||||||
/// extension operation if Ty is larger.
|
/// can be computed by computing V in the smaller type. If V is an instruction,
|
||||||
|
/// then trunc(inst(x,y)) can be computed as inst(trunc(x),trunc(y)), which only
|
||||||
|
/// makes sense if x and y can be efficiently truncated.
|
||||||
///
|
///
|
||||||
/// If CastOpc is a truncation, then Ty will be a type smaller than V. We
|
static bool CanEvaluateTruncated(Value *V, const Type *Ty) {
|
||||||
/// should return true if trunc(V) can be computed by computing V in the smaller
|
|
||||||
/// type. If V is an instruction, then trunc(inst(x,y)) can be computed as
|
|
||||||
/// inst(trunc(x),trunc(y)), which only makes sense if x and y can be
|
|
||||||
/// efficiently truncated.
|
|
||||||
///
|
|
||||||
/// If CastOpc is zext, we are asking if the low bits of the value can be
|
|
||||||
/// computed in a larger type, which is then and'd to get the final result.
|
|
||||||
static bool CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
|
||||||
unsigned CastOpc,
|
|
||||||
unsigned &NumCastsRemoved) {
|
|
||||||
// FIXME: Eliminate CastOpc
|
|
||||||
assert(CastOpc == Instruction::Trunc);
|
|
||||||
|
|
||||||
// We can always evaluate constants in another type.
|
// We can always evaluate constants in another type.
|
||||||
if (isa<Constant>(V))
|
if (isa<Constant>(V))
|
||||||
return true;
|
return true;
|
||||||
@@ -179,19 +166,10 @@ static bool CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
|||||||
|
|
||||||
const Type *OrigTy = V->getType();
|
const Type *OrigTy = V->getType();
|
||||||
|
|
||||||
// If this is an extension or truncate, we can often eliminate it.
|
// If this is an extension from the dest type, we can eliminate it.
|
||||||
if (isa<TruncInst>(I) || isa<ZExtInst>(I) || isa<SExtInst>(I)) {
|
if ((isa<ZExtInst>(I) || isa<SExtInst>(I)) &&
|
||||||
// If this is a cast from the destination type, we can trivially eliminate
|
I->getOperand(0)->getType() == Ty)
|
||||||
// it, and this will remove a cast overall.
|
|
||||||
if (I->getOperand(0)->getType() == Ty) {
|
|
||||||
// If the first operand is itself a cast, and is eliminable, do not count
|
|
||||||
// this as an eliminable cast. We would prefer to eliminate those two
|
|
||||||
// casts first.
|
|
||||||
if (!isa<CastInst>(I->getOperand(0)) && I->hasOneUse())
|
|
||||||
++NumCastsRemoved;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -206,10 +184,8 @@ static bool CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
|||||||
case Instruction::Or:
|
case Instruction::Or:
|
||||||
case Instruction::Xor:
|
case Instruction::Xor:
|
||||||
// These operators can all arbitrarily be extended or truncated.
|
// These operators can all arbitrarily be extended or truncated.
|
||||||
return CanEvaluateInDifferentType(I->getOperand(0), Ty, CastOpc,
|
return CanEvaluateTruncated(I->getOperand(0), Ty) &&
|
||||||
NumCastsRemoved) &&
|
CanEvaluateTruncated(I->getOperand(1), Ty);
|
||||||
CanEvaluateInDifferentType(I->getOperand(1), Ty, CastOpc,
|
|
||||||
NumCastsRemoved);
|
|
||||||
|
|
||||||
case Instruction::UDiv:
|
case Instruction::UDiv:
|
||||||
case Instruction::URem: {
|
case Instruction::URem: {
|
||||||
@@ -220,10 +196,8 @@ static bool CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
|||||||
APInt Mask = APInt::getHighBitsSet(OrigBitWidth, OrigBitWidth-BitWidth);
|
APInt Mask = APInt::getHighBitsSet(OrigBitWidth, OrigBitWidth-BitWidth);
|
||||||
if (MaskedValueIsZero(I->getOperand(0), Mask) &&
|
if (MaskedValueIsZero(I->getOperand(0), Mask) &&
|
||||||
MaskedValueIsZero(I->getOperand(1), Mask)) {
|
MaskedValueIsZero(I->getOperand(1), Mask)) {
|
||||||
return CanEvaluateInDifferentType(I->getOperand(0), Ty, CastOpc,
|
return CanEvaluateTruncated(I->getOperand(0), Ty) &&
|
||||||
NumCastsRemoved) &&
|
CanEvaluateTruncated(I->getOperand(1), Ty);
|
||||||
CanEvaluateInDifferentType(I->getOperand(1), Ty, CastOpc,
|
|
||||||
NumCastsRemoved);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -233,10 +207,8 @@ static bool CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
|||||||
// constant amount, we can always perform a SHL in a smaller type.
|
// constant amount, we can always perform a SHL in a smaller type.
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
||||||
uint32_t BitWidth = Ty->getScalarSizeInBits();
|
uint32_t BitWidth = Ty->getScalarSizeInBits();
|
||||||
if (BitWidth < OrigTy->getScalarSizeInBits() &&
|
if (CI->getLimitedValue(BitWidth) < BitWidth)
|
||||||
CI->getLimitedValue(BitWidth) < BitWidth)
|
return CanEvaluateTruncated(I->getOperand(0), Ty);
|
||||||
return CanEvaluateInDifferentType(I->getOperand(0), Ty, CastOpc,
|
|
||||||
NumCastsRemoved);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Instruction::LShr:
|
case Instruction::LShr:
|
||||||
@@ -246,34 +218,20 @@ static bool CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
|||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
||||||
uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits();
|
uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits();
|
||||||
uint32_t BitWidth = Ty->getScalarSizeInBits();
|
uint32_t BitWidth = Ty->getScalarSizeInBits();
|
||||||
if (BitWidth < OrigBitWidth &&
|
if (MaskedValueIsZero(I->getOperand(0),
|
||||||
MaskedValueIsZero(I->getOperand(0),
|
|
||||||
APInt::getHighBitsSet(OrigBitWidth, OrigBitWidth-BitWidth)) &&
|
APInt::getHighBitsSet(OrigBitWidth, OrigBitWidth-BitWidth)) &&
|
||||||
CI->getLimitedValue(BitWidth) < BitWidth) {
|
CI->getLimitedValue(BitWidth) < BitWidth) {
|
||||||
return CanEvaluateInDifferentType(I->getOperand(0), Ty, CastOpc,
|
return CanEvaluateTruncated(I->getOperand(0), Ty);
|
||||||
NumCastsRemoved);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Instruction::ZExt:
|
|
||||||
case Instruction::SExt:
|
|
||||||
case Instruction::Trunc:
|
case Instruction::Trunc:
|
||||||
// If this is the same kind of case as our original (e.g. zext+zext), we
|
// trunc(trunc(x)) -> trunc(x)
|
||||||
// can safely replace it. Note that replacing it does not reduce the number
|
|
||||||
// of casts in the input.
|
|
||||||
if (Opc == CastOpc)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// sext (zext ty1), ty2 -> zext ty2
|
|
||||||
if (CastOpc == Instruction::SExt && Opc == Instruction::ZExt)
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
case Instruction::Select: {
|
case Instruction::Select: {
|
||||||
SelectInst *SI = cast<SelectInst>(I);
|
SelectInst *SI = cast<SelectInst>(I);
|
||||||
return CanEvaluateInDifferentType(SI->getTrueValue(), Ty, CastOpc,
|
return CanEvaluateTruncated(SI->getTrueValue(), Ty) &&
|
||||||
NumCastsRemoved) &&
|
CanEvaluateTruncated(SI->getFalseValue(), Ty);
|
||||||
CanEvaluateInDifferentType(SI->getFalseValue(), Ty, CastOpc,
|
|
||||||
NumCastsRemoved);
|
|
||||||
}
|
}
|
||||||
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
|
||||||
@@ -281,8 +239,7 @@ static bool CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
|||||||
// instructions with a single use.
|
// instructions with a single use.
|
||||||
PHINode *PN = cast<PHINode>(I);
|
PHINode *PN = cast<PHINode>(I);
|
||||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
||||||
if (!CanEvaluateInDifferentType(PN->getIncomingValue(i), Ty, CastOpc,
|
if (!CanEvaluateTruncated(PN->getIncomingValue(i), Ty))
|
||||||
NumCastsRemoved))
|
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -515,10 +472,11 @@ static unsigned CanEvaluateSExtd(Value *V, const Type *Ty,
|
|||||||
|
|
||||||
|
|
||||||
/// EvaluateInDifferentType - Given an expression that
|
/// EvaluateInDifferentType - Given an expression that
|
||||||
/// CanEvaluateInDifferentType or CanEvaluateSExtd returns true for, actually
|
/// CanEvaluateTruncated or CanEvaluateSExtd returns true for, actually
|
||||||
/// insert the code to evaluate the expression.
|
/// insert the code to evaluate the expression.
|
||||||
Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type *Ty,
|
Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type *Ty,
|
||||||
bool isSigned) {
|
bool isSigned) {
|
||||||
|
// FIXME: use libanalysis constant folding.
|
||||||
if (Constant *C = dyn_cast<Constant>(V))
|
if (Constant *C = dyn_cast<Constant>(V))
|
||||||
return ConstantExpr::getIntegerCast(C, Ty, isSigned /*Sext or ZExt*/);
|
return ConstantExpr::getIntegerCast(C, Ty, isSigned /*Sext or ZExt*/);
|
||||||
|
|
||||||
@@ -699,8 +657,7 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
|
|||||||
switch (CI.getOpcode()) {
|
switch (CI.getOpcode()) {
|
||||||
default: assert(0 && "not an integer cast");
|
default: assert(0 && "not an integer cast");
|
||||||
case Instruction::Trunc: {
|
case Instruction::Trunc: {
|
||||||
if (!CanEvaluateInDifferentType(Src, DestTy,
|
if (!CanEvaluateTruncated(Src, DestTy))
|
||||||
Instruction::Trunc, NumCastsRemoved))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// If this cast is a truncate, evaluting in a different type always
|
// If this cast is a truncate, evaluting in a different type always
|
||||||
|
Reference in New Issue
Block a user