29 changes: 14 additions & 15 deletions llvm/include/llvm/Analysis/BasicAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,18 @@ class BasicAAResult : public AAResultBase<BasicAAResult> {
bool invalidate(Function &Fn, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv);

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI);

ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
AAQueryInfo &AAQI);

ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2);
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
AAQueryInfo &AAQI);

/// Chases pointers until we find a (constant global) or not.
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal);
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool OrLocal);

/// Get the location associated with a pointer argument of a callsite.
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
Expand Down Expand Up @@ -140,13 +144,6 @@ class BasicAAResult : public AAResultBase<BasicAAResult> {
SmallVector<VariableGEPIndex, 4> VarIndices;
};

/// Track alias queries to guard against recursion.
using LocPair = std::pair<MemoryLocation, MemoryLocation>;
using AliasCacheTy = SmallDenseMap<LocPair, AliasResult, 8>;
AliasCacheTy AliasCache;
using IsCapturedCacheTy = SmallDenseMap<const Value *, bool, 8>;
IsCapturedCacheTy IsCapturedCache;

/// Tracks phi nodes we have visited.
///
/// When interpret "Value" pointer equality as value equality we need to make
Expand Down Expand Up @@ -201,22 +198,24 @@ class BasicAAResult : public AAResultBase<BasicAAResult> {
AliasResult aliasGEP(const GEPOperator *V1, LocationSize V1Size,
const AAMDNodes &V1AAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
const Value *UnderlyingV1, const Value *UnderlyingV2);
const Value *UnderlyingV1, const Value *UnderlyingV2,
AAQueryInfo &AAQI);

AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize,
const AAMDNodes &PNAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
const Value *UnderV2);
const Value *UnderV2, AAQueryInfo &AAQI);

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

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

/// Analysis pass providing a never-invalidated alias analysis result.
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/Analysis/CFLAndersAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class CFLAndersAAResult : public AAResultBase<CFLAndersAAResult> {
const cflaa::AliasSummary *getAliasSummary(const Function &);

AliasResult query(const MemoryLocation &, const MemoryLocation &);
AliasResult alias(const MemoryLocation &, const MemoryLocation &);
AliasResult alias(const MemoryLocation &, const MemoryLocation &,
AAQueryInfo &);

private:
/// Ensures that the given function is available in the cache.
Expand Down
7 changes: 4 additions & 3 deletions llvm/include/llvm/Analysis/CFLSteensAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ class CFLSteensAAResult : public AAResultBase<CFLSteensAAResult> {

AliasResult query(const MemoryLocation &LocA, const MemoryLocation &LocB);

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
if (LocA.Ptr == LocB.Ptr)
return MustAlias;

Expand All @@ -79,11 +80,11 @@ class CFLSteensAAResult : public AAResultBase<CFLSteensAAResult> {
// ConstantExpr, but every query needs to have at least one Value tied to a
// Function, and neither GlobalValues nor ConstantExprs are.
if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr))
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);

AliasResult QueryResult = query(LocA, LocB);
if (QueryResult == MayAlias)
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);

return QueryResult;
}
Expand Down
8 changes: 5 additions & 3 deletions llvm/include/llvm/Analysis/GlobalsModRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,12 @@ class GlobalsAAResult : public AAResultBase<GlobalsAAResult> {
//------------------------------------------------
// Implement the AliasAnalysis API
//
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI);

using AAResultBase::getModRefInfo;
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
AAQueryInfo &AAQI);

/// getModRefBehavior - Return the behavior of the specified function if
/// called from the specified call site. The call site may be null in which
Expand All @@ -113,7 +115,7 @@ class GlobalsAAResult : public AAResultBase<GlobalsAAResult> {

bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V);
ModRefInfo getModRefInfoForArgument(const CallBase *Call,
const GlobalValue *GV);
const GlobalValue *GV, AAQueryInfo &AAQI);
};

/// Analysis pass providing a never-invalidated alias analysis result.
Expand Down
19 changes: 10 additions & 9 deletions llvm/include/llvm/Analysis/MemorySSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -830,13 +830,13 @@ class MemorySSA {
const MemoryUseOrDef *Template = nullptr);

