llvm.org GIT mirror llvm / 4334f66
[LSR] Create fewer redundant instructions. 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263644 91177308-0d34-0410-b5e6-96231b3b80d8 Geoff Berry 3 years ago
2 changed file(s) with 56 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
43304330 LSRInstance::HoistInsertPosition(BasicBlock::iterator IP,
43314331 const SmallVectorImpl &Inputs)
43324332 const {
4333 Instruction *Tentative = &*IP;
43334334 for (;;) {
4334 const Loop *IPLoop = LI.getLoopFor(IP->getParent());
4335 unsigned IPLoopDepth = IPLoop ? IPLoop->getLoopDepth() : 0;
4336
4337 BasicBlock *IDom;
4338 for (DomTreeNode *Rung = DT.getNode(IP->getParent()); ; ) {
4339 if (!Rung) return IP;
4340 Rung = Rung->getIDom();
4341 if (!Rung) return IP;
4342 IDom = Rung->getBlock();
4343
4344 // Don't climb into a loop though.
4345 const Loop *IDomLoop = LI.getLoopFor(IDom);
4346 unsigned IDomDepth = IDomLoop ? IDomLoop->getLoopDepth() : 0;
4347 if (IDomDepth <= IPLoopDepth &&
4348 (IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
4349 break;
4350 }
4351
43524335 bool AllDominate = true;
43534336 Instruction *BetterPos = nullptr;
4354 Instruction *Tentative = IDom->getTerminator();
43554337 for (Instruction *Inst : Inputs) {
43564338 if (Inst == Tentative || !DT.dominates(Inst, Tentative)) {
43574339 AllDominate = false;
43594341 }
43604342 // Attempt to find an insert position in the middle of the block,
43614343 // instead of at the end, so that it can be used for other expansions.
4362 if (IDom == Inst->getParent() &&
4344 if (Tentative->getParent() == Inst->getParent() &&
43634345 (!BetterPos || !DT.dominates(Inst, BetterPos)))
43644346 BetterPos = &*std::next(BasicBlock::iterator(Inst));
43654347 }
43694351 IP = BetterPos->getIterator();
43704352 else
43714353 IP = Tentative->getIterator();
4354
4355 const Loop *IPLoop = LI.getLoopFor(IP->getParent());
4356 unsigned IPLoopDepth = IPLoop ? IPLoop->getLoopDepth() : 0;
4357
4358 BasicBlock *IDom;
4359 for (DomTreeNode *Rung = DT.getNode(IP->getParent()); ; ) {
4360 if (!Rung) return IP;
4361 Rung = Rung->getIDom();
4362 if (!Rung) return IP;
4363 IDom = Rung->getBlock();
4364
4365 // Don't climb into a loop though.
4366 const Loop *IDomLoop = LI.getLoopFor(IDom);
4367 unsigned IDomDepth = IDomLoop ? IDomLoop->getLoopDepth() : 0;
4368 if (IDomDepth <= IPLoopDepth &&
4369 (IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
4370 break;
4371 }
4372
4373 Tentative = IDom->getTerminator();
43724374 }
43734375
43744376 return IP;
0 ; RUN: llc -mtriple=arm64-unknown-unknown -print-lsr-output < %s 2>&1 | FileCheck %s
1
2 declare void @foo(i64)
3
4 ; Verify that redundant adds aren't inserted by LSR.
5 ; CHECK-LABEL: @bar(
6 define void @bar(double* %A) {
7 entry:
8 br label %while.cond
9
10 while.cond:
11 ; CHECK-LABEL: while.cond:
12 ; CHECK: add i64 %lsr.iv, 1
13 ; CHECK-NOT: add i64 %lsr.iv, 1
14 ; CHECK-LABEL: land.rhs:
15 %indvars.iv28 = phi i64 [ %indvars.iv.next29, %land.rhs ], [ 50, %entry ]
16 %cmp = icmp sgt i64 %indvars.iv28, 0
17 br i1 %cmp, label %land.rhs, label %while.end
18
19 land.rhs:
20 %indvars.iv.next29 = add nsw i64 %indvars.iv28, -1
21 %arrayidx = getelementptr inbounds double, double* %A, i64 %indvars.iv.next29
22 %Aload = load double, double* %arrayidx, align 8
23 %cmp1 = fcmp oeq double %Aload, 0.000000e+00
24 br i1 %cmp1, label %while.cond, label %if.end
25
26 while.end:
27 %indvars.iv28.lcssa = phi i64 [ %indvars.iv28, %while.cond ]
28 tail call void @foo(i64 %indvars.iv28.lcssa)
29 br label %if.end
30
31 if.end:
32 ret void
33 }