diff options
author | Chris Lattner <sabre@nondot.org> | 2004-02-22 05:25:17 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-02-22 05:25:17 +0000 |
commit | c6bd1953366ec3ff109792c0ce260b26b60e1f94 (patch) | |
tree | cbad811ca810b4958ad0fbb0def9477f5b6345c3 | |
parent | 0ca4418b955f4497eea7f573164aa0afff629902 (diff) | |
download | external_llvm-c6bd1953366ec3ff109792c0ce260b26b60e1f94.zip external_llvm-c6bd1953366ec3ff109792c0ce260b26b60e1f94.tar.gz external_llvm-c6bd1953366ec3ff109792c0ce260b26b60e1f94.tar.bz2 |
Implement Transforms/InstCombine/cast.ll:test13, a case which occurs in a
hot 164.gzip loop.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11702 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 36 | ||||
-rw-r--r-- | lib/Transforms/Scalar/TailDuplication.cpp | 3 |
2 files changed, 35 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index b89785d..4c9cc0a 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -2004,9 +2004,14 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) { Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { // Is it 'getelementptr %P, long 0' or 'getelementptr %P' // If so, eliminate the noop. - if ((GEP.getNumOperands() == 2 && - GEP.getOperand(1) == Constant::getNullValue(Type::LongTy)) || - GEP.getNumOperands() == 1) + if (GEP.getNumOperands() == 1) + return ReplaceInstUsesWith(GEP, GEP.getOperand(0)); + + bool HasZeroPointerIndex = false; + if (Constant *C = dyn_cast<Constant>(GEP.getOperand(1))) + HasZeroPointerIndex = C->isNullValue(); + + if (GEP.getNumOperands() == 2 && HasZeroPointerIndex) return ReplaceInstUsesWith(GEP, GEP.getOperand(0)); // Combine Indices - If the source pointer to this getelementptr instruction @@ -2073,6 +2078,31 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { // Replace all uses of the GEP with the new constexpr... return ReplaceInstUsesWith(GEP, CE); } + } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(GEP.getOperand(0))) { + if (CE->getOpcode() == Instruction::Cast) { + if (HasZeroPointerIndex) { + // transform: GEP (cast [10 x ubyte]* X to [0 x ubyte]*), long 0, ... + // into : GEP [10 x ubyte]* X, long 0, ... + // + // This occurs when the program declares an array extern like "int X[];" + // + Constant *X = CE->getOperand(0); + const PointerType *CPTy = cast<PointerType>(CE->getType()); + if (const PointerType *XTy = dyn_cast<PointerType>(X->getType())) + if (const ArrayType *XATy = + dyn_cast<ArrayType>(XTy->getElementType())) + if (const ArrayType *CATy = + dyn_cast<ArrayType>(CPTy->getElementType())) + if (CATy->getElementType() == XATy->getElementType()) { + // At this point, we know that the cast source type is a pointer + // to an array of the same type as the destination pointer + // array. Because the array type is never stepped over (there + // is a leading zero) we can fold the cast into this GEP. + GEP.setOperand(0, X); + return &GEP; + } + } + } } return 0; diff --git a/lib/Transforms/Scalar/TailDuplication.cpp b/lib/Transforms/Scalar/TailDuplication.cpp index 52552d5..7d5aac4 100644 --- a/lib/Transforms/Scalar/TailDuplication.cpp +++ b/lib/Transforms/Scalar/TailDuplication.cpp @@ -126,7 +126,8 @@ bool TailDup::canEliminateUnconditionalBranch(TerminatorInst *TI) { // Basically, we refuse to make the transformation if any of the values // computed in the 'tail' are used in any other basic blocks. BasicBlock *Tail = TI->getSuccessor(0); - + assert(isa<BranchInst>(TI) && cast<BranchInst>(TI)->isUnconditional()); + for (BasicBlock::iterator I = Tail->begin(), E = Tail->end(); I != E; ++I) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) { |