void removeInstruction(Instruction *I);
};
-/// Reduced version of MemoryLocation that only stores a pointer and size.
-/// Used for caching AATags independent BasicAA results.
+/// Cache key for BasicAA results. It only includes the pointer and size from
+/// MemoryLocation, as BasicAA is AATags independent. Additionally, it includes
+/// the value of MayBeCrossIteration, which may affect BasicAA results.
struct AACacheLoc {
- const Value *Ptr;
+ using PtrTy = PointerIntPair<const Value *, 1, bool>;
+ PtrTy Ptr;
LocationSize Size;
+
+ AACacheLoc(PtrTy Ptr, LocationSize Size) : Ptr(Ptr), Size(Size) {}
+ AACacheLoc(const Value *Ptr, LocationSize Size, bool MayBeCrossIteration)
+ : Ptr(Ptr, MayBeCrossIteration), Size(Size) {}
};
template <> struct DenseMapInfo<AACacheLoc> {
static inline AACacheLoc getEmptyKey() {
- return {DenseMapInfo<const Value *>::getEmptyKey(),
+ return {DenseMapInfo<AACacheLoc::PtrTy>::getEmptyKey(),
DenseMapInfo<LocationSize>::getEmptyKey()};
}
static inline AACacheLoc getTombstoneKey() {
- return {DenseMapInfo<const Value *>::getTombstoneKey(),
+ return {DenseMapInfo<AACacheLoc::PtrTy>::getTombstoneKey(),
DenseMapInfo<LocationSize>::getTombstoneKey()};
}
static unsigned getHashValue(const AACacheLoc &Val) {
- return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
+ return DenseMapInfo<AACacheLoc::PtrTy>::getHashValue(Val.Ptr) ^
DenseMapInfo<LocationSize>::getHashValue(Val.Size);
}
static bool isEqual(const AACacheLoc &LHS, const AACacheLoc &RHS) {
SmallVector<AAQueryInfo::LocPair, 4> AssumptionBasedResults;
AAQueryInfo(AAResults &AAR, CaptureInfo *CI) : AAR(AAR), CI(CI) {}
-
- /// Create a new AAQueryInfo based on this one, but with the cache cleared.
- /// This is used for recursive queries across phis, where cache results may
- /// not be valid.
- AAQueryInfo withEmptyCache() {
- AAQueryInfo NewAAQI(AAR, CI);
- NewAAQI.Depth = Depth;
- return NewAAQI;
- }
};
/// AAQueryInfo that uses SimpleCaptureInfo.
// different loop iterations.
SaveAndRestore<bool> SavedMayBeCrossIteration(MayBeCrossIteration, true);
- // If we enabled the MayBeCrossIteration flag, alias analysis results that
- // have been cached earlier may no longer be valid. Perform recursive queries
- // with a new AAQueryInfo.
- AAQueryInfo NewAAQI = AAQI.withEmptyCache();
- AAQueryInfo *UseAAQI = !SavedMayBeCrossIteration.get() ? &NewAAQI : &AAQI;
-
AliasResult Alias = AAQI.AAR.alias(MemoryLocation(V1Srcs[0], PNSize),
- MemoryLocation(V2, V2Size), *UseAAQI);
+ MemoryLocation(V2, V2Size), AAQI);
// Early exit if the check of the first PHI source against V2 is MayAlias.
// Other results are not possible.
Value *V = V1Srcs[i];
AliasResult ThisAlias = AAQI.AAR.alias(
- MemoryLocation(V, PNSize), MemoryLocation(V2, V2Size), *UseAAQI);
+ MemoryLocation(V, PNSize), MemoryLocation(V2, V2Size), AAQI);
Alias = MergeAliasResults(ThisAlias, Alias);
if (Alias == AliasResult::MayAlias)
break;
return AliasResult::MayAlias;
// Check the cache before climbing up use-def chains. This also terminates
- // otherwise infinitely recursive queries.
- AAQueryInfo::LocPair Locs({V1, V1Size}, {V2, V2Size});
+ // otherwise infinitely recursive queries. Include MayBeCrossIteration in the
+ // cache key, because some cases where MayBeCrossIteration==false returns
+ // MustAlias or NoAlias may become MayAlias under MayBeCrossIteration==true.
+ AAQueryInfo::LocPair Locs({V1, V1Size, MayBeCrossIteration},
+ {V2, V2Size, MayBeCrossIteration});
const bool Swapped = V1 > V2;
if (Swapped)
std::swap(Locs.first, Locs.second);