diff options
author | Chris Lattner <sabre@nondot.org> | 2004-10-11 23:06:50 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-10-11 23:06:50 +0000 |
commit | a4b9c7841f94b6a3a2ba6c562b5dc4f4de02c637 (patch) | |
tree | 4d1f6e25d22af6d9d3b881c0e208412d8aedd153 /lib | |
parent | 7fa6e666ece60455cf9d75eff6e6915bebf05cbc (diff) | |
download | external_llvm-a4b9c7841f94b6a3a2ba6c562b5dc4f4de02c637.zip external_llvm-a4b9c7841f94b6a3a2ba6c562b5dc4f4de02c637.tar.gz external_llvm-a4b9c7841f94b6a3a2ba6c562b5dc4f4de02c637.tar.bz2 |
Handle a common case more carefully. In particular, instead of transforming
pointer recurrences into expressions from this:
%P_addr.0.i.0 = phi sbyte* [ getelementptr ([8 x sbyte]* %.str_1, int 0, int 0), %entry ], [ %inc.0.i, %no_exit.i ]
%inc.0.i = getelementptr sbyte* %P_addr.0.i.0, int 1 ; <sbyte*> [#uses=2]
into this:
%inc.0.i = getelementptr sbyte* getelementptr ([8 x sbyte]* %.str_1, int 0, int 0), int %inc.0.i.rec
Actually create something nice, like this:
%inc.0.i = getelementptr [8 x sbyte]* %.str_1, int 0, int %inc.0.i.rec
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16924 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 72ad30c..3398b37 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -45,6 +45,7 @@ #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CommandLine.h" #include "llvm/ADT/Statistic.h" @@ -135,9 +136,9 @@ namespace { while (isa<PHINode>(It)) ++It; if (It != BasicBlock::iterator(CI)) { // Splice the cast immediately after the operand in question. - I->getParent()->getInstList().splice(It, - CI->getParent()->getInstList(), - CI); + BasicBlock::InstListType &InstList = + I->getParent()->getInstList(); + InstList.splice(It, InstList, CI); } return CI; } @@ -345,7 +346,7 @@ DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts) { if (Instruction *U = dyn_cast<Instruction>(I->getOperand(i))) Insts.insert(U); SE->deleteInstructionFromRecords(I); - I->getParent()->getInstList().erase(I); + I->eraseFromParent(); Changed = true; } } @@ -387,6 +388,34 @@ void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN, // Update the GEP to use the new recurrence we just inserted. GEPI->setOperand(1, NewAdd); + // If the incoming value is a constant expr GEP, try peeling out the array + // 0 index if possible to make things simpler. + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(GEPI->getOperand(0))) + if (CE->getOpcode() == Instruction::GetElementPtr) { + unsigned NumOps = CE->getNumOperands(); + assert(NumOps > 1 && "CE folding didn't work!"); + if (CE->getOperand(NumOps-1)->isNullValue()) { + // Check to make sure the last index really is an array index. + gep_type_iterator GTI = gep_type_begin(GEPI); + for (unsigned i = 1, e = GEPI->getNumOperands()-1; + i != e; ++i, ++GTI) + /*empty*/; + if (isa<SequentialType>(*GTI)) { + // Pull the last index out of the constant expr GEP. + std::vector<Value*> CEIdxs(CE->op_begin()+1, CE->op_end()-1); + Constant *NCE = ConstantExpr::getGetElementPtr(CE->getOperand(0), + CEIdxs); + GetElementPtrInst *NGEPI = + new GetElementPtrInst(NCE, Constant::getNullValue(Type::IntTy), + NewAdd, GEPI->getName(), GEPI); + GEPI->replaceAllUsesWith(NGEPI); + GEPI->eraseFromParent(); + GEPI = NGEPI; + } + } + } + + // Finally, if there are any other users of the PHI node, we must // insert a new GEP instruction that uses the pre-incremented version // of the induction amount. |