summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-04-13 20:42:26 +0000
committerChris Lattner <sabre@nondot.org>2007-04-13 20:42:26 +0000
commitefd3051d60ddf653ec9515b802687305ff5bbb38 (patch)
tree718a00b90f359d47ab67734f72ddcf3defeef5ab /llvm/lib/Transforms
parent03bf40e70ecbedc3bc5951f59cbb16a96923aefb (diff)
downloadbcm5719-llvm-efd3051d60ddf653ec9515b802687305ff5bbb38.tar.gz
bcm5719-llvm-efd3051d60ddf653ec9515b802687305ff5bbb38.zip
Now that codegen prepare isn't defeating me, I can finally fix what I set
out to do! :) This fixes a problem where LSR would insert a bunch of code into each MBB that uses a particular subexpression (e.g. IV+base+C). The problem is that this code cannot be CSE'd back together if inserted into different blocks. This patch changes LSR to attempt to insert a single copy of this code and share it, allowing codegenprepare to duplicate the code if it can be sunk into various addressing modes. On CodeGen/ARM/lsr-code-insertion.ll, for example, this gives us code like: add r8, r0, r5 str r6, [r8, #+4] .. ble LBB1_4 @cond_next LBB1_3: @cond_true str r10, [r8, #+4] LBB1_4: @cond_next ... LBB1_5: @cond_true55 ldr r6, LCPI1_1 str r6, [r8, #+4] instead of: add r10, r0, r6 str r8, [r10, #+4] ... ble LBB1_4 @cond_next LBB1_3: @cond_true add r8, r0, r6 str r10, [r8, #+4] LBB1_4: @cond_next ... LBB1_5: @cond_true55 add r8, r0, r6 ldr r10, LCPI1_1 str r10, [r8, #+4] Besides being smaller and more efficient, this makes it immediately obvious that it is profitable to predicate LBB1_3 now :) llvm-svn: 35972
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 7540f44e4e7..332ddfa488e 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -568,7 +568,25 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
SCEVExpander &Rewriter,
Loop *L, Pass *P) {
if (!isa<PHINode>(Inst)) {
- Value *NewVal = InsertCodeForBaseAtPosition(NewBase, Rewriter, Inst, L);
+ // By default, insert code at the user instruction.
+ BasicBlock::iterator InsertPt = Inst;
+
+ // However, if the Operand is itself an instruction, the (potentially
+ // complex) inserted code may be shared by many users. Because of this, we
+ // want to emit code for the computation of the operand right before its old
+ // computation. This is usually safe, because we obviously used to use the
+ // computation when it was computed in its current block. However, in some
+ // cases (e.g. use of a post-incremented induction variable) the NewBase
+ // value will be pinned to live somewhere after the original computation.
+ // In this case, we have to back off.
+ if (!isUseOfPostIncrementedValue) {
+ if (Instruction *OpInst = dyn_cast<Instruction>(OperandValToReplace)) {
+ InsertPt = OpInst;
+ while (isa<PHINode>(InsertPt)) ++InsertPt;
+ }
+ }
+
+ Value *NewVal = InsertCodeForBaseAtPosition(NewBase, Rewriter, InsertPt, L);
// Replace the use of the operand Value with the new Phi we just created.
Inst->replaceUsesOfWith(OperandValToReplace, NewVal);
DOUT << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst;
OpenPOWER on IntegriCloud