From 69bb1545d16132b76d9eb9240cf30648722522a3 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 22 Feb 2004 05:25:17 +0000 Subject: [PATCH] Implement Transforms/InstCombine/cast.ll:test13, a case which occurs in a hot 164.gzip loop. llvm-svn: 11702 --- .../Scalar/InstructionCombining.cpp | 36 +++++++++++++++++-- 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 b89785db961..4c9cc0a29a8 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(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(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(CE->getType()); + if (const PointerType *XTy = dyn_cast(X->getType())) + if (const ArrayType *XATy = + dyn_cast(XTy->getElementType())) + if (const ArrayType *CATy = + dyn_cast(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 52552d5b094..7d5aac4fe73 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(TI) && cast(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) {