[SCEV] Introduce add operation inlining limit

Inlining in getAddExpr() can cause abnormal computational time in some cases.
New parameter -scev-addops-inline-threshold is intruduced with default value 500.

Reviewers: sanjoy

Subscribers: mzolotukhin, llvm-commits

Differential Revision: https://reviews.llvm.org/D28812

llvm-svn: 293176
This commit is contained in:
Daniil Fukalov 2017-01-26 13:33:17 +00:00
parent 3057fd53f9
commit b09dac59fc
2 changed files with 25 additions and 0 deletions

View File

@ -127,6 +127,11 @@ static cl::opt<unsigned> MulOpsInlineThreshold(
cl::desc("Threshold for inlining multiplication operands into a SCEV"),
cl::init(1000));
static cl::opt<unsigned> AddOpsInlineThreshold(
"scev-addops-inline-threshold", cl::Hidden,
cl::desc("Threshold for inlining multiplication operands into a SCEV"),
cl::init(500));
static cl::opt<unsigned>
MaxCompareDepth("scalar-evolution-max-compare-depth", cl::Hidden,
cl::desc("Maximum depth of recursive compare complexity"),
@ -2219,6 +2224,9 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
if (Idx < Ops.size()) {
bool DeletedAdd = false;
while (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[Idx])) {
if (Ops.size() > AddOpsInlineThreshold ||
Add->getNumOperands() > AddOpsInlineThreshold)
break;
// If we have an add, expand the add operands onto the end of the operands
// list.
Ops.erase(Ops.begin()+Idx);

View File

@ -0,0 +1,17 @@
; RUN: opt -analyze -scalar-evolution -scev-addops-inline-threshold=1 < %s | FileCheck --check-prefix=CHECK1 %s
; RUN: opt -analyze -scalar-evolution -scev-addops-inline-threshold=10 < %s | FileCheck --check-prefix=CHECK10 %s
define i32 @foo(i64 %p0, i32 %p1) {
; CHECK1: %add2 = add nsw i32 %mul1, %add
; CHECK1-NEXT: --> ((trunc i64 %p0 to i32) * (1 + (trunc i64 %p0 to i32)) * (1 + %p1))
; CHECK10: %add2 = add nsw i32 %mul1, %add
; CHECK10-NEXT: --> ((trunc i64 %p0 to i32) * (1 + ((trunc i64 %p0 to i32) * (1 + %p1)) + %p1))
entry:
%tr = trunc i64 %p0 to i32
%mul = mul nsw i32 %tr, %p1
%add = add nsw i32 %mul, %tr
%mul1 = mul nsw i32 %add, %tr
%add2 = add nsw i32 %mul1, %add
ret i32 %add2
}