@@ -342,12 +342,17 @@ struct IntersectVarInfo {
342
342
IntersectionResult TrueIntersection;
343
343
llvm::Optional<int64_t > CmpStart;
344
344
llvm::Optional<int64_t > CmpEnd;
345
- llvm::Optional<int64_t > CmpLERS ;
346
- llvm::Optional<int64_t > CmpLSRE ;
345
+ llvm::Optional<int64_t > CmpLeftEndRightStart ;
346
+ llvm::Optional<int64_t > CmpLeftStartRightEnd ;
347
347
bool IsValidStep;
348
348
};
349
349
350
- // A + Const or A
350
+ // / We can compare the bounds of the segments only if they can be represented
351
+ // / as f(V) = V + C, where V is a variable expression and C is an integer
352
+ // / constant. For the expression S representing one bound of the segment
353
+ // / this function returns a pair consisting of an llvm::Value* of V and an
354
+ // / integer value of C. If S does not have the form f(V), this function
355
+ // / returns llvm::None.
351
356
llvm::Optional<std::pair<Value *, int64_t >>
352
357
parseBoundExpression (const llvm::SCEV *S) {
353
358
if (auto *Unknown = dyn_cast<SCEVUnknown>(S))
@@ -375,62 +380,57 @@ parseBoundExpression(const llvm::SCEV *S) {
375
380
return std::make_pair (Variable, Constant);
376
381
}
377
382
383
+ inline std::function<Dimension& (llvm::SmallVectorImpl<MemoryLocationRange> *)>
384
+ getGrowFunction (const MemoryLocationRange &LeftRange, std::size_t DimIdx) {
385
+ auto Lambda = [&LeftRange, DimIdx](
386
+ llvm::SmallVectorImpl<MemoryLocationRange> *C) -> Dimension & {
387
+ return C->emplace_back (LeftRange).DimList [DimIdx];
388
+ };
389
+ return Lambda;
390
+ }
391
+
378
392
IntersectionResult processBothVariable (const MemoryLocationRange &LeftRange,
379
- std::size_t DimIdx, const Dimension &Right, Dimension &Intersection,
380
- llvm::SmallVectorImpl<MemoryLocationRange> *LC,
381
- llvm::SmallVectorImpl<MemoryLocationRange> *RC, IntersectVarInfo &Info) {
393
+ std::size_t DimIdx, const Dimension &Right, const IntersectVarInfo &Info,
394
+ Dimension &Intersection, llvm::SmallVectorImpl<MemoryLocationRange> *LC,
395
+ llvm::SmallVectorImpl<MemoryLocationRange> *RC) {
396
+ auto Grow = getGrowFunction (LeftRange, DimIdx);
382
397
auto &Left = LeftRange.DimList [DimIdx];
383
398
auto SE = LeftRange.SE ;
384
399
auto &CmpStart = Info.CmpStart ;
385
400
auto &CmpEnd = Info.CmpEnd ;
386
- auto &CmpLSRE = Info.CmpLSRE ;
387
- auto &CmpLERS = Info.CmpLERS ;
388
- if (Info. CmpLERS && *Info. CmpLERS < 0 || Info. CmpLSRE && *Info. CmpLSRE > 0 )
401
+ auto &CmpLSRE = Info.CmpLeftStartRightEnd ;
402
+ auto &CmpLERS = Info.CmpLeftEndRightStart ;
403
+ if (CmpLERS && *CmpLERS < 0 || CmpLSRE && *CmpLSRE > 0 )
389
404
return Info.EmptyIntersection ;
390
405
if (!CmpStart || !CmpEnd || !Info.IsValidStep )
391
406
return Info.UnknownIntersection ;
392
- if (*CmpStart >= 0 && *CmpEnd <= 0 ) {
393
- Intersection = Left;
394
- if (RC && *CmpStart > 0 ) {
395
- auto &Dim = RC->emplace_back (LeftRange).DimList [DimIdx];
396
- Dim.Start = Right.Start ;
397
- Dim.End = subtractSCEVAndCast (Left.Start ,
398
- SE->getOne (Left.Start ->getType ()), SE);
399
- }
400
- if (RC && *CmpEnd < 0 ) {
401
- auto &Dim = RC->emplace_back (LeftRange).DimList [DimIdx];
402
- Dim.Start = addSCEVAndCast (
403
- Left.End , SE->getOne (Left.End ->getType ()), SE);
404
- Dim.End = Right.End ;
405
- }
406
- } else if (*CmpStart <= 0 && *CmpEnd >= 0 && Left.Step == Right.Step ) {
407
- Intersection = Right;
408
- if (LC && *CmpStart < 0 ) {
409
- auto &Dim = LC->emplace_back (LeftRange).DimList [DimIdx];
410
- Dim.Start = Left.Start ;
411
- Dim.End = subtractSCEVAndCast (Right.Start ,
412
- SE->getOne (Right.Start ->getType ()), SE);
413
- }
414
- if (LC && *CmpEnd > 0 ) {
415
- auto &Dim = LC->emplace_back (LeftRange).DimList [DimIdx];
416
- Dim.Start = addSCEVAndCast (
417
- Right.End , SE->getOne (Right.End ->getType ()), SE);
418
- Dim.End = Left.End ;
419
- }
420
- } else if (CmpLERS && CmpLSRE && *CmpLERS >= 0 && *CmpLSRE <= 0 ) {
407
+ if (CmpLERS && CmpLSRE && *CmpLERS >= 0 && *CmpLSRE <= 0 ) {
408
+ // The left dimension overlaps the right.
421
409
Intersection.Start = (*CmpStart) > 0 ? Left.Start : Right.Start ;
422
410
Intersection.End = (*CmpEnd) < 0 ? Left.End : Right.End ;
423
- if (LC && *CmpStart < 0 ) {
424
- auto &Dim = LC->emplace_back (LeftRange).DimList [DimIdx];
425
- Dim.Start = Left.Start ;
426
- Dim.End = subtractSCEVAndCast (Right.Start ,
427
- SE->getOne (Right.Start ->getType ()), SE);
411
+ if (LC) {
412
+ if (*CmpStart < 0 ) {
413
+ auto &Dim = Grow (LC);
414
+ Dim.Start = Left.Start ;
415
+ Dim.End = subtractOneFromSCEV (Right.Start , SE);
416
+ }
417
+ if (*CmpEnd > 0 ) {
418
+ auto &Dim = Grow (LC);
419
+ Dim.Start = addOneToSCEV (Right.End , SE);
420
+ Dim.End = Left.End ;
421
+ }
428
422
}
429
- if (RC && *CmpEnd < 0 ) {
430
- auto &Dim = RC->emplace_back (LeftRange).DimList [DimIdx];
431
- Dim.Start = addSCEVAndCast (
432
- Left.End , SE->getOne (Left.End ->getType ()), SE);
433
- Dim.End = Right.End ;
423
+ if (RC) {
424
+ if (*CmpStart > 0 ) {
425
+ auto &Dim = Grow (RC);
426
+ Dim.Start = Right.Start ;
427
+ Dim.End = subtractOneFromSCEV (Left.Start , SE);
428
+ }
429
+ if (*CmpEnd < 0 ) {
430
+ auto &Dim = Grow (RC);
431
+ Dim.Start = addOneToSCEV (Left.End , SE);
432
+ Dim.End = Right.End ;
433
+ }
434
434
}
435
435
} else
436
436
return Info.UnknownIntersection ;
@@ -442,60 +442,123 @@ IntersectionResult processOneStartOtherEndConst(
442
442
const Dimension &Right, Dimension &Intersection,
443
443
llvm::SmallVectorImpl<MemoryLocationRange> *LC,
444
444
llvm::SmallVectorImpl<MemoryLocationRange> *RC, IntersectVarInfo &Info) {
445
+ auto Grow = getGrowFunction (LeftRange, DimIdx);
445
446
auto &Left = LeftRange.DimList [DimIdx];
447
+ assert ((isa<SCEVConstant>(Left.Start ) && !isa<SCEVConstant>(Left.End ) &&
448
+ !isa<SCEVConstant>(Right.Start ) && isa<SCEVConstant>(Right.End )) ||
449
+ (isa<SCEVConstant>(Right.Start ) && !isa<SCEVConstant>(Right.End ) &&
450
+ !isa<SCEVConstant>(Left.Start ) && isa<SCEVConstant>(Left.End )));
446
451
auto SE = LeftRange.SE ;
447
- auto &CmpLSRE = Info.CmpLSRE ;
448
- auto &CmpLERS = Info.CmpLERS ;
449
- if (isa<SCEVConstant>(Left.Start )) {
450
- if (!CmpLERS)
451
- return Info.UnknownIntersection ;
452
- if (*CmpLERS >= 0 ) {
453
- if (Info.IsValidStep ) {
454
- Intersection.Start = Right.Start ;
455
- Intersection.End = Left.End ;
456
- if (LC) {
457
- auto &Dim = LC->emplace_back (LeftRange).DimList [DimIdx];
458
- Dim.Start = Left.Start ;
459
- Dim.End = subtractSCEVAndCast (Right.Start ,
460
- SE->getOne (Right.Start ->getType ()), SE);
461
- }
462
- if (RC) {
463
- auto &Dim = RC->emplace_back (LeftRange).DimList [DimIdx];
464
- Dim.Start = addSCEVAndCast (Left.End , SE->getOne (Left.End ->getType ()),
465
- SE);
466
- Dim.End = Right.End ;
467
- }
468
- } else {
469
- return Info.UnknownIntersection ;
452
+ auto *AM = LeftRange.AM ;
453
+ // Let the First dimension be a dimension whose Start is constant and End
454
+ // is variable. We will denote the segments as follows:
455
+ // First = [m, N], Second = [P, q], where lowercase letters mean constants,
456
+ // and capital letters mean variables.
457
+ auto *First { &Left }, *Second { &Right };
458
+ auto *FC { LC }, *SC { RC };
459
+ auto &Cmpmq { Info.CmpLeftStartRightEnd },
460
+ &CmpNP { Info.CmpLeftEndRightStart };
461
+ if (!isa<SCEVConstant>(Left.Start )) {
462
+ std::swap (First, Second);
463
+ std::swap (FC, SC);
464
+ std::swap (Cmpmq, CmpNP);
465
+ }
466
+ assert (Cmpmq && " Constant bounds must be comparable!" );
467
+ if (*Cmpmq > 0 )
468
+ return Info.EmptyIntersection ;
469
+ if (!CmpNP)
470
+ return Info.UnknownIntersection ;
471
+ if (*CmpNP < 0 )
472
+ return Info.EmptyIntersection ;
473
+ if (!Info.IsValidStep )
474
+ return Info.UnknownIntersection ;
475
+ // N >= P
476
+ auto *M = First->Start , *N = First->End ;
477
+ auto *P = Second->Start , *Q = Second->End ;
478
+ auto BN = parseBoundExpression (N);
479
+ auto BP = parseBoundExpression (P);
480
+ if (!BP || !BN || !AM)
481
+ return Info.UnknownIntersection ;
482
+ auto BPItr = AM->find (BP->first );
483
+ auto BNItr = AM->find (BN->first );
484
+ if (BPItr == AM->end () || BNItr == AM->end ())
485
+ return Info.UnknownIntersection ;
486
+ auto &BoundsP = BPItr->second ;
487
+ auto &BoundsN = BNItr->second ;
488
+ auto MInt = cast<SCEVConstant>(M)->getAPInt ().getSExtValue ();
489
+ auto QInt = cast<SCEVConstant>(Q)->getAPInt ().getSExtValue ();
490
+ if (!BoundsN.Lower || !BoundsN.Upper || !BoundsP.Lower || !BoundsP.Upper )
491
+ return Info.UnknownIntersection ;
492
+ if (MInt < *BoundsP.Lower ) {
493
+ if (QInt > *BoundsN.Upper ) {
494
+ Intersection.Start = P;
495
+ Intersection.End = N;
496
+ if (FC) {
497
+ // [m, P-1]
498
+ auto &Dim = Grow (FC);
499
+ Dim.Start = M;
500
+ Dim.End = subtractOneFromSCEV (P, SE);
501
+ }
502
+ if (SC) {
503
+ // [N+1, q]
504
+ auto &Dim = Grow (SC);
505
+ Dim.Start = addOneToSCEV (N, SE);
506
+ Dim.End = Q;
507
+ }
508
+ } else if (QInt < *BoundsN.Lower ) {
509
+ Intersection = *Second;
510
+ if (FC) {
511
+ // [m, P-1], [q+1, N]
512
+ auto &Dim1 = Grow (FC);
513
+ Dim1.Start = M;
514
+ Dim1.End = subtractOneFromSCEV (P, SE);
515
+ auto &Dim2 = Grow (FC);
516
+ Dim2.Start = addOneToSCEV (Q, SE);
517
+ Dim2.End = N;
470
518
}
471
519
} else {
472
- return Info.EmptyIntersection ;
520
+ return Info.UnknownIntersection ;
473
521
}
474
- } else {
475
- if (!CmpLSRE )
522
+ } else if (MInt <= *BoundsP. Lower && *BoundsN. Lower >= QInt) {
523
+ if (FC || SC )
476
524
return Info.UnknownIntersection ;
477
- if (*CmpLSRE <= 0 ) {
478
- if (Info.IsValidStep ) {
479
- Intersection.Start = Left.Start ;
480
- Intersection.End = Right.End ;
481
- if (LC) {
482
- auto &Dim = LC->emplace_back (LeftRange).DimList [DimIdx];
483
- Dim.Start = Right.Start ;
484
- Dim.End = subtractSCEVAndCast (Left.Start ,
485
- SE->getOne (Left.Start ->getType ()), SE);
486
- }
487
- if (RC) {
488
- auto &Dim = RC->emplace_back (LeftRange).DimList [DimIdx];
489
- Dim.Start = addSCEVAndCast (
490
- Right.End , SE->getOne (Right.End ->getType ()), SE);
491
- Dim.End = Left.End ;
492
- }
493
- } else {
494
- return Info.UnknownIntersection ;
525
+ Intersection = *Second;
526
+ } else if (MInt > *BoundsP.Upper ) {
527
+ if (QInt < BoundsN.Lower ) {
528
+ Intersection.Start = M;
529
+ Intersection.End = Q;
530
+ if (FC) {
531
+ // [P, m-1]
532
+ auto &Dim = Grow (FC);
533
+ Dim.Start = P;
534
+ Dim.End = subtractOneFromSCEV (M, SE);
535
+ }
536
+ if (SC) {
537
+ // [q+1, N]
538
+ auto &Dim = Grow (SC);
539
+ Dim.Start = addOneToSCEV (Q, SE);
540
+ Dim.End = N;
541
+ }
542
+ } else if (QInt > BoundsN.Upper ) {
543
+ Intersection = *First;
544
+ if (SC) {
545
+ // [P, m-1], [N+1, q]
546
+ auto &Dim1 = Grow (SC);
547
+ Dim1.Start = P;
548
+ Dim1.End = subtractOneFromSCEV (M, SE);
549
+ auto &Dim2 = Grow (SC);
550
+ Dim2.Start = subtractOneFromSCEV (N, SE);
551
+ Dim2.End = Q;
495
552
}
496
553
} else {
497
- return Info.EmptyIntersection ;
554
+ return Info.UnknownIntersection ;
498
555
}
556
+ } else if (MInt >= *BoundsP.Upper && BoundsN.Upper <= QInt) {
557
+ if (FC || SC)
558
+ return Info.UnknownIntersection ;
559
+ Intersection = *First;
560
+ } else {
561
+ return Info.UnknownIntersection ;
499
562
}
500
563
return Info.TrueIntersection ;
501
564
}
@@ -504,14 +567,15 @@ IntersectionResult processBothStartConst(const MemoryLocationRange &LeftRange,
504
567
std::size_t DimIdx, const Dimension &Right, Dimension &Intersection,
505
568
llvm::SmallVectorImpl<MemoryLocationRange> *LC,
506
569
llvm::SmallVectorImpl<MemoryLocationRange> *RC, IntersectVarInfo &Info) {
507
- assert (DimIdx < LeftRange.DimList .size () && " DimIdx must match the size of LeftRange.DimList!" );
570
+ assert (DimIdx < LeftRange.DimList .size () &&
571
+ " DimIdx must match the size of LeftRange.DimList!" );
508
572
auto &Left = LeftRange.DimList [DimIdx];
509
573
auto SE = LeftRange.SE ;
510
574
auto *AM = LeftRange.AM ;
511
575
auto &CmpStart = Info.CmpStart ;
512
576
auto &CmpEnd = Info.CmpEnd ;
513
- auto &CmpLSRE = Info.CmpLSRE ;
514
- auto &CmpLERS = Info.CmpLERS ;
577
+ auto &CmpLSRE = Info.CmpLeftStartRightEnd ;
578
+ auto &CmpLERS = Info.CmpLeftEndRightStart ;
515
579
if (!CmpEnd || !Info.IsValidStep )
516
580
return Info.UnknownIntersection ;
517
581
assert (CmpStart && " Starts of dimensions must be comparable!" );
@@ -603,8 +667,8 @@ IntersectionResult processBothEndConst(const MemoryLocationRange &LeftRange,
603
667
auto SE = LeftRange.SE ;
604
668
auto &CmpStart = Info.CmpStart ;
605
669
auto &CmpEnd = Info.CmpEnd ;
606
- auto &CmpLSRE = Info.CmpLSRE ;
607
- auto &CmpLERS = Info.CmpLERS ;
670
+ auto &CmpLSRE = Info.CmpLeftStartRightEnd ;
671
+ auto &CmpLERS = Info.CmpLeftEndRightStart ;
608
672
if (!CmpStart || Left.End != Right.End || !Info.IsValidStep )
609
673
return Info.UnknownIntersection ;
610
674
Intersection.Start = *CmpStart > 0 ? Left.Start : Right.Start ;
@@ -687,7 +751,7 @@ IntersectionResult processOneVariableOtherSemiconst(
687
751
llvm::SmallVectorImpl<MemoryLocationRange> *RC, IntersectVarInfo &Info) {
688
752
auto &Left = LeftRange.DimList [DimIdx];
689
753
auto SE = LeftRange.SE ;
690
- auto &CmpLSRE = Info.CmpLSRE ;
754
+ auto &CmpLSRE = Info.CmpLeftStartRightEnd ;
691
755
const Dimension *FullVar = &Left, *Semiconst = &Right;
692
756
if (isa<SCEVConstant>(Left.Start ) || isa<SCEVConstant>(Left.End ))
693
757
std::swap (FullVar, Semiconst);
@@ -772,12 +836,12 @@ IntersectionResult intersectVarDims(const MemoryLocationRange &LeftRange,
772
836
cast<SCEVConstant>(Left.Step )->getAPInt ().getSExtValue () == 1 ;
773
837
Info.CmpStart = compareSCEVs (Left.Start , Right.Start , LeftRange.SE );
774
838
Info.CmpEnd = compareSCEVs (Left.End , Right.End , LeftRange.SE );
775
- Info.CmpLERS = compareSCEVs (Left.End , Right.Start , LeftRange.SE );
776
- Info.CmpLSRE = compareSCEVs (Left.Start , Right.End , LeftRange.SE );
839
+ Info.CmpLeftEndRightStart = compareSCEVs (Left.End , Right.Start , LeftRange.SE );
840
+ Info.CmpLeftStartRightEnd = compareSCEVs (Left.Start , Right.End , LeftRange.SE );
777
841
switch (PairKind) {
778
842
case DimPairKind::BothVariable:
779
- return processBothVariable (LeftRange, DimIdx, Right, Intersection,
780
- LC, RC, Info );
843
+ return processBothVariable (LeftRange, DimIdx, Right, Info, Intersection,
844
+ LC, RC);
781
845
case DimPairKind::OneStartOtherEndConst:
782
846
return processOneStartOtherEndConst (LeftRange, DimIdx, Right,
783
847
Intersection, LC, RC, Info);
0 commit comments