diff options
author | Chris Lattner <sabre@nondot.org> | 2002-05-02 17:06:02 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-05-02 17:06:02 +0000 |
commit | a1be566213aa495c782b9871b03233f9d1d1659c (patch) | |
tree | f6b982a9c28cc130d28a8c2f23c7cb57ff71d8de /lib/Transforms/Scalar | |
parent | fa49f810c2df4ded6755edbe0625029758c81657 (diff) | |
download | external_llvm-a1be566213aa495c782b9871b03233f9d1d1659c.zip external_llvm-a1be566213aa495c782b9871b03233f9d1d1659c.tar.gz external_llvm-a1be566213aa495c782b9871b03233f9d1d1659c.tar.bz2 |
* Add ability to eliminate a bunch of different cascading cast variations
* Allow elimination of getelementptr X, uint 0 (which is a noop)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2428 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 62 |
1 files changed, 60 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 2ad2356..59172b5 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -61,6 +61,7 @@ namespace { Instruction *visitSub(BinaryOperator *I); Instruction *visitMul(BinaryOperator *I); Instruction *visitCastInst(CastInst *CI); + Instruction *visitGetElementPtrInst(GetElementPtrInst *GEP); Instruction *visitMemAccessInst(MemAccessInst *MAI); // visitInstruction - Specify what to return for unhandled instructions... @@ -163,18 +164,75 @@ Instruction *InstCombiner::visitMul(BinaryOperator *I) { } -// CastInst simplification - If the user is casting a value to the same type, -// eliminate this cast instruction... +// isEliminableCastOfCast - Return true if it is valid to eliminate the CI +// instruction. +// +static inline bool isEliminableCastOfCast(const CastInst *CI, + const CastInst *CSrc) { + assert(CI->getOperand(0) == CSrc); + const Type *SrcTy = CSrc->getOperand(0)->getType(); + const Type *MidTy = CSrc->getType(); + const Type *DstTy = CI->getType(); + + // It is legal to eliminate the instruction if casting A->B->A + if (SrcTy == DstTy) return true; + + // Allow free casting and conversion of sizes as long as the sign doesn't + // change... + if (SrcTy->isSigned() == MidTy->isSigned() && + MidTy->isSigned() == DstTy->isSigned()) + return true; + + // Otherwise, we cannot succeed. Specifically we do not want to allow things + // like: short -> ushort -> uint, because this can create wrong results if + // the input short is negative! + // + return false; +} + + +// CastInst simplification // Instruction *InstCombiner::visitCastInst(CastInst *CI) { + // If the user is casting a value to the same type, eliminate this cast + // instruction... if (CI->getType() == CI->getOperand(0)->getType() && !CI->use_empty()) { AddUsesToWorkList(CI); // Add all modified instrs to worklist CI->replaceAllUsesWith(CI->getOperand(0)); return CI; } + + + // If casting the result of another cast instruction, try to eliminate this + // one! + // + if (CastInst *CSrc = dyn_cast<CastInst>(CI->getOperand(0))) + if (isEliminableCastOfCast(CI, CSrc)) { + // This instruction now refers directly to the cast's src operand. This + // has a good chance of making CSrc dead. + CI->setOperand(0, CSrc->getOperand(0)); + return CI; + } + return 0; } + + +Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst *GEP) { + // Is it getelementptr %P, uint 0 + // If so, elminate the noop. + if (GEP->getNumOperands() == 2 && !GEP->use_empty() && + GEP->getOperand(1) == Constant::getNullValue(Type::UIntTy)) { + AddUsesToWorkList(GEP); // Add all modified instrs to worklist + GEP->replaceAllUsesWith(GEP->getOperand(0)); + return GEP; + } + + return visitMemAccessInst(GEP); +} + + // Combine Indices - If the source pointer to this mem access instruction is a // getelementptr instruction, combine the indices of the GEP into this // instruction |