aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-10-11 23:06:50 +0000
committerChris Lattner <sabre@nondot.org>2004-10-11 23:06:50 +0000
commita4b9c7841f94b6a3a2ba6c562b5dc4f4de02c637 (patch)
tree4d1f6e25d22af6d9d3b881c0e208412d8aedd153 /lib
parent7fa6e666ece60455cf9d75eff6e6915bebf05cbc (diff)
downloadexternal_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.cpp37
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.