llvm.org GIT mirror llvm / 4db5270
[IndVars] Try to use existing values in RewriteLoopExitValues. Summary: In RewriteLoopExitValues, before expanding out an SCEV expression using SCEVExpander, try to see if an existing LLVM IR expression already computes the value we're interested in. If so use that existing expression. Apart from reducing IndVars' reliance on the rest of the compilation pipeline, this also prevents IndVars from concluding some expressions as "high cost" when they're not. For instance, `InductiveRangeCheckElimination` often emits code of the following form: ``` len = umin(len_A, len_B) loop: ... if (i++ < len) goto loop outside_loop: use(i) ``` `SCEVExpander` refuses to rewrite the use of `i` in `outside_loop`, since it thinks the value of `i` on loop exit, `len`, is a high cost expansion since it contains an `umax` in it. With this change, `IndVars` can see that it can re-use `len` instead of creating a new expression to compute `umin(len_A, len_B)`. I considered putting this cleverness in `SCEVExpander`, but I was worried that it may then have a deterimental effect on other passes that use it. So I decided it was better to just do this in the one place where it seems like an obviously good idea, with the intent of generalizing later if needed. Reviewers: atrick, reames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10782 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241838 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 4 years ago
2 changed file(s) with 90 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
4040 #include "llvm/IR/Instructions.h"
4141 #include "llvm/IR/IntrinsicInst.h"
4242 #include "llvm/IR/LLVMContext.h"
43 #include "llvm/IR/PatternMatch.h"
4344 #include "llvm/IR/Type.h"
4445 #include "llvm/Support/CommandLine.h"
4546 #include "llvm/Support/Debug.h"
134135 PHINode *IndVar, SCEVExpander &Rewriter);
135136
136137 void SinkUnusedInvariants(Loop *L);
138
139 Value *ExpandSCEVIfNeeded(SCEVExpander &Rewriter, const SCEV *S, Loop *L,
140 Instruction *InsertPt, Type *Ty,
141 bool &IsHighCostExpansion);
137142 };
138143 }
139144
493498 RewritePhi(PHINode *P, unsigned I, Value *V, bool H, bool S)
494499 : PN(P), Ith(I), Val(V), HighCost(H), SafePhi(S) {}
495500 };
501 }
502
503 Value *IndVarSimplify::ExpandSCEVIfNeeded(SCEVExpander &Rewriter, const SCEV *S,
504 Loop *L, Instruction *InsertPt,
505 Type *ResultTy,
506 bool &IsHighCostExpansion) {
507 using namespace llvm::PatternMatch;
508
509 if (!Rewriter.isHighCostExpansion(S, L)) {
510 IsHighCostExpansion = false;
511 return Rewriter.expandCodeFor(S, ResultTy, InsertPt);
512 }
513
514 // Before expanding S into an expensive LLVM expression, see if we can use an
515 // already existing value as the expansion for S. There is potential to make
516 // this significantly smarter, but this simple heuristic already gets some
517 // interesting cases.
518
519 SmallVector Latches;
520 L->getLoopLatches(Latches);
521
522 for (BasicBlock *BB : Latches) {
523 ICmpInst::Predicate Pred;
524 Instruction *LHS, *RHS;
525 BasicBlock *TrueBB, *FalseBB;
526
527 if (!match(BB->getTerminator(),
528 m_Br(m_ICmp(Pred, m_Instruction(LHS), m_Instruction(RHS)),
529 TrueBB, FalseBB)))
530 continue;
531
532 if (SE->getSCEV(LHS) == S && DT->dominates(LHS, InsertPt)) {
533 IsHighCostExpansion = false;
534 return LHS;
535 }
536
537 if (SE->getSCEV(RHS) == S && DT->dominates(RHS, InsertPt)) {
538 IsHighCostExpansion = false;
539 return RHS;
540 }
541 }
542
543 // We didn't find anything, fall back to using SCEVExpander.
544 assert(Rewriter.isHighCostExpansion(S, L) && "this should not have changed!");
545 IsHighCostExpansion = true;
546 return Rewriter.expandCodeFor(S, ResultTy, InsertPt);
496547 }
497548
498549 //===----------------------------------------------------------------------===//
627678 continue;
628679 }
629680
630 Value *ExitVal = Rewriter.expandCodeFor(ExitValue, PN->getType(), Inst);
681 bool HighCost = false;
682 Value *ExitVal = ExpandSCEVIfNeeded(Rewriter, ExitValue, L, Inst,
683 PN->getType(), HighCost);
631684
632685 DEBUG(dbgs() << "INDVARS: RLEV: AfterLoopVal = " << *ExitVal << '\n'
633686 << " LoopVal = " << *Inst << "\n");
636689 DeadInsts.push_back(ExitVal);
637690 continue;
638691 }
639 bool HighCost = Rewriter.isHighCostExpansion(ExitValue, L);
640692
641693 // Collect all the candidate PHINodes to be rewritten.
642694 RewritePhiSet.push_back(
0 ; RUN: opt -S -indvars < %s | FileCheck %s
1
2 define void @f(i32 %length.i.88, i32 %length.i, i8* %tmp12, i32 %tmp10, i8* %tmp8) {
3 ; CHECK-LABEL: @f(
4 not_zero11.preheader:
5 %tmp13 = icmp ugt i32 %length.i, %length.i.88
6 %tmp14 = select i1 %tmp13, i32 %length.i.88, i32 %length.i
7 %tmp15 = icmp sgt i32 %tmp14, 0
8 br i1 %tmp15, label %not_zero11, label %not_zero11.postloop
9
10 not_zero11:
11 %v_1 = phi i32 [ %tmp22, %not_zero11 ], [ 0, %not_zero11.preheader ]
12 %tmp16 = zext i32 %v_1 to i64
13 %tmp17 = getelementptr inbounds i8, i8* %tmp8, i64 %tmp16
14 %tmp18 = load i8, i8* %tmp17, align 1
15 %tmp19 = zext i8 %tmp18 to i32
16 %tmp20 = or i32 %tmp19, %tmp10
17 %tmp21 = trunc i32 %tmp20 to i8
18 %addr22 = getelementptr inbounds i8, i8* %tmp12, i64 %tmp16
19 store i8 %tmp21, i8* %addr22, align 1
20 %tmp22 = add nuw nsw i32 %v_1, 1
21 %tmp23 = icmp slt i32 %tmp22, %tmp14
22 br i1 %tmp23, label %not_zero11, label %main.exit.selector
23
24 main.exit.selector:
25 ; CHECK-LABEL: main.exit.selector:
26 ; CHECK: %tmp24 = icmp slt i32 %tmp14, %length.i
27 %tmp24 = icmp slt i32 %tmp22, %length.i
28 br i1 %tmp24, label %not_zero11.postloop, label %leave
29
30 leave:
31 ret void
32
33 not_zero11.postloop:
34 ret void
35 }