@@ -806,8 +806,12 @@ AliasResult BasicAAResult::alias(const MemoryLocation &LocA,
806
806
if (Locs.first .Ptr > Locs.second .Ptr )
807
807
std::swap (Locs.first , Locs.second );
808
808
auto CacheIt = AAQI.AliasCache .find (Locs);
809
- if (CacheIt != AAQI.AliasCache .end ())
810
- return CacheIt->second ;
809
+ if (CacheIt != AAQI.AliasCache .end ()) {
810
+ // This code exists to skip a second BasicAA call while recursing into
811
+ // BestAA. Don't make use of assumptions here.
812
+ const auto &Entry = CacheIt->second ;
813
+ return Entry.isDefinitive () ? Entry.Result : MayAlias;
814
+ }
811
815
812
816
AliasResult Alias = aliasCheck (LocA.Ptr , LocA.Size , LocA.AATags , LocB.Ptr ,
813
817
LocB.Size , LocB.AATags , AAQI);
@@ -1376,42 +1380,20 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
1376
1380
// on corresponding edges.
1377
1381
if (const PHINode *PN2 = dyn_cast<PHINode>(V2))
1378
1382
if (PN2->getParent () == PN->getParent ()) {
1379
- AAQueryInfo::LocPair Locs (MemoryLocation (PN, PNSize, PNAAInfo),
1380
- MemoryLocation (V2, V2Size, V2AAInfo));
1381
- if (PN > V2)
1382
- std::swap (Locs.first , Locs.second );
1383
- // Analyse the PHIs' inputs under the assumption that the PHIs are
1384
- // NoAlias.
1385
- // If the PHIs are May/MustAlias there must be (recursively) an input
1386
- // operand from outside the PHIs' cycle that is MayAlias/MustAlias or
1387
- // there must be an operation on the PHIs within the PHIs' value cycle
1388
- // that causes a MayAlias.
1389
- // Pretend the phis do not alias.
1390
- AliasResult Alias = NoAlias;
1391
- AliasResult OrigAliasResult;
1392
- {
1393
- // Limited lifetime iterator invalidated by the aliasCheck call below.
1394
- auto CacheIt = AAQI.AliasCache .find (Locs);
1395
- assert ((CacheIt != AAQI.AliasCache .end ()) &&
1396
- " There must exist an entry for the phi node" );
1397
- OrigAliasResult = CacheIt->second ;
1398
- CacheIt->second = NoAlias;
1399
- }
1400
-
1383
+ Optional<AliasResult> Alias;
1401
1384
for (unsigned i = 0 , e = PN->getNumIncomingValues (); i != e; ++i) {
1402
1385
AliasResult ThisAlias =
1403
1386
aliasCheck (PN->getIncomingValue (i), PNSize, PNAAInfo,
1404
1387
PN2->getIncomingValueForBlock (PN->getIncomingBlock (i)),
1405
1388
V2Size, V2AAInfo, AAQI);
1406
- Alias = MergeAliasResults (ThisAlias, Alias);
1407
- if (Alias == MayAlias)
1389
+ if (Alias)
1390
+ *Alias = MergeAliasResults (*Alias, ThisAlias);
1391
+ else
1392
+ Alias = ThisAlias;
1393
+ if (*Alias == MayAlias)
1408
1394
break ;
1409
1395
}
1410
-
1411
- // Reset if speculation failed.
1412
- if (Alias != NoAlias)
1413
- AAQI.updateResult (Locs, OrigAliasResult);
1414
- return Alias;
1396
+ return *Alias;
1415
1397
}
1416
1398
1417
1399
SmallVector<Value *, 4 > V1Srcs;
@@ -1630,64 +1612,106 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
1630
1612
MemoryLocation (V2, V2Size, V2AAInfo));
1631
1613
if (V1 > V2)
1632
1614
std::swap (Locs.first , Locs.second );
1633
- std::pair<AAQueryInfo::AliasCacheT::iterator, bool > Pair =
1634
- AAQI.AliasCache .try_emplace (Locs, MayAlias);
1635
- if (!Pair.second )
1636
- return Pair.first ->second ;
1615
+ const auto &Pair = AAQI.AliasCache .try_emplace (
1616
+ Locs, AAQueryInfo::CacheEntry{NoAlias, 0 });
1617
+ if (!Pair.second ) {
1618
+ auto &Entry = Pair.first ->second ;
1619
+ if (!Entry.isDefinitive ()) {
1620
+ // Remember that we used an assumption.
1621
+ ++Entry.NumAssumptionUses ;
1622
+ ++NumAssumptionUses;
1623
+ }
1624
+ return Entry.Result ;
1625
+ }
1637
1626
1627
+ int OrigNumAssumptionUses = NumAssumptionUses;
1628
+ unsigned OrigNumAssumptionBasedResults = AssumptionBasedResults.size ();
1629
+ AliasResult Result = aliasCheckRecursive (V1, V1Size, V1AAInfo, V2, V2Size,
1630
+ V2AAInfo, AAQI, O1, O2);
1631
+
1632
+ auto It = AAQI.AliasCache .find (Locs);
1633
+ assert (It != AAQI.AliasCache .end () && " Must be in cache" );
1634
+ auto &Entry = It->second ;
1635
+
1636
+ // Check whether a NoAlias assumption has been used, but disproven.
1637
+ bool AssumptionDisproven = Entry.NumAssumptionUses > 0 && Result != NoAlias;
1638
+ if (AssumptionDisproven)
1639
+ Result = MayAlias;
1640
+
1641
+ // This is a definitive result now, when considered as a root query.
1642
+ NumAssumptionUses -= Entry.NumAssumptionUses ;
1643
+ Entry.Result = Result;
1644
+ Entry.NumAssumptionUses = -1 ;
1645
+
1646
+ // If the assumption has been disproven, remove any results that may have
1647
+ // been based on this assumption. Do this after the Entry updates above to
1648
+ // avoid iterator invalidation.
1649
+ if (AssumptionDisproven)
1650
+ while (AssumptionBasedResults.size () > OrigNumAssumptionBasedResults)
1651
+ AAQI.AliasCache .erase (AssumptionBasedResults.pop_back_val ());
1652
+
1653
+ // The result may still be based on assumptions higher up in the chain.
1654
+ // Remember it, so it can be purged from the cache later.
1655
+ if (OrigNumAssumptionUses != NumAssumptionUses && Result != MayAlias)
1656
+ AssumptionBasedResults.push_back (Locs);
1657
+ return Result;
1658
+ }
1659
+
1660
+ AliasResult BasicAAResult::aliasCheckRecursive (
1661
+ const Value *V1, LocationSize V1Size, const AAMDNodes &V1AAInfo,
1662
+ const Value *V2, LocationSize V2Size, const AAMDNodes &V2AAInfo,
1663
+ AAQueryInfo &AAQI, const Value *O1, const Value *O2) {
1638
1664
if (const GEPOperator *GV1 = dyn_cast<GEPOperator>(V1)) {
1639
1665
AliasResult Result =
1640
1666
aliasGEP (GV1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O1, O2, AAQI);
1641
1667
if (Result != MayAlias)
1642
- return AAQI. updateResult (Locs, Result) ;
1668
+ return Result;
1643
1669
} else if (const GEPOperator *GV2 = dyn_cast<GEPOperator>(V2)) {
1644
1670
AliasResult Result =
1645
1671
aliasGEP (GV2, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, O2, O1, AAQI);
1646
1672
if (Result != MayAlias)
1647
- return AAQI. updateResult (Locs, Result) ;
1673
+ return Result;
1648
1674
}
1649
1675
1650
1676
if (const PHINode *PN = dyn_cast<PHINode>(V1)) {
1651
1677
AliasResult Result =
1652
1678
aliasPHI (PN, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O2, AAQI);
1653
1679
if (Result != MayAlias)
1654
- return AAQI. updateResult (Locs, Result) ;
1680
+ return Result;
1655
1681
} else if (const PHINode *PN = dyn_cast<PHINode>(V2)) {
1656
1682
AliasResult Result =
1657
1683
aliasPHI (PN, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, O1, AAQI);
1658
1684
if (Result != MayAlias)
1659
- return AAQI. updateResult (Locs, Result) ;
1685
+ return Result;
1660
1686
}
1661
1687
1662
1688
if (const SelectInst *S1 = dyn_cast<SelectInst>(V1)) {
1663
1689
AliasResult Result =
1664
1690
aliasSelect (S1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O2, AAQI);
1665
1691
if (Result != MayAlias)
1666
- return AAQI. updateResult (Locs, Result) ;
1692
+ return Result;
1667
1693
} else if (const SelectInst *S2 = dyn_cast<SelectInst>(V2)) {
1668
1694
AliasResult Result =
1669
1695
aliasSelect (S2, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, O1, AAQI);
1670
1696
if (Result != MayAlias)
1671
- return AAQI. updateResult (Locs, Result) ;
1697
+ return Result;
1672
1698
}
1673
1699
1674
1700
// If both pointers are pointing into the same object and one of them
1675
1701
// accesses the entire object, then the accesses must overlap in some way.
1676
- if (O1 == O2)
1702
+ if (O1 == O2) {
1703
+ bool NullIsValidLocation = NullPointerIsDefined (&F);
1677
1704
if (V1Size.isPrecise () && V2Size.isPrecise () &&
1678
1705
(isObjectSize (O1, V1Size.getValue (), DL, TLI, NullIsValidLocation) ||
1679
1706
isObjectSize (O2, V2Size.getValue (), DL, TLI, NullIsValidLocation)))
1680
- return AAQI.updateResult (Locs, PartialAlias);
1707
+ return PartialAlias;
1708
+ }
1681
1709
1682
1710
// Recurse back into the best AA results we have, potentially with refined
1683
1711
// memory locations. We have already ensured that BasicAA has a MayAlias
1684
1712
// cache result for these, so any recursion back into BasicAA won't loop.
1685
- AliasResult Result = getBestAAResults ().alias (Locs.first , Locs.second , AAQI);
1686
- if (Result != MayAlias)
1687
- return AAQI.updateResult (Locs, Result);
1688
-
1689
- // MayAlias is already in the cache.
1690
- return MayAlias;
1713
+ return getBestAAResults ().alias (MemoryLocation (V1, V1Size, V1AAInfo),
1714
+ MemoryLocation (V2, V2Size, V2AAInfo), AAQI);
1691
1715
}
1692
1716
1693
1717
// / Check whether two Values can be considered equivalent.
0 commit comments