@@ -185,7 +185,8 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
185
185
if (DstI->mayReadOrWriteMemory ()) {
186
186
OS << " Src:" << *SrcI << " --> Dst:" << *DstI << " \n " ;
187
187
OS << " da analyze - " ;
188
- if (auto D = DA->depends (&*SrcI, &*DstI)) {
188
+ if (auto D = DA->depends (&*SrcI, &*DstI,
189
+ /* UnderRuntimeAssumptions=*/ true )) {
189
190
// Normalize negative direction vectors if required by clients.
190
191
if (NormalizeResults && D->normalize (&SE))
191
192
OS << " normalized - " ;
@@ -197,13 +198,17 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
197
198
OS << " !\n " ;
198
199
}
199
200
}
200
- }
201
- else
201
+ } else
202
202
OS << " none!\n " ;
203
203
}
204
204
}
205
205
}
206
206
}
207
+ SCEVUnionPredicate Assumptions = DA->getRuntimeAssumptions ();
208
+ if (!Assumptions.isAlwaysTrue ()) {
209
+ OS << " Runtime Assumptions:\n " ;
210
+ Assumptions.print (OS, 0 );
211
+ }
207
212
}
208
213
209
214
void DependenceAnalysisWrapperPass::print (raw_ostream &OS,
@@ -262,9 +267,10 @@ bool Dependence::isScalar(unsigned level) const {
262
267
// FullDependence methods
263
268
264
269
FullDependence::FullDependence (Instruction *Source, Instruction *Destination,
270
+ const SCEVUnionPredicate &Assumes,
265
271
bool PossiblyLoopIndependent,
266
272
unsigned CommonLevels)
267
- : Dependence(Source, Destination), Levels(CommonLevels),
273
+ : Dependence(Source, Destination, Assumes ), Levels(CommonLevels),
268
274
LoopIndependent(PossiblyLoopIndependent) {
269
275
Consistent = true ;
270
276
if (CommonLevels)
@@ -704,6 +710,12 @@ void Dependence::dump(raw_ostream &OS) const {
704
710
OS << " splitable" ;
705
711
}
706
712
OS << " !\n " ;
713
+
714
+ SCEVUnionPredicate Assumptions = getRuntimeAssumptions ();
715
+ if (!Assumptions.isAlwaysTrue ()) {
716
+ OS << " Runtime Assumptions:\n " ;
717
+ Assumptions.print (OS, 2 );
718
+ }
707
719
}
708
720
709
721
// Returns NoAlias/MayAliass/MustAlias for two memory locations based upon their
@@ -3567,6 +3579,10 @@ bool DependenceInfo::invalidate(Function &F, const PreservedAnalyses &PA,
3567
3579
Inv.invalidate <LoopAnalysis>(F, PA);
3568
3580
}
3569
3581
3582
+ SCEVUnionPredicate DependenceInfo::getRuntimeAssumptions () const {
3583
+ return SCEVUnionPredicate (Assumptions, *SE);
3584
+ }
3585
+
3570
3586
// depends -
3571
3587
// Returns NULL if there is no dependence.
3572
3588
// Otherwise, return a Dependence with as many details as possible.
@@ -3579,7 +3595,9 @@ bool DependenceInfo::invalidate(Function &F, const PreservedAnalyses &PA,
3579
3595
// Care is required to keep the routine below, getSplitIteration(),
3580
3596
// up to date with respect to this routine.
3581
3597
std::unique_ptr<Dependence>
3582
- DependenceInfo::depends (Instruction *Src, Instruction *Dst) {
3598
+ DependenceInfo::depends (Instruction *Src, Instruction *Dst,
3599
+ bool UnderRuntimeAssumptions) {
3600
+ SmallVector<const SCEVPredicate *, 4 > Assume;
3583
3601
bool PossiblyLoopIndependent = true ;
3584
3602
if (Src == Dst)
3585
3603
PossiblyLoopIndependent = false ;
@@ -3591,22 +3609,20 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst) {
3591
3609
if (!isLoadOrStore (Src) || !isLoadOrStore (Dst)) {
3592
3610
// can only analyze simple loads and stores, i.e., no calls, invokes, etc.
3593
3611
LLVM_DEBUG (dbgs () << " can only handle simple loads and stores\n " );
3594
- return std::make_unique<Dependence>(Src, Dst);
3612
+ return std::make_unique<Dependence>(Src, Dst,
3613
+ SCEVUnionPredicate (Assume, *SE));
3595
3614
}
3596
3615
3597
- assert (isLoadOrStore (Src) && " instruction is not load or store" );
3598
- assert (isLoadOrStore (Dst) && " instruction is not load or store" );
3599
- Value *SrcPtr = getLoadStorePointerOperand (Src);
3600
- Value *DstPtr = getLoadStorePointerOperand (Dst);
3616
+ const MemoryLocation &DstLoc = MemoryLocation::get (Dst);
3617
+ const MemoryLocation &SrcLoc = MemoryLocation::get (Src);
3601
3618
3602
- switch (underlyingObjectsAlias (AA, F->getDataLayout (),
3603
- MemoryLocation::get (Dst),
3604
- MemoryLocation::get (Src))) {
3619
+ switch (underlyingObjectsAlias (AA, F->getDataLayout (), DstLoc, SrcLoc)) {
3605
3620
case AliasResult::MayAlias:
3606
3621
case AliasResult::PartialAlias:
3607
3622
// cannot analyse objects if we don't understand their aliasing.
3608
3623
LLVM_DEBUG (dbgs () << " can't analyze may or partial alias\n " );
3609
- return std::make_unique<Dependence>(Src, Dst);
3624
+ return std::make_unique<Dependence>(Src, Dst,
3625
+ SCEVUnionPredicate (Assume, *SE));
3610
3626
case AliasResult::NoAlias:
3611
3627
// If the objects noalias, they are distinct, accesses are independent.
3612
3628
LLVM_DEBUG (dbgs () << " no alias\n " );
@@ -3615,30 +3631,75 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst) {
3615
3631
break ; // The underlying objects alias; test accesses for dependence.
3616
3632
}
3617
3633
3618
- // establish loop nesting levels
3619
- establishNestingLevels (Src, Dst);
3620
- LLVM_DEBUG (dbgs () << " common nesting levels = " << CommonLevels << " \n " );
3621
- LLVM_DEBUG (dbgs () << " maximum nesting levels = " << MaxLevels << " \n " );
3622
-
3623
- FullDependence Result (Src, Dst, PossiblyLoopIndependent, CommonLevels);
3624
- ++TotalArrayPairs;
3634
+ if (DstLoc.Size != SrcLoc.Size || !DstLoc.Size .isPrecise () ||
3635
+ !SrcLoc.Size .isPrecise ()) {
3636
+ // The dependence test gets confused if the size of the memory accesses
3637
+ // differ.
3638
+ LLVM_DEBUG (dbgs () << " can't analyze must alias with different sizes\n " );
3639
+ return std::make_unique<Dependence>(Src, Dst,
3640
+ SCEVUnionPredicate (Assume, *SE));
3641
+ }
3625
3642
3626
- unsigned Pairs = 1 ;
3627
- SmallVector<Subscript, 2 > Pair (Pairs );
3643
+ Value *SrcPtr = getLoadStorePointerOperand (Src) ;
3644
+ Value *DstPtr = getLoadStorePointerOperand (Dst );
3628
3645
const SCEV *SrcSCEV = SE->getSCEV (SrcPtr);
3629
3646
const SCEV *DstSCEV = SE->getSCEV (DstPtr);
3630
3647
LLVM_DEBUG (dbgs () << " SrcSCEV = " << *SrcSCEV << " \n " );
3631
3648
LLVM_DEBUG (dbgs () << " DstSCEV = " << *DstSCEV << " \n " );
3632
- if (SE->getPointerBase (SrcSCEV) != SE->getPointerBase (DstSCEV)) {
3649
+ const SCEV *SrcBase = SE->getPointerBase (SrcSCEV);
3650
+ const SCEV *DstBase = SE->getPointerBase (DstSCEV);
3651
+ if (SrcBase != DstBase) {
3633
3652
// If two pointers have different bases, trying to analyze indexes won't
3634
3653
// work; we can't compare them to each other. This can happen, for example,
3635
3654
// if one is produced by an LCSSA PHI node.
3636
3655
//
3637
3656
// We check this upfront so we don't crash in cases where getMinusSCEV()
3638
3657
// returns a SCEVCouldNotCompute.
3639
3658
LLVM_DEBUG (dbgs () << " can't analyze SCEV with different pointer base\n " );
3640
- return std::make_unique<Dependence>(Src, Dst);
3659
+ return std::make_unique<Dependence>(Src, Dst,
3660
+ SCEVUnionPredicate (Assume, *SE));
3661
+ }
3662
+
3663
+ uint64_t EltSize = SrcLoc.Size .toRaw ();
3664
+ const SCEV *SrcEv = SE->getMinusSCEV (SrcSCEV, SrcBase);
3665
+ const SCEV *DstEv = SE->getMinusSCEV (DstSCEV, DstBase);
3666
+
3667
+ if (Src != Dst) {
3668
+ // Check that memory access offsets are multiples of element sizes.
3669
+ if (!SE->isKnownMultipleOf (SrcEv, EltSize, Assume) ||
3670
+ !SE->isKnownMultipleOf (DstEv, EltSize, Assume)) {
3671
+ LLVM_DEBUG (dbgs () << " can't analyze SCEV with different offsets\n " );
3672
+ return std::make_unique<Dependence>(Src, Dst,
3673
+ SCEVUnionPredicate (Assume, *SE));
3674
+ }
3675
+ }
3676
+
3677
+ if (!Assume.empty ()) {
3678
+ if (!UnderRuntimeAssumptions)
3679
+ return std::make_unique<Dependence>(Src, Dst,
3680
+ SCEVUnionPredicate (Assume, *SE));
3681
+ // Add non-redundant assumptions.
3682
+ unsigned N = Assumptions.size ();
3683
+ for (const SCEVPredicate *P : Assume) {
3684
+ bool Implied = false ;
3685
+ for (unsigned I = 0 ; I != N && !Implied; I++)
3686
+ if (Assumptions[I]->implies (P, *SE))
3687
+ Implied = true ;
3688
+ if (!Implied)
3689
+ Assumptions.push_back (P);
3690
+ }
3641
3691
}
3692
+
3693
+ establishNestingLevels (Src, Dst);
3694
+ LLVM_DEBUG (dbgs () << " common nesting levels = " << CommonLevels << " \n " );
3695
+ LLVM_DEBUG (dbgs () << " maximum nesting levels = " << MaxLevels << " \n " );
3696
+
3697
+ FullDependence Result (Src, Dst, SCEVUnionPredicate (Assume, *SE),
3698
+ PossiblyLoopIndependent, CommonLevels);
3699
+ ++TotalArrayPairs;
3700
+
3701
+ unsigned Pairs = 1 ;
3702
+ SmallVector<Subscript, 2 > Pair (Pairs);
3642
3703
Pair[0 ].Src = SrcSCEV;
3643
3704
Pair[0 ].Dst = DstSCEV;
3644
3705
@@ -4032,7 +4093,7 @@ const SCEV *DependenceInfo::getSplitIteration(const Dependence &Dep,
4032
4093
// establish loop nesting levels
4033
4094
establishNestingLevels (Src, Dst);
4034
4095
4035
- FullDependence Result (Src, Dst, false , CommonLevels);
4096
+ FullDependence Result (Src, Dst, Dep. Assumptions , false , CommonLevels);
4036
4097
4037
4098
unsigned Pairs = 1 ;
4038
4099
SmallVector<Subscript, 2 > Pair (Pairs);
0 commit comments