mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-05 12:31:33 +00:00
simplify this code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92800 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d7d1a29003
commit
68c6e8998b
@ -456,123 +456,80 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
|
|||||||
Instruction *Src = dyn_cast<Instruction>(CI.getOperand(0));
|
Instruction *Src = dyn_cast<Instruction>(CI.getOperand(0));
|
||||||
if (!Src || !Src->hasOneUse())
|
if (!Src || !Src->hasOneUse())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Check to see if we can eliminate the cast by changing the entire
|
||||||
|
// computation chain to do the computation in the result type.
|
||||||
const Type *SrcTy = Src->getType();
|
const Type *SrcTy = Src->getType();
|
||||||
const Type *DestTy = CI.getType();
|
const Type *DestTy = CI.getType();
|
||||||
uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
|
|
||||||
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
|
|
||||||
|
|
||||||
// Attempt to propagate the cast into the instruction for int->int casts.
|
|
||||||
int NumCastsRemoved = 0;
|
|
||||||
// Only do this if the dest type is a simple type, don't convert the
|
// 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) ||
|
if (!isa<VectorType>(DestTy) && !ShouldChangeType(SrcTy, DestTy))
|
||||||
ShouldChangeType(Src->getType(), DestTy)) &&
|
return 0;
|
||||||
CanEvaluateInDifferentType(Src, DestTy,
|
|
||||||
CI.getOpcode(), NumCastsRemoved)) {
|
// Attempt to propagate the cast into the instruction for int->int casts.
|
||||||
|
int NumCastsRemoved = 0;
|
||||||
|
if (!CanEvaluateInDifferentType(Src, DestTy, CI.getOpcode(), NumCastsRemoved))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (CI.getOpcode()) {
|
||||||
|
default: assert(0 && "not an integer cast");
|
||||||
|
case Instruction::Trunc:
|
||||||
// If this cast is a truncate, evaluting in a different type always
|
// If this cast is a truncate, evaluting in a different type always
|
||||||
// eliminates the cast, so it is always a win. If this is a zero-extension,
|
// eliminates the cast, so it is always a win.
|
||||||
// we need to do an AND to maintain the clear top-part of the computation,
|
break;
|
||||||
// so we require that the input have eliminated at least one cast. If this
|
case Instruction::ZExt:
|
||||||
// is a sign extension, we insert two new casts (to do the extension) so we
|
// If this is a zero-extension, we need to do an AND to maintain the clear
|
||||||
// require that two casts have been eliminated.
|
// top-part of the computation, so we require that the input have eliminated
|
||||||
bool DoXForm = false;
|
// at least one cast.
|
||||||
bool JustReplace = false;
|
if (NumCastsRemoved < 1)
|
||||||
switch (CI.getOpcode()) {
|
return 0;
|
||||||
default:
|
break;
|
||||||
// All the others use floating point so we shouldn't actually
|
case Instruction::SExt:
|
||||||
// get here because of the check above.
|
// If this is a sign extension, we insert two new shifts (to do the
|
||||||
llvm_unreachable("Unknown cast type");
|
// extension) so we require that two casts have been eliminated.
|
||||||
case Instruction::Trunc:
|
if (NumCastsRemoved < 2)
|
||||||
DoXForm = true;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case Instruction::ZExt: {
|
|
||||||
DoXForm = NumCastsRemoved >= 1;
|
|
||||||
|
|
||||||
if (!DoXForm && 0) {
|
|
||||||
// If it's unnecessary to issue an AND to clear the high bits, it's
|
|
||||||
// always profitable to do this xform.
|
|
||||||
Value *TryRes = EvaluateInDifferentType(Src, DestTy, false);
|
|
||||||
APInt Mask(APInt::getBitsSet(DestBitSize, SrcBitSize, DestBitSize));
|
|
||||||
if (MaskedValueIsZero(TryRes, Mask))
|
|
||||||
return ReplaceInstUsesWith(CI, TryRes);
|
|
||||||
|
|
||||||
if (Instruction *TryI = dyn_cast<Instruction>(TryRes))
|
|
||||||
if (TryI->use_empty())
|
|
||||||
EraseInstFromFunction(*TryI);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Instruction::SExt: {
|
|
||||||
DoXForm = NumCastsRemoved >= 2;
|
|
||||||
if (!DoXForm && !isa<TruncInst>(Src) && 0) {
|
|
||||||
// If we do not have to emit the truncate + sext pair, then it's always
|
|
||||||
// profitable to do this xform.
|
|
||||||
//
|
|
||||||
// It's not safe to eliminate the trunc + sext pair if one of the
|
|
||||||
// eliminated cast is a truncate. e.g.
|
|
||||||
// t2 = trunc i32 t1 to i16
|
|
||||||
// t3 = sext i16 t2 to i32
|
|
||||||
// !=
|
|
||||||
// i32 t1
|
|
||||||
Value *TryRes = EvaluateInDifferentType(Src, DestTy, true);
|
|
||||||
unsigned NumSignBits = ComputeNumSignBits(TryRes);
|
|
||||||
if (NumSignBits > (DestBitSize - SrcBitSize))
|
|
||||||
return ReplaceInstUsesWith(CI, TryRes);
|
|
||||||
|
|
||||||
if (Instruction *TryI = dyn_cast<Instruction>(TryRes))
|
|
||||||
if (TryI->use_empty())
|
|
||||||
EraseInstFromFunction(*TryI);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DoXForm) {
|
|
||||||
DEBUG(errs() << "ICE: EvaluateInDifferentType converting expression type"
|
|
||||||
" to avoid cast: " << CI);
|
|
||||||
Value *Res = EvaluateInDifferentType(Src, DestTy,
|
|
||||||
CI.getOpcode() == Instruction::SExt);
|
|
||||||
if (JustReplace)
|
|
||||||
// Just replace this cast with the result.
|
|
||||||
return ReplaceInstUsesWith(CI, Res);
|
|
||||||
|
|
||||||
assert(Res->getType() == DestTy);
|
|
||||||
switch (CI.getOpcode()) {
|
|
||||||
default: llvm_unreachable("Unknown cast type!");
|
|
||||||
case Instruction::Trunc:
|
|
||||||
// Just replace this cast with the result.
|
|
||||||
return ReplaceInstUsesWith(CI, Res);
|
|
||||||
case Instruction::ZExt: {
|
|
||||||
assert(SrcBitSize < DestBitSize && "Not a zext?");
|
|
||||||
|
|
||||||
// If the high bits are already zero, just replace this cast with the
|
|
||||||
// result.
|
|
||||||
APInt Mask(APInt::getBitsSet(DestBitSize, SrcBitSize, DestBitSize));
|
|
||||||
if (MaskedValueIsZero(Res, Mask))
|
|
||||||
return ReplaceInstUsesWith(CI, Res);
|
|
||||||
|
|
||||||
// We need to emit an AND to clear the high bits.
|
|
||||||
Constant *C = ConstantInt::get(CI.getContext(),
|
|
||||||
APInt::getLowBitsSet(DestBitSize, SrcBitSize));
|
|
||||||
return BinaryOperator::CreateAnd(Res, C);
|
|
||||||
}
|
|
||||||
case Instruction::SExt: {
|
|
||||||
// If the high bits are already filled with sign bit, just replace this
|
|
||||||
// cast with the result.
|
|
||||||
unsigned NumSignBits = ComputeNumSignBits(Res);
|
|
||||||
if (NumSignBits > (DestBitSize - SrcBitSize))
|
|
||||||
return ReplaceInstUsesWith(CI, Res);
|
|
||||||
|
|
||||||
// We need to emit a cast to truncate, then a cast to sext.
|
|
||||||
return new SExtInst(Builder->CreateTrunc(Res, Src->getType()), DestTy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
DEBUG(errs() << "ICE: EvaluateInDifferentType converting expression type"
|
||||||
|
" to avoid cast: " << CI);
|
||||||
|
Value *Res = EvaluateInDifferentType(Src, DestTy,
|
||||||
|
CI.getOpcode() == Instruction::SExt);
|
||||||
|
assert(Res->getType() == DestTy);
|
||||||
|
|
||||||
|
uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||||
|
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
|
||||||
|
switch (CI.getOpcode()) {
|
||||||
|
default: assert(0 && "Unknown cast type!");
|
||||||
|
case Instruction::Trunc:
|
||||||
|
// Just replace this cast with the result.
|
||||||
|
return ReplaceInstUsesWith(CI, Res);
|
||||||
|
case Instruction::ZExt: {
|
||||||
|
// If the high bits are already zero, just replace this cast with the
|
||||||
|
// result.
|
||||||
|
APInt Mask(APInt::getBitsSet(DestBitSize, SrcBitSize, DestBitSize));
|
||||||
|
if (MaskedValueIsZero(Res, Mask))
|
||||||
|
return ReplaceInstUsesWith(CI, Res);
|
||||||
|
|
||||||
|
// We need to emit an AND to clear the high bits.
|
||||||
|
Constant *C = ConstantInt::get(CI.getContext(),
|
||||||
|
APInt::getLowBitsSet(DestBitSize, SrcBitSize));
|
||||||
|
return BinaryOperator::CreateAnd(Res, C);
|
||||||
|
}
|
||||||
|
case Instruction::SExt: {
|
||||||
|
// If the high bits are already filled with sign bit, just replace this
|
||||||
|
// cast with the result.
|
||||||
|
unsigned NumSignBits = ComputeNumSignBits(Res);
|
||||||
|
if (NumSignBits > (DestBitSize - SrcBitSize))
|
||||||
|
return ReplaceInstUsesWith(CI, Res);
|
||||||
|
|
||||||
|
// We need to emit a cast to truncate, then a cast to sext.
|
||||||
|
return new SExtInst(Builder->CreateTrunc(Res, Src->getType()), DestTy);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
|
Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
|
||||||
|
Loading…
Reference in New Issue
Block a user