diff options
author | Chris Lattner <sabre@nondot.org> | 2005-08-04 20:03:32 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-08-04 20:03:32 +0000 |
commit | 2114b273ef0520cec99c253ef6ddf717eaa7657a (patch) | |
tree | e1646970889b28d66c1d771314e1b1b78dc4ce3d /lib/Transforms/Scalar/LoopStrengthReduce.cpp | |
parent | 763103c87d1b580d2df9d5823be9ae36fb02634a (diff) |
* Refactor some code into a new BasedUser::RewriteInstructionToUseNewBase
method.
* Fix a crash on 178.galgel, where we would insert expressions before PHI
nodes instead of into the PHI node predecessor blocks.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22657 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/LoopStrengthReduce.cpp')
-rw-r--r-- | lib/Transforms/Scalar/LoopStrengthReduce.cpp | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index dfe72c11fc..44e8b2e977 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -356,6 +356,10 @@ namespace { BasedUser(Instruction *I, Value *Op, const SCEVHandle &IMM) : Inst(I), OperandValToReplace(Op), Imm(IMM), EmittedBase(0) {} + // Once we rewrite the code to insert the new IVs we want, update the + // operands of Inst to use the new expression 'NewBase', with 'Imm' added + // to it. + void RewriteInstructionToUseNewBase(Value *NewBase, SCEVExpander &Rewriter); // No need to compare these. bool operator<(const BasedUser &BU) const { return 0; } @@ -372,6 +376,45 @@ void BasedUser::dump() const { std::cerr << " Inst: " << *Inst; } +// Once we rewrite the code to insert the new IVs we want, update the +// operands of Inst to use the new expression 'NewBase', with 'Imm' added +// to it. +void BasedUser::RewriteInstructionToUseNewBase(Value *NewBase, + SCEVExpander &Rewriter) { + if (!isa<PHINode>(Inst)) { + SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(NewBase), Imm); + Value *NewVal = Rewriter.expandCodeFor(NewValSCEV, Inst, + OperandValToReplace->getType()); + + // Replace the use of the operand Value with the new Phi we just created. + Inst->replaceUsesOfWith(OperandValToReplace, NewVal); + DEBUG(std::cerr << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst); + return; + } + + // PHI nodes are more complex. We have to insert one copy of the NewBase+Imm + // expression into each operand block that uses it. + PHINode *PN = cast<PHINode>(Inst); + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + if (PN->getIncomingValue(i) == OperandValToReplace) { + // FIXME: this should split any critical edges. + + // Insert the code into the end of the predecessor block. + BasicBlock::iterator InsertPt = PN->getIncomingBlock(i)->getTerminator(); + + SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(NewBase), Imm); + Value *NewVal = Rewriter.expandCodeFor(NewValSCEV, InsertPt, + OperandValToReplace->getType()); + + // Replace the use of the operand Value with the new Phi we just created. + PN->setIncomingValue(i, NewVal); + Rewriter.clear(); + } + } + DEBUG(std::cerr << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst); +} + + /// isTargetConstant - Return true if the following can be referenced by the /// immediate field of a target instruction. static bool isTargetConstant(const SCEVHandle &V) { @@ -526,20 +569,14 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(Value *Stride, // Clear the SCEVExpander's expression map so that we are guaranteed // to have the code emitted where we expect it. Rewriter.clear(); - SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(NewPHI), - User.Imm); - Value *Replaced = User.OperandValToReplace; - Value *newVal = Rewriter.expandCodeFor(NewValSCEV, User.Inst, - Replaced->getType()); - - // Replace the use of the operand Value with the new Phi we just created. - User.Inst->replaceUsesOfWith(Replaced, newVal); - DEBUG(std::cerr << " CHANGED: IMM =" << *User.Imm << " Inst = " - << *User.Inst); + + // Now that we know what we need to do, insert code before User for the + // immediate and any loop-variant expressions. + User.RewriteInstructionToUseNewBase(NewPHI, Rewriter); // Mark old value we replaced as possibly dead, so that it is elminated // if we just replaced the last use of that value. - DeadInsts.insert(cast<Instruction>(Replaced)); + DeadInsts.insert(cast<Instruction>(User.OperandValToReplace)); UsersToProcess.erase(UsersToProcess.begin()); ++NumReduced; @@ -549,11 +586,6 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(Value *Stride, // IMPORTANT TODO: Figure out how to partition the IV's with this stride, but // different starting values, into different PHIs. - - // BEFORE writing this, it's probably useful to handle GEP's. - - // NOTE: pull all constants together, for REG+IMM addressing, include &GV in - // 'IMM' if the target supports it. } |