forked from OSchip/llvm-project
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 llvm-svn: 16924
This commit is contained in:
parent
13128ab8fb
commit
9776f7259b
|
@ -45,6 +45,7 @@
|
||||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
@ -135,9 +136,9 @@ namespace {
|
||||||
while (isa<PHINode>(It)) ++It;
|
while (isa<PHINode>(It)) ++It;
|
||||||
if (It != BasicBlock::iterator(CI)) {
|
if (It != BasicBlock::iterator(CI)) {
|
||||||
// Splice the cast immediately after the operand in question.
|
// Splice the cast immediately after the operand in question.
|
||||||
I->getParent()->getInstList().splice(It,
|
BasicBlock::InstListType &InstList =
|
||||||
CI->getParent()->getInstList(),
|
I->getParent()->getInstList();
|
||||||
CI);
|
InstList.splice(It, InstList, CI);
|
||||||
}
|
}
|
||||||
return CI;
|
return CI;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +346,7 @@ DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts) {
|
||||||
if (Instruction *U = dyn_cast<Instruction>(I->getOperand(i)))
|
if (Instruction *U = dyn_cast<Instruction>(I->getOperand(i)))
|
||||||
Insts.insert(U);
|
Insts.insert(U);
|
||||||
SE->deleteInstructionFromRecords(I);
|
SE->deleteInstructionFromRecords(I);
|
||||||
I->getParent()->getInstList().erase(I);
|
I->eraseFromParent();
|
||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,6 +388,34 @@ void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN,
|
||||||
// Update the GEP to use the new recurrence we just inserted.
|
// Update the GEP to use the new recurrence we just inserted.
|
||||||
GEPI->setOperand(1, NewAdd);
|
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
|
// Finally, if there are any other users of the PHI node, we must
|
||||||
// insert a new GEP instruction that uses the pre-incremented version
|
// insert a new GEP instruction that uses the pre-incremented version
|
||||||
// of the induction amount.
|
// of the induction amount.
|
||||||
|
|
Loading…
Reference in New Issue