private:
class ClobberWalkerBase;
class CachingWalker;
class SkipSelfWalker;
template <class AliasAnalysisType> class ClobberWalkerBase;
template <class AliasAnalysisType> class CachingWalker;
template <class AliasAnalysisType> class SkipSelfWalker;
class OptimizeUses;

CachingWalker *getWalkerImpl();
void buildMemorySSA();
CachingWalker<AliasAnalysis> *getWalkerImpl();
void buildMemorySSA(BatchAAResults &BAA);
void optimizeUses();

void prepareForMoveTo(MemoryAccess *, BasicBlock *);
Expand All @@ -850,7 +850,8 @@ class MemorySSA {
void markUnreachableAsLiveOnEntry(BasicBlock *BB);
bool dominatesUse(const MemoryAccess *, const MemoryAccess *) const;
MemoryPhi *createMemoryPhi(BasicBlock *BB);
MemoryUseOrDef *createNewAccess(Instruction *,
template <typename AliasAnalysisType>
MemoryUseOrDef *createNewAccess(Instruction *, AliasAnalysisType *,
const MemoryUseOrDef *Template = nullptr);
MemoryAccess *findDominatingDef(BasicBlock *, enum InsertionPlace);
void placePHINodes(const SmallPtrSetImpl<BasicBlock *> &);
Expand Down Expand Up @@ -886,9 +887,9 @@ class MemorySSA {
mutable DenseMap<const MemoryAccess *, unsigned long> BlockNumbering;

// Memory SSA building info
std::unique_ptr<ClobberWalkerBase> WalkerBase;
std::unique_ptr<CachingWalker> Walker;
std::unique_ptr<SkipSelfWalker> SkipWalker;
std::unique_ptr<ClobberWalkerBase<AliasAnalysis>> WalkerBase;
std::unique_ptr<CachingWalker<AliasAnalysis>> Walker;
std::unique_ptr<SkipSelfWalker<AliasAnalysis>> SkipWalker;
unsigned NextID;
};

Expand Down
9 changes: 6 additions & 3 deletions llvm/include/llvm/Analysis/ObjCARCAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,17 @@ class ObjCARCAAResult : public AAResultBase<ObjCARCAAResult> {
return false;
}

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI);
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool OrLocal);

using AAResultBase::getModRefBehavior;
FunctionModRefBehavior getModRefBehavior(const Function *F);

using AAResultBase::getModRefInfo;
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
AAQueryInfo &AAQI);
};

/// Analysis pass providing a never-invalidated alias analysis result.
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class SCEVAAResult : public AAResultBase<SCEVAAResult> {
explicit SCEVAAResult(ScalarEvolution &SE) : AAResultBase(), SE(SE) {}
SCEVAAResult(SCEVAAResult &&Arg) : AAResultBase(std::move(Arg)), SE(Arg.SE) {}

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI);

private:
Value *GetBaseValue(const SCEV *S);
Expand Down
9 changes: 6 additions & 3 deletions llvm/include/llvm/Analysis/ScopedNoAliasAA.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ class ScopedNoAliasAAResult : public AAResultBase<ScopedNoAliasAAResult> {
return false;
}

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
AAQueryInfo &AAQI);
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
AAQueryInfo &AAQI);

private:
bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias) const;
Expand Down
12 changes: 8 additions & 4 deletions llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@ class TypeBasedAAResult : public AAResultBase<TypeBasedAAResult> {
return false;
}

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI);
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool OrLocal);
FunctionModRefBehavior getModRefBehavior(const CallBase *Call);
FunctionModRefBehavior getModRefBehavior(const Function *F);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2);
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
AAQueryInfo &AAQI);
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
AAQueryInfo &AAQI);

