Index: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h =================================================================== --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h @@ -43,6 +43,7 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/PassManager.h" #include "llvm/Analysis/MemoryLocation.h" +#include "llvm/Analysis/TargetLibraryInfo.h" namespace llvm { class BasicAAResult; @@ -50,7 +51,6 @@ class StoreInst; class VAArgInst; class DataLayout; -class TargetLibraryInfo; class Pass; class AnalysisUsage; class MemTransferInst; @@ -161,9 +161,8 @@ public: // Make these results default constructable and movable. We have to spell // these out because MSVC won't synthesize them. - AAResults() {} + AAResults(const TargetLibraryInfo &TLI) : TLI(TLI) {} AAResults(AAResults &&Arg); - AAResults &operator=(AAResults &&Arg); ~AAResults(); /// Register a specific AA result. @@ -557,6 +556,8 @@ template friend class AAResultBase; + const TargetLibraryInfo &TLI; + std::vector> AAs; }; @@ -753,20 +754,23 @@ } }; - const TargetLibraryInfo &TLI; - - explicit AAResultBase(const TargetLibraryInfo &TLI) : TLI(TLI) {} + explicit AAResultBase() {} // Provide all the copy and move constructors so that derived types aren't // constrained. - AAResultBase(const AAResultBase &Arg) : TLI(Arg.TLI) {} - AAResultBase(AAResultBase &&Arg) : TLI(Arg.TLI) {} + AAResultBase(const AAResultBase &Arg) {} + AAResultBase(AAResultBase &&Arg) {} /// Get a proxy for the best AA result set to query at this time. /// /// When this result is part of a larger aggregation, this will proxy to that /// aggregation. When this result is used in isolation, it will just delegate /// back to the derived class's implementation. + /// + /// Note that callers of this need to take considerable care to not cause + /// performance problems when they use this routine, in the case of a large + /// number of alias analyses being aggregated, it can be expensive to walk + /// back across the chain. AAResultsProxy getBestAAResults() { return AAResultsProxy(AAR, derived()); } public: @@ -783,13 +787,6 @@ } FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) { - if (!CS.hasOperandBundles()) - // If CS has operand bundles then aliasing attributes from the function it - // calls do not directly apply to the CallSite. This can be made more - // precise in the future. - if (const Function *F = CS.getCalledFunction()) - return getBestAAResults().getModRefBehavior(F); - return FMRB_UnknownModRefBehavior; } @@ -797,153 +794,15 @@ return FMRB_UnknownModRefBehavior; } - ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); - - ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); -}; - -/// Synthesize \c ModRefInfo for a call site and memory location by examining -/// the general behavior of the call site and any specific information for its -/// arguments. -/// -/// This essentially, delegates across the alias analysis interface to collect -/// information which may be enough to (conservatively) fulfill the query. -template -ModRefInfo AAResultBase::getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) { - auto MRB = getBestAAResults().getModRefBehavior(CS); - if (MRB == FMRB_DoesNotAccessMemory) - return MRI_NoModRef; - - ModRefInfo Mask = MRI_ModRef; - if (AAResults::onlyReadsMemory(MRB)) - Mask = MRI_Ref; - - if (AAResults::onlyAccessesArgPointees(MRB)) { - bool DoesAlias = false; - ModRefInfo AllArgsMask = MRI_NoModRef; - if (AAResults::doesAccessArgPointees(MRB)) { - for (auto AI = CS.arg_begin(), AE = CS.arg_end(); AI != AE; ++AI) { - const Value *Arg = *AI; - if (!Arg->getType()->isPointerTy()) - continue; - unsigned ArgIdx = std::distance(CS.arg_begin(), AI); - MemoryLocation ArgLoc = MemoryLocation::getForArgument(CS, ArgIdx, TLI); - AliasResult ArgAlias = getBestAAResults().alias(ArgLoc, Loc); - if (ArgAlias != NoAlias) { - ModRefInfo ArgMask = getBestAAResults().getArgModRefInfo(CS, ArgIdx); - DoesAlias = true; - AllArgsMask = ModRefInfo(AllArgsMask | ArgMask); - } - } - } - if (!DoesAlias) - return MRI_NoModRef; - Mask = ModRefInfo(Mask & AllArgsMask); - } - - // If Loc is a constant memory location, the call definitely could not - // modify the memory location. - if ((Mask & MRI_Mod) && - getBestAAResults().pointsToConstantMemory(Loc, /*OrLocal*/ false)) - Mask = ModRefInfo(Mask & ~MRI_Mod); - - return Mask; -} - -/// Synthesize \c ModRefInfo for two call sites by examining the general -/// behavior of the call site and any specific information for its arguments. -/// -/// This essentially, delegates across the alias analysis interface to collect -/// information which may be enough to (conservatively) fulfill the query. -template -ModRefInfo AAResultBase::getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) { - // If CS1 or CS2 are readnone, they don't interact. - auto CS1B = getBestAAResults().getModRefBehavior(CS1); - if (CS1B == FMRB_DoesNotAccessMemory) - return MRI_NoModRef; - - auto CS2B = getBestAAResults().getModRefBehavior(CS2); - if (CS2B == FMRB_DoesNotAccessMemory) - return MRI_NoModRef; - - // If they both only read from memory, there is no dependence. - if (AAResults::onlyReadsMemory(CS1B) && AAResults::onlyReadsMemory(CS2B)) - return MRI_NoModRef; - - ModRefInfo Mask = MRI_ModRef; - - // If CS1 only reads memory, the only dependence on CS2 can be - // from CS1 reading memory written by CS2. - if (AAResults::onlyReadsMemory(CS1B)) - Mask = ModRefInfo(Mask & MRI_Ref); - - // If CS2 only access memory through arguments, accumulate the mod/ref - // information from CS1's references to the memory referenced by - // CS2's arguments. - if (AAResults::onlyAccessesArgPointees(CS2B)) { - ModRefInfo R = MRI_NoModRef; - if (AAResults::doesAccessArgPointees(CS2B)) { - for (auto I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) { - const Value *Arg = *I; - if (!Arg->getType()->isPointerTy()) - continue; - unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I); - auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI); - - // ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence - // of CS1 on that location is the inverse. - ModRefInfo ArgMask = - getBestAAResults().getArgModRefInfo(CS2, CS2ArgIdx); - if (ArgMask == MRI_Mod) - ArgMask = MRI_ModRef; - else if (ArgMask == MRI_Ref) - ArgMask = MRI_Mod; - - ArgMask = ModRefInfo(ArgMask & - getBestAAResults().getModRefInfo(CS1, CS2ArgLoc)); - - R = ModRefInfo((R | ArgMask) & Mask); - if (R == Mask) - break; - } - } - return R; + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) { + return MRI_ModRef; } - // If CS1 only accesses memory through arguments, check if CS2 references - // any of the memory referenced by CS1's arguments. If not, return NoModRef. - if (AAResults::onlyAccessesArgPointees(CS1B)) { - ModRefInfo R = MRI_NoModRef; - if (AAResults::doesAccessArgPointees(CS1B)) { - for (auto I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) { - const Value *Arg = *I; - if (!Arg->getType()->isPointerTy()) - continue; - unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I); - auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI); - - // ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod - // CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If CS1 - // might Ref, then we care only about a Mod by CS2. - ModRefInfo ArgMask = getBestAAResults().getArgModRefInfo(CS1, CS1ArgIdx); - ModRefInfo ArgR = getBestAAResults().getModRefInfo(CS2, CS1ArgLoc); - if (((ArgMask & MRI_Mod) != MRI_NoModRef && - (ArgR & MRI_ModRef) != MRI_NoModRef) || - ((ArgMask & MRI_Ref) != MRI_NoModRef && - (ArgR & MRI_Mod) != MRI_NoModRef)) - R = ModRefInfo((R | ArgMask) & Mask); - - if (R == Mask) - break; - } - } - return R; + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { + return MRI_ModRef; } +}; - return Mask; -} /// Return true if this pointer is returned by a noalias function. bool isNoAliasCall(const Value *V); @@ -1005,7 +864,7 @@ } Result run(Function &F, AnalysisManager *AM) { - Result R; + Result R(AM->getResult(F)); for (auto &Getter : FunctionResultGetters) (*Getter)(F, *AM, R); return R; @@ -1067,7 +926,7 @@ /// A helper for the legacy pass manager to populate \p AU to add uses to make /// sure the analyses required by \p createLegacyPMAAResults are available. -void addUsedAAAnalyses(AnalysisUsage &AU); +void getAAResultsAnalysisUsage(AnalysisUsage &AU); } // End llvm namespace Index: llvm/trunk/include/llvm/Analysis/BasicAliasAnalysis.h =================================================================== --- llvm/trunk/include/llvm/Analysis/BasicAliasAnalysis.h +++ llvm/trunk/include/llvm/Analysis/BasicAliasAnalysis.h @@ -40,6 +40,7 @@ friend AAResultBase; const DataLayout &DL; + const TargetLibraryInfo &TLI; AssumptionCache ∾ DominatorTree *DT; LoopInfo *LI; @@ -48,13 +49,14 @@ BasicAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI, AssumptionCache &AC, DominatorTree *DT = nullptr, LoopInfo *LI = nullptr) - : AAResultBase(TLI), DL(DL), AC(AC), DT(DT), LI(LI) {} + : AAResultBase(), DL(DL), TLI(TLI), AC(AC), DT(DT), LI(LI) {} BasicAAResult(const BasicAAResult &Arg) - : AAResultBase(Arg), DL(Arg.DL), AC(Arg.AC), DT(Arg.DT), LI(Arg.LI) {} - BasicAAResult(BasicAAResult &&Arg) - : AAResultBase(std::move(Arg)), DL(Arg.DL), AC(Arg.AC), DT(Arg.DT), + : AAResultBase(Arg), DL(Arg.DL), TLI(Arg.TLI), AC(Arg.AC), DT(Arg.DT), LI(Arg.LI) {} + BasicAAResult(BasicAAResult &&Arg) + : AAResultBase(std::move(Arg)), DL(Arg.DL), TLI(Arg.TLI), AC(Arg.AC), + DT(Arg.DT), LI(Arg.LI) {} /// Handle invalidation events from the new pass manager. /// Index: llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h =================================================================== --- llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h +++ llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h @@ -32,7 +32,7 @@ struct FunctionInfo; public: - explicit CFLAAResult(const TargetLibraryInfo &TLI); + explicit CFLAAResult(); CFLAAResult(CFLAAResult &&Arg); ~CFLAAResult(); Index: llvm/trunk/include/llvm/Analysis/GlobalsModRef.h =================================================================== --- llvm/trunk/include/llvm/Analysis/GlobalsModRef.h +++ llvm/trunk/include/llvm/Analysis/GlobalsModRef.h @@ -35,6 +35,7 @@ class FunctionInfo; const DataLayout &DL; + const TargetLibraryInfo &TLI; /// The globals that do not have their addresses taken. SmallPtrSet NonAddressTakenGlobals; Index: llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h =================================================================== --- llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h +++ llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h @@ -24,7 +24,6 @@ #define LLVM_ANALYSIS_OBJCARCALIASANALYSIS_H #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Pass.h" namespace llvm { @@ -42,8 +41,7 @@ const DataLayout &DL; public: - explicit ObjCARCAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI) - : AAResultBase(TLI), DL(DL) {} + explicit ObjCARCAAResult(const DataLayout &DL) : AAResultBase(), DL(DL) {} ObjCARCAAResult(ObjCARCAAResult &&Arg) : AAResultBase(std::move(Arg)), DL(Arg.DL) {} Index: llvm/trunk/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h =================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h @@ -28,8 +28,7 @@ ScalarEvolution &SE; public: - explicit SCEVAAResult(const TargetLibraryInfo &TLI, ScalarEvolution &SE) - : AAResultBase(TLI), SE(SE) {} + 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); Index: llvm/trunk/include/llvm/Analysis/ScopedNoAliasAA.h =================================================================== --- llvm/trunk/include/llvm/Analysis/ScopedNoAliasAA.h +++ llvm/trunk/include/llvm/Analysis/ScopedNoAliasAA.h @@ -27,8 +27,7 @@ friend AAResultBase; public: - explicit ScopedNoAliasAAResult(const TargetLibraryInfo &TLI) - : AAResultBase(TLI) {} + explicit ScopedNoAliasAAResult() : AAResultBase() {} ScopedNoAliasAAResult(ScopedNoAliasAAResult &&Arg) : AAResultBase(std::move(Arg)) {} Index: llvm/trunk/include/llvm/Analysis/TypeBasedAliasAnalysis.h =================================================================== --- llvm/trunk/include/llvm/Analysis/TypeBasedAliasAnalysis.h +++ llvm/trunk/include/llvm/Analysis/TypeBasedAliasAnalysis.h @@ -27,8 +27,7 @@ friend AAResultBase; public: - explicit TypeBasedAAResult(const TargetLibraryInfo &TLI) - : AAResultBase(TLI) {} + explicit TypeBasedAAResult() {} TypeBasedAAResult(TypeBasedAAResult &&Arg) : AAResultBase(std::move(Arg)) {} /// Handle invalidation events from the new pass manager. Index: llvm/trunk/include/llvm/LinkAllPasses.h =================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h +++ llvm/trunk/include/llvm/LinkAllPasses.h @@ -32,6 +32,7 @@ #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/ScopedNoAliasAA.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Function.h" @@ -194,7 +195,9 @@ (void)new llvm::ScalarEvolutionWrapperPass(); llvm::Function::Create(nullptr, llvm::GlobalValue::ExternalLinkage)->viewCFGOnly(); llvm::RGPassManager RGM; - llvm::AliasAnalysis AA; + llvm::TargetLibraryInfoImpl TLII; + llvm::TargetLibraryInfo TLI(TLII); + llvm::AliasAnalysis AA(TLI); llvm::AliasSetTracker X(AA); X.add(nullptr, 0, llvm::AAMDNodes()); // for -print-alias-sets (void) llvm::AreStatisticsEnabled(); Index: llvm/trunk/lib/Analysis/AliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp @@ -52,18 +52,11 @@ static cl::opt DisableBasicAA("disable-basicaa", cl::Hidden, cl::init(false)); -AAResults::AAResults(AAResults &&Arg) : AAs(std::move(Arg.AAs)) { +AAResults::AAResults(AAResults &&Arg) : TLI(Arg.TLI), AAs(std::move(Arg.AAs)) { for (auto &AA : AAs) AA->setAAResults(this); } -AAResults &AAResults::operator=(AAResults &&Arg) { - AAs = std::move(Arg.AAs); - for (auto &AA : AAs) - AA->setAAResults(this); - return *this; -} - AAResults::~AAResults() { // FIXME; It would be nice to at least clear out the pointers back to this // aggregation here, but we end up with non-nesting lifetimes in the legacy @@ -141,6 +134,44 @@ return Result; } + // Try to refine the mod-ref info further using other API entry points to the + // aggregate set of AA results. + auto MRB = getModRefBehavior(CS); + if (MRB == FMRB_DoesNotAccessMemory) + return MRI_NoModRef; + + if (onlyReadsMemory(MRB)) + Result = ModRefInfo(Result & MRI_Ref); + + if (onlyAccessesArgPointees(MRB)) { + bool DoesAlias = false; + ModRefInfo AllArgsMask = MRI_NoModRef; + if (doesAccessArgPointees(MRB)) { + for (auto AI = CS.arg_begin(), AE = CS.arg_end(); AI != AE; ++AI) { + const Value *Arg = *AI; + if (!Arg->getType()->isPointerTy()) + continue; + unsigned ArgIdx = std::distance(CS.arg_begin(), AI); + MemoryLocation ArgLoc = MemoryLocation::getForArgument(CS, ArgIdx, TLI); + AliasResult ArgAlias = alias(ArgLoc, Loc); + if (ArgAlias != NoAlias) { + ModRefInfo ArgMask = getArgModRefInfo(CS, ArgIdx); + DoesAlias = true; + AllArgsMask = ModRefInfo(AllArgsMask | ArgMask); + } + } + } + if (!DoesAlias) + return MRI_NoModRef; + Result = ModRefInfo(Result & AllArgsMask); + } + + // If Loc is a constant memory location, the call definitely could not + // modify the memory location. + if ((Result & MRI_Mod) && + pointsToConstantMemory(Loc, /*OrLocal*/ false)) + Result = ModRefInfo(Result & ~MRI_Mod); + return Result; } @@ -156,6 +187,88 @@ return Result; } + // Try to refine the mod-ref info further using other API entry points to the + // aggregate set of AA results. + + // If CS1 or CS2 are readnone, they don't interact. + auto CS1B = getModRefBehavior(CS1); + if (CS1B == FMRB_DoesNotAccessMemory) + return MRI_NoModRef; + + auto CS2B = getModRefBehavior(CS2); + if (CS2B == FMRB_DoesNotAccessMemory) + return MRI_NoModRef; + + // If they both only read from memory, there is no dependence. + if (onlyReadsMemory(CS1B) && onlyReadsMemory(CS2B)) + return MRI_NoModRef; + + // If CS1 only reads memory, the only dependence on CS2 can be + // from CS1 reading memory written by CS2. + if (onlyReadsMemory(CS1B)) + Result = ModRefInfo(Result & MRI_Ref); + + // If CS2 only access memory through arguments, accumulate the mod/ref + // information from CS1's references to the memory referenced by + // CS2's arguments. + if (onlyAccessesArgPointees(CS2B)) { + ModRefInfo R = MRI_NoModRef; + if (doesAccessArgPointees(CS2B)) { + for (auto I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) { + const Value *Arg = *I; + if (!Arg->getType()->isPointerTy()) + continue; + unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I); + auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI); + + // ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence + // of CS1 on that location is the inverse. + ModRefInfo ArgMask = getArgModRefInfo(CS2, CS2ArgIdx); + if (ArgMask == MRI_Mod) + ArgMask = MRI_ModRef; + else if (ArgMask == MRI_Ref) + ArgMask = MRI_Mod; + + ArgMask = ModRefInfo(ArgMask & getModRefInfo(CS1, CS2ArgLoc)); + + R = ModRefInfo((R | ArgMask) & Result); + if (R == Result) + break; + } + } + return R; + } + + // If CS1 only accesses memory through arguments, check if CS2 references + // any of the memory referenced by CS1's arguments. If not, return NoModRef. + if (onlyAccessesArgPointees(CS1B)) { + ModRefInfo R = MRI_NoModRef; + if (doesAccessArgPointees(CS1B)) { + for (auto I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) { + const Value *Arg = *I; + if (!Arg->getType()->isPointerTy()) + continue; + unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I); + auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI); + + // ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod + // CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If CS1 + // might Ref, then we care only about a Mod by CS2. + ModRefInfo ArgMask = getArgModRefInfo(CS1, CS1ArgIdx); + ModRefInfo ArgR = getModRefInfo(CS2, CS1ArgLoc); + if (((ArgMask & MRI_Mod) != MRI_NoModRef && + (ArgR & MRI_ModRef) != MRI_NoModRef) || + ((ArgMask & MRI_Ref) != MRI_NoModRef && + (ArgR & MRI_Mod) != MRI_NoModRef)) + R = ModRefInfo((R | ArgMask) & Result); + + if (R == Result) + break; + } + } + return R; + } + return Result; } @@ -464,7 +577,8 @@ // unregistering themselves with them. We need to carefully tear down the // previous object first, in this case replacing it with an empty one, before // registering new results. - AAR.reset(new AAResults()); + AAR.reset( + new AAResults(getAnalysis().getTLI())); // BasicAA is always available for function analyses. Also, we add it first // so that it can trump TBAA results when it proves MustAlias. @@ -501,6 +615,7 @@ void AAResultsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); + AU.addRequired(); // We also need to mark all the alias analysis passes we will potentially // probe in runOnFunction as used here to ensure the legacy pass manager @@ -516,7 +631,7 @@ AAResults llvm::createLegacyPMAAResults(Pass &P, Function &F, BasicAAResult &BAR) { - AAResults AAR; + AAResults AAR(P.getAnalysis().getTLI()); // Add in our explicitly constructed BasicAA results. if (!DisableBasicAA) @@ -567,10 +682,11 @@ return isa(V) || isNoAliasCall(V) || isNoAliasArgument(V); } -void llvm::addUsedAAAnalyses(AnalysisUsage &AU) { +void llvm::getAAResultsAnalysisUsage(AnalysisUsage &AU) { // This function needs to be in sync with llvm::createLegacyPMAAResults -- if // more alias analyses are added to llvm::createLegacyPMAAResults, they need // to be added here also. + AU.addRequired(); AU.addUsedIfAvailable(); AU.addUsedIfAvailable(); AU.addUsedIfAvailable(); Index: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp @@ -573,8 +573,15 @@ if (CS.onlyAccessesArgMemory()) Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees); - // The AAResultBase base class has some smarts, lets use them. - return FunctionModRefBehavior(AAResultBase::getModRefBehavior(CS) & Min); + // If CS has operand bundles then aliasing attributes from the function it + // calls do not directly apply to the CallSite. This can be made more + // precise in the future. + if (!CS.hasOperandBundles()) + if (const Function *F = CS.getCalledFunction()) + Min = + FunctionModRefBehavior(Min & getBestAAResults().getModRefBehavior(F)); + + return Min; } /// Returns the behavior when calling the given function. For use when the call @@ -593,8 +600,7 @@ if (F->onlyAccessesArgMemory()) Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees); - // Otherwise be conservative. - return FunctionModRefBehavior(AAResultBase::getModRefBehavior(F) & Min); + return Min; } /// Returns true if this is a writeonly (i.e Mod only) parameter. Currently, Index: llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp @@ -39,7 +39,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" -#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstVisitor.h" @@ -59,7 +58,7 @@ #define DEBUG_TYPE "cfl-aa" -CFLAAResult::CFLAAResult(const TargetLibraryInfo &TLI) : AAResultBase(TLI) {} +CFLAAResult::CFLAAResult() : AAResultBase() {} CFLAAResult::CFLAAResult(CFLAAResult &&Arg) : AAResultBase(std::move(Arg)) {} CFLAAResult::~CFLAAResult() {} @@ -1090,15 +1089,12 @@ } CFLAAResult CFLAA::run(Function &F, AnalysisManager *AM) { - return CFLAAResult(AM->getResult(F)); + return CFLAAResult(); } char CFLAAWrapperPass::ID = 0; -INITIALIZE_PASS_BEGIN(CFLAAWrapperPass, "cfl-aa", "CFL-Based Alias Analysis", - false, true) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_END(CFLAAWrapperPass, "cfl-aa", "CFL-Based Alias Analysis", - false, true) +INITIALIZE_PASS(CFLAAWrapperPass, "cfl-aa", "CFL-Based Alias Analysis", false, + true) ImmutablePass *llvm::createCFLAAWrapperPass() { return new CFLAAWrapperPass(); } @@ -1107,8 +1103,7 @@ } bool CFLAAWrapperPass::doInitialization(Module &M) { - Result.reset( - new CFLAAResult(getAnalysis().getTLI())); + Result.reset(new CFLAAResult()); return false; } @@ -1119,5 +1114,4 @@ void CFLAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequired(); } Index: llvm/trunk/lib/Analysis/GlobalsModRef.cpp =================================================================== --- llvm/trunk/lib/Analysis/GlobalsModRef.cpp +++ llvm/trunk/lib/Analysis/GlobalsModRef.cpp @@ -901,10 +901,10 @@ GlobalsAAResult::GlobalsAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI) - : AAResultBase(TLI), DL(DL) {} + : AAResultBase(), DL(DL), TLI(TLI) {} GlobalsAAResult::GlobalsAAResult(GlobalsAAResult &&Arg) - : AAResultBase(std::move(Arg)), DL(Arg.DL), + : AAResultBase(std::move(Arg)), DL(Arg.DL), TLI(Arg.TLI), NonAddressTakenGlobals(std::move(Arg.NonAddressTakenGlobals)), IndirectGlobals(std::move(Arg.IndirectGlobals)), AllocsForIndirectGlobals(std::move(Arg.AllocsForIndirectGlobals)), Index: llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp @@ -132,16 +132,12 @@ } ObjCARCAAResult ObjCARCAA::run(Function &F, AnalysisManager *AM) { - return ObjCARCAAResult(F.getParent()->getDataLayout(), - AM->getResult(F)); + return ObjCARCAAResult(F.getParent()->getDataLayout()); } char ObjCARCAAWrapperPass::ID = 0; -INITIALIZE_PASS_BEGIN(ObjCARCAAWrapperPass, "objc-arc-aa", - "ObjC-ARC-Based Alias Analysis", false, true) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_END(ObjCARCAAWrapperPass, "objc-arc-aa", - "ObjC-ARC-Based Alias Analysis", false, true) +INITIALIZE_PASS(ObjCARCAAWrapperPass, "objc-arc-aa", + "ObjC-ARC-Based Alias Analysis", false, true) ImmutablePass *llvm::createObjCARCAAWrapperPass() { return new ObjCARCAAWrapperPass(); @@ -152,8 +148,7 @@ } bool ObjCARCAAWrapperPass::doInitialization(Module &M) { - Result.reset(new ObjCARCAAResult( - M.getDataLayout(), getAnalysis().getTLI())); + Result.reset(new ObjCARCAAResult(M.getDataLayout())); return false; } @@ -164,5 +159,4 @@ void ObjCARCAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequired(); } Index: llvm/trunk/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp @@ -20,7 +20,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" -#include "llvm/Analysis/TargetLibraryInfo.h" using namespace llvm; AliasResult SCEVAAResult::alias(const MemoryLocation &LocA, @@ -112,15 +111,13 @@ } SCEVAAResult SCEVAA::run(Function &F, AnalysisManager *AM) { - return SCEVAAResult(AM->getResult(F), - AM->getResult(F)); + return SCEVAAResult(AM->getResult(F)); } char SCEVAAWrapperPass::ID = 0; INITIALIZE_PASS_BEGIN(SCEVAAWrapperPass, "scev-aa", "ScalarEvolution-based Alias Analysis", false, true) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(SCEVAAWrapperPass, "scev-aa", "ScalarEvolution-based Alias Analysis", false, true) @@ -134,13 +131,11 @@ bool SCEVAAWrapperPass::runOnFunction(Function &F) { Result.reset( - new SCEVAAResult(getAnalysis().getTLI(), - getAnalysis().getSE())); + new SCEVAAResult(getAnalysis().getSE())); return false; } void SCEVAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); - AU.addRequired(); } Index: llvm/trunk/lib/Analysis/ScopedNoAliasAA.cpp =================================================================== --- llvm/trunk/lib/Analysis/ScopedNoAliasAA.cpp +++ llvm/trunk/lib/Analysis/ScopedNoAliasAA.cpp @@ -34,7 +34,6 @@ #include "llvm/Analysis/ScopedNoAliasAA.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" @@ -175,15 +174,12 @@ ScopedNoAliasAAResult ScopedNoAliasAA::run(Function &F, AnalysisManager *AM) { - return ScopedNoAliasAAResult(AM->getResult(F)); + return ScopedNoAliasAAResult(); } char ScopedNoAliasAAWrapperPass::ID = 0; -INITIALIZE_PASS_BEGIN(ScopedNoAliasAAWrapperPass, "scoped-noalias", - "Scoped NoAlias Alias Analysis", false, true) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_END(ScopedNoAliasAAWrapperPass, "scoped-noalias", - "Scoped NoAlias Alias Analysis", false, true) +INITIALIZE_PASS(ScopedNoAliasAAWrapperPass, "scoped-noalias", + "Scoped NoAlias Alias Analysis", false, true) ImmutablePass *llvm::createScopedNoAliasAAWrapperPass() { return new ScopedNoAliasAAWrapperPass(); @@ -194,8 +190,7 @@ } bool ScopedNoAliasAAWrapperPass::doInitialization(Module &M) { - Result.reset(new ScopedNoAliasAAResult( - getAnalysis().getTLI())); + Result.reset(new ScopedNoAliasAAResult()); return false; } @@ -206,5 +201,4 @@ void ScopedNoAliasAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequired(); } Index: llvm/trunk/lib/Analysis/TypeBasedAliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -122,7 +122,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/TypeBasedAliasAnalysis.h" -#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/ADT/SetVector.h" #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" @@ -585,15 +584,12 @@ } TypeBasedAAResult TypeBasedAA::run(Function &F, AnalysisManager *AM) { - return TypeBasedAAResult(AM->getResult(F)); + return TypeBasedAAResult(); } char TypeBasedAAWrapperPass::ID = 0; -INITIALIZE_PASS_BEGIN(TypeBasedAAWrapperPass, "tbaa", - "Type-Based Alias Analysis", false, true) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_END(TypeBasedAAWrapperPass, "tbaa", "Type-Based Alias Analysis", - false, true) +INITIALIZE_PASS(TypeBasedAAWrapperPass, "tbaa", "Type-Based Alias Analysis", + false, true) ImmutablePass *llvm::createTypeBasedAAWrapperPass() { return new TypeBasedAAWrapperPass(); @@ -604,8 +600,7 @@ } bool TypeBasedAAWrapperPass::doInitialization(Module &M) { - Result.reset(new TypeBasedAAResult( - getAnalysis().getTLI())); + Result.reset(new TypeBasedAAResult()); return false; } @@ -616,5 +611,4 @@ void TypeBasedAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequired(); } Index: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -69,7 +69,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); - addUsedAAAnalyses(AU); + getAAResultsAnalysisUsage(AU); CallGraphSCCPass::getAnalysisUsage(AU); } Index: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp +++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp @@ -1062,7 +1062,7 @@ AU.setPreservesCFG(); AU.addRequired(); AU.addRequired(); - addUsedAAAnalyses(AU); + getAAResultsAnalysisUsage(AU); CallGraphSCCPass::getAnalysisUsage(AU); } Index: llvm/trunk/lib/Transforms/IPO/Inliner.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/Inliner.cpp +++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp @@ -58,7 +58,7 @@ void Inliner::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); - addUsedAAAnalyses(AU); + getAAResultsAnalysisUsage(AU); CallGraphSCCPass::getAnalysisUsage(AU); } Index: llvm/trunk/unittests/Analysis/AliasAnalysisTest.cpp =================================================================== --- llvm/trunk/unittests/Analysis/AliasAnalysisTest.cpp +++ llvm/trunk/unittests/Analysis/AliasAnalysisTest.cpp @@ -80,9 +80,8 @@ std::function CB; - explicit TestCustomAAResult(const TargetLibraryInfo &TLI, - std::function CB) - : AAResultBase(TLI), CB(std::move(CB)) {} + explicit TestCustomAAResult(std::function CB) + : AAResultBase(), CB(std::move(CB)) {} TestCustomAAResult(TestCustomAAResult &&Arg) : AAResultBase(std::move(Arg)), CB(std::move(Arg.CB)) {} @@ -117,8 +116,7 @@ } bool doInitialization(Module &M) override { - Result.reset(new TestCustomAAResult( - getAnalysis().getTLI(), std::move(CB))); + Result.reset(new TestCustomAAResult(std::move(CB))); return true; } @@ -155,7 +153,7 @@ AAResults &getAAResults(Function &F) { // Reset the Function AA results first to clear out any references. - AAR.reset(new AAResults()); + AAR.reset(new AAResults(TLI)); // Build the various AA results and register them. AC.reset(new AssumptionCache(F)); Index: llvm/trunk/unittests/Transforms/Utils/MemorySSA.cpp =================================================================== --- llvm/trunk/unittests/Transforms/Utils/MemorySSA.cpp +++ llvm/trunk/unittests/Transforms/Utils/MemorySSA.cpp @@ -49,7 +49,7 @@ std::unique_ptr MSSA(new MemorySSA(*F)); std::unique_ptr DT(new DominatorTree(*F)); std::unique_ptr AC(new AssumptionCache(*F)); - AAResults *AA = new AAResults(); + AAResults *AA = new AAResults(TLI); BasicAAResult *BAA = new BasicAAResult(DL, TLI, *AC, &*DT); AA->addAAResult(*BAA); MemorySSAWalker *Walker = MSSA->buildMemorySSA(AA, &*DT);