Skip to content

Commit

Permalink
[LSR] Create fewer redundant instructions.
Browse files Browse the repository at this point in the history
Summary:
Fix LSRInstance::HoistInsertPosition() to check the original insert
position block first for a canonical insertion point that is dominated
by all inputs.  This leads to SCEV being able to reuse more instructions
since it currently tracks the instructions it creates for reuse by
keeping a table of <Value, insert point> pairs.

Reviewers: atrick

Subscribers: mcrosier, mzolotukhin, llvm-commits

Differential Revision: http://reviews.llvm.org/D18001

llvm-svn: 263644
  • Loading branch information
geoffberry committed Mar 16, 2016
1 parent 46bf454 commit 459b750
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 20 deletions.
42 changes: 22 additions & 20 deletions llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
Expand Up @@ -4331,36 +4331,18 @@ BasicBlock::iterator
LSRInstance::HoistInsertPosition(BasicBlock::iterator IP,
const SmallVectorImpl<Instruction *> &Inputs)
const {
Instruction *Tentative = &*IP;
for (;;) {
const Loop *IPLoop = LI.getLoopFor(IP->getParent());
unsigned IPLoopDepth = IPLoop ? IPLoop->getLoopDepth() : 0;

BasicBlock *IDom;
for (DomTreeNode *Rung = DT.getNode(IP->getParent()); ; ) {
if (!Rung) return IP;
Rung = Rung->getIDom();
if (!Rung) return IP;
IDom = Rung->getBlock();

// Don't climb into a loop though.
const Loop *IDomLoop = LI.getLoopFor(IDom);
unsigned IDomDepth = IDomLoop ? IDomLoop->getLoopDepth() : 0;
if (IDomDepth <= IPLoopDepth &&
(IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
break;
}

bool AllDominate = true;
Instruction *BetterPos = nullptr;
Instruction *Tentative = IDom->getTerminator();
for (Instruction *Inst : Inputs) {
if (Inst == Tentative || !DT.dominates(Inst, Tentative)) {
AllDominate = false;
break;
}
// Attempt to find an insert position in the middle of the block,
// instead of at the end, so that it can be used for other expansions.
if (IDom == Inst->getParent() &&
if (Tentative->getParent() == Inst->getParent() &&
(!BetterPos || !DT.dominates(Inst, BetterPos)))
BetterPos = &*std::next(BasicBlock::iterator(Inst));
}
Expand All @@ -4370,6 +4352,26 @@ LSRInstance::HoistInsertPosition(BasicBlock::iterator IP,
IP = BetterPos->getIterator();
else
IP = Tentative->getIterator();

const Loop *IPLoop = LI.getLoopFor(IP->getParent());
unsigned IPLoopDepth = IPLoop ? IPLoop->getLoopDepth() : 0;

BasicBlock *IDom;
for (DomTreeNode *Rung = DT.getNode(IP->getParent()); ; ) {
if (!Rung) return IP;
Rung = Rung->getIDom();
if (!Rung) return IP;
IDom = Rung->getBlock();

// Don't climb into a loop though.
const Loop *IDomLoop = LI.getLoopFor(IDom);
unsigned IDomDepth = IDomLoop ? IDomLoop->getLoopDepth() : 0;
if (IDomDepth <= IPLoopDepth &&
(IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
break;
}

Tentative = IDom->getTerminator();
}

return IP;
Expand Down
34 changes: 34 additions & 0 deletions llvm/test/Transforms/LoopStrengthReduce/AArch64/lsr-reuse.ll
@@ -0,0 +1,34 @@
; RUN: llc -mtriple=arm64-unknown-unknown -print-lsr-output < %s 2>&1 | FileCheck %s

declare void @foo(i64)

; Verify that redundant adds aren't inserted by LSR.
; CHECK-LABEL: @bar(
define void @bar(double* %A) {
entry:
br label %while.cond

while.cond:
; CHECK-LABEL: while.cond:
; CHECK: add i64 %lsr.iv, 1
; CHECK-NOT: add i64 %lsr.iv, 1
; CHECK-LABEL: land.rhs:
%indvars.iv28 = phi i64 [ %indvars.iv.next29, %land.rhs ], [ 50, %entry ]
%cmp = icmp sgt i64 %indvars.iv28, 0
br i1 %cmp, label %land.rhs, label %while.end

land.rhs:
%indvars.iv.next29 = add nsw i64 %indvars.iv28, -1
%arrayidx = getelementptr inbounds double, double* %A, i64 %indvars.iv.next29
%Aload = load double, double* %arrayidx, align 8
%cmp1 = fcmp oeq double %Aload, 0.000000e+00
br i1 %cmp1, label %while.cond, label %if.end

while.end:
%indvars.iv28.lcssa = phi i64 [ %indvars.iv28, %while.cond ]
tail call void @foo(i64 %indvars.iv28.lcssa)
br label %if.end

if.end:
ret void
}

0 comments on commit 459b750

Please sign in to comment.