private:
bool Aliases(const MDNode *A, const MDNode *B) const;
Expand Down
117 changes: 101 additions & 16 deletions llvm/lib/Analysis/AliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,14 @@ bool AAResults::invalidate(Function &F, const PreservedAnalyses &PA,

AliasResult AAResults::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
AAQueryInfo AAQIP;
return alias(LocA, LocB, AAQIP);
}

AliasResult AAResults::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB, AAQueryInfo &AAQI) {
for (const auto &AA : AAs) {
auto Result = AA->alias(LocA, LocB);
auto Result = AA->alias(LocA, LocB, AAQI);
if (Result != MayAlias)
return Result;
}
Expand All @@ -109,8 +115,14 @@ AliasResult AAResults::alias(const MemoryLocation &LocA,

bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) {
AAQueryInfo AAQIP;
return pointsToConstantMemory(Loc, AAQIP, OrLocal);
}

bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
AAQueryInfo &AAQI, bool OrLocal) {
for (const auto &AA : AAs)
if (AA->pointsToConstantMemory(Loc, OrLocal))
if (AA->pointsToConstantMemory(Loc, AAQI, OrLocal))
return true;

return false;
Expand All @@ -131,10 +143,16 @@ ModRefInfo AAResults::getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
}

ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2) {
AAQueryInfo AAQIP;
return getModRefInfo(I, Call2, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2,
AAQueryInfo &AAQI) {
// We may have two calls.
if (const auto *Call1 = dyn_cast<CallBase>(I)) {
// Check if the two calls modify the same memory.
return getModRefInfo(Call1, Call2);
return getModRefInfo(Call1, Call2, AAQI);
} else if (I->isFenceLike()) {
// If this is a fence, just return ModRef.
return ModRefInfo::ModRef;
Expand All @@ -144,7 +162,7 @@ ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2) {
// is that if the call references what this instruction
// defines, it must be clobbered by this location.
const MemoryLocation DefLoc = MemoryLocation::get(I);
ModRefInfo MR = getModRefInfo(Call2, DefLoc);
ModRefInfo MR = getModRefInfo(Call2, DefLoc, AAQI);
if (isModOrRefSet(MR))
return setModAndRef(MR);
}
Expand All @@ -153,10 +171,17 @@ ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2) {

ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(Call, Loc, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
ModRefInfo Result = ModRefInfo::ModRef;

for (const auto &AA : AAs) {
Result = intersectModRef(Result, AA->getModRefInfo(Call, Loc));
Result = intersectModRef(Result, AA->getModRefInfo(Call, Loc, AAQI));

// Early-exit the moment we reach the bottom of the lattice.
if (isNoModRef(Result))
Expand Down Expand Up @@ -214,10 +239,16 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,

ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
const CallBase *Call2) {
AAQueryInfo AAQIP;
return getModRefInfo(Call1, Call2, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
const CallBase *Call2, AAQueryInfo &AAQI) {
ModRefInfo Result = ModRefInfo::ModRef;

for (const auto &AA : AAs) {
Result = intersectModRef(Result, AA->getModRefInfo(Call1, Call2));
Result = intersectModRef(Result, AA->getModRefInfo(Call1, Call2, AAQI));

// Early-exit the moment we reach the bottom of the lattice.
if (isNoModRef(Result))
Expand Down Expand Up @@ -396,14 +427,20 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, AliasResult AR) {

ModRefInfo AAResults::getModRefInfo(const LoadInst *L,
const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(L, Loc, AAQIP);
}
ModRefInfo AAResults::getModRefInfo(const LoadInst *L,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
// Be conservative in the face of atomic.
if (isStrongerThan(L->getOrdering(), AtomicOrdering::Unordered))
return ModRefInfo::ModRef;

// 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);
AliasResult AR = alias(MemoryLocation::get(L), Loc, AAQI);
if (AR == NoAlias)
return ModRefInfo::NoModRef;
if (AR == MustAlias)
Expand All @@ -415,20 +452,26 @@ ModRefInfo AAResults::getModRefInfo(const LoadInst *L,

ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(S, Loc, AAQIP);
}
ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
// Be conservative in the face of atomic.
if (isStrongerThan(S->getOrdering(), AtomicOrdering::Unordered))
return ModRefInfo::ModRef;

if (Loc.Ptr) {
AliasResult AR = alias(MemoryLocation::get(S), Loc);
AliasResult AR = alias(MemoryLocation::get(S), Loc, AAQI);
// If the store address cannot alias the pointer in question, then the
// specified memory cannot be modified by the store.
if (AR == NoAlias)
return ModRefInfo::NoModRef;

// If the pointer is a pointer to constant memory, then it could not have
// been modified by this store.
if (pointsToConstantMemory(Loc))
if (pointsToConstantMemory(Loc, AAQI))
return ModRefInfo::NoModRef;

// If the store address aliases the pointer as must alias, set Must.
Expand All @@ -441,25 +484,39 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
}

ModRefInfo AAResults::getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(S, Loc, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(const FenceInst *S,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
// If we know that the location is a constant memory location, the fence
// cannot modify this location.
if (Loc.Ptr && pointsToConstantMemory(Loc))
if (Loc.Ptr && pointsToConstantMemory(Loc, AAQI))
return ModRefInfo::Ref;
return ModRefInfo::ModRef;
}

ModRefInfo AAResults::getModRefInfo(const VAArgInst *V,
const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(V, Loc, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(const VAArgInst *V,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
if (Loc.Ptr) {
AliasResult AR = alias(MemoryLocation::get(V), Loc);
AliasResult AR = alias(MemoryLocation::get(V), Loc, AAQI);
// If the va_arg address cannot alias the pointer in question, then the
// specified memory cannot be accessed by the va_arg.
if (AR == NoAlias)
return ModRefInfo::NoModRef;

// If the pointer is a pointer to constant memory, then it could not have
// been modified by this va_arg.
if (pointsToConstantMemory(Loc))
if (pointsToConstantMemory(Loc, AAQI))
return ModRefInfo::NoModRef;

// If the va_arg aliases the pointer as must alias, set Must.
Expand All @@ -473,10 +530,17 @@ ModRefInfo AAResults::getModRefInfo(const VAArgInst *V,

ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad,
const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(CatchPad, Loc, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
if (Loc.Ptr) {
// If the pointer is a pointer to constant memory,
// then it could not have been modified by this catchpad.
if (pointsToConstantMemory(Loc))
if (pointsToConstantMemory(Loc, AAQI))
return ModRefInfo::NoModRef;
}

Expand All @@ -486,10 +550,17 @@ ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad,

ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet,
const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(CatchRet, Loc, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
if (Loc.Ptr) {
// If the pointer is a pointer to constant memory,
// then it could not have been modified by this catchpad.
if (pointsToConstantMemory(Loc))
if (pointsToConstantMemory(Loc, AAQI))
return ModRefInfo::NoModRef;
}

Expand All @@ -499,12 +570,19 @@ ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet,

ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX,
const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(CX, Loc, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
// Acquire/Release cmpxchg has properties that matter for arbitrary addresses.
if (isStrongerThanMonotonic(CX->getSuccessOrdering()))
return ModRefInfo::ModRef;

if (Loc.Ptr) {
AliasResult AR = alias(MemoryLocation::get(CX), Loc);
AliasResult AR = alias(MemoryLocation::get(CX), Loc, AAQI);
// If the cmpxchg address does not alias the location, it does not access
// it.
if (AR == NoAlias)
Expand All @@ -520,12 +598,19 @@ ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX,

ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW,
const MemoryLocation &Loc) {
AAQueryInfo AAQIP;
return getModRefInfo(RMW, Loc, AAQIP);
}

ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
// Acquire/Release atomicrmw has properties that matter for arbitrary addresses.
if (isStrongerThanMonotonic(RMW->getOrdering()))
return ModRefInfo::ModRef;

if (Loc.Ptr) {
AliasResult AR = alias(MemoryLocation::get(RMW), Loc);
AliasResult AR = alias(MemoryLocation::get(RMW), Loc, AAQI);
// If the atomicrmw address does not alias the location, it does not access
// it.
if (AR == NoAlias)
Expand Down
166 changes: 86 additions & 80 deletions llvm/lib/Analysis/BasicAliasAnalysis.cpp

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions llvm/lib/Analysis/CFLAndersAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,8 @@ AliasResult CFLAndersAAResult::query(const MemoryLocation &LocA,
}

AliasResult CFLAndersAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
if (LocA.Ptr == LocB.Ptr)
return MustAlias;

Expand All @@ -885,11 +886,11 @@ AliasResult CFLAndersAAResult::alias(const MemoryLocation &LocA,
// ConstantExpr, but every query needs to have at least one Value tied to a
// Function, and neither GlobalValues nor ConstantExprs are.
if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr))
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);

AliasResult QueryResult = query(LocA, LocB);
if (QueryResult == MayAlias)
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);

return QueryResult;
}
Expand Down
18 changes: 11 additions & 7 deletions llvm/lib/Analysis/GlobalsModRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,8 @@ bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV,
/// other is some random pointer, we know there cannot be an alias, because the
/// address of the global isn't taken.
AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
// Get the base object these pointers point to.
const Value *UV1 = GetUnderlyingObject(LocA.Ptr, DL);
const Value *UV2 = GetUnderlyingObject(LocB.Ptr, DL);
Expand Down Expand Up @@ -881,11 +882,12 @@ AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA,
if ((GV1 || GV2) && GV1 != GV2)
return NoAlias;

return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);
}

ModRefInfo GlobalsAAResult::getModRefInfoForArgument(const CallBase *Call,
const GlobalValue *GV) {
const GlobalValue *GV,
AAQueryInfo &AAQI) {
if (Call->doesNotAccessMemory())
return ModRefInfo::NoModRef;
ModRefInfo ConservativeResult =
Expand All @@ -901,7 +903,8 @@ ModRefInfo GlobalsAAResult::getModRefInfoForArgument(const CallBase *Call,
if (!all_of(Objects, isIdentifiedObject) &&
// Try ::alias to see if all objects are known not to alias GV.
!all_of(Objects, [&](Value *V) {
return this->alias(MemoryLocation(V), MemoryLocation(GV)) == NoAlias;
return this->alias(MemoryLocation(V), MemoryLocation(GV), AAQI) ==
NoAlias;
}))
return ConservativeResult;

Expand All @@ -914,7 +917,8 @@ ModRefInfo GlobalsAAResult::getModRefInfoForArgument(const CallBase *Call,
}

ModRefInfo GlobalsAAResult::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc) {
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
ModRefInfo Known = ModRefInfo::ModRef;

// If we are asking for mod/ref info of a direct call with a pointer to a
Expand All @@ -926,11 +930,11 @@ ModRefInfo GlobalsAAResult::getModRefInfo(const CallBase *Call,
if (NonAddressTakenGlobals.count(GV))
if (const FunctionInfo *FI = getFunctionInfo(F))
Known = unionModRef(FI->getModRefInfoForGlobal(*GV),
getModRefInfoForArgument(Call, GV));
getModRefInfoForArgument(Call, GV, AAQI));

if (!isModOrRefSet(Known))
return ModRefInfo::NoModRef; // No need to query other mod/ref analyses
return intersectModRef(Known, AAResultBase::getModRefInfo(Call, Loc));
return intersectModRef(Known, AAResultBase::getModRefInfo(Call, Loc, AAQI));
}

GlobalsAAResult::GlobalsAAResult(const DataLayout &DL,
Expand Down
153 changes: 83 additions & 70 deletions llvm/lib/Analysis/MemorySSA.cpp

Large diffs are not rendered by default.

25 changes: 14 additions & 11 deletions llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,18 @@ using namespace llvm;
using namespace llvm::objcarc;

AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
if (!EnableARCOpts)
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);

// 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));
MemoryLocation(SB, LocB.Size, LocB.AATags), AAQI);
if (Result != MayAlias)
return Result;

Expand All @@ -56,7 +57,7 @@ AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
const Value *UA = GetUnderlyingObjCPtr(SA, DL);
const Value *UB = GetUnderlyingObjCPtr(SB, DL);
if (UA != SA || UB != SB) {
Result = AAResultBase::alias(MemoryLocation(UA), MemoryLocation(UB));
Result = AAResultBase::alias(MemoryLocation(UA), MemoryLocation(UB), AAQI);
// We can't use MustAlias or PartialAlias results here because
// GetUnderlyingObjCPtr may return an offsetted pointer value.
if (Result == NoAlias)
Expand All @@ -69,22 +70,23 @@ AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
}

bool ObjCARCAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) {
AAQueryInfo &AAQI, bool OrLocal) {
if (!EnableARCOpts)
return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);

// First, strip off no-ops, including ObjC-specific no-ops, and try making
// a precise alias query.
const Value *S = GetRCIdentityRoot(Loc.Ptr);
if (AAResultBase::pointsToConstantMemory(
MemoryLocation(S, Loc.Size, Loc.AATags), OrLocal))
MemoryLocation(S, Loc.Size, Loc.AATags), AAQI, OrLocal))
return true;

// If that failed, climb to the underlying object, including climbing through
// ObjC-specific no-ops, and try making an imprecise alias query.
const Value *U = GetUnderlyingObjCPtr(S, DL);
if (U != S)
return AAResultBase::pointsToConstantMemory(MemoryLocation(U), OrLocal);
return AAResultBase::pointsToConstantMemory(MemoryLocation(U), AAQI,
OrLocal);

// If that failed, fail. We don't need to chain here, since that's covered
// by the earlier precise query.
Expand All @@ -106,9 +108,10 @@ FunctionModRefBehavior ObjCARCAAResult::getModRefBehavior(const Function *F) {
}

ModRefInfo ObjCARCAAResult::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc) {
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
if (!EnableARCOpts)
return AAResultBase::getModRefInfo(Call, Loc);
return AAResultBase::getModRefInfo(Call, Loc, AAQI);

switch (GetBasicARCInstKind(Call)) {
case ARCInstKind::Retain:
Expand All @@ -127,7 +130,7 @@ ModRefInfo ObjCARCAAResult::getModRefInfo(const CallBase *Call,
break;
}

return AAResultBase::getModRefInfo(Call, Loc);
return AAResultBase::getModRefInfo(Call, Loc, AAQI);
}

ObjCARCAAResult ObjCARCAA::run(Function &F, FunctionAnalysisManager &AM) {
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
using namespace llvm;

AliasResult SCEVAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
const MemoryLocation &LocB, AAQueryInfo &AAQI) {
// 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.
Expand Down Expand Up @@ -85,11 +85,12 @@ AliasResult SCEVAAResult::alias(const MemoryLocation &LocA,
AO ? AAMDNodes() : LocA.AATags),
MemoryLocation(BO ? BO : LocB.Ptr,
BO ? LocationSize::unknown() : LocB.Size,
BO ? AAMDNodes() : LocB.AATags)) == NoAlias)
BO ? AAMDNodes() : LocB.AATags),
AAQI) == NoAlias)
return NoAlias;

// Forward the query to the next analysis.
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);
}

/// Given an expression, try to find a base value.
Expand Down
21 changes: 12 additions & 9 deletions llvm/lib/Analysis/ScopedNoAliasAA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ class AliasScopeNode {
} // end anonymous namespace

AliasResult ScopedNoAliasAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
if (!EnableScopedNoAlias)
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);

// Get the attached MDNodes.
const MDNode *AScopes = LocA.AATags.Scope, *BScopes = LocB.AATags.Scope;
Expand All @@ -91,13 +92,14 @@ AliasResult ScopedNoAliasAAResult::alias(const MemoryLocation &LocA,
return NoAlias;

// If they may alias, chain to the next AliasAnalysis.
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);
}

