@@ -149,9 +149,9 @@ static cl::opt<unsigned> MaxValueCompareDepth(
149
149
cl::init(2));
150
150
151
151
static cl::opt<unsigned>
152
- MaxAddExprDepth (" scalar-evolution-max-addexpr -depth" , cl::Hidden,
153
- cl::desc (" Maximum depth of recursive AddExpr " ),
154
- cl::init(32 ));
152
+ MaxArithDepth ("scalar-evolution-max-arith -depth", cl::Hidden,
153
+ cl::desc("Maximum depth of recursive arithmetics "),
154
+ cl::init(32));
155
155
156
156
static cl::opt<unsigned> MaxConstantEvolvingDepth(
157
157
"scalar-evolution-max-constant-evolving-depth", cl::Hidden,
@@ -2276,8 +2276,8 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
2276
2276
if (Ops.size() == 1) return Ops[0];
2277
2277
}
2278
2278
2279
- // Limit recursion calls depth
2280
- if (Depth > MaxAddExprDepth )
2279
+ // Limit recursion calls depth.
2280
+ if (Depth > MaxArithDepth )
2281
2281
return getOrCreateAddExpr(Ops, Flags);
2282
2282
2283
2283
// Okay, check to see if the same value occurs in the operand list more than
@@ -2293,7 +2293,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
2293
2293
++Count;
2294
2294
// Merge the values into a multiply.
2295
2295
const SCEV *Scale = getConstant(Ty, Count);
2296
- const SCEV *Mul = getMulExpr (Scale, Ops[i]);
2296
+ const SCEV *Mul = getMulExpr(Scale, Ops[i], SCEV::FlagAnyWrap, Depth + 1 );
2297
2297
if (Ops.size() == Count)
2298
2298
return Mul;
2299
2299
Ops[i] = Mul;
@@ -2343,7 +2343,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
2343
2343
}
2344
2344
}
2345
2345
if (Ok)
2346
- LargeOps.push_back (getMulExpr (LargeMulOps));
2346
+ LargeOps.push_back(getMulExpr(LargeMulOps, SCEV::FlagAnyWrap, Depth + 1 ));
2347
2347
} else {
2348
2348
Ok = false;
2349
2349
break;
@@ -2417,7 +2417,8 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
2417
2417
if (MulOp.first != 0)
2418
2418
Ops.push_back(getMulExpr(
2419
2419
getConstant(MulOp.first),
2420
- getAddExpr (MulOp.second , SCEV::FlagAnyWrap, Depth + 1 )));
2420
+ getAddExpr(MulOp.second, SCEV::FlagAnyWrap, Depth + 1),
2421
+ SCEV::FlagAnyWrap, Depth + 1));
2421
2422
if (Ops.empty())
2422
2423
return getZero(Ty);
2423
2424
if (Ops.size() == 1)
@@ -2445,11 +2446,12 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
2445
2446
SmallVector<const SCEV *, 4> MulOps(Mul->op_begin(),
2446
2447
Mul->op_begin()+MulOp);
2447
2448
MulOps.append(Mul->op_begin()+MulOp+1, Mul->op_end());
2448
- InnerMul = getMulExpr (MulOps);
2449
+ InnerMul = getMulExpr(MulOps, SCEV::FlagAnyWrap, Depth + 1 );
2449
2450
}
2450
2451
SmallVector<const SCEV *, 2> TwoOps = {getOne(Ty), InnerMul};
2451
2452
const SCEV *AddOne = getAddExpr(TwoOps, SCEV::FlagAnyWrap, Depth + 1);
2452
- const SCEV *OuterMul = getMulExpr (AddOne, MulOpSCEV);
2453
+ const SCEV *OuterMul = getMulExpr(AddOne, MulOpSCEV,
2454
+ SCEV::FlagAnyWrap, Depth + 1);
2453
2455
if (Ops.size() == 2) return OuterMul;
2454
2456
if (AddOp < Idx) {
2455
2457
Ops.erase(Ops.begin()+AddOp);
@@ -2478,19 +2480,20 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
2478
2480
SmallVector<const SCEV *, 4> MulOps(Mul->op_begin(),
2479
2481
Mul->op_begin()+MulOp);
2480
2482
MulOps.append(Mul->op_begin()+MulOp+1, Mul->op_end());
2481
- InnerMul1 = getMulExpr (MulOps);
2483
+ InnerMul1 = getMulExpr(MulOps, SCEV::FlagAnyWrap, Depth + 1 );
2482
2484
}
2483
2485
const SCEV *InnerMul2 = OtherMul->getOperand(OMulOp == 0);
2484
2486
if (OtherMul->getNumOperands() != 2) {
2485
2487
SmallVector<const SCEV *, 4> MulOps(OtherMul->op_begin(),
2486
2488
OtherMul->op_begin()+OMulOp);
2487
2489
MulOps.append(OtherMul->op_begin()+OMulOp+1, OtherMul->op_end());
2488
- InnerMul2 = getMulExpr (MulOps);
2490
+ InnerMul2 = getMulExpr(MulOps, SCEV::FlagAnyWrap, Depth + 1 );
2489
2491
}
2490
2492
SmallVector<const SCEV *, 2> TwoOps = {InnerMul1, InnerMul2};
2491
2493
const SCEV *InnerMulSum =
2492
2494
getAddExpr(TwoOps, SCEV::FlagAnyWrap, Depth + 1);
2493
- const SCEV *OuterMul = getMulExpr (MulOpSCEV, InnerMulSum);
2495
+ const SCEV *OuterMul = getMulExpr(MulOpSCEV, InnerMulSum,
2496
+ SCEV::FlagAnyWrap, Depth + 1);
2494
2497
if (Ops.size() == 2) return OuterMul;
2495
2498
Ops.erase(Ops.begin()+Idx);
2496
2499
Ops.erase(Ops.begin()+OtherMulIdx-1);
@@ -2621,6 +2624,27 @@ ScalarEvolution::getOrCreateAddExpr(SmallVectorImpl<const SCEV *> &Ops,
2621
2624
return S;
2622
2625
}
2623
2626
2627
+ const SCEV *
2628
+ ScalarEvolution::getOrCreateMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2629
+ SCEV::NoWrapFlags Flags) {
2630
+ FoldingSetNodeID ID;
2631
+ ID.AddInteger(scMulExpr);
2632
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
2633
+ ID.AddPointer(Ops[i]);
2634
+ void *IP = nullptr;
2635
+ SCEVMulExpr *S =
2636
+ static_cast<SCEVMulExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
2637
+ if (!S) {
2638
+ const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Ops.size());
2639
+ std::uninitialized_copy(Ops.begin(), Ops.end(), O);
2640
+ S = new (SCEVAllocator) SCEVMulExpr(ID.Intern(SCEVAllocator),
2641
+ O, Ops.size());
2642
+ UniqueSCEVs.InsertNode(S, IP);
2643
+ }
2644
+ S->setNoWrapFlags(Flags);
2645
+ return S;
2646
+ }
2647
+
2624
2648
static uint64_t umul_ov(uint64_t i, uint64_t j, bool &Overflow) {
2625
2649
uint64_t k = i*j;
2626
2650
if (j > 1 && k / j != i) Overflow = true;
@@ -2673,7 +2697,8 @@ static bool containsConstantSomewhere(const SCEV *StartExpr) {
2673
2697
2674
2698
/// Get a canonical multiply expression, or something simpler if possible.
2675
2699
const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2676
- SCEV::NoWrapFlags Flags) {
2700
+ SCEV::NoWrapFlags Flags,
2701
+ unsigned Depth) {
2677
2702
assert(Flags == maskFlags(Flags, SCEV::FlagNUW | SCEV::FlagNSW) &&
2678
2703
"only nuw or nsw allowed");
2679
2704
assert(!Ops.empty() && "Cannot get empty mul!");
@@ -2690,6 +2715,10 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2690
2715
2691
2716
Flags = StrengthenNoWrapFlags(this, scMulExpr, Ops, Flags);
2692
2717
2718
+ // Limit recursion calls depth.
2719
+ if (Depth > MaxArithDepth)
2720
+ return getOrCreateMulExpr(Ops, Flags);
2721
+
2693
2722
// If there are any constants, fold them together.
2694
2723
unsigned Idx = 0;
2695
2724
if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
@@ -2701,8 +2730,11 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2701
2730
// apply this transformation as well.
2702
2731
if (Add->getNumOperands() == 2)
2703
2732
if (containsConstantSomewhere(Add))
2704
- return getAddExpr (getMulExpr (LHSC, Add->getOperand (0 )),
2705
- getMulExpr (LHSC, Add->getOperand (1 )));
2733
+ return getAddExpr(getMulExpr(LHSC, Add->getOperand(0),
2734
+ SCEV::FlagAnyWrap, Depth + 1),
2735
+ getMulExpr(LHSC, Add->getOperand(1),
2736
+ SCEV::FlagAnyWrap, Depth + 1),
2737
+ SCEV::FlagAnyWrap, Depth + 1);
2706
2738
2707
2739
++Idx;
2708
2740
while (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(Ops[Idx])) {
@@ -2730,17 +2762,19 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2730
2762
SmallVector<const SCEV *, 4> NewOps;
2731
2763
bool AnyFolded = false;
2732
2764
for (const SCEV *AddOp : Add->operands()) {
2733
- const SCEV *Mul = getMulExpr (Ops[0 ], AddOp);
2765
+ const SCEV *Mul = getMulExpr(Ops[0], AddOp, SCEV::FlagAnyWrap,
2766
+ Depth + 1);
2734
2767
if (!isa<SCEVMulExpr>(Mul)) AnyFolded = true;
2735
2768
NewOps.push_back(Mul);
2736
2769
}
2737
2770
if (AnyFolded)
2738
- return getAddExpr (NewOps);
2771
+ return getAddExpr(NewOps, SCEV::FlagAnyWrap, Depth + 1 );
2739
2772
} else if (const auto *AddRec = dyn_cast<SCEVAddRecExpr>(Ops[1])) {
2740
2773
// Negation preserves a recurrence's no self-wrap property.
2741
2774
SmallVector<const SCEV *, 4> Operands;
2742
2775
for (const SCEV *AddRecOp : AddRec->operands())
2743
- Operands.push_back (getMulExpr (Ops[0 ], AddRecOp));
2776
+ Operands.push_back(getMulExpr(Ops[0], AddRecOp, SCEV::FlagAnyWrap,
2777
+ Depth + 1));
2744
2778
2745
2779
return getAddRecExpr(Operands, AddRec->getLoop(),
2746
2780
AddRec->getNoWrapFlags(SCEV::FlagNW));
@@ -2762,18 +2796,18 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2762
2796
while (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(Ops[Idx])) {
2763
2797
if (Ops.size() > MulOpsInlineThreshold)
2764
2798
break;
2765
- // If we have an mul, expand the mul operands onto the end of the operands
2766
- // list.
2799
+ // If we have an mul, expand the mul operands onto the end of the
2800
+ // operands list.
2767
2801
Ops.erase(Ops.begin()+Idx);
2768
2802
Ops.append(Mul->op_begin(), Mul->op_end());
2769
2803
DeletedMul = true;
2770
2804
}
2771
2805
2772
- // If we deleted at least one mul, we added operands to the end of the list,
2773
- // and they are not necessarily sorted. Recurse to resort and resimplify
2774
- // any operands we just acquired.
2806
+ // If we deleted at least one mul, we added operands to the end of the
2807
+ // list, and they are not necessarily sorted. Recurse to resort and
2808
+ // resimplify any operands we just acquired.
2775
2809
if (DeletedMul)
2776
- return getMulExpr (Ops);
2810
+ return getMulExpr(Ops, SCEV::FlagAnyWrap, Depth + 1 );
2777
2811
}
2778
2812
2779
2813
// If there are any add recurrences in the operands list, see if any other
@@ -2784,8 +2818,8 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2784
2818
2785
2819
// Scan over all recurrences, trying to fold loop invariants into them.
2786
2820
for (; Idx < Ops.size() && isa<SCEVAddRecExpr>(Ops[Idx]); ++Idx) {
2787
- // Scan all of the other operands to this mul and add them to the vector if
2788
- // they are loop invariant w.r.t. the recurrence.
2821
+ // Scan all of the other operands to this mul and add them to the vector
2822
+ // if they are loop invariant w.r.t. the recurrence.
2789
2823
SmallVector<const SCEV *, 8> LIOps;
2790
2824
const SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ops[Idx]);
2791
2825
const Loop *AddRecLoop = AddRec->getLoop();
@@ -2801,9 +2835,10 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2801
2835
// NLI * LI * {Start,+,Step} --> NLI * {LI*Start,+,LI*Step}
2802
2836
SmallVector<const SCEV *, 4> NewOps;
2803
2837
NewOps.reserve(AddRec->getNumOperands());
2804
- const SCEV *Scale = getMulExpr (LIOps);
2838
+ const SCEV *Scale = getMulExpr(LIOps, SCEV::FlagAnyWrap, Depth + 1 );
2805
2839
for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i)
2806
- NewOps.push_back (getMulExpr (Scale, AddRec->getOperand (i)));
2840
+ NewOps.push_back(getMulExpr(Scale, AddRec->getOperand(i),
2841
+ SCEV::FlagAnyWrap, Depth + 1));
2807
2842
2808
2843
// Build the new addrec. Propagate the NUW and NSW flags if both the
2809
2844
// outer mul and the inner addrec are guaranteed to have no overflow.
@@ -2822,12 +2857,12 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2822
2857
Ops[i] = NewRec;
2823
2858
break;
2824
2859
}
2825
- return getMulExpr (Ops);
2860
+ return getMulExpr(Ops, SCEV::FlagAnyWrap, Depth + 1 );
2826
2861
}
2827
2862
2828
- // Okay, if there weren't any loop invariants to be folded, check to see if
2829
- // there are multiple AddRec's with the same loop induction variable being
2830
- // multiplied together. If so, we can fold them.
2863
+ // Okay, if there weren't any loop invariants to be folded, check to see
2864
+ // if there are multiple AddRec's with the same loop induction variable
2865
+ // being multiplied together. If so, we can fold them.
2831
2866
2832
2867
// {A1,+,A2,+,...,+,An}<L> * {B1,+,B2,+,...,+,Bn}<L>
2833
2868
// = {x=1 in [ sum y=x..2x [ sum z=max(y-x, y-n)..min(x,n) [
@@ -2869,7 +2904,9 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2869
2904
const SCEV *CoeffTerm = getConstant(Ty, Coeff);
2870
2905
const SCEV *Term1 = AddRec->getOperand(y-z);
2871
2906
const SCEV *Term2 = OtherAddRec->getOperand(z);
2872
- Term = getAddExpr (Term, getMulExpr (CoeffTerm, Term1,Term2));
2907
+ Term = getAddExpr(Term, getMulExpr(CoeffTerm, Term1, Term2,
2908
+ SCEV::FlagAnyWrap, Depth + 1),
2909
+ SCEV::FlagAnyWrap, Depth + 1);
2873
2910
}
2874
2911
}
2875
2912
AddRecOps.push_back(Term);
@@ -2887,30 +2924,15 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
2887
2924
}
2888
2925
}
2889
2926
if (OpsModified)
2890
- return getMulExpr (Ops);
2927
+ return getMulExpr(Ops, SCEV::FlagAnyWrap, Depth + 1 );
2891
2928
2892
2929
// Otherwise couldn't fold anything into this recurrence. Move onto the
2893
2930
// next one.
2894
2931
}
2895
2932
2896
2933
// Okay, it looks like we really DO need an mul expr. Check to see if we
2897
2934
// already have one, otherwise create a new one.
2898
- FoldingSetNodeID ID;
2899
- ID.AddInteger (scMulExpr);
2900
- for (unsigned i = 0 , e = Ops.size (); i != e; ++i)
2901
- ID.AddPointer (Ops[i]);
2902
- void *IP = nullptr ;
2903
- SCEVMulExpr *S =
2904
- static_cast <SCEVMulExpr *>(UniqueSCEVs.FindNodeOrInsertPos (ID, IP));
2905
- if (!S) {
2906
- const SCEV **O = SCEVAllocator.Allocate <const SCEV *>(Ops.size ());
2907
- std::uninitialized_copy (Ops.begin (), Ops.end (), O);
2908
- S = new (SCEVAllocator) SCEVMulExpr (ID.Intern (SCEVAllocator),
2909
- O, Ops.size ());
2910
- UniqueSCEVs.InsertNode (S, IP);
2911
- }
2912
- S->setNoWrapFlags (Flags);
2913
- return S;
2935
+ return getOrCreateMulExpr(Ops, Flags);
2914
2936
}
2915
2937
2916
2938
/// Get a canonical unsigned division expression, or something simpler if
@@ -3713,7 +3735,8 @@ const SCEV *ScalarEvolution::getNotSCEV(const SCEV *V) {
3713
3735
}
3714
3736
3715
3737
const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
3716
- SCEV::NoWrapFlags Flags) {
3738
+ SCEV::NoWrapFlags Flags,
3739
+ unsigned Depth) {
3717
3740
// Fast path: X - X --> 0.
3718
3741
if (LHS == RHS)
3719
3742
return getZero(LHS->getType());
@@ -3747,7 +3770,7 @@ const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
3747
3770
// larger scope than intended.
3748
3771
auto NegFlags = RHSIsNotMinSigned ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
3749
3772
3750
- return getAddExpr (LHS, getNegativeSCEV (RHS, NegFlags), AddFlags);
3773
+ return getAddExpr(LHS, getNegativeSCEV(RHS, NegFlags), AddFlags, Depth );
3751
3774
}
3752
3775
3753
3776
const SCEV *
0 commit comments