return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode);
}
+ // CtxI can be nullptr, in which case the query is whether or not the aliasing
+ // relationship holds through the entire function.
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI = nullptr);
+
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool OrLocal = false);
ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
/// each other. This is the interface that must be implemented by specific
/// alias analysis implementations.
virtual AliasResult alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB, AAQueryInfo &AAQI) = 0;
+ const MemoryLocation &LocB, AAQueryInfo &AAQI,
+ const Instruction *CtxI) = 0;
/// @}
//===--------------------------------------------------------------------===//
~Model() override = default;
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI) override {
- return Result.alias(LocA, LocB, AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI) override {
+ return Result.alias(LocA, LocB, AAQI, CtxI);
}
ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
public:
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI, const Instruction *I) {
return AliasResult::MayAlias;
}
FunctionAnalysisManager::Invalidator &Inv);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
AAQueryInfo &AAQI);
// Implement the AliasAnalysis API
//
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI);
using AAResultBase::getModRefInfo;
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
}
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI);
ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool IgnoreLocals);
SCEVAAResult(SCEVAAResult &&Arg) : AAResultBase(std::move(Arg)), SE(Arg.SE) {}
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI);
bool invalidate(Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv);
}
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
AAQueryInfo &AAQI);
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
}
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI);
ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool IgnoreLocals);
+
MemoryEffects getMemoryEffects(const CallBase *Call, AAQueryInfo &AAQI);
MemoryEffects getMemoryEffects(const Function *F);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
AliasResult AAResults::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
SimpleAAQueryInfo AAQIP(*this);
- return alias(LocA, LocB, AAQIP);
+ return alias(LocA, LocB, AAQIP, nullptr);
}
AliasResult AAResults::alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB, AAQueryInfo &AAQI) {
+ const MemoryLocation &LocB, AAQueryInfo &AAQI,
+ const Instruction *CtxI) {
AliasResult Result = AliasResult::MayAlias;
if (EnableAATrace) {
AAQI.Depth++;
for (const auto &AA : AAs) {
- Result = AA->alias(LocA, LocB, AAQI);
+ Result = AA->alias(LocA, LocB, AAQI, CtxI);
if (Result != AliasResult::MayAlias)
break;
}
continue;
unsigned ArgIdx = I.index();
MemoryLocation ArgLoc = MemoryLocation::getForArgument(Call, ArgIdx, TLI);
- AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI);
+ AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI, Call);
if (ArgAlias != AliasResult::NoAlias)
AllArgsMask |= getArgModRefInfo(Call, ArgIdx);
}
// If the load address doesn't alias the given address, it doesn't read
// or write the specified memory.
if (Loc.Ptr) {
- AliasResult AR = alias(MemoryLocation::get(L), Loc, AAQI);
+ AliasResult AR = alias(MemoryLocation::get(L), Loc, AAQI, L);
if (AR == AliasResult::NoAlias)
return ModRefInfo::NoModRef;
}
return ModRefInfo::ModRef;
if (Loc.Ptr) {
- AliasResult AR = alias(MemoryLocation::get(S), Loc, AAQI);
+ AliasResult AR = alias(MemoryLocation::get(S), Loc, AAQI, S);
// If the store address cannot alias the pointer in question, then the
// specified memory cannot be modified by the store.
if (AR == AliasResult::NoAlias)
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
if (Loc.Ptr) {
- AliasResult AR = alias(MemoryLocation::get(V), Loc, AAQI);
+ AliasResult AR = alias(MemoryLocation::get(V), Loc, AAQI, V);
// If the va_arg address cannot alias the pointer in question, then the
// specified memory cannot be accessed by the va_arg.
if (AR == AliasResult::NoAlias)
return ModRefInfo::ModRef;
if (Loc.Ptr) {
- AliasResult AR = alias(MemoryLocation::get(CX), Loc, AAQI);
+ AliasResult AR = alias(MemoryLocation::get(CX), Loc, AAQI, CX);
// If the cmpxchg address does not alias the location, it does not access
// it.
if (AR == AliasResult::NoAlias)
return ModRefInfo::ModRef;
if (Loc.Ptr) {
- AliasResult AR = alias(MemoryLocation::get(RMW), Loc, AAQI);
+ AliasResult AR = alias(MemoryLocation::get(RMW), Loc, AAQI, RMW);
// If the atomicrmw address does not alias the location, it does not access
// it.
if (AR == AliasResult::NoAlias)
!Call->isByValArgument(ArgNo)))
continue;
- AliasResult AR = alias(
- MemoryLocation::getBeforeOrAfter(*CI),
- MemoryLocation::getBeforeOrAfter(Object), AAQI);
+ AliasResult AR =
+ alias(MemoryLocation::getBeforeOrAfter(*CI),
+ MemoryLocation::getBeforeOrAfter(Object), AAQI, Call);
// If this is a no-capture pointer argument, see if we can tell that it
// is impossible to alias the pointer we're checking. If not, we have to
// assume that the call could touch the pointer, even though it doesn't
#endif
AliasResult BasicAAResult::alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB,
- AAQueryInfo &AAQI) {
+ const MemoryLocation &LocB, AAQueryInfo &AAQI,
+ const Instruction *) {
assert(notDifferentParent(LocA.Ptr, LocB.Ptr) &&
"BasicAliasAnalysis doesn't support interprocedural queries.");
return aliasCheck(LocA.Ptr, LocA.Size, LocB.Ptr, LocB.Size, AAQI);
/// address of the global isn't taken.
AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI, const Instruction *) {
// Get the base object these pointers point to.
const Value *UV1 =
getUnderlyingObject(LocA.Ptr->stripPointerCastsForAliasAnalysis());
if ((GV1 || GV2) && GV1 != GV2)
return AliasResult::NoAlias;
- return AAResultBase::alias(LocA, LocB, AAQI);
+ return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
}
ModRefInfo GlobalsAAResult::getModRefInfoForArgument(const CallBase *Call,
// Try ::alias to see if all objects are known not to alias GV.
!all_of(Objects, [&](const Value *V) {
return this->alias(MemoryLocation::getBeforeOrAfter(V),
- MemoryLocation::getBeforeOrAfter(GV),
- AAQI) == AliasResult::NoAlias;
+ MemoryLocation::getBeforeOrAfter(GV), AAQI,
+ nullptr) == AliasResult::NoAlias;
}))
return ConservativeResult;
AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI, const Instruction *) {
if (!EnableARCOpts)
- return AAResultBase::alias(LocA, LocB, AAQI);
+ return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
// First, strip off no-ops, including ObjC-specific no-ops, and try making a
// precise alias query.
const Value *SA = GetRCIdentityRoot(LocA.Ptr);
const Value *SB = GetRCIdentityRoot(LocB.Ptr);
- AliasResult Result =
- AAResultBase::alias(MemoryLocation(SA, LocA.Size, LocA.AATags),
- MemoryLocation(SB, LocB.Size, LocB.AATags), AAQI);
+ AliasResult Result = AAResultBase::alias(
+ MemoryLocation(SA, LocA.Size, LocA.AATags),
+ MemoryLocation(SB, LocB.Size, LocB.AATags), AAQI, nullptr);
if (Result != AliasResult::MayAlias)
return Result;
const Value *UB = GetUnderlyingObjCPtr(SB);
if (UA != SA || UB != SB) {
Result = AAResultBase::alias(MemoryLocation::getBeforeOrAfter(UA),
- MemoryLocation::getBeforeOrAfter(UB), AAQI);
+ MemoryLocation::getBeforeOrAfter(UB), AAQI,
+ nullptr);
// We can't use MustAlias or PartialAlias results here because
// GetUnderlyingObjCPtr may return an offsetted pointer value.
if (Result == AliasResult::NoAlias)
}
AliasResult SCEVAAResult::alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB, AAQueryInfo &AAQI) {
+ const MemoryLocation &LocB, AAQueryInfo &AAQI,
+ const Instruction *) {
// If either of the memory references is empty, it doesn't matter what the
// pointer values are. This allows the code below to ignore this special
// case.
BO ? LocationSize::beforeOrAfterPointer()
: LocB.Size,
BO ? AAMDNodes() : LocB.AATags),
- AAQI) == AliasResult::NoAlias)
+ AAQI, nullptr) == AliasResult::NoAlias)
return AliasResult::NoAlias;
// Forward the query to the next analysis.
- return AAResultBase::alias(LocA, LocB, AAQI);
+ return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
}
/// Given an expression, try to find a base value.
AliasResult ScopedNoAliasAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI,
+ const Instruction *) {
if (!EnableScopedNoAlias)
- return AAResultBase::alias(LocA, LocB, AAQI);
+ return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
// Get the attached MDNodes.
const MDNode *AScopes = LocA.AATags.Scope, *BScopes = LocB.AATags.Scope;
return AliasResult::NoAlias;
// If they may alias, chain to the next AliasAnalysis.
- return AAResultBase::alias(LocA, LocB, AAQI);
+ return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
}
ModRefInfo ScopedNoAliasAAResult::getModRefInfo(const CallBase *Call,
AliasResult TypeBasedAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI, const Instruction *) {
if (!EnableTBAA)
- return AAResultBase::alias(LocA, LocB, AAQI);
+ return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
// If accesses may alias, chain to the next AliasAnalysis.
if (Aliases(LocA.AATags.TBAA, LocB.AATags.TBAA))
- return AAResultBase::alias(LocA, LocB, AAQI);
+ return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
// Otherwise return a definitive result.
return AliasResult::NoAlias;
}
AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB,
- AAQueryInfo &AAQI) {
+ const MemoryLocation &LocB, AAQueryInfo &AAQI,
+ const Instruction *) {
unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
}
// Forward the query to the next alias analysis.
- return AAResultBase::alias(LocA, LocB, AAQI);
+ return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
}
ModRefInfo AMDGPUAAResult::getModRefInfoMask(const MemoryLocation &Loc,
}
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI, const Instruction *CtxI);
ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool IgnoreLocals);
};
bool invalidate(Function &, const PreservedAnalyses &) { return false; }
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI, const Instruction *) {
CB();
return AliasResult::MayAlias;
}
AAQueryInfo &AAQI = AllAnalyses.AAQI;
ASSERT_EQ(
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::precise(4)),
- MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
+ MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI,
+ nullptr),
AliasResult::NoAlias);
ASSERT_EQ(
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::upperBound(4)),
- MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
+ MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI,
+ nullptr),
AliasResult::MayAlias);
}
ASSERT_EQ(BasicAA.alias(
MemoryLocation(I8, LocationSize::precise(2)),
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
- AAQI),
+ AAQI, nullptr),
AliasResult::PartialAlias);
ASSERT_EQ(BasicAA.alias(
MemoryLocation(I8, LocationSize::upperBound(2)),
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
- AAQI),
+ AAQI, nullptr),
AliasResult::MayAlias);
}
auto &AllAnalyses = setupAnalyses();
BasicAAResult &BasicAA = AllAnalyses.BAA;
AAQueryInfo &AAQI = AllAnalyses.AAQI;
- AliasResult AR =
- BasicAA.alias(MemoryLocation(Ptr, LocationSize::precise(2)),
- MemoryLocation(Phi, LocationSize::precise(1)), AAQI);
+ AliasResult AR = BasicAA.alias(MemoryLocation(Ptr, LocationSize::precise(2)),
+ MemoryLocation(Phi, LocationSize::precise(1)),
+ AAQI, nullptr);
ASSERT_EQ(AR.getOffset(), 1);
}
auto &AllAnalyses = setupAnalyses();
BasicAAResult &BasicAA = AllAnalyses.BAA;
AAQueryInfo &AAQI = AllAnalyses.AAQI;
- AliasResult AR =
- BasicAA.alias(MemoryLocation(Ptr, LocationSize::precise(2)),
- MemoryLocation(Select, LocationSize::precise(1)), AAQI);
+ AliasResult AR = BasicAA.alias(
+ MemoryLocation(Ptr, LocationSize::precise(2)),
+ MemoryLocation(Select, LocationSize::precise(1)), AAQI, nullptr);
ASSERT_EQ(AR.getOffset(), 1);
}