ModRefInfo ScopedNoAliasAAResult::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc) {
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
if (!EnableScopedNoAlias)
return AAResultBase::getModRefInfo(Call, Loc);
return AAResultBase::getModRefInfo(Call, Loc, AAQI);

if (!mayAliasInScopes(Loc.AATags.Scope,
Call->getMetadata(LLVMContext::MD_noalias)))
Expand All @@ -107,13 +109,14 @@ ModRefInfo ScopedNoAliasAAResult::getModRefInfo(const CallBase *Call,
Loc.AATags.NoAlias))
return ModRefInfo::NoModRef;

return AAResultBase::getModRefInfo(Call, Loc);
return AAResultBase::getModRefInfo(Call, Loc, AAQI);
}

ModRefInfo ScopedNoAliasAAResult::getModRefInfo(const CallBase *Call1,
const CallBase *Call2) {
const CallBase *Call2,
AAQueryInfo &AAQI) {
if (!EnableScopedNoAlias)
return AAResultBase::getModRefInfo(Call1, Call2);
return AAResultBase::getModRefInfo(Call1, Call2, AAQI);

if (!mayAliasInScopes(Call1->getMetadata(LLVMContext::MD_alias_scope),
Call2->getMetadata(LLVMContext::MD_noalias)))
Expand All @@ -123,7 +126,7 @@ ModRefInfo ScopedNoAliasAAResult::getModRefInfo(const CallBase *Call1,
Call1->getMetadata(LLVMContext::MD_noalias)))
return ModRefInfo::NoModRef;

