@@ -2345,6 +2345,43 @@ static std::optional<APInt> getConstantPart(const SCEV *Expr) {
2345
2345
return std::nullopt;
2346
2346
}
2347
2347
2348
+ bool DependenceInfo::accumulateCoefficientsGCD (const SCEV *Expr,
2349
+ const Loop *CurLoop,
2350
+ const SCEV *&CurLoopCoeff,
2351
+ APInt &RunningGCD) const {
2352
+ // If RunningGCD is already 1, exit early.
2353
+ // TODO: It might be better to continue the recursion to find CurLoopCoeff.
2354
+ if (RunningGCD == 1 )
2355
+ return true ;
2356
+
2357
+ const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
2358
+ if (!AddRec) {
2359
+ assert (isLoopInvariant (Expr, CurLoop) &&
2360
+ " Expected loop invariant expression" );
2361
+ return true ;
2362
+ }
2363
+
2364
+ assert (AddRec->isAffine () && " Unexpected Expr" );
2365
+ const SCEV *Start = AddRec->getStart ();
2366
+ const SCEV *Step = AddRec->getStepRecurrence (*SE);
2367
+ if (AddRec->getLoop () == CurLoop) {
2368
+ CurLoopCoeff = Step;
2369
+ } else {
2370
+ std::optional<APInt> ConstCoeff = getConstantPart (Step);
2371
+
2372
+ // If the coefficient is the product of a constant and other stuff, we can
2373
+ // use the constant in the GCD computation.
2374
+ if (!ConstCoeff)
2375
+ return false ;
2376
+
2377
+ // TODO: What happens if ConstCoeff is the "most negative" signed number
2378
+ // (e.g. -128 for 8 bit wide APInt)?
2379
+ RunningGCD = APIntOps::GreatestCommonDivisor (RunningGCD, ConstCoeff->abs ());
2380
+ }
2381
+
2382
+ return accumulateCoefficientsGCD (Start, CurLoop, CurLoopCoeff, RunningGCD);
2383
+ }
2384
+
2348
2385
// ===----------------------------------------------------------------------===//
2349
2386
// gcdMIVtest -
2350
2387
// Tests an MIV subscript pair for dependence.
@@ -2464,40 +2501,11 @@ bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst,
2464
2501
RunningGCD = ExtraGCD;
2465
2502
const SCEV *SrcCoeff = AddRec->getStepRecurrence (*SE);
2466
2503
const SCEV *DstCoeff = SE->getMinusSCEV (SrcCoeff, SrcCoeff);
2467
- const SCEV *Inner = Src;
2468
- while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2469
- AddRec = cast<SCEVAddRecExpr>(Inner);
2470
- const SCEV *Coeff = AddRec->getStepRecurrence (*SE);
2471
- if (CurLoop == AddRec->getLoop ())
2472
- ; // SrcCoeff == Coeff
2473
- else {
2474
- // If the coefficient is the product of a constant and other stuff,
2475
- // we can use the constant in the GCD computation.
2476
- std::optional<APInt> ConstCoeff = getConstantPart (Coeff);
2477
- if (!ConstCoeff)
2478
- return false ;
2479
- RunningGCD =
2480
- APIntOps::GreatestCommonDivisor (RunningGCD, ConstCoeff->abs ());
2481
- }
2482
- Inner = AddRec->getStart ();
2483
- }
2484
- Inner = Dst;
2485
- while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2486
- AddRec = cast<SCEVAddRecExpr>(Inner);
2487
- const SCEV *Coeff = AddRec->getStepRecurrence (*SE);
2488
- if (CurLoop == AddRec->getLoop ())
2489
- DstCoeff = Coeff;
2490
- else {
2491
- // If the coefficient is the product of a constant and other stuff,
2492
- // we can use the constant in the GCD computation.
2493
- std::optional<APInt> ConstCoeff = getConstantPart (Coeff);
2494
- if (!ConstCoeff)
2495
- return false ;
2496
- RunningGCD =
2497
- APIntOps::GreatestCommonDivisor (RunningGCD, ConstCoeff->abs ());
2498
- }
2499
- Inner = AddRec->getStart ();
2500
- }
2504
+
2505
+ if (!accumulateCoefficientsGCD (Src, CurLoop, SrcCoeff, RunningGCD) ||
2506
+ !accumulateCoefficientsGCD (Dst, CurLoop, DstCoeff, RunningGCD))
2507
+ return false ;
2508
+
2501
2509
Delta = SE->getMinusSCEV (SrcCoeff, DstCoeff);
2502
2510
// If the coefficient is the product of a constant and other stuff,
2503
2511
// we can use the constant in the GCD computation.
0 commit comments