llvm.org GIT mirror llvm / b1b95a5
[IndVarSimplify] Make cost estimation in RewriteLoopExitValues smarter Differential Revision: http://reviews.llvm.org/D11687 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244474 91177308-0d34-0410-b5e6-96231b3b80d8 Igor Laevsky 4 years ago
3 changed file(s) with 67 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
116116
117117 /// \brief Return true for expressions that may incur non-trivial cost to
118118 /// evaluate at runtime.
119 bool isHighCostExpansion(const SCEV *Expr, Loop *L) {
119 /// 'At' is an optional parameter which specifies point in code where user
120 /// is going to expand this expression. Sometimes this knowledge can lead to
121 /// a more accurate cost estimation.
122 bool isHighCostExpansion(const SCEV *Expr, Loop *L,
123 const Instruction *At = nullptr) {
120124 SmallPtrSet Processed;
121 return isHighCostExpansionHelper(Expr, L, Processed);
125 return isHighCostExpansionHelper(Expr, L, At, Processed);
122126 }
123127
124128 /// \brief This method returns the canonical induction variable of the
192196
193197 void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
194198
199 /// \brief Try to find LLVM IR value for 'S' available at the point 'At'.
200 // 'L' is a hint which tells in which loop to look for the suitable value.
201 // On success return value which is equivalent to the expanded 'S' at point
202 // 'At'. Return nullptr if value was not found.
203 // Note that this function does not perform exhaustive search. I.e if it
204 // didn't find any value it does not mean that there is no such value.
205 Value *findExistingExpansion(const SCEV *S, const Instruction *At, Loop *L);
206
195207 private:
196208 LLVMContext &getContext() const { return SE.getContext(); }
197209
198210 /// \brief Recursive helper function for isHighCostExpansion.
199211 bool isHighCostExpansionHelper(const SCEV *S, Loop *L,
212 const Instruction *At,
200213 SmallPtrSetImpl &Processed);
201214
202215 /// \brief Insert the specified binary operator, doing a small amount
18111811 return NumElim;
18121812 }
18131813
1814 Value *SCEVExpander::findExistingExpansion(const SCEV *S,
1815 const Instruction *At, Loop *L) {
1816 using namespace llvm::PatternMatch;
1817
1818 SmallVector Latches;
1819 L->getLoopLatches(Latches);
1820
1821 // Look for suitable value in simple conditions at the loop latches.
1822 for (BasicBlock *BB : Latches) {
1823 ICmpInst::Predicate Pred;
1824 Instruction *LHS, *RHS;
1825 BasicBlock *TrueBB, *FalseBB;
1826
1827 if (!match(BB->getTerminator(),
1828 m_Br(m_ICmp(Pred, m_Instruction(LHS), m_Instruction(RHS)),
1829 TrueBB, FalseBB)))
1830 continue;
1831
1832 if (SE.getSCEV(LHS) == S && SE.DT->dominates(LHS, At))
1833 return LHS;
1834
1835 if (SE.getSCEV(RHS) == S && SE.DT->dominates(RHS, At))
1836 return RHS;
1837 }
1838
1839 // There is potential to make this significantly smarter, but this simple
1840 // heuristic already gets some interesting cases.
1841
1842 // Can not find suitable value.
1843 return nullptr;
1844 }
1845
18141846 bool SCEVExpander::isHighCostExpansionHelper(
1815 const SCEV *S, Loop *L, SmallPtrSetImpl &Processed) {
1847 const SCEV *S, Loop *L, const Instruction *At,
1848 SmallPtrSetImpl &Processed) {
1849
1850 // If we can find an existing value for this scev avaliable at the point "At"
1851 // then consider the expression cheap.
1852 if (At && findExistingExpansion(S, At, L) != nullptr)
1853 return false;
18161854
18171855 // Zero/One operand expressions
18181856 switch (S->getSCEVType()) {
18201858 case scConstant:
18211859 return false;
18221860 case scTruncate:
1823 return isHighCostExpansionHelper(cast(S)->getOperand(), L,
1824 Processed);
1861 return isHighCostExpansionHelper(cast(S)->getOperand(),
1862 L, At, Processed);
18251863 case scZeroExtend:
18261864 return isHighCostExpansionHelper(cast(S)->getOperand(),
1827 L, Processed);
1865 L, At, Processed);
18281866 case scSignExtend:
18291867 return isHighCostExpansionHelper(cast(S)->getOperand(),
1830 L, Processed);
1868 L, At, Processed);
18311869 }
18321870
18331871 if (!Processed.insert(S).second)
18831921 if (const SCEVNAryExpr *NAry = dyn_cast(S)) {
18841922 for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end();
18851923 I != E; ++I) {
1886 if (isHighCostExpansionHelper(*I, L, Processed))
1924 if (isHighCostExpansionHelper(*I, L, At, Processed))
18871925 return true;
18881926 }
18891927 }
137137 void SinkUnusedInvariants(Loop *L);
138138
139139 Value *ExpandSCEVIfNeeded(SCEVExpander &Rewriter, const SCEV *S, Loop *L,
140 Instruction *InsertPt, Type *Ty,
141 bool &IsHighCostExpansion);
140 Instruction *InsertPt, Type *Ty);
142141 };
143142 }
144143
502501
503502 Value *IndVarSimplify::ExpandSCEVIfNeeded(SCEVExpander &Rewriter, const SCEV *S,
504503 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
504 Type *ResultTy) {
514505 // 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 }
506 // already existing value as the expansion for S.
507 if (Value *RetValue = Rewriter.findExistingExpansion(S, InsertPt, L))
508 return RetValue;
542509
543510 // We didn't find anything, fall back to using SCEVExpander.
544 assert(Rewriter.isHighCostExpansion(S, L) && "this should not have changed!");
545 IsHighCostExpansion = true;
546511 return Rewriter.expandCodeFor(S, ResultTy, InsertPt);
547512 }
548513
678643 continue;
679644 }
680645
681 bool HighCost = false;
682 Value *ExitVal = ExpandSCEVIfNeeded(Rewriter, ExitValue, L, Inst,
683 PN->getType(), HighCost);
646 bool HighCost = Rewriter.isHighCostExpansion(ExitValue, L, Inst);
647 Value *ExitVal =
648 ExpandSCEVIfNeeded(Rewriter, ExitValue, L, Inst, PN->getType());
684649
685650 DEBUG(dbgs() << "INDVARS: RLEV: AfterLoopVal = " << *ExitVal << '\n'
686651 << " LoopVal = " << *Inst << "\n");