return AAResultBase::getModRefInfo(Call1, Call2);
return AAResultBase::getModRefInfo(Call1, Call2, AAQI);
}

static void collectMDInDomain(const MDNode *List, const MDNode *Domain,
Expand Down
28 changes: 16 additions & 12 deletions llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,34 +367,36 @@ static bool isStructPathTBAA(const MDNode *MD) {
}

AliasResult TypeBasedAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
if (!EnableTBAA)
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);

// If accesses may alias, chain to the next AliasAnalysis.
if (Aliases(LocA.AATags.TBAA, LocB.AATags.TBAA))
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);

// Otherwise return a definitive result.
return NoAlias;
}

bool TypeBasedAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
AAQueryInfo &AAQI,
bool OrLocal) {
if (!EnableTBAA)
return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);

const MDNode *M = Loc.AATags.TBAA;
if (!M)
return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);

// If this is an "immutable" type, we can assume the pointer is pointing
// to constant memory.
if ((!isStructPathTBAA(M) && TBAANode(M).isTypeImmutable()) ||
(isStructPathTBAA(M) && TBAAStructTagNode(M).isTypeImmutable()))
return true;

return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
}

FunctionModRefBehavior
Expand All @@ -420,29 +422,31 @@ FunctionModRefBehavior TypeBasedAAResult::getModRefBehavior(const Function *F) {
}

