Skip to content

Commit

Permalink
Merged main:0b84afa5fcb4 into amd-gfx:1a56045b754d
Browse files Browse the repository at this point in the history
Local branch amd-gfx 1a56045 Merged main:3809f4ebabde into amd-gfx:a0d6dcabb5f7
Remote branch main 0b84afa Reapply [BasicAA] Handle recursive queries more efficiently
  • Loading branch information
Sw authored and Sw committed Jan 17, 2021
2 parents 1a56045 + 0b84afa commit 81b8a3d
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 87 deletions.
8 changes: 8 additions & 0 deletions llvm/include/llvm/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ class AAQueryInfo {
using IsCapturedCacheT = SmallDenseMap<const Value *, bool, 8>;
IsCapturedCacheT IsCapturedCache;

/// How many active NoAlias assumption uses there are.
int NumAssumptionUses = 0;

/// Location pairs for which an assumption based result is currently stored.
/// Used to remove all potentially incorrect results from the cache if an
/// assumption is disproven.
SmallVector<AAQueryInfo::LocPair, 4> AssumptionBasedResults;

AAQueryInfo() : AliasCache(), IsCapturedCache() {}
};

Expand Down
15 changes: 3 additions & 12 deletions llvm/include/llvm/Analysis/BasicAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,6 @@ class BasicAAResult : public AAResultBase<BasicAAResult> {
/// Tracks instructions visited by pointsToConstantMemory.
SmallPtrSet<const Value *, 16> Visited;

/// How many active NoAlias assumption uses there are.
int NumAssumptionUses = 0;

/// Location pairs for which an assumption based result is currently stored.
/// Used to remove all potentially incorrect results from the cache if an
/// assumption is disproven.
SmallVector<AAQueryInfo::LocPair, 4> AssumptionBasedResults;

static const Value *
GetLinearExpression(const Value *V, APInt &Scale, APInt &Offset,
unsigned &ZExtBits, unsigned &SExtBits,
Expand Down Expand Up @@ -240,18 +232,17 @@ class BasicAAResult : public AAResultBase<BasicAAResult> {
AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize,
const AAMDNodes &PNAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
const Value *UnderV2, AAQueryInfo &AAQI);
AAQueryInfo &AAQI);

AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize,
const AAMDNodes &SIAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
const Value *UnderV2, AAQueryInfo &AAQI);
AAQueryInfo &AAQI);

AliasResult aliasCheck(const Value *V1, LocationSize V1Size,
const AAMDNodes &V1AATag, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AATag,
AAQueryInfo &AAQI, const Value *O1 = nullptr,
const Value *O2 = nullptr);
AAQueryInfo &AAQI);

AliasResult aliasCheckRecursive(const Value *V1, LocationSize V1Size,
const AAMDNodes &V1AATag, const Value *V2,
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Config/llvm-config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

/* Indicate that this is LLVM compiled from the amd-gfx branch. */
#define LLVM_HAVE_BRANCH_AMD_GFX
#define LLVM_MAIN_REVISION 377230
#define LLVM_MAIN_REVISION 377232

/* Define if LLVM_ENABLE_DUMP is enabled */
#cmakedefine LLVM_ENABLE_DUMP
Expand Down
125 changes: 53 additions & 72 deletions llvm/lib/Analysis/BasicAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,26 +798,8 @@ AliasResult BasicAAResult::alias(const MemoryLocation &LocA,
AAQueryInfo &AAQI) {
assert(notDifferentParent(LocA.Ptr, LocB.Ptr) &&
"BasicAliasAnalysis doesn't support interprocedural queries.");

// If we have a directly cached entry for these locations, we have recursed
// through this once, so just return the cached results. Notably, when this
// happens, we don't clear the cache.
AAQueryInfo::LocPair Locs(LocA, LocB);
if (Locs.first.Ptr > Locs.second.Ptr)
std::swap(Locs.first, Locs.second);
auto CacheIt = AAQI.AliasCache.find(Locs);
if (CacheIt != AAQI.AliasCache.end()) {
// This code exists to skip a second BasicAA call while recursing into
// BestAA. Don't make use of assumptions here.
const auto &Entry = CacheIt->second;
return Entry.isDefinitive() ? Entry.Result : MayAlias;
}

AliasResult Alias = aliasCheck(LocA.Ptr, LocA.Size, LocA.AATags, LocB.Ptr,
LocB.Size, LocB.AATags, AAQI);

assert(VisitedPhiBBs.empty());
return Alias;
return aliasCheck(LocA.Ptr, LocA.Size, LocA.AATags, LocB.Ptr, LocB.Size,
LocB.AATags, AAQI);
}

/// Checks to see if the specified callsite can clobber the specified memory
Expand Down Expand Up @@ -1130,16 +1112,17 @@ AliasResult BasicAAResult::aliasGEP(
if (isGEPBaseAtNegativeOffset(GEP2, DecompGEP2, DecompGEP1, V1Size))
return NoAlias;
// Do the base pointers alias?
AliasResult BaseAlias = aliasCheck(
UnderlyingV1, LocationSize::beforeOrAfterPointer(), AAMDNodes(),
UnderlyingV2, LocationSize::beforeOrAfterPointer(), AAMDNodes(), AAQI);
AliasResult BaseAlias = getBestAAResults().alias(
MemoryLocation::getBeforeOrAfter(UnderlyingV1),
MemoryLocation::getBeforeOrAfter(UnderlyingV2), AAQI);

// For GEPs with identical offsets, we can preserve the size and AAInfo
// when performing the alias check on the underlying objects.
if (BaseAlias == MayAlias && DecompGEP1.Offset == DecompGEP2.Offset &&
DecompGEP1.VarIndices == DecompGEP2.VarIndices) {
AliasResult PreciseBaseAlias = aliasCheck(
UnderlyingV1, V1Size, V1AAInfo, UnderlyingV2, V2Size, V2AAInfo, AAQI);
AliasResult PreciseBaseAlias = getBestAAResults().alias(
MemoryLocation(UnderlyingV1, V1Size, V1AAInfo),
MemoryLocation(UnderlyingV2, V2Size, V2AAInfo), AAQI);
if (PreciseBaseAlias == NoAlias)
return NoAlias;
}
Expand All @@ -1165,9 +1148,9 @@ AliasResult BasicAAResult::aliasGEP(
if (!V1Size.hasValue() && !V2Size.hasValue())
return MayAlias;

AliasResult R = aliasCheck(
UnderlyingV1, LocationSize::beforeOrAfterPointer(), AAMDNodes(),
V2, V2Size, V2AAInfo, AAQI, nullptr, UnderlyingV2);
AliasResult R = getBestAAResults().alias(
MemoryLocation::getBeforeOrAfter(UnderlyingV1),
MemoryLocation(V2, V2Size, V2AAInfo), AAQI);
if (R != MustAlias) {
// If V2 may alias GEP base pointer, conservatively returns MayAlias.
// If V2 is known not to alias GEP base pointer, then the two values
Expand Down Expand Up @@ -1340,31 +1323,33 @@ AliasResult
BasicAAResult::aliasSelect(const SelectInst *SI, LocationSize SISize,
const AAMDNodes &SIAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
const Value *UnderV2, AAQueryInfo &AAQI) {
AAQueryInfo &AAQI) {
// If the values are Selects with the same condition, we can do a more precise
// check: just check for aliases between the values on corresponding arms.
if (const SelectInst *SI2 = dyn_cast<SelectInst>(V2))
if (SI->getCondition() == SI2->getCondition()) {
AliasResult Alias =
aliasCheck(SI->getTrueValue(), SISize, SIAAInfo, SI2->getTrueValue(),
V2Size, V2AAInfo, AAQI);
AliasResult Alias = getBestAAResults().alias(
MemoryLocation(SI->getTrueValue(), SISize, SIAAInfo),
MemoryLocation(SI2->getTrueValue(), V2Size, V2AAInfo), AAQI);
if (Alias == MayAlias)
return MayAlias;
AliasResult ThisAlias =
aliasCheck(SI->getFalseValue(), SISize, SIAAInfo,
SI2->getFalseValue(), V2Size, V2AAInfo, AAQI);
AliasResult ThisAlias = getBestAAResults().alias(
MemoryLocation(SI->getFalseValue(), SISize, SIAAInfo),
MemoryLocation(SI2->getFalseValue(), V2Size, V2AAInfo), AAQI);
return MergeAliasResults(ThisAlias, Alias);
}

// If both arms of the Select node NoAlias or MustAlias V2, then returns
// NoAlias / MustAlias. Otherwise, returns MayAlias.
AliasResult Alias = aliasCheck(V2, V2Size, V2AAInfo, SI->getTrueValue(),
SISize, SIAAInfo, AAQI, UnderV2);
AliasResult Alias = getBestAAResults().alias(
MemoryLocation(V2, V2Size, V2AAInfo),
MemoryLocation(SI->getTrueValue(), SISize, SIAAInfo), AAQI);
if (Alias == MayAlias)
return MayAlias;

AliasResult ThisAlias = aliasCheck(V2, V2Size, V2AAInfo, SI->getFalseValue(),
SISize, SIAAInfo, AAQI, UnderV2);
AliasResult ThisAlias = getBestAAResults().alias(
MemoryLocation(V2, V2Size, V2AAInfo),
MemoryLocation(SI->getFalseValue(), SISize, SIAAInfo), AAQI);
return MergeAliasResults(ThisAlias, Alias);
}

Expand All @@ -1374,18 +1359,20 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
const AAMDNodes &PNAAInfo, const Value *V2,
LocationSize V2Size,
const AAMDNodes &V2AAInfo,
const Value *UnderV2, AAQueryInfo &AAQI) {
AAQueryInfo &AAQI) {
// If the values are PHIs in the same block, we can do a more precise
// as well as efficient check: just check for aliases between the values
// on corresponding edges.
if (const PHINode *PN2 = dyn_cast<PHINode>(V2))
if (PN2->getParent() == PN->getParent()) {
Optional<AliasResult> Alias;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
AliasResult ThisAlias =
aliasCheck(PN->getIncomingValue(i), PNSize, PNAAInfo,
PN2->getIncomingValueForBlock(PN->getIncomingBlock(i)),
V2Size, V2AAInfo, AAQI);
AliasResult ThisAlias = getBestAAResults().alias(
MemoryLocation(PN->getIncomingValue(i), PNSize, PNAAInfo),
MemoryLocation(
PN2->getIncomingValueForBlock(PN->getIncomingBlock(i)), V2Size,
V2AAInfo),
AAQI);
if (Alias)
*Alias = MergeAliasResults(*Alias, ThisAlias);
else
Expand Down Expand Up @@ -1473,8 +1460,9 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
AAQueryInfo NewAAQI;
AAQueryInfo *UseAAQI = BlockInserted ? &NewAAQI : &AAQI;

AliasResult Alias = aliasCheck(V2, V2Size, V2AAInfo, V1Srcs[0], PNSize,
PNAAInfo, *UseAAQI, UnderV2);
AliasResult Alias = getBestAAResults().alias(
MemoryLocation(V2, V2Size, V2AAInfo),
MemoryLocation(V1Srcs[0], PNSize, PNAAInfo), *UseAAQI);

// Early exit if the check of the first PHI source against V2 is MayAlias.
// Other results are not possible.
Expand All @@ -1490,8 +1478,9 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
for (unsigned i = 1, e = V1Srcs.size(); i != e; ++i) {
Value *V = V1Srcs[i];

AliasResult ThisAlias = aliasCheck(V2, V2Size, V2AAInfo, V, PNSize,
PNAAInfo, *UseAAQI, UnderV2);
AliasResult ThisAlias = getBestAAResults().alias(
MemoryLocation(V2, V2Size, V2AAInfo),
MemoryLocation(V, PNSize, PNAAInfo), *UseAAQI);
Alias = MergeAliasResults(ThisAlias, Alias);
if (Alias == MayAlias)
break;
Expand All @@ -1506,8 +1495,7 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
const AAMDNodes &V1AAInfo,
const Value *V2, LocationSize V2Size,
const AAMDNodes &V2AAInfo,
AAQueryInfo &AAQI, const Value *O1,
const Value *O2) {
AAQueryInfo &AAQI) {
// If either of the memory references is empty, it doesn't matter what the
// pointer values are.
if (V1Size.isZero() || V2Size.isZero())
Expand Down Expand Up @@ -1535,11 +1523,8 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
return NoAlias; // Scalars cannot alias each other

// Figure out what objects these things are pointing to if we can.
if (O1 == nullptr)
O1 = getUnderlyingObject(V1, MaxLookupSearchDepth);

if (O2 == nullptr)
O2 = getUnderlyingObject(V2, MaxLookupSearchDepth);
const Value *O1 = getUnderlyingObject(V1, MaxLookupSearchDepth);
const Value *O2 = getUnderlyingObject(V2, MaxLookupSearchDepth);

// Null values in the default address space don't point to any object, so they
// don't alias any other pointer.
Expand Down Expand Up @@ -1619,13 +1604,13 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
if (!Entry.isDefinitive()) {
// Remember that we used an assumption.
++Entry.NumAssumptionUses;
++NumAssumptionUses;
++AAQI.NumAssumptionUses;
}
return Entry.Result;
}

int OrigNumAssumptionUses = NumAssumptionUses;
unsigned OrigNumAssumptionBasedResults = AssumptionBasedResults.size();
int OrigNumAssumptionUses = AAQI.NumAssumptionUses;
unsigned OrigNumAssumptionBasedResults = AAQI.AssumptionBasedResults.size();
AliasResult Result = aliasCheckRecursive(V1, V1Size, V1AAInfo, V2, V2Size,
V2AAInfo, AAQI, O1, O2);

Expand All @@ -1639,21 +1624,21 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
Result = MayAlias;

// This is a definitive result now, when considered as a root query.
NumAssumptionUses -= Entry.NumAssumptionUses;
AAQI.NumAssumptionUses -= Entry.NumAssumptionUses;
Entry.Result = Result;
Entry.NumAssumptionUses = -1;

// If the assumption has been disproven, remove any results that may have
// been based on this assumption. Do this after the Entry updates above to
// avoid iterator invalidation.
if (AssumptionDisproven)
while (AssumptionBasedResults.size() > OrigNumAssumptionBasedResults)
AAQI.AliasCache.erase(AssumptionBasedResults.pop_back_val());
while (AAQI.AssumptionBasedResults.size() > OrigNumAssumptionBasedResults)
AAQI.AliasCache.erase(AAQI.AssumptionBasedResults.pop_back_val());

// The result may still be based on assumptions higher up in the chain.
// Remember it, so it can be purged from the cache later.
if (OrigNumAssumptionUses != NumAssumptionUses && Result != MayAlias)
AssumptionBasedResults.push_back(Locs);
if (OrigNumAssumptionUses != AAQI.NumAssumptionUses && Result != MayAlias)
AAQI.AssumptionBasedResults.push_back(Locs);
return Result;
}

Expand All @@ -1675,24 +1660,24 @@ AliasResult BasicAAResult::aliasCheckRecursive(

if (const PHINode *PN = dyn_cast<PHINode>(V1)) {
AliasResult Result =
aliasPHI(PN, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O2, AAQI);
aliasPHI(PN, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, AAQI);
if (Result != MayAlias)
return Result;
} else if (const PHINode *PN = dyn_cast<PHINode>(V2)) {
AliasResult Result =
aliasPHI(PN, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, O1, AAQI);
aliasPHI(PN, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, AAQI);
if (Result != MayAlias)
return Result;
}

if (const SelectInst *S1 = dyn_cast<SelectInst>(V1)) {
AliasResult Result =
aliasSelect(S1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O2, AAQI);
aliasSelect(S1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, AAQI);
if (Result != MayAlias)
return Result;
} else if (const SelectInst *S2 = dyn_cast<SelectInst>(V2)) {
AliasResult Result =
aliasSelect(S2, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, O1, AAQI);
aliasSelect(S2, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, AAQI);
if (Result != MayAlias)
return Result;
}
Expand All @@ -1707,11 +1692,7 @@ AliasResult BasicAAResult::aliasCheckRecursive(
return PartialAlias;
}

// Recurse back into the best AA results we have, potentially with refined
// memory locations. We have already ensured that BasicAA has a MayAlias
// cache result for these, so any recursion back into BasicAA won't loop.
return getBestAAResults().alias(MemoryLocation(V1, V1Size, V1AAInfo),
MemoryLocation(V2, V2Size, V2AAInfo), AAQI);
return MayAlias;
}

/// Check whether two Values can be considered equivalent.
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Analysis/GlobalsModRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -827,8 +827,10 @@ AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
// Get the base object these pointers point to.
const Value *UV1 = getUnderlyingObject(LocA.Ptr);
const Value *UV2 = getUnderlyingObject(LocB.Ptr);
const Value *UV1 =
getUnderlyingObject(LocA.Ptr->stripPointerCastsAndInvariantGroups());
const Value *UV2 =
getUnderlyingObject(LocB.Ptr->stripPointerCastsAndInvariantGroups());

// If either of the underlying values is a global, they may be non-addr-taken
// globals, which we can answer queries about.
Expand Down
Loading

0 comments on commit 81b8a3d

Please sign in to comment.