ModRefInfo TypeBasedAAResult::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc) {
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
if (!EnableTBAA)
return AAResultBase::getModRefInfo(Call, Loc);
return AAResultBase::getModRefInfo(Call, Loc, AAQI);

if (const MDNode *L = Loc.AATags.TBAA)
if (const MDNode *M = Call->getMetadata(LLVMContext::MD_tbaa))
if (!Aliases(L, M))
return ModRefInfo::NoModRef;

return AAResultBase::getModRefInfo(Call, Loc);
return AAResultBase::getModRefInfo(Call, Loc, AAQI);
}

ModRefInfo TypeBasedAAResult::getModRefInfo(const CallBase *Call1,
const CallBase *Call2) {
const CallBase *Call2,
AAQueryInfo &AAQI) {
if (!EnableTBAA)
return AAResultBase::getModRefInfo(Call1, Call2);
return AAResultBase::getModRefInfo(Call1, Call2, AAQI);

if (const MDNode *M1 = Call1->getMetadata(LLVMContext::MD_tbaa))
if (const MDNode *M2 = Call2->getMetadata(LLVMContext::MD_tbaa))
if (!Aliases(M1, M2))
return ModRefInfo::NoModRef;

return AAResultBase::getModRefInfo(Call1, Call2);
return AAResultBase::getModRefInfo(Call1, Call2, AAQI);
}

bool MDNode::isTBAAVtableAccess() const {
Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ static AliasResult getAliasResult(unsigned AS1, unsigned AS2) {
}

AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) {
const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();

Expand All @@ -85,11 +86,11 @@ AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
return Result;

// Forward the query to the next alias analysis.
return AAResultBase::alias(LocA, LocB);
return AAResultBase::alias(LocA, LocB, AAQI);
}

bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) {
AAQueryInfo &AAQI, bool OrLocal) {
const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
unsigned AS = Base->getType()->getPointerAddressSpace();
if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
Expand All @@ -106,7 +107,7 @@ bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
// Only assume constant memory for arguments on kernels.
switch (F->getCallingConv()) {
default:
return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
case CallingConv::AMDGPU_LS:
case CallingConv::AMDGPU_HS:
case CallingConv::AMDGPU_ES:
Expand All @@ -133,5 +134,5 @@ bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
return true;
}
}
return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
}
6 changes: 4 additions & 2 deletions llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ class AMDGPUAAResult : public AAResultBase<AMDGPUAAResult> {
/// By definition, this result is stateless and so remains valid.
bool invalidate(Function &, const PreservedAnalyses &) { return false; }

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI);
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool OrLocal);

private:
bool Aliases(const MDNode *A, const MDNode *B) const;
Expand Down
3 changes: 2 additions & 1 deletion llvm/unittests/Analysis/AliasAnalysisTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ struct TestCustomAAResult : AAResultBase<TestCustomAAResult> {

bool invalidate(Function &, const PreservedAnalyses &) { return false; }

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
CB();
return MayAlias;
}
Expand Down
26 changes: 17 additions & 9 deletions llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,19 @@ class BasicAATest : public testing::Test {
DominatorTree DT;
AssumptionCache AC;
BasicAAResult BAA;
AAQueryInfo AAQI;

TestAnalyses(BasicAATest &Test)
: DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT) {}
: DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT),
AAQI() {}
};

llvm::Optional<TestAnalyses> Analyses;

BasicAAResult &setupAnalyses() {
TestAnalyses &setupAnalyses() {
assert(F);
Analyses.emplace(*this);
return Analyses->BAA;
return Analyses.getValue();
}

public:
Expand Down Expand Up @@ -83,15 +85,17 @@ TEST_F(BasicAATest, AliasInstWithObjectOfImpreciseSize) {
GlobalPtr->setLinkage(GlobalValue::LinkageTypes::InternalLinkage);
GlobalPtr->setInitializer(B.getInt8(0));

BasicAAResult &BasicAA = setupAnalyses();
auto &AllAnalyses = setupAnalyses();
BasicAAResult &BasicAA = AllAnalyses.BAA;
AAQueryInfo &AAQI = AllAnalyses.AAQI;
ASSERT_EQ(
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::precise(4)),
MemoryLocation(GlobalPtr, LocationSize::precise(1))),
MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
AliasResult::NoAlias);

ASSERT_EQ(
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::upperBound(4)),
MemoryLocation(GlobalPtr, LocationSize::precise(1))),
MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
AliasResult::MayAlias);
}

Expand All @@ -110,14 +114,18 @@ TEST_F(BasicAATest, AliasInstWithFullObjectOfImpreciseSize) {
auto *I8AtUncertainOffset =
cast<GetElementPtrInst>(B.CreateGEP(B.getInt8Ty(), I8, ArbitraryI32));

BasicAAResult &BasicAA = setupAnalyses();
auto &AllAnalyses = setupAnalyses();
BasicAAResult &BasicAA = AllAnalyses.BAA;
AAQueryInfo &AAQI = AllAnalyses.AAQI;
ASSERT_EQ(BasicAA.alias(
MemoryLocation(I8, LocationSize::precise(2)),
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1))),
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
AAQI),
AliasResult::PartialAlias);

ASSERT_EQ(BasicAA.alias(
MemoryLocation(I8, LocationSize::upperBound(2)),
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1))),
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
AAQI),
AliasResult::MayAlias);
}