Index: examples/Kaleidoscope/Chapter4/toy.cpp =================================================================== --- examples/Kaleidoscope/Chapter4/toy.cpp +++ examples/Kaleidoscope/Chapter4/toy.cpp @@ -1,5 +1,4 @@ #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/Passes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" @@ -534,8 +533,6 @@ // Create a new pass manager attached to it. TheFPM = llvm::make_unique(TheModule.get()); - // Provide basic AliasAnalysis support for GVN. - TheFPM->add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. TheFPM->add(createInstructionCombiningPass()); // Reassociate expressions. Index: examples/Kaleidoscope/Chapter5/toy.cpp =================================================================== --- examples/Kaleidoscope/Chapter5/toy.cpp +++ examples/Kaleidoscope/Chapter5/toy.cpp @@ -1,5 +1,4 @@ #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/Passes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" @@ -808,8 +807,6 @@ // Create a new pass manager attached to it. TheFPM = llvm::make_unique(TheModule.get()); - // Provide basic AliasAnalysis support for GVN. - TheFPM->add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. TheFPM->add(createInstructionCombiningPass()); // Reassociate expressions. Index: examples/Kaleidoscope/Chapter6/toy.cpp =================================================================== --- examples/Kaleidoscope/Chapter6/toy.cpp +++ examples/Kaleidoscope/Chapter6/toy.cpp @@ -1,5 +1,4 @@ #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/Passes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" @@ -926,8 +925,6 @@ // Create a new pass manager attached to it. TheFPM = llvm::make_unique(TheModule.get()); - // Provide basic AliasAnalysis support for GVN. - TheFPM->add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. TheFPM->add(createInstructionCombiningPass()); // Reassociate expressions. Index: examples/Kaleidoscope/Chapter7/toy.cpp =================================================================== --- examples/Kaleidoscope/Chapter7/toy.cpp +++ examples/Kaleidoscope/Chapter7/toy.cpp @@ -1,5 +1,4 @@ #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/Passes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" @@ -1092,8 +1091,6 @@ // Create a new pass manager attached to it. TheFPM = llvm::make_unique(TheModule.get()); - // Provide basic AliasAnalysis support for GVN. - TheFPM->add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. TheFPM->add(createInstructionCombiningPass()); // Reassociate expressions. Index: include/llvm/Analysis/AliasAnalysis.h =================================================================== --- include/llvm/Analysis/AliasAnalysis.h +++ include/llvm/Analysis/AliasAnalysis.h @@ -41,10 +41,11 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/PassManager.h" #include "llvm/Analysis/MemoryLocation.h" namespace llvm { - +class BasicAAResult; class LoadInst; class StoreInst; class VAArgInst; @@ -156,35 +157,22 @@ FMRB_UnknownModRefBehavior = FMRL_Anywhere | MRI_ModRef }; -class AliasAnalysis { -protected: - const DataLayout *DL; - const TargetLibraryInfo *TLI; - -private: - AliasAnalysis *AA; // Previous Alias Analysis to chain to. - -protected: - /// InitializeAliasAnalysis - Subclasses must call this method to initialize - /// the AliasAnalysis interface before any other methods are called. This is - /// typically called by the run* methods of these subclasses. This may be - /// called multiple times. - /// - void InitializeAliasAnalysis(Pass *P, const DataLayout *DL); - - /// getAnalysisUsage - All alias analysis implementations should invoke this - /// directly (using AliasAnalysis::getAnalysisUsage(AU)). - virtual void getAnalysisUsage(AnalysisUsage &AU) const; - +class AAResults { public: - static char ID; // Class identification, replacement for typeinfo - AliasAnalysis() : DL(nullptr), TLI(nullptr), AA(nullptr) {} - virtual ~AliasAnalysis(); // We want to be subclassed - - /// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo - /// object, or null if no TargetLibraryInfo object is available. - /// - const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; } + // Make these results default constructable and movable. We have to spell + // these out because MSVC won't synthesize them. + AAResults() {} + AAResults(AAResults &&Arg); + AAResults &operator=(AAResults &&Arg); + ~AAResults(); + + /// Register a specific AA result. + template void addAAResult(AAResultT &AAResult) { + // FIXME: We should use a much lighter weight system than the usual + // polymorphic pattern because we don't own AAResult. It should + // ideally involve two pointers and no separate allocation. + AAs.emplace_back(new Model(AAResult, *this)); + } //===--------------------------------------------------------------------===// /// \name Alias Queries @@ -194,8 +182,7 @@ /// Returns an AliasResult indicating whether the two pointers are aliased to /// each other. This is the interface that must be implemented by specific /// alias analysis implementations. - virtual AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB); + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); /// A convenience wrapper around the primary \c alias interface. AliasResult alias(const Value *V1, uint64_t V1Size, const Value *V2, @@ -239,8 +226,7 @@ /// Checks whether the given location points to constant memory, or if /// \p OrLocal is true whether it points to a local alloca. - virtual bool pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal = false); + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false); /// A convenience wrapper around the primary \c pointsToConstantMemory /// interface. @@ -258,13 +244,13 @@ /// that these bits do not necessarily account for the overall behavior of /// the function, but rather only provide additional per-argument /// information. - virtual ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx); + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx); /// Return the behavior of the given call site. - virtual FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); /// Return the behavior when calling the given function. - virtual FunctionModRefBehavior getModRefBehavior(const Function *F); + FunctionModRefBehavior getModRefBehavior(const Function *F); /// Checks if the specified call is known to never read or write memory. /// @@ -344,8 +330,7 @@ /// getModRefInfo (for call sites) - Return information about whether /// a particular call site modifies or reads the specified memory location. - virtual ModRefInfo getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc); + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); /// getModRefInfo (for call sites) - A convenience wrapper. ModRefInfo getModRefInfo(ImmutableCallSite CS, const Value *P, @@ -494,8 +479,7 @@ /// Return information about whether two call sites may refer to the same set /// of memory locations. See the AA documentation for details: /// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo - virtual ModRefInfo getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2); + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); /// \brief Return information about whether a particular call site modifies /// or reads the specified memory location \p MemLoc before instruction \p I @@ -542,8 +526,403 @@ const ModRefInfo Mode) { return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode); } + +private: + class Concept; + template class Model; + + template friend class AAResultBase; + + std::vector> AAs; +}; + +/// Temporary typedef for legacy code that uses a generic \c AliasAnalysis +/// pointer or reference. +typedef AAResults AliasAnalysis; + +/// A private abstract base class describing the concept of an individual alias +/// analysis implementation. +/// +/// This interface is implemented by any \c Model instantiation. It is also the +/// interface which a type used to instantiate the model must provide. +/// +/// All of these methods model methods by the same name in the \c +/// AAResults class. Only differences and specifics to how the +/// implementations are called are documented here. +class AAResults::Concept { +public: + virtual ~Concept() = 0; + + /// An update API used internally by the AAResults to provide + /// a handle back to the top level aggregation. + virtual void setAAResults(AAResults *NewAAR) = 0; + + //===--------------------------------------------------------------------===// + /// \name Alias Queries + /// @{ + + /// The main low level interface to the alias analysis implementation. + /// Returns an AliasResult indicating whether the two pointers are aliased to + /// each other. This is the interface that must be implemented by specific + /// alias analysis implementations. + virtual AliasResult alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) = 0; + + /// Checks whether the given location points to constant memory, or if + /// \p OrLocal is true whether it points to a local alloca. + virtual bool pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) = 0; + + /// @} + //===--------------------------------------------------------------------===// + /// \name Simple mod/ref information + /// @{ + + /// Get the ModRef info associated with a pointer argument of a callsite. The + /// result's bits are set to indicate the allowed aliasing ModRef kinds. Note + /// that these bits do not necessarily account for the overall behavior of + /// the function, but rather only provide additional per-argument + /// information. + virtual ModRefInfo getArgModRefInfo(ImmutableCallSite CS, + unsigned ArgIdx) = 0; + + /// Return the behavior of the given call site. + virtual FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) = 0; + + /// Return the behavior when calling the given function. + virtual FunctionModRefBehavior getModRefBehavior(const Function *F) = 0; + + /// getModRefInfo (for call sites) - Return information about whether + /// a particular call site modifies or reads the specified memory location. + virtual ModRefInfo getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) = 0; + + /// Return information about whether two call sites may refer to the same set + /// of memory locations. See the AA documentation for details: + /// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo + virtual ModRefInfo getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) = 0; + + /// @} }; +/// A private class template which derives from \c Concept and wraps some other +/// type. +/// +/// This models the concept by directly forwarding each interface point to the +/// wrapped type which must implement a compatible interface. This provides +/// a type erased binding. +template class AAResults::Model final : public Concept { + AAResultT &Result; + +public: + explicit Model(AAResultT &Result, AAResults &AAR) : Result(Result) { + Result.setAAResults(&AAR); + } + ~Model() override {} + + void setAAResults(AAResults *NewAAR) override { Result.setAAResults(NewAAR); } + + AliasResult alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) override { + return Result.alias(LocA, LocB); + } + + bool pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) override { + return Result.pointsToConstantMemory(Loc, OrLocal); + } + + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override { + return Result.getArgModRefInfo(CS, ArgIdx); + } + + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override { + return Result.getModRefBehavior(CS); + } + + FunctionModRefBehavior getModRefBehavior(const Function *F) override { + return Result.getModRefBehavior(F); + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) override { + return Result.getModRefInfo(CS, Loc); + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) override { + return Result.getModRefInfo(CS1, CS2); + } +}; + +/// A CRTP-driven "mixin" base class to help implement the function alias +/// analysis results concept. +/// +/// Because of the nature of many alias analysis implementations, they often +/// only implement a subset of the interface. This base class will attempt to +/// implement the remaining portions of the interface in terms of simpler forms +/// of the interface where possible, and otherwise provide conservatively +/// correct fallback implementations. +/// +/// Implementors of an alias analysis should derive from this CRTP, and then +/// override specific methods that they wish to customize. There is no need to +/// use virtual anywhere, the CRTP base class does static dispatch to the +/// derived type passed into it. +template class AAResultBase { + // Expose some parts of the interface only to the AAResults::Model + // for wrapping. Specifically, this allows the model to call our + // setAAResults method without exposing it as a fully public API. + friend class AAResults::Model; + + /// A pointer to the AAResults object that this AAResult is + /// aggregated within. May be null if not aggregated. + AAResults *AAR; + + /// Helper to dispatch calls back through the derived type. + DerivedT &derived() { return static_cast(*this); } + + /// A setter for the AAResults pointer, which is used to satisfy the + /// AAResults::Model contract. + void setAAResults(AAResults *NewAAR) { AAR = NewAAR; } + +protected: + /// This proxy class models a common pattern where we delegate to either the + /// top-level \c AAResults aggregation if one is registered, or to the + /// current result if none are registered. + class AAResultsProxy { + AAResults *AAR; + DerivedT &CurrentResult; + + public: + AAResultsProxy(AAResults *AAR, DerivedT &CurrentResult) + : AAR(AAR), CurrentResult(CurrentResult) {} + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { + return AAR ? AAR->alias(LocA, LocB) : CurrentResult.alias(LocA, LocB); + } + + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) { + return AAR ? AAR->pointsToConstantMemory(Loc, OrLocal) + : CurrentResult.pointsToConstantMemory(Loc, OrLocal); + } + + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { + return AAR ? AAR->getArgModRefInfo(CS, ArgIdx) : CurrentResult.getArgModRefInfo(CS, ArgIdx); + } + + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) { + return AAR ? AAR->getModRefBehavior(CS) : CurrentResult.getModRefBehavior(CS); + } + + FunctionModRefBehavior getModRefBehavior(const Function *F) { + return AAR ? AAR->getModRefBehavior(F) : CurrentResult.getModRefBehavior(F); + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) { + return AAR ? AAR->getModRefInfo(CS, Loc) + : CurrentResult.getModRefInfo(CS, Loc); + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { + return AAR ? AAR->getModRefInfo(CS1, CS2) : CurrentResult.getModRefInfo(CS1, CS2); + } + }; + + const TargetLibraryInfo &TLI; + + explicit AAResultBase(const TargetLibraryInfo &TLI) : TLI(TLI) {} + + // 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) {} + + /// 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. + AAResultsProxy getBestAAResults() { return AAResultsProxy(AAR, derived()); } + +public: + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { + return MayAlias; + } + + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) { + return false; + } + + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { + return MRI_ModRef; + } + + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) { + if (const Function *F = CS.getCalledFunction()) + return getBestAAResults().getModRefBehavior(F); + + return FMRB_UnknownModRefBehavior; + } + + FunctionModRefBehavior getModRefBehavior(const Function *F) { + 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 (ImmutableCallSite::arg_iterator 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 (ImmutableCallSite::arg_iterator 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; + } + + // 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 (ImmutableCallSite::arg_iterator 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; + } + + return Mask; +} + /// isNoAliasCall - Return true if this pointer is returned by a noalias /// function. bool isNoAliasCall(const Value *V); @@ -568,6 +947,88 @@ /// IdentifiedObjects. bool isIdentifiedFunctionLocal(const Value *V); +/// A manager for alias analyses. +/// +/// This class can have analyses registered with it and when run, it will run +/// all of them and aggregate their results into single AA results interface +/// that dispatches across all of the alias analysis results available. +/// +/// Note that the order in which analyses are registered is very significant. +/// That is the order in which the results will be aggregated and queried. +/// +/// This manager effectively wraps the AnalysisManager for registering alias +/// analyses. When you register your alias analysis with this manager, it will +/// ensure the analysis itself is registered with its AnalysisManager. +class AAManager { +public: + typedef AAResults Result; + + // This type hase value semantics. We have to spell these out because MSVC + // won't synthesize them. + AAManager() {} + AAManager(AAManager &&Arg) + : FunctionResultGetters(std::move(Arg.FunctionResultGetters)) {} + AAManager(const AAManager &Arg) + : FunctionResultGetters(Arg.FunctionResultGetters) {} + AAManager &operator=(AAManager &&RHS) { + FunctionResultGetters = std::move(RHS.FunctionResultGetters); + return *this; + } + AAManager &operator=(const AAManager &RHS) { + FunctionResultGetters = RHS.FunctionResultGetters; + return *this; + } + + /// Register a specific AA result. + template void registerFunctionAnalysis() { + FunctionResultGetters.push_back(&getFunctionAAResultImpl); + } + + Result run(Function &F, AnalysisManager &AM) { + Result R; + for (auto &Getter : FunctionResultGetters) + (*Getter)(F, AM, R); + return R; + } + +private: + SmallVector &AM, + AAResults &AAResults), + 4> FunctionResultGetters; + + template + static void getFunctionAAResultImpl(Function &F, + AnalysisManager &AM, + AAResults &AAResults) { + AAResults.addAAResult(AM.template getResult(F)); + } +}; + +/// A wrapper pass to provide the legacy pass manager access to a suitably +/// prepared AAResults object. +class AAResultsWrapperPass : public FunctionPass { + std::unique_ptr AAR; + +public: + static char ID; + + AAResultsWrapperPass(); + + AAResults &getAAResults() { return *AAR; } + const AAResults &getAAResults() const { return *AAR; } + + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +FunctionPass *createAAResultsWrapperPass(); + +/// A helper for the legacy pass manager to create a \c AAResults +/// object populated to the best of our ability for a particular function when +/// inside of a \c ModulePass or a \c CallGraphSCCPass. +AAResults createLegacyPMAAResults(Pass &P, Function &F, BasicAAResult &BAR); + } // End llvm namespace #endif Index: include/llvm/Analysis/AliasAnalysisCounter.h =================================================================== --- include/llvm/Analysis/AliasAnalysisCounter.h +++ /dev/null @@ -1,65 +0,0 @@ -//===- AliasAnalysisCounter.h - Alias Analysis Query Counter ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// \file -/// This declares an alias analysis which counts and prints queries made -/// through it. By inserting this between other AAs you can track when specific -/// layers of LLVM's AA get queried. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_ALIASANALYSISCOUNTER_H -#define LLVM_ANALYSIS_ALIASANALYSISCOUNTER_H - -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/IR/Module.h" -#include "llvm/Pass.h" - -namespace llvm { - -class AliasAnalysisCounter : public ModulePass, public AliasAnalysis { - unsigned No, May, Partial, Must; - unsigned NoMR, JustRef, JustMod, MR; - Module *M; - -public: - static char ID; // Class identification, replacement for typeinfo - - AliasAnalysisCounter(); - ~AliasAnalysisCounter() override; - - bool runOnModule(Module &M) override; - - void getAnalysisUsage(AnalysisUsage &AU) const override; - - /// getAdjustedAnalysisPointer - This method is used when a pass implements - /// an analysis interface through multiple inheritance. If needed, it - /// should override this to adjust the this pointer as needed for the - /// specified pass info. - void *getAdjustedAnalysisPointer(AnalysisID PI) override; - - // Forwarding functions: just delegate to a real AA implementation, counting - // the number of responses... - AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) override; - - using AliasAnalysis::getModRefInfo; - ModRefInfo getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) override; -}; - -//===--------------------------------------------------------------------===// -// -// createAliasAnalysisCounterPass - This pass counts alias queries and how the -// alias analysis implementation responds. -// -ModulePass *createAliasAnalysisCounterPass(); - -} - -#endif Index: include/llvm/Analysis/AliasSetTracker.h =================================================================== --- include/llvm/Analysis/AliasSetTracker.h +++ include/llvm/Analysis/AliasSetTracker.h @@ -20,13 +20,13 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/ValueHandle.h" #include namespace llvm { -class AliasAnalysis; class LoadInst; class StoreInst; class VAArgInst; Index: include/llvm/Analysis/BasicAliasAnalysis.h =================================================================== --- include/llvm/Analysis/BasicAliasAnalysis.h +++ include/llvm/Analysis/BasicAliasAnalysis.h @@ -23,14 +23,26 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" -#include "llvm/Pass.h" +#include "llvm/IR/PassManager.h" #include "llvm/Support/ErrorHandling.h" namespace llvm { - -/// This is the primary alias analysis implementation. -struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis { - static char ID; // Class identification, replacement for typeinfo +class AssumptionCache; +class DominatorTree; +class LoopInfo; + +/// This is the AA result object for the basic, local, and stateless alias +/// analysis. It implements the AA query interface in an entirely stateless +/// manner. As one consequence, it is never invalidated. While it does retain +/// some storage, that is used as an optimization and not to preserve +/// information from query to query. +class BasicAAResult : public AAResultBase { + friend AAResultBase; + + const DataLayout &DL; + AssumptionCache &AC; + DominatorTree *DT; + LoopInfo *LI; #ifndef NDEBUG static const Function *getParent(const Value *V) { @@ -52,20 +64,24 @@ } #endif - BasicAliasAnalysis() : ImmutablePass(ID) { - initializeBasicAliasAnalysisPass(*PassRegistry::getPassRegistry()); - } +public: + 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) {} - bool doInitialization(Module &M) override; + 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), + LI(Arg.LI) {} - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - } + /// Handle invalidation events from the new pass manager. + /// + /// 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) override { + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { assert(AliasCache.empty() && "AliasCache must be cleared after use!"); assert(notDifferentParent(LocA.Ptr, LocB.Ptr) && "BasicAliasAnalysis doesn't support interprocedural queries."); @@ -80,33 +96,22 @@ return Alias; } - ModRefInfo getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) override; + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); - ModRefInfo getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) override; + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); /// Chases pointers until we find a (constant global) or not. - bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override; + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal); /// Get the location associated with a pointer argument of a callsite. - ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override; + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx); /// Returns the behavior when calling the given call site. - FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); /// Returns the behavior when calling the given function. For use when the /// call site is not known. - FunctionModRefBehavior getModRefBehavior(const Function *F) override; - - /// This method is used when a pass implements an analysis interface through - /// multiple inheritance. If needed, it should override this to adjust the - /// this pointer as needed for the specified pass info. - void *getAdjustedAnalysisPointer(const void *ID) override { - if (ID == &AliasAnalysis::ID) - return (AliasAnalysis *)this; - return this; - } + FunctionModRefBehavior getModRefBehavior(const Function *F); private: // A linear transformation of a Value; this class represents ZExt(SExt(V, @@ -181,8 +186,7 @@ bool constantOffsetHeuristic(const SmallVectorImpl &VarIndices, uint64_t V1Size, uint64_t V2Size, int64_t BaseOffset, - const DataLayout *DL, AssumptionCache *AC, - DominatorTree *DT); + AssumptionCache *AC, DominatorTree *DT); bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2); @@ -206,13 +210,47 @@ const Value *V2, uint64_t V2Size, AAMDNodes V2AATag); }; -//===--------------------------------------------------------------------===// -// -// createBasicAliasAnalysisPass - This pass implements the stateless alias -// analysis. -// -ImmutablePass *createBasicAliasAnalysisPass(); +/// Analysis pass providing a never-invalidated alias analysis result. +class BasicAA { +public: + typedef BasicAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + BasicAAResult run(Function &F, AnalysisManager *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "BasicAliasAnalysis"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the BasicAAResult object. +class BasicAAWrapperPass : public FunctionPass { + std::unique_ptr Result; + + virtual void anchor(); + +public: + static char ID; + + BasicAAWrapperPass() : FunctionPass(ID) {} + + BasicAAResult &getResult() { return *Result; } + const BasicAAResult &getResult() const { return *Result; } + + bool runOnFunction(Function &F) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +FunctionPass *createBasicAAWrapperPass(); +/// A helper for the legacy pass manager to create a \c BasicAAResult object +/// populated to the best of our ability for a particular function when inside +/// of a \c ModulePass or a \c CallGraphSCCPass. +BasicAAResult createLegacyPMBasicAAResult(Pass &P, Function &F); } #endif Index: include/llvm/Analysis/CFLAliasAnalysis.h =================================================================== --- include/llvm/Analysis/CFLAliasAnalysis.h +++ include/llvm/Analysis/CFLAliasAnalysis.h @@ -26,47 +26,19 @@ namespace llvm { -class CFLAliasAnalysis : public ImmutablePass, public AliasAnalysis { - struct FunctionInfo; - - struct FunctionHandle final : public CallbackVH { - FunctionHandle(Function *Fn, CFLAliasAnalysis *CFLAA) - : CallbackVH(Fn), CFLAA(CFLAA) { - assert(Fn != nullptr); - assert(CFLAA != nullptr); - } - - void deleted() override { removeSelfFromCache(); } - void allUsesReplacedWith(Value *) override { removeSelfFromCache(); } - - private: - CFLAliasAnalysis *CFLAA; +class CFLAAResult : public AAResultBase { + friend AAResultBase; - void removeSelfFromCache() { - assert(CFLAA != nullptr); - auto *Val = getValPtr(); - CFLAA->evict(cast(Val)); - setValPtr(nullptr); - } - }; - - /// \brief Cached mapping of Functions to their StratifiedSets. - /// If a function's sets are currently being built, it is marked - /// in the cache as an Optional without a value. This way, if we - /// have any kind of recursion, it is discernable from a function - /// that simply has empty sets. - DenseMap> Cache; - std::forward_list Handles; + struct FunctionInfo; public: - static char ID; - - CFLAliasAnalysis(); - ~CFLAliasAnalysis() override; - - void getAnalysisUsage(AnalysisUsage &AU) const override; + explicit CFLAAResult(const TargetLibraryInfo &TLI); + CFLAAResult(CFLAAResult &&Arg); - void *getAdjustedAnalysisPointer(const void *ID) override; + /// Handle invalidation events from the new pass manager. + /// + /// By definition, this result is stateless and so remains valid. + bool invalidate(Function &, const PreservedAnalyses &) { return false; } /// \brief Inserts the given Function into the cache. void scan(Function *Fn); @@ -79,8 +51,7 @@ AliasResult query(const MemoryLocation &LocA, const MemoryLocation &LocB); - AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) override { + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { if (LocA.Ptr == LocB.Ptr) { if (LocA.Size == LocB.Size) { return MustAlias; @@ -96,29 +67,92 @@ // one Value tied to a Function, and neither GlobalValues nor ConstantExprs // are. if (isa(LocA.Ptr) && isa(LocB.Ptr)) { - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); } AliasResult QueryResult = query(LocA, LocB); if (QueryResult == MayAlias) - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); return QueryResult; } - bool doInitialization(Module &M) override; - private: + struct FunctionHandle final : public CallbackVH { + FunctionHandle(Function *Fn, CFLAAResult *Result) + : CallbackVH(Fn), Result(Result) { + assert(Fn != nullptr); + assert(Result != nullptr); + } + + void deleted() override { removeSelfFromCache(); } + void allUsesReplacedWith(Value *) override { removeSelfFromCache(); } + + private: + CFLAAResult *Result; + + void removeSelfFromCache() { + assert(Result != nullptr); + auto *Val = getValPtr(); + Result->evict(cast(Val)); + setValPtr(nullptr); + } + }; + + /// \brief Cached mapping of Functions to their StratifiedSets. + /// If a function's sets are currently being built, it is marked + /// in the cache as an Optional without a value. This way, if we + /// have any kind of recursion, it is discernable from a function + /// that simply has empty sets. + DenseMap> Cache; + std::forward_list Handles; + FunctionInfo buildSetsFrom(Function *F); }; +/// Analysis pass providing a never-invalidated alias analysis result. +/// +/// FIXME: We really should refactor CFL to use the analysis more heavily, and +/// in particular to leverage invalidation to trigger re-computation of sets. +class CFLAA { +public: + typedef CFLAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + CFLAAResult run(Function &F, AnalysisManager *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "CFLAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the CFLAAResult object. +class CFLAAWrapperPass : public ImmutablePass { + std::unique_ptr Result; + +public: + static char ID; + + CFLAAWrapperPass(); + + CFLAAResult &getResult() { return *Result; } + const CFLAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + //===--------------------------------------------------------------------===// // -// createCFLAliasAnalysisPass - This pass implements a set-based approach to +// createCFLAAWrapperPass - This pass implements a set-based approach to // alias analysis. // -ImmutablePass *createCFLAliasAnalysisPass(); - +ImmutablePass *createCFLAAWrapperPass(); } #endif Index: include/llvm/Analysis/DependenceAnalysis.h =================================================================== --- include/llvm/Analysis/DependenceAnalysis.h +++ include/llvm/Analysis/DependenceAnalysis.h @@ -42,11 +42,11 @@ #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/Instructions.h" #include "llvm/Pass.h" namespace llvm { - class AliasAnalysis; class Loop; class LoopInfo; class ScalarEvolution; Index: include/llvm/Analysis/GlobalsModRef.h =================================================================== --- include/llvm/Analysis/GlobalsModRef.h +++ include/llvm/Analysis/GlobalsModRef.h @@ -25,10 +25,17 @@ namespace llvm { -/// GlobalsModRef - The actual analysis pass. -class GlobalsModRef : public ModulePass, public AliasAnalysis { +/// An alias analysis result set for globals. +/// +/// This focuses on handling aliasing properties of globals and interprocedural +/// function call mod/ref information. +class GlobalsAAResult : public AAResultBase { + friend AAResultBase; + class FunctionInfo; + const DataLayout &DL; + /// The globals that do not have their addresses taken. SmallPtrSet NonAddressTakenGlobals; @@ -45,11 +52,11 @@ /// Handle to clear this analysis on deletion of values. struct DeletionCallbackHandle final : CallbackVH { - GlobalsModRef &GMR; + GlobalsAAResult &GAR; std::list::iterator I; - DeletionCallbackHandle(GlobalsModRef &GMR, Value *V) - : CallbackVH(V), GMR(GMR) {} + DeletionCallbackHandle(GlobalsAAResult &GAR, Value *V) + : CallbackVH(V), GAR(GAR) {} void deleted() override; }; @@ -60,56 +67,31 @@ /// could perform to the memory utilization here if this becomes a problem. std::list Handles; + explicit GlobalsAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI); + public: - static char ID; - GlobalsModRef(); - - bool runOnModule(Module &M) override { - InitializeAliasAnalysis(this, &M.getDataLayout()); - - // Find non-addr taken globals. - AnalyzeGlobals(M); - - // Propagate on CG. - AnalyzeCallGraph(getAnalysis().getCallGraph(), M); - return false; - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AliasAnalysis::getAnalysisUsage(AU); - AU.addRequired(); - AU.setPreservesAll(); // Does not transform code - } - - /// getAdjustedAnalysisPointer - This method is used when a pass implements - /// an analysis interface through multiple inheritance. If needed, it - /// should override this to adjust the this pointer as needed for the - /// specified pass info. - void *getAdjustedAnalysisPointer(AnalysisID PI) override { - if (PI == &AliasAnalysis::ID) - return (AliasAnalysis *)this; - return this; - } + GlobalsAAResult(GlobalsAAResult &&Arg); + + static GlobalsAAResult analyzeModule(Module &M, const TargetLibraryInfo &TLI, + CallGraph &CG); //------------------------------------------------ // Implement the AliasAnalysis API // - AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) override; + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); - using AliasAnalysis::getModRefInfo; - ModRefInfo getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) override; + using AAResultBase::getModRefInfo; + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); /// getModRefBehavior - Return the behavior of the specified function if /// called from the specified call site. The call site may be null in which /// case the most generic behavior of this function should be returned. - FunctionModRefBehavior getModRefBehavior(const Function *F) override; + FunctionModRefBehavior getModRefBehavior(const Function *F); /// getModRefBehavior - Return the behavior of the specified function if /// called from the specified call site. The call site may be null in which /// case the most generic behavior of this function should be returned. - FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); private: FunctionInfo *getFunctionInfo(const Function *F); @@ -125,13 +107,46 @@ bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V); }; +/// Analysis pass providing a never-invalidated alias analysis result. +class GlobalsAA { +public: + typedef GlobalsAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + GlobalsAAResult run(Module &M, AnalysisManager *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "GlobalsAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the GlobalsAAResult object. +class GlobalsAAWrapperPass : public ModulePass { + std::unique_ptr Result; + +public: + static char ID; + + GlobalsAAWrapperPass(); + + GlobalsAAResult &getResult() { return *Result; } + const GlobalsAAResult &getResult() const { return *Result; } + + bool runOnModule(Module &M) override; + bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + //===--------------------------------------------------------------------===// // -// createGlobalsModRefPass - This pass provides alias and mod/ref info for +// createGlobalsAAWrapperPass - This pass provides alias and mod/ref info for // global values that do not have their addresses taken. // -Pass *createGlobalsModRefPass(); - +ModulePass *createGlobalsAAWrapperPass(); } #endif Index: include/llvm/Analysis/Loads.h =================================================================== --- include/llvm/Analysis/Loads.h +++ include/llvm/Analysis/Loads.h @@ -14,11 +14,11 @@ #ifndef LLVM_ANALYSIS_LOADS_H #define LLVM_ANALYSIS_LOADS_H +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/BasicBlock.h" namespace llvm { -class AliasAnalysis; class DataLayout; class MDNode; Index: include/llvm/Analysis/LoopAccessAnalysis.h =================================================================== --- include/llvm/Analysis/LoopAccessAnalysis.h +++ include/llvm/Analysis/LoopAccessAnalysis.h @@ -29,7 +29,6 @@ class Value; class DataLayout; -class AliasAnalysis; class ScalarEvolution; class Loop; class SCEV; Index: include/llvm/Analysis/MemoryDependenceAnalysis.h =================================================================== --- include/llvm/Analysis/MemoryDependenceAnalysis.h +++ include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -28,7 +28,6 @@ class FunctionPass; class Instruction; class CallSite; - class AliasAnalysis; class AssumptionCache; class MemoryDependenceAnalysis; class PredIteratorCache; Index: include/llvm/Analysis/ObjCARCAliasAnalysis.h =================================================================== --- include/llvm/Analysis/ObjCARCAliasAnalysis.h +++ include/llvm/Analysis/ObjCARCAliasAnalysis.h @@ -24,6 +24,7 @@ #define LLVM_ANALYSIS_OBJCARCALIASANALYSIS_H #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Pass.h" namespace llvm { @@ -35,35 +36,64 @@ /// TODO: This class could be generalized to know about other ObjC-specific /// tricks. Such as knowing that ivars in the non-fragile ABI are non-aliasing /// even though their offsets are dynamic. -class ObjCARCAliasAnalysis : public ImmutablePass, public AliasAnalysis { +class ObjCARCAAResult : public AAResultBase { + friend AAResultBase; + + const DataLayout &DL; + +public: + explicit ObjCARCAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI) + : AAResultBase(TLI), DL(DL) {} + ObjCARCAAResult(ObjCARCAAResult &&Arg) + : AAResultBase(std::move(Arg)), DL(Arg.DL) {} + + /// Handle invalidation events from the new pass manager. + /// + /// 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); + + using AAResultBase::getModRefBehavior; + FunctionModRefBehavior getModRefBehavior(const Function *F); + + using AAResultBase::getModRefInfo; + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class ObjCARCAA { public: - static char ID; // Class identification, replacement for typeinfo - ObjCARCAliasAnalysis() : ImmutablePass(ID) { - initializeObjCARCAliasAnalysisPass(*PassRegistry::getPassRegistry()); - } + typedef ObjCARCAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + ObjCARCAAResult run(Function &F, AnalysisManager *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "ObjCARCAA"; } private: - bool doInitialization(Module &M) override; + static char PassID; +}; - /// This method is used when a pass implements an analysis interface through - /// multiple inheritance. If needed, it should override this to adjust the - /// this pointer as needed for the specified pass info. - void *getAdjustedAnalysisPointer(const void *PI) override { - if (PI == &AliasAnalysis::ID) - return static_cast(this); - return this; - } +/// Legacy wrapper pass to provide the ObjCARCAAResult object. +class ObjCARCAAWrapperPass : public ImmutablePass { + std::unique_ptr Result; +public: + static char ID; + + ObjCARCAAWrapperPass(); + + ObjCARCAAResult &getResult() { return *Result; } + const ObjCARCAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; void getAnalysisUsage(AnalysisUsage &AU) const override; - AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) override; - bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override; - FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; - FunctionModRefBehavior getModRefBehavior(const Function *F) override; - ModRefInfo getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) override; - ModRefInfo getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) override; }; } // namespace objcarc Index: include/llvm/Analysis/Passes.h =================================================================== --- include/llvm/Analysis/Passes.h +++ include/llvm/Analysis/Passes.h @@ -32,16 +32,10 @@ //===--------------------------------------------------------------------===// // - // createNoAAPass - This pass implements a "I don't know" alias analysis. - // - ImmutablePass *createNoAAPass(); - - //===--------------------------------------------------------------------===// - // - // createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based + // createObjCARCAAWrapperPass - This pass implements ObjC-ARC-based // alias analysis. // - ImmutablePass *createObjCARCAliasAnalysisPass(); + ImmutablePass *createObjCARCAAWrapperPass(); FunctionPass *createPAEvalPass(); Index: include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h =================================================================== --- include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h +++ include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h @@ -24,38 +24,55 @@ /// A simple alias analysis implementation that uses ScalarEvolution to answer /// queries. -class ScalarEvolutionAliasAnalysis : public FunctionPass, public AliasAnalysis { - ScalarEvolution *SE; +class SCEVAAResult : public AAResultBase { + ScalarEvolution &SE; public: - static char ID; // Class identification, replacement for typeinfo - ScalarEvolutionAliasAnalysis() : FunctionPass(ID), SE(nullptr) { - initializeScalarEvolutionAliasAnalysisPass( - *PassRegistry::getPassRegistry()); - } - - /// This method is used when a pass implements an analysis interface through - /// multiple inheritance. - /// - /// If needed, it should override this to adjust the this pointer as needed - /// for the specified pass info. - void *getAdjustedAnalysisPointer(AnalysisID PI) override { - if (PI == &AliasAnalysis::ID) - return (AliasAnalysis *)this; - return this; - } + explicit SCEVAAResult(const TargetLibraryInfo &TLI, ScalarEvolution &SE) + : AAResultBase(TLI), SE(SE) {} + SCEVAAResult(SCEVAAResult &&Arg) : AAResultBase(std::move(Arg)), SE(Arg.SE) {} -private: - void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnFunction(Function &F) override; - AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) override; + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); +private: Value *GetBaseValue(const SCEV *S); }; -/// Creates an instance of \c ScalarEvolutionAliasAnalysis. -FunctionPass *createScalarEvolutionAliasAnalysisPass(); +/// Analysis pass providing a never-invalidated alias analysis result. +class SCEVAA { +public: + typedef SCEVAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + SCEVAAResult run(Function &F, AnalysisManager *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "SCEVAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the SCEVAAResult object. +class SCEVAAWrapperPass : public FunctionPass { + std::unique_ptr Result; + +public: + static char ID; + + SCEVAAWrapperPass(); + + SCEVAAResult &getResult() { return *Result; } + const SCEVAAResult &getResult() const { return *Result; } + + bool runOnFunction(Function &F) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +/// Creates an instance of \c SCEVAAWrapperPass. +FunctionPass *createSCEVAAWrapperPass(); } Index: include/llvm/Analysis/ScopedNoAliasAA.h =================================================================== --- include/llvm/Analysis/ScopedNoAliasAA.h +++ include/llvm/Analysis/ScopedNoAliasAA.h @@ -22,52 +22,71 @@ namespace llvm { -/// ScopedNoAliasAA - This is a simple alias analysis -/// implementation that uses scoped-noalias metadata to answer queries. -class ScopedNoAliasAA : public ImmutablePass, public AliasAnalysis { +/// A simple AA result which uses scoped-noalias metadata to answer queries. +class ScopedNoAliasAAResult : public AAResultBase { + friend AAResultBase; + public: - static char ID; // Class identification, replacement for typeinfo - ScopedNoAliasAA() : ImmutablePass(ID) { - initializeScopedNoAliasAAPass(*PassRegistry::getPassRegistry()); - } + explicit ScopedNoAliasAAResult(const TargetLibraryInfo &TLI) + : AAResultBase(TLI) {} + ScopedNoAliasAAResult(ScopedNoAliasAAResult &&Arg) + : AAResultBase(std::move(Arg)) {} - bool doInitialization(Module &M) override; + /// Handle invalidation events from the new pass manager. + /// + /// 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); + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); - /// getAdjustedAnalysisPointer - This method is used when a pass implements - /// an analysis interface through multiple inheritance. If needed, it - /// should override this to adjust the this pointer as needed for the - /// specified pass info. - void *getAdjustedAnalysisPointer(const void *PI) override { - if (PI == &AliasAnalysis::ID) - return (AliasAnalysis *)this; - return this; - } - -protected: +private: bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias) const; void collectMDInDomain(const MDNode *List, const MDNode *Domain, SmallPtrSetImpl &Nodes) const; +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class ScopedNoAliasAA { +public: + typedef ScopedNoAliasAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + ScopedNoAliasAAResult run(Function &F, AnalysisManager *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "ScopedNoAliasAA"; } private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the ScopedNoAliasAAResult object. +class ScopedNoAliasAAWrapperPass : public ImmutablePass { + std::unique_ptr Result; + +public: + static char ID; + + ScopedNoAliasAAWrapperPass(); + + ScopedNoAliasAAResult &getResult() { return *Result; } + const ScopedNoAliasAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; void getAnalysisUsage(AnalysisUsage &AU) const override; - AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) override; - bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override; - FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; - FunctionModRefBehavior getModRefBehavior(const Function *F) override; - ModRefInfo getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) override; - ModRefInfo getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) override; }; //===--------------------------------------------------------------------===// // -// createScopedNoAliasAAPass - This pass implements metadata-based +// createScopedNoAliasAAWrapperPass - This pass implements metadata-based // scoped noalias analysis. // -ImmutablePass *createScopedNoAliasAAPass(); - +ImmutablePass *createScopedNoAliasAAWrapperPass(); } #endif Index: include/llvm/Analysis/TypeBasedAliasAnalysis.h =================================================================== --- include/llvm/Analysis/TypeBasedAliasAnalysis.h +++ include/llvm/Analysis/TypeBasedAliasAnalysis.h @@ -22,50 +22,72 @@ namespace llvm { -/// TypeBasedAliasAnalysis - This is a simple alias analysis -/// implementation that uses TypeBased to answer queries. -class TypeBasedAliasAnalysis : public ImmutablePass, public AliasAnalysis { +/// A simple AA result that uses TBAA metadata to answer queries. +class TypeBasedAAResult : public AAResultBase { + friend AAResultBase; + public: - static char ID; // Class identification, replacement for typeinfo - TypeBasedAliasAnalysis() : ImmutablePass(ID) { - initializeTypeBasedAliasAnalysisPass(*PassRegistry::getPassRegistry()); - } + explicit TypeBasedAAResult(const TargetLibraryInfo &TLI) + : AAResultBase(TLI) {} + TypeBasedAAResult(TypeBasedAAResult &&Arg) : AAResultBase(std::move(Arg)) {} - bool doInitialization(Module &M) override; + /// Handle invalidation events from the new pass manager. + /// + /// By definition, this result is stateless and so remains valid. + bool invalidate(Function &, const PreservedAnalyses &) { return false; } - /// getAdjustedAnalysisPointer - This method is used when a pass implements - /// an analysis interface through multiple inheritance. If needed, it - /// should override this to adjust the this pointer as needed for the - /// specified pass info. - void *getAdjustedAnalysisPointer(const void *PI) override { - if (PI == &AliasAnalysis::ID) - return (AliasAnalysis *)this; - return this; - } + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal); + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); + FunctionModRefBehavior getModRefBehavior(const Function *F); + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); +private: bool Aliases(const MDNode *A, const MDNode *B) const; bool PathAliases(const MDNode *A, const MDNode *B) const; +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class TypeBasedAA { +public: + typedef TypeBasedAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + TypeBasedAAResult run(Function &F, AnalysisManager *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "TypeBasedAA"; } private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the TypeBasedAAResult object. +class TypeBasedAAWrapperPass : public ImmutablePass { + std::unique_ptr Result; + +public: + static char ID; + + TypeBasedAAWrapperPass(); + + TypeBasedAAResult &getResult() { return *Result; } + const TypeBasedAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; void getAnalysisUsage(AnalysisUsage &AU) const override; - AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) override; - bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override; - FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; - FunctionModRefBehavior getModRefBehavior(const Function *F) override; - ModRefInfo getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) override; - ModRefInfo getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) override; }; //===--------------------------------------------------------------------===// // -// createTypeBasedAliasAnalysisPass - This pass implements metadata-based +// createTypeBasedAAWrapperPass - This pass implements metadata-based // type-based alias analysis. // -ImmutablePass *createTypeBasedAliasAnalysisPass(); - +ImmutablePass *createTypeBasedAAWrapperPass(); } #endif Index: include/llvm/CodeGen/LiveIntervalAnalysis.h =================================================================== --- include/llvm/CodeGen/LiveIntervalAnalysis.h +++ include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -22,6 +22,7 @@ #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -36,7 +37,6 @@ extern cl::opt UseSegmentSetForPhysRegs; - class AliasAnalysis; class BitVector; class BlockFrequency; class LiveRangeCalc; Index: include/llvm/CodeGen/LiveRangeEdit.h =================================================================== --- include/llvm/CodeGen/LiveRangeEdit.h +++ include/llvm/CodeGen/LiveRangeEdit.h @@ -21,6 +21,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" @@ -28,7 +29,6 @@ namespace llvm { -class AliasAnalysis; class LiveIntervals; class MachineBlockFrequencyInfo; class MachineLoopInfo; Index: include/llvm/CodeGen/MachineInstr.h =================================================================== --- include/llvm/CodeGen/MachineInstr.h +++ include/llvm/CodeGen/MachineInstr.h @@ -23,6 +23,7 @@ #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugLoc.h" @@ -34,7 +35,6 @@ namespace llvm { template class SmallVectorImpl; -class AliasAnalysis; class TargetInstrInfo; class TargetRegisterClass; class TargetRegisterInfo; Index: include/llvm/CodeGen/MachineScheduler.h =================================================================== --- include/llvm/CodeGen/MachineScheduler.h +++ include/llvm/CodeGen/MachineScheduler.h @@ -77,6 +77,7 @@ #ifndef LLVM_CODEGEN_MACHINESCHEDULER_H #define LLVM_CODEGEN_MACHINESCHEDULER_H +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/RegisterPressure.h" #include "llvm/CodeGen/ScheduleDAGInstrs.h" @@ -87,7 +88,6 @@ extern cl::opt ForceTopDown; extern cl::opt ForceBottomUp; -class AliasAnalysis; class LiveIntervals; class MachineDominatorTree; class MachineLoopInfo; Index: include/llvm/CodeGen/ScheduleDAG.h =================================================================== --- include/llvm/CodeGen/ScheduleDAG.h +++ include/llvm/CodeGen/ScheduleDAG.h @@ -20,11 +20,11 @@ #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Target/TargetLowering.h" namespace llvm { - class AliasAnalysis; class SUnit; class MachineConstantPool; class MachineFunction; Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -19,6 +19,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/ilist.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/DAGCombine.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAGNodes.h" @@ -31,7 +32,6 @@ namespace llvm { -class AliasAnalysis; class MachineConstantPoolValue; class MachineFunction; class MDNode; Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -63,8 +63,6 @@ void initializeAddDiscriminatorsPass(PassRegistry&); void initializeADCEPass(PassRegistry&); void initializeBDCEPass(PassRegistry&); -void initializeAliasAnalysisAnalysisGroup(PassRegistry&); -void initializeAliasAnalysisCounterPass(PassRegistry&); void initializeAliasSetPrinterPass(PassRegistry&); void initializeAlwaysInlinerPass(PassRegistry&); void initializeArgPromotionPass(PassRegistry&); @@ -72,7 +70,7 @@ void initializeSampleProfileLoaderPass(PassRegistry&); void initializeAlignmentFromAssumptionsPass(PassRegistry&); void initializeBarrierNoopPass(PassRegistry&); -void initializeBasicAliasAnalysisPass(PassRegistry&); +void initializeBasicAAWrapperPassPass(PassRegistry&); void initializeCallGraphWrapperPassPass(PassRegistry &); void initializeBlockExtractorPassPass(PassRegistry&); void initializeBlockFrequencyInfoWrapperPassPass(PassRegistry&); @@ -86,7 +84,7 @@ void initializeCFGOnlyViewerPass(PassRegistry&); void initializeCFGPrinterPass(PassRegistry&); void initializeCFGSimplifyPassPass(PassRegistry&); -void initializeCFLAliasAnalysisPass(PassRegistry&); +void initializeCFLAAWrapperPassPass(PassRegistry&); void initializeForwardControlFlowIntegrityPass(PassRegistry&); void initializeFlattenCFGPassPass(PassRegistry&); void initializeStructurizeCFGPass(PassRegistry&); @@ -116,6 +114,7 @@ void initializeEarlyIfConverterPass(PassRegistry&); void initializeEdgeBundlesPass(PassRegistry&); void initializeExpandPostRAPass(PassRegistry&); +void initializeAAResultsWrapperPassPass(PassRegistry &); void initializeGCOVProfilerPass(PassRegistry&); void initializeInstrProfilingPass(PassRegistry&); void initializeAddressSanitizerPass(PassRegistry&); @@ -134,7 +133,7 @@ void initializeGVNPass(PassRegistry&); void initializeGlobalDCEPass(PassRegistry&); void initializeGlobalOptPass(PassRegistry&); -void initializeGlobalsModRefPass(PassRegistry&); +void initializeGlobalsAAWrapperPassPass(PassRegistry&); void initializeIPCPPass(PassRegistry&); void initializeIPSCCPPass(PassRegistry&); void initializeIVUsersPass(PassRegistry&); @@ -205,7 +204,7 @@ void initializeModuleDebugInfoPrinterPass(PassRegistry&); void initializeNaryReassociatePass(PassRegistry&); void initializeNoAAPass(PassRegistry&); -void initializeObjCARCAliasAnalysisPass(PassRegistry&); +void initializeObjCARCAAWrapperPassPass(PassRegistry&); void initializeObjCARCAPElimPass(PassRegistry&); void initializeObjCARCExpandPass(PassRegistry&); void initializeObjCARCContractPass(PassRegistry&); @@ -243,7 +242,7 @@ void initializeSROAPass(PassRegistry&); void initializeSROA_DTPass(PassRegistry&); void initializeSROA_SSAUpPass(PassRegistry&); -void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&); +void initializeSCEVAAWrapperPassPass(PassRegistry&); void initializeScalarEvolutionWrapperPassPass(PassRegistry&); void initializeShrinkWrapPass(PassRegistry &); void initializeSimpleInlinerPass(PassRegistry&); @@ -271,8 +270,8 @@ void initializeTargetLibraryInfoWrapperPassPass(PassRegistry &); void initializeAssumptionCacheTrackerPass(PassRegistry &); void initializeTwoAddressInstructionPassPass(PassRegistry&); -void initializeTypeBasedAliasAnalysisPass(PassRegistry&); -void initializeScopedNoAliasAAPass(PassRegistry&); +void initializeTypeBasedAAWrapperPassPass(PassRegistry&); +void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&); void initializeUnifyFunctionExitNodesPass(PassRegistry&); void initializeUnreachableBlockElimPass(PassRegistry&); void initializeUnreachableMachineBlockElimPass(PassRegistry&); Index: include/llvm/LinkAllPasses.h =================================================================== --- include/llvm/LinkAllPasses.h +++ include/llvm/LinkAllPasses.h @@ -17,7 +17,6 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasSetTracker.h" -#include "llvm/Analysis/AliasAnalysisCounter.h" #include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/CFLAliasAnalysis.h" #include "llvm/Analysis/CallPrinter.h" @@ -59,19 +58,18 @@ (void) llvm::createAAEvalPass(); (void) llvm::createAggressiveDCEPass(); (void) llvm::createBitTrackingDCEPass(); - (void) llvm::createAliasAnalysisCounterPass(); (void) llvm::createArgumentPromotionPass(); (void) llvm::createAlignmentFromAssumptionsPass(); - (void) llvm::createBasicAliasAnalysisPass(); - (void) llvm::createScalarEvolutionAliasAnalysisPass(); - (void) llvm::createTypeBasedAliasAnalysisPass(); - (void) llvm::createScopedNoAliasAAPass(); + (void) llvm::createBasicAAWrapperPass(); + (void) llvm::createSCEVAAWrapperPass(); + (void) llvm::createTypeBasedAAWrapperPass(); + (void) llvm::createScopedNoAliasAAWrapperPass(); (void) llvm::createBoundsCheckingPass(); (void) llvm::createBreakCriticalEdgesPass(); (void) llvm::createCallGraphPrinterPass(); (void) llvm::createCallGraphViewerPass(); (void) llvm::createCFGSimplificationPass(); - (void) llvm::createCFLAliasAnalysisPass(); + (void) llvm::createCFLAAWrapperPass(); (void) llvm::createStructurizeCFGPass(); (void) llvm::createConstantMergePass(); (void) llvm::createConstantPropagationPass(); @@ -92,7 +90,7 @@ (void) llvm::createAlwaysInlinerPass(); (void) llvm::createGlobalDCEPass(); (void) llvm::createGlobalOptimizerPass(); - (void) llvm::createGlobalsModRefPass(); + (void) llvm::createGlobalsAAWrapperPass(); (void) llvm::createIPConstantPropagationPass(); (void) llvm::createIPSCCPPass(); (void) llvm::createInductiveRangeCheckEliminationPass(); @@ -115,8 +113,7 @@ (void) llvm::createLowerInvokePass(); (void) llvm::createLowerSwitchPass(); (void) llvm::createNaryReassociatePass(); - (void) llvm::createNoAAPass(); - (void) llvm::createObjCARCAliasAnalysisPass(); + (void) llvm::createObjCARCAAWrapperPass(); (void) llvm::createObjCARCAPElimPass(); (void) llvm::createObjCARCExpandPass(); (void) llvm::createObjCARCContractPass(); Index: include/llvm/Transforms/Utils/Cloning.h =================================================================== --- include/llvm/Transforms/Utils/Cloning.h +++ include/llvm/Transforms/Utils/Cloning.h @@ -20,6 +20,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueMap.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -44,7 +45,6 @@ class Loop; class LoopInfo; class AllocaInst; -class AliasAnalysis; class AssumptionCacheTracker; class DominatorTree; @@ -202,14 +202,12 @@ class InlineFunctionInfo { public: explicit InlineFunctionInfo(CallGraph *cg = nullptr, - AliasAnalysis *AA = nullptr, AssumptionCacheTracker *ACT = nullptr) - : CG(cg), AA(AA), ACT(ACT) {} + : CG(cg), ACT(ACT) {} /// CG - If non-null, InlineFunction will update the callgraph to reflect the /// changes it makes. CallGraph *CG; - AliasAnalysis *AA; AssumptionCacheTracker *ACT; /// StaticAllocas - InlineFunction fills this in with all static allocas that @@ -237,11 +235,11 @@ /// function by one level. /// bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, - bool InsertLifetime = true); + AAResults *CalleeAAR = nullptr, bool InsertLifetime = true); bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, - bool InsertLifetime = true); + AAResults *CalleeAAR = nullptr, bool InsertLifetime = true); bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, - bool InsertLifetime = true); + AAResults *CalleeAAR = nullptr, bool InsertLifetime = true); /// \brief Clones a loop \p OrigLoop. Returns the loop and the blocks in \p /// Blocks. Index: include/llvm/Transforms/Utils/Local.h =================================================================== --- include/llvm/Transforms/Utils/Local.h +++ include/llvm/Transforms/Utils/Local.h @@ -15,6 +15,7 @@ #ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H #define LLVM_TRANSFORMS_UTILS_LOCAL_H +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/GetElementPtrTypeIterator.h" @@ -40,7 +41,6 @@ class TargetLibraryInfo; class TargetTransformInfo; class DIBuilder; -class AliasAnalysis; class DominatorTree; template class SmallVectorImpl; Index: include/llvm/Transforms/Utils/LoopUtils.h =================================================================== --- include/llvm/Transforms/Utils/LoopUtils.h +++ include/llvm/Transforms/Utils/LoopUtils.h @@ -15,11 +15,11 @@ #define LLVM_TRANSFORMS_UTILS_LOOPUTILS_H #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRBuilder.h" namespace llvm { -class AliasAnalysis; class AliasSet; class AliasSetTracker; class AssumptionCache; Index: lib/Analysis/AliasAnalysis.cpp =================================================================== --- lib/Analysis/AliasAnalysis.cpp +++ lib/Analysis/AliasAnalysis.cpp @@ -25,9 +25,16 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/CFG.h" +#include "llvm/Analysis/CFLAliasAnalysis.h" #include "llvm/Analysis/CaptureTracking.h" +#include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/ObjCARCAliasAnalysis.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" +#include "llvm/Analysis/ScopedNoAliasAA.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/DataLayout.h" @@ -40,34 +47,72 @@ #include "llvm/Pass.h" using namespace llvm; -// Register the AliasAnalysis interface, providing a nice name to refer to. -INITIALIZE_ANALYSIS_GROUP(AliasAnalysis, "Alias Analysis", NoAA) -char AliasAnalysis::ID = 0; +/// Allow disabling BasicAA from the AA results. This is particularly useful +/// when testing to isolate a single AA implementation. +static cl::opt DisableBasicAA("disable-basicaa", cl::Hidden, + cl::init(false)); + +AAResults::AAResults(AAResults &&Arg) : 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 +// pass manager that prevent this from working. In the legacy pass manager +// we'll end up with dangling references here in some cases. +#if 0 + for (auto &AA : AAs) + AA->setAAResults(nullptr); +#endif +} //===----------------------------------------------------------------------===// // Default chaining methods //===----------------------------------------------------------------------===// -AliasResult AliasAnalysis::alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) { - assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); - return AA->alias(LocA, LocB); +AliasResult AAResults::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) { + for (const auto &AA : AAs) { + auto Result = AA->alias(LocA, LocB); + if (Result != MayAlias) + return Result; + } + return MayAlias; } -bool AliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal) { - assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); - return AA->pointsToConstantMemory(Loc, OrLocal); +bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) { + for (const auto &AA : AAs) + if (AA->pointsToConstantMemory(Loc, OrLocal)) + return true; + + return false; } -ModRefInfo AliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, - unsigned ArgIdx) { - assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); - return AA->getArgModRefInfo(CS, ArgIdx); +ModRefInfo AAResults::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { + ModRefInfo Result = MRI_ModRef; + + for (const auto &AA : AAs) { + Result = ModRefInfo(Result & AA->getArgModRefInfo(CS, ArgIdx)); + + // Early-exit the moment we reach the bottom of the lattice. + if (Result == MRI_NoModRef) + return Result; + } + + return Result; } -ModRefInfo AliasAnalysis::getModRefInfo(Instruction *I, - ImmutableCallSite Call) { +ModRefInfo AAResults::getModRefInfo(Instruction *I, ImmutableCallSite Call) { // We may have two calls if (auto CS = ImmutableCallSite(I)) { // Check if the two calls modify the same memory @@ -84,177 +129,70 @@ return MRI_NoModRef; } -ModRefInfo AliasAnalysis::getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) { - assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); +ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) { + ModRefInfo Result = MRI_ModRef; - auto MRB = getModRefBehavior(CS); - if (MRB == FMRB_DoesNotAccessMemory) - return MRI_NoModRef; + for (const auto &AA : AAs) { + Result = ModRefInfo(Result & AA->getModRefInfo(CS, Loc)); - ModRefInfo Mask = MRI_ModRef; - if (onlyReadsMemory(MRB)) - Mask = MRI_Ref; - - if (onlyAccessesArgPointees(MRB)) { - bool doesAlias = false; - ModRefInfo AllArgsMask = MRI_NoModRef; - if (doesAccessArgPointees(MRB)) { - for (ImmutableCallSite::arg_iterator 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); - if (!isNoAlias(ArgLoc, Loc)) { - ModRefInfo ArgMask = getArgModRefInfo(CS, ArgIdx); - doesAlias = true; - AllArgsMask = ModRefInfo(AllArgsMask | ArgMask); - } - } - } - if (!doesAlias) - return MRI_NoModRef; - Mask = ModRefInfo(Mask & AllArgsMask); + // Early-exit the moment we reach the bottom of the lattice. + if (Result == MRI_NoModRef) + return Result; } - // If Loc is a constant memory location, the call definitely could not - // modify the memory location. - if ((Mask & MRI_Mod) && pointsToConstantMemory(Loc)) - Mask = ModRefInfo(Mask & ~MRI_Mod); - - // If this is the end of the chain, don't forward. - if (!AA) return Mask; - - // Otherwise, fall back to the next AA in the chain. But we can merge - // in any mask we've managed to compute. - return ModRefInfo(AA->getModRefInfo(CS, Loc) & Mask); + return Result; } -ModRefInfo AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) { - assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); +ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) { + ModRefInfo Result = MRI_ModRef; - // If CS1 or CS2 are readnone, they don't interact. - auto CS1B = getModRefBehavior(CS1); - if (CS1B == FMRB_DoesNotAccessMemory) - return MRI_NoModRef; + for (const auto &AA : AAs) { + Result = ModRefInfo(Result & AA->getModRefInfo(CS1, CS2)); - 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; - - ModRefInfo Mask = MRI_ModRef; - - // If CS1 only reads memory, the only dependence on CS2 can be - // from CS1 reading memory written by CS2. - if (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 (onlyAccessesArgPointees(CS2B)) { - ModRefInfo R = MRI_NoModRef; - if (doesAccessArgPointees(CS2B)) { - for (ImmutableCallSite::arg_iterator - 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; - - R = ModRefInfo((R | (getModRefInfo(CS1, CS2ArgLoc) & ArgMask)) & Mask); - if (R == Mask) - break; - } - } - return R; + // Early-exit the moment we reach the bottom of the lattice. + if (Result == MRI_NoModRef) + return Result; } - // 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 (ImmutableCallSite::arg_iterator - 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) & Mask); - - if (R == Mask) - break; - } - } - return R; - } + return Result; +} - // If this is the end of the chain, don't forward. - if (!AA) return Mask; +FunctionModRefBehavior AAResults::getModRefBehavior(ImmutableCallSite CS) { + FunctionModRefBehavior Result = FMRB_UnknownModRefBehavior; - // Otherwise, fall back to the next AA in the chain. But we can merge - // in any mask we've managed to compute. - return ModRefInfo(AA->getModRefInfo(CS1, CS2) & Mask); -} + for (const auto &AA : AAs) { + Result = FunctionModRefBehavior(Result & AA->getModRefBehavior(CS)); -FunctionModRefBehavior AliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { - assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + // Early-exit the moment we reach the bottom of the lattice. + if (Result == FMRB_DoesNotAccessMemory) + return Result; + } - auto Min = FMRB_UnknownModRefBehavior; + return Result; +} - // Call back into the alias analysis with the other form of getModRefBehavior - // to see if it can give a better response. - if (const Function *F = CS.getCalledFunction()) - Min = getModRefBehavior(F); +FunctionModRefBehavior AAResults::getModRefBehavior(const Function *F) { + FunctionModRefBehavior Result = FMRB_UnknownModRefBehavior; - // If this is the end of the chain, don't forward. - if (!AA) return Min; + for (const auto &AA : AAs) { + Result = FunctionModRefBehavior(Result & AA->getModRefBehavior(F)); - // Otherwise, fall back to the next AA in the chain. But we can merge - // in any result we've managed to compute. - return FunctionModRefBehavior(AA->getModRefBehavior(CS) & Min); -} + // Early-exit the moment we reach the bottom of the lattice. + if (Result == FMRB_DoesNotAccessMemory) + return Result; + } -FunctionModRefBehavior AliasAnalysis::getModRefBehavior(const Function *F) { - assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); - return AA->getModRefBehavior(F); + return Result; } //===----------------------------------------------------------------------===// -// AliasAnalysis non-virtual helper method implementation +// Helper method implementation //===----------------------------------------------------------------------===// -ModRefInfo AliasAnalysis::getModRefInfo(const LoadInst *L, - const MemoryLocation &Loc) { +ModRefInfo AAResults::getModRefInfo(const LoadInst *L, + const MemoryLocation &Loc) { // Be conservative in the face of volatile/atomic. if (!L->isUnordered()) return MRI_ModRef; @@ -268,8 +206,8 @@ return MRI_Ref; } -ModRefInfo AliasAnalysis::getModRefInfo(const StoreInst *S, - const MemoryLocation &Loc) { +ModRefInfo AAResults::getModRefInfo(const StoreInst *S, + const MemoryLocation &Loc) { // Be conservative in the face of volatile/atomic. if (!S->isUnordered()) return MRI_ModRef; @@ -290,8 +228,8 @@ return MRI_Mod; } -ModRefInfo AliasAnalysis::getModRefInfo(const VAArgInst *V, - const MemoryLocation &Loc) { +ModRefInfo AAResults::getModRefInfo(const VAArgInst *V, + const MemoryLocation &Loc) { if (Loc.Ptr) { // If the va_arg address cannot alias the pointer in question, then the @@ -309,8 +247,8 @@ return MRI_ModRef; } -ModRefInfo AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX, - const MemoryLocation &Loc) { +ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX, + const MemoryLocation &Loc) { // Acquire/Release cmpxchg has properties that matter for arbitrary addresses. if (CX->getSuccessOrdering() > Monotonic) return MRI_ModRef; @@ -322,8 +260,8 @@ return MRI_ModRef; } -ModRefInfo AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW, - const MemoryLocation &Loc) { +ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW, + const MemoryLocation &Loc) { // Acquire/Release atomicrmw has properties that matter for arbitrary addresses. if (RMW->getOrdering() > Monotonic) return MRI_ModRef; @@ -343,14 +281,15 @@ /// BasicAA isn't willing to spend linear time determining whether an alloca /// was captured before or after this particular call, while we are. However, /// with a smarter AA in place, this test is just wasting compile time. -ModRefInfo AliasAnalysis::callCapturesBefore(const Instruction *I, - const MemoryLocation &MemLoc, - DominatorTree *DT, - OrderedBasicBlock *OBB) { +ModRefInfo AAResults::callCapturesBefore(const Instruction *I, + const MemoryLocation &MemLoc, + DominatorTree *DT, + OrderedBasicBlock *OBB) { if (!DT) return MRI_ModRef; - const Value *Object = GetUnderlyingObject(MemLoc.Ptr, *DL); + const Value *Object = + GetUnderlyingObject(MemLoc.Ptr, I->getModule()->getDataLayout()); if (!isIdentifiedObject(Object) || isa(Object) || isa(Object)) return MRI_ModRef; @@ -393,34 +332,11 @@ return R; } -// AliasAnalysis destructor: DO NOT move this to the header file for -// AliasAnalysis or else clients of the AliasAnalysis class may not depend on -// the AliasAnalysis.o file in the current .a file, causing alias analysis -// support to not be included in the tool correctly! -// -AliasAnalysis::~AliasAnalysis() {} - -/// InitializeAliasAnalysis - Subclasses must call this method to initialize the -/// AliasAnalysis interface before any other methods are called. -/// -void AliasAnalysis::InitializeAliasAnalysis(Pass *P, const DataLayout *NewDL) { - DL = NewDL; - auto *TLIP = P->getAnalysisIfAvailable(); - TLI = TLIP ? &TLIP->getTLI() : nullptr; - AA = &P->getAnalysis(); -} - -// getAnalysisUsage - All alias analysis implementations should invoke this -// directly (using AliasAnalysis::getAnalysisUsage(AU)). -void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); // All AA's chain -} - /// canBasicBlockModify - Return true if it is possible for execution of the /// specified basic block to modify the location Loc. /// -bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB, - const MemoryLocation &Loc) { +bool AAResults::canBasicBlockModify(const BasicBlock &BB, + const MemoryLocation &Loc) { return canInstructionRangeModRef(BB.front(), BB.back(), Loc, MRI_Mod); } @@ -429,10 +345,10 @@ /// mode) the location Loc. The instructions to consider are all /// of the instructions in the range of [I1,I2] INCLUSIVE. /// I1 and I2 must be in the same basic block. -bool AliasAnalysis::canInstructionRangeModRef(const Instruction &I1, - const Instruction &I2, - const MemoryLocation &Loc, - const ModRefInfo Mode) { +bool AAResults::canInstructionRangeModRef(const Instruction &I1, + const Instruction &I2, + const MemoryLocation &Loc, + const ModRefInfo Mode) { assert(I1.getParent() == I2.getParent() && "Instructions not in same basic block!"); BasicBlock::const_iterator I = &I1; @@ -445,6 +361,117 @@ return false; } +// Provide a definition for the root virtual destructor. +AAResults::Concept::~Concept() {} + +AAResultsWrapperPass::AAResultsWrapperPass() : FunctionPass(ID) { + initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +char AAResultsWrapperPass::ID = 0; + +INITIALIZE_PASS_BEGIN(AAResultsWrapperPass, "aa", + "Function Alias Analysis Results", false, true) +INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(CFLAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(ObjCARCAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(ScopedNoAliasAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TypeBasedAAWrapperPass) +INITIALIZE_PASS_END(AAResultsWrapperPass, "aa", + "Function Alias Analysis Results", false, true) + +FunctionPass *llvm::createAAResultsWrapperPass() { + return new AAResultsWrapperPass(); +} + +/// Run the wrapper pass to rebuild an aggregation over known AA passes. +/// +/// This is the legacy pass manager's interface to the new-style AA results +/// aggregation object. Because this is somewhat shoe-horned into the legacy +/// pass manager, we hard code all the specific alias analyses available into +/// it. While the particular set enabled is configured via commandline flags, +/// adding a new alias analysis to LLVM will require adding support for it to +/// this list. +bool AAResultsWrapperPass::runOnFunction(Function &F) { + // NB! This *must* be reset before adding new AA results to the new + // AAResults object because in the legacy pass manager, each instance + // of these will refer to the *same* immutable analyses, registering and + // 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()); + + // BasicAA is always available for function analyses. Also, we add it first + // so that it can trump TBAA results when it proves MustAlias. + // FIXME: TBAA should have an explicit mode to support this and then we + // should reconsider the ordering here. + if (!DisableBasicAA) + AAR->addAAResult(getAnalysis().getResult()); + + // Populate the results with the currently available AAs. + if (auto *WrapperPass = getAnalysisIfAvailable()) + AAR->addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = getAnalysisIfAvailable()) + AAR->addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = + getAnalysisIfAvailable()) + AAR->addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = getAnalysisIfAvailable()) + AAR->addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = getAnalysisIfAvailable()) + AAR->addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = getAnalysisIfAvailable()) + AAR->addAAResult(WrapperPass->getResult()); + + // Analyses don't mutate the IR, so return false. + return false; +} + +void AAResultsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + 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 + // preserves them. This hard coding of lists of alias analyses is specific to + // the legacy pass manager. + AU.addUsedIfAvailable(); + AU.addUsedIfAvailable(); + AU.addUsedIfAvailable(); + AU.addUsedIfAvailable(); + AU.addUsedIfAvailable(); + AU.addUsedIfAvailable(); +} + +AAResults llvm::createLegacyPMAAResults(Pass &P, Function &F, + BasicAAResult &BAR) { + AAResults AAR; + + // Add in our explicitly constructed BasicAA results. + if (!DisableBasicAA) + AAR.addAAResult(BAR); + + // Populate the results with the other currently available AAs. + if (auto *WrapperPass = + P.getAnalysisIfAvailable()) + AAR.addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = P.getAnalysisIfAvailable()) + AAR.addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = + P.getAnalysisIfAvailable()) + AAR.addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = P.getAnalysisIfAvailable()) + AAR.addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = P.getAnalysisIfAvailable()) + AAR.addAAResult(WrapperPass->getResult()); + if (auto *WrapperPass = P.getAnalysisIfAvailable()) + AAR.addAAResult(WrapperPass->getResult()); + + return AAR; +} + /// isNoAliasCall - Return true if this pointer is returned by a noalias /// function. bool llvm::isNoAliasCall(const Value *V) { Index: lib/Analysis/AliasAnalysisCounter.cpp =================================================================== --- lib/Analysis/AliasAnalysisCounter.cpp +++ /dev/null @@ -1,165 +0,0 @@ -//===- AliasAnalysisCounter.cpp - Alias Analysis Query Counter ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements a pass which can be used to count how many alias queries -// are being made and how the alias analysis implementation being used responds. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/AliasAnalysisCounter.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/IR/Module.h" -#include "llvm/Pass.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -static cl::opt PrintAll("count-aa-print-all-queries", cl::ReallyHidden, - cl::init(true)); -static cl::opt PrintAllFailures("count-aa-print-all-failed-queries", - cl::ReallyHidden); - -char AliasAnalysisCounter::ID = 0; -INITIALIZE_AG_PASS(AliasAnalysisCounter, AliasAnalysis, "count-aa", - "Count Alias Analysis Query Responses", false, true, false) - -ModulePass *llvm::createAliasAnalysisCounterPass() { - return new AliasAnalysisCounter(); -} - -AliasAnalysisCounter::AliasAnalysisCounter() : ModulePass(ID) { - initializeAliasAnalysisCounterPass(*PassRegistry::getPassRegistry()); - No = May = Partial = Must = 0; - NoMR = JustRef = JustMod = MR = 0; -} - -static void printLine(const char *Desc, unsigned Val, unsigned Sum) { - errs() << " " << Val << " " << Desc << " responses (" << Val * 100 / Sum - << "%)\n"; -} - -AliasAnalysisCounter::~AliasAnalysisCounter() { - unsigned AASum = No + May + Partial + Must; - unsigned MRSum = NoMR + JustRef + JustMod + MR; - if (AASum + MRSum) { // Print a report if any counted queries occurred... - errs() << "\n===== Alias Analysis Counter Report =====\n" - << " Analysis counted:\n" - << " " << AASum << " Total Alias Queries Performed\n"; - if (AASum) { - printLine("no alias", No, AASum); - printLine("may alias", May, AASum); - printLine("partial alias", Partial, AASum); - printLine("must alias", Must, AASum); - errs() << " Alias Analysis Counter Summary: " << No * 100 / AASum << "%/" - << May * 100 / AASum << "%/" << Partial * 100 / AASum << "%/" - << Must * 100 / AASum << "%\n\n"; - } - - errs() << " " << MRSum << " Total MRI_Mod/MRI_Ref Queries Performed\n"; - if (MRSum) { - printLine("no mod/ref", NoMR, MRSum); - printLine("ref", JustRef, MRSum); - printLine("mod", JustMod, MRSum); - printLine("mod/ref", MR, MRSum); - errs() << " MRI_Mod/MRI_Ref Analysis Counter Summary: " - << NoMR * 100 / MRSum << "%/" << JustRef * 100 / MRSum << "%/" - << JustMod * 100 / MRSum << "%/" << MR * 100 / MRSum << "%\n\n"; - } - } -} - -bool AliasAnalysisCounter::runOnModule(Module &M) { - this->M = &M; - InitializeAliasAnalysis(this, &M.getDataLayout()); - return false; -} - -void AliasAnalysisCounter::getAnalysisUsage(AnalysisUsage &AU) const { - AliasAnalysis::getAnalysisUsage(AU); - AU.addRequired(); - AU.setPreservesAll(); -} - -void *AliasAnalysisCounter::getAdjustedAnalysisPointer(AnalysisID PI) { - if (PI == &AliasAnalysis::ID) - return (AliasAnalysis *)this; - return this; -} - -AliasResult AliasAnalysisCounter::alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) { - AliasResult R = getAnalysis().alias(LocA, LocB); - - const char *AliasString = nullptr; - switch (R) { - case NoAlias: - No++; - AliasString = "No alias"; - break; - case MayAlias: - May++; - AliasString = "May alias"; - break; - case PartialAlias: - Partial++; - AliasString = "Partial alias"; - break; - case MustAlias: - Must++; - AliasString = "Must alias"; - break; - } - - if (PrintAll || (PrintAllFailures && R == MayAlias)) { - errs() << AliasString << ":\t"; - errs() << "[" << LocA.Size << "B] "; - LocA.Ptr->printAsOperand(errs(), true, M); - errs() << ", "; - errs() << "[" << LocB.Size << "B] "; - LocB.Ptr->printAsOperand(errs(), true, M); - errs() << "\n"; - } - - return R; -} - -ModRefInfo AliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) { - ModRefInfo R = getAnalysis().getModRefInfo(CS, Loc); - - const char *MRString = nullptr; - switch (R) { - case MRI_NoModRef: - NoMR++; - MRString = "MRI_NoModRef"; - break; - case MRI_Ref: - JustRef++; - MRString = "JustRef"; - break; - case MRI_Mod: - JustMod++; - MRString = "JustMod"; - break; - case MRI_ModRef: - MR++; - MRString = "MRI_ModRef"; - break; - } - - if (PrintAll || (PrintAllFailures && R == MRI_ModRef)) { - errs() << MRString << ": Ptr: "; - errs() << "[" << Loc.Size << "B] "; - Loc.Ptr->printAsOperand(errs(), true, M); - errs() << "\t<->" << *CS.getInstruction() << '\n'; - } - return R; -} Index: lib/Analysis/AliasAnalysisEvaluator.cpp =================================================================== --- lib/Analysis/AliasAnalysisEvaluator.cpp +++ lib/Analysis/AliasAnalysisEvaluator.cpp @@ -59,7 +59,7 @@ } void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); AU.setPreservesAll(); } @@ -83,7 +83,7 @@ char AAEval::ID = 0; INITIALIZE_PASS_BEGIN(AAEval, "aa-eval", "Exhaustive Alias Analysis Precision Evaluator", false, true) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(AAEval, "aa-eval", "Exhaustive Alias Analysis Precision Evaluator", false, true) @@ -142,7 +142,7 @@ bool AAEval::runOnFunction(Function &F) { const DataLayout &DL = F.getParent()->getDataLayout(); - AliasAnalysis &AA = getAnalysis(); + AliasAnalysis &AA = getAnalysis().getAAResults(); SetVector Pointers; SetVector CallSites; Index: lib/Analysis/AliasSetTracker.cpp =================================================================== --- lib/Analysis/AliasSetTracker.cpp +++ lib/Analysis/AliasSetTracker.cpp @@ -649,11 +649,12 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequired(); } bool runOnFunction(Function &F) override { - Tracker = new AliasSetTracker(getAnalysis()); + auto &AAWP = getAnalysis(); + Tracker = new AliasSetTracker(AAWP.getAAResults()); for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) Tracker->add(&*I); @@ -667,6 +668,6 @@ char AliasSetPrinter::ID = 0; INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets", "Alias Set Printer", false, true) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets", "Alias Set Printer", false, true) Index: lib/Analysis/Analysis.cpp =================================================================== --- lib/Analysis/Analysis.cpp +++ lib/Analysis/Analysis.cpp @@ -20,12 +20,9 @@ /// initializeAnalysis - Initialize all passes linked into the Analysis library. void llvm::initializeAnalysis(PassRegistry &Registry) { - initializeAliasAnalysisAnalysisGroup(Registry); - initializeAliasAnalysisCounterPass(Registry); initializeAAEvalPass(Registry); initializeAliasSetPrinterPass(Registry); - initializeNoAAPass(Registry); - initializeBasicAliasAnalysisPass(Registry); + initializeBasicAAWrapperPassPass(Registry); initializeBlockFrequencyInfoWrapperPassPass(Registry); initializeBranchProbabilityInfoWrapperPassPass(Registry); initializeCallGraphWrapperPassPass(Registry); @@ -36,7 +33,7 @@ initializeCFGPrinterPass(Registry); initializeCFGOnlyViewerPass(Registry); initializeCFGOnlyPrinterPass(Registry); - initializeCFLAliasAnalysisPass(Registry); + initializeCFLAAWrapperPassPass(Registry); initializeDependenceAnalysisPass(Registry); initializeDelinearizationPass(Registry); initializeDemandedBitsPass(Registry); @@ -50,7 +47,8 @@ initializePostDomPrinterPass(Registry); initializePostDomOnlyViewerPass(Registry); initializePostDomOnlyPrinterPass(Registry); - initializeGlobalsModRefPass(Registry); + initializeAAResultsWrapperPassPass(Registry); + initializeGlobalsAAWrapperPassPass(Registry); initializeIVUsersPass(Registry); initializeInstCountPass(Registry); initializeIntervalPartitionPass(Registry); @@ -61,18 +59,18 @@ initializeMemDerefPrinterPass(Registry); initializeMemoryDependenceAnalysisPass(Registry); initializeModuleDebugInfoPrinterPass(Registry); - initializeObjCARCAliasAnalysisPass(Registry); + initializeObjCARCAAWrapperPassPass(Registry); initializePostDominatorTreePass(Registry); initializeRegionInfoPassPass(Registry); initializeRegionViewerPass(Registry); initializeRegionPrinterPass(Registry); initializeRegionOnlyViewerPass(Registry); initializeRegionOnlyPrinterPass(Registry); + initializeSCEVAAWrapperPassPass(Registry); initializeScalarEvolutionWrapperPassPass(Registry); - initializeScalarEvolutionAliasAnalysisPass(Registry); initializeTargetTransformInfoWrapperPassPass(Registry); - initializeTypeBasedAliasAnalysisPass(Registry); - initializeScopedNoAliasAAPass(Registry); + initializeTypeBasedAAWrapperPassPass(Registry); + initializeScopedNoAliasAAWrapperPassPass(Registry); } void LLVMInitializeAnalysis(LLVMPassRegistryRef R) { Index: lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- lib/Analysis/BasicAliasAnalysis.cpp +++ lib/Analysis/BasicAliasAnalysis.cpp @@ -23,6 +23,7 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Analysis/AssumptionCache.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -177,7 +178,7 @@ /// /// Note that this looks through extends, so the high bits may not be /// represented in the result. -/*static*/ const Value *BasicAliasAnalysis::GetLinearExpression( +/*static*/ const Value *BasicAAResult::GetLinearExpression( const Value *V, APInt &Scale, APInt &Offset, unsigned &ZExtBits, unsigned &SExtBits, const DataLayout &DL, unsigned Depth, AssumptionCache *AC, DominatorTree *DT, bool &NSW, bool &NUW) { @@ -331,7 +332,7 @@ /// GetUnderlyingObject and DecomposeGEPExpression must use the same search /// depth (MaxLookupSearchDepth). When DataLayout not is around, it just looks /// through pointer casts. -/*static*/ const Value *BasicAliasAnalysis::DecomposeGEPExpression( +/*static*/ const Value *BasicAAResult::DecomposeGEPExpression( const Value *V, int64_t &BaseOffs, SmallVectorImpl &VarIndices, bool &MaxLookupReached, const DataLayout &DL, AssumptionCache *AC, DominatorTree *DT) { @@ -466,40 +467,21 @@ return V; } -//===----------------------------------------------------------------------===// -// BasicAliasAnalysis Pass -//===----------------------------------------------------------------------===// - -// Register the pass... -char BasicAliasAnalysis::ID = 0; -INITIALIZE_AG_PASS_BEGIN(BasicAliasAnalysis, AliasAnalysis, "basicaa", - "Basic Alias Analysis (stateless AA impl)", false, - true, false) -INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_AG_PASS_END(BasicAliasAnalysis, AliasAnalysis, "basicaa", - "Basic Alias Analysis (stateless AA impl)", false, true, - false) - -ImmutablePass *llvm::createBasicAliasAnalysisPass() { - return new BasicAliasAnalysis(); -} - /// Returns whether the given pointer value points to memory that is local to /// the function, with global constants being considered local to all /// functions. -bool BasicAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal) { +bool BasicAAResult::pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) { assert(Visited.empty() && "Visited must be cleared after use!"); unsigned MaxLookup = 8; SmallVector Worklist; Worklist.push_back(Loc.Ptr); do { - const Value *V = GetUnderlyingObject(Worklist.pop_back_val(), *DL); + const Value *V = GetUnderlyingObject(Worklist.pop_back_val(), DL); if (!Visited.insert(V).second) { Visited.clear(); - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); } // An alloca instruction defines local memory. @@ -513,7 +495,7 @@ // others. GV may even be a declaration, not a definition. if (!GV->isConstant()) { Visited.clear(); - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); } continue; } @@ -531,7 +513,7 @@ // Don't bother inspecting phi nodes with many operands. if (PN->getNumIncomingValues() > MaxLookup) { Visited.clear(); - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); } for (Value *IncValue : PN->incoming_values()) Worklist.push_back(IncValue); @@ -540,7 +522,7 @@ // Otherwise be conservative. Visited.clear(); - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); } while (!Worklist.empty() && --MaxLookup); @@ -566,8 +548,7 @@ } /// Returns the behavior when calling the given call site. -FunctionModRefBehavior -BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { +FunctionModRefBehavior BasicAAResult::getModRefBehavior(ImmutableCallSite CS) { if (CS.doesNotAccessMemory()) // Can't do better than this. return FMRB_DoesNotAccessMemory; @@ -582,14 +563,13 @@ if (CS.onlyAccessesArgMemory()) Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees); - // The AliasAnalysis base class has some smarts, lets use them. - return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min); + // The AAResultBase base class has some smarts, lets use them. + return FunctionModRefBehavior(AAResultBase::getModRefBehavior(CS) & Min); } /// Returns the behavior when calling the given function. For use when the call /// site is not known. -FunctionModRefBehavior -BasicAliasAnalysis::getModRefBehavior(const Function *F) { +FunctionModRefBehavior BasicAAResult::getModRefBehavior(const Function *F) { // If the function declares it doesn't access memory, we can't do better. if (F->doesNotAccessMemory()) return FMRB_DoesNotAccessMemory; @@ -603,17 +583,15 @@ if (F->onlyAccessesArgMemory()) Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees); - const TargetLibraryInfo &TLI = - getAnalysis().getTLI(); if (isMemsetPattern16(F, TLI)) Min = FMRB_OnlyAccessesArgumentPointees; // Otherwise be conservative. - return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min); + return FunctionModRefBehavior(AAResultBase::getModRefBehavior(F) & Min); } -ModRefInfo BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, - unsigned ArgIdx) { +ModRefInfo BasicAAResult::getArgModRefInfo(ImmutableCallSite CS, + unsigned ArgIdx) { if (const IntrinsicInst *II = dyn_cast(CS.getInstruction())) switch (II->getIntrinsicID()) { default: @@ -631,14 +609,14 @@ // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 // whenever possible. if (CS.getCalledFunction() && - isMemsetPattern16(CS.getCalledFunction(), *TLI)) { + isMemsetPattern16(CS.getCalledFunction(), TLI)) { assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for memset_pattern16"); return ArgIdx ? MRI_Ref : MRI_Mod; } // FIXME: Handle memset_pattern4 and memset_pattern8 also. - return AliasAnalysis::getArgModRefInfo(CS, ArgIdx); + return AAResultBase::getArgModRefInfo(CS, ArgIdx); } static bool isAssumeIntrinsic(ImmutableCallSite CS) { @@ -649,23 +627,18 @@ return false; } -bool BasicAliasAnalysis::doInitialization(Module &M) { - InitializeAliasAnalysis(this, &M.getDataLayout()); - return true; -} - /// Checks to see if the specified callsite can clobber the specified memory /// object. /// /// Since we only look at local properties of this function, we really can't /// say much about this query. We do, however, use simple "address taken" /// analysis on local objects. -ModRefInfo BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) { +ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) { assert(notDifferentParent(CS.getInstruction(), Loc.Ptr) && "AliasAnalysis query involving multiple functions!"); - const Value *Object = GetUnderlyingObject(Loc.Ptr, *DL); + const Value *Object = GetUnderlyingObject(Loc.Ptr, DL); // If this is a tail call and Loc.Ptr points to a stack location, we know that // the tail call cannot access or modify the local stack. @@ -697,7 +670,9 @@ // 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 // escape. - if (!isNoAlias(MemoryLocation(*CI), MemoryLocation(Object))) { + AliasResult AR = + getBestAAResults().alias(MemoryLocation(*CI), MemoryLocation(Object)); + if (AR) { PassedAsArg = true; break; } @@ -713,20 +688,20 @@ if (isAssumeIntrinsic(CS)) return MRI_NoModRef; - // The AliasAnalysis base class has some smarts, lets use them. - return AliasAnalysis::getModRefInfo(CS, Loc); + // The AAResultBase base class has some smarts, lets use them. + return AAResultBase::getModRefInfo(CS, Loc); } -ModRefInfo BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) { +ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) { // While the assume intrinsic is marked as arbitrarily writing so that // proper control dependencies will be maintained, it never aliases any // particular memory location. if (isAssumeIntrinsic(CS1) || isAssumeIntrinsic(CS2)) return MRI_NoModRef; - // The AliasAnalysis base class has some smarts, lets use them. - return AliasAnalysis::getModRefInfo(CS1, CS2); + // The AAResultBase base class has some smarts, lets use them. + return AAResultBase::getModRefInfo(CS1, CS2); } /// Provide ad-hoc rules to disambiguate accesses through two GEP operators, @@ -829,34 +804,15 @@ /// We know that V1 is a GEP, but we don't know anything about V2. /// UnderlyingV1 is GetUnderlyingObject(GEP1, DL), UnderlyingV2 is the same for /// V2. -AliasResult BasicAliasAnalysis::aliasGEP( - const GEPOperator *GEP1, uint64_t V1Size, const AAMDNodes &V1AAInfo, - const Value *V2, uint64_t V2Size, const AAMDNodes &V2AAInfo, - const Value *UnderlyingV1, const Value *UnderlyingV2) { +AliasResult BasicAAResult::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, + const AAMDNodes &V1AAInfo, const Value *V2, + uint64_t V2Size, const AAMDNodes &V2AAInfo, + const Value *UnderlyingV1, + const Value *UnderlyingV2) { int64_t GEP1BaseOffset; bool GEP1MaxLookupReached; SmallVector GEP1VariableIndices; - // We have to get two AssumptionCaches here because GEP1 and V2 may be from - // different functions. - // FIXME: This really doesn't make any sense. We get a dominator tree below - // that can only refer to a single function. But this function (aliasGEP) is - // a method on an immutable pass that can be called when there *isn't* - // a single function. The old pass management layer makes this "work", but - // this isn't really a clean solution. - AssumptionCacheTracker &ACT = getAnalysis(); - AssumptionCache *AC1 = nullptr, *AC2 = nullptr; - if (auto *GEP1I = dyn_cast(GEP1)) - AC1 = &ACT.getAssumptionCache( - const_cast(*GEP1I->getParent()->getParent())); - if (auto *I2 = dyn_cast(V2)) - AC2 = &ACT.getAssumptionCache( - const_cast(*I2->getParent()->getParent())); - - DominatorTreeWrapperPass *DTWP = - getAnalysisIfAvailable(); - DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr; - // If we have two gep instructions with must-alias or not-alias'ing base // pointers, figure out if the indexes to the GEP tell us anything about the // derived pointer. @@ -880,15 +836,15 @@ SmallVector GEP2VariableIndices; const Value *GEP2BasePtr = DecomposeGEPExpression(GEP2, GEP2BaseOffset, GEP2VariableIndices, - GEP2MaxLookupReached, *DL, AC2, DT); + GEP2MaxLookupReached, DL, &AC, DT); const Value *GEP1BasePtr = DecomposeGEPExpression(GEP1, GEP1BaseOffset, GEP1VariableIndices, - GEP1MaxLookupReached, *DL, AC1, DT); + GEP1MaxLookupReached, DL, &AC, DT); // DecomposeGEPExpression and GetUnderlyingObject should return the // same result except when DecomposeGEPExpression has no DataLayout. + // FIXME: They always have a DataLayout so this should become an + // assert. if (GEP1BasePtr != UnderlyingV1 || GEP2BasePtr != UnderlyingV2) { - assert(!DL && - "DecomposeGEPExpression and GetUnderlyingObject disagree!"); return MayAlias; } // If the max search depth is reached the result is undefined @@ -913,27 +869,27 @@ // about the relation of the resulting pointer. const Value *GEP1BasePtr = DecomposeGEPExpression(GEP1, GEP1BaseOffset, GEP1VariableIndices, - GEP1MaxLookupReached, *DL, AC1, DT); + GEP1MaxLookupReached, DL, &AC, DT); int64_t GEP2BaseOffset; bool GEP2MaxLookupReached; SmallVector GEP2VariableIndices; const Value *GEP2BasePtr = DecomposeGEPExpression(GEP2, GEP2BaseOffset, GEP2VariableIndices, - GEP2MaxLookupReached, *DL, AC2, DT); + GEP2MaxLookupReached, DL, &AC, DT); // DecomposeGEPExpression and GetUnderlyingObject should return the // same result except when DecomposeGEPExpression has no DataLayout. + // FIXME: They always have a DataLayout so this should become an assert. if (GEP1BasePtr != UnderlyingV1 || GEP2BasePtr != UnderlyingV2) { - assert(!DL && "DecomposeGEPExpression and GetUnderlyingObject disagree!"); return MayAlias; } // If we know the two GEPs are based off of the exact same pointer (and not // just the same underlying object), see if that tells us anything about // the resulting pointers. - if (DL && GEP1->getPointerOperand() == GEP2->getPointerOperand()) { - AliasResult R = aliasSameBasePointerGEPs(GEP1, V1Size, GEP2, V2Size, *DL); + if (GEP1->getPointerOperand() == GEP2->getPointerOperand()) { + AliasResult R = aliasSameBasePointerGEPs(GEP1, V1Size, GEP2, V2Size, DL); // If we couldn't find anything interesting, don't abandon just yet. if (R != MayAlias) return R; @@ -970,12 +926,12 @@ const Value *GEP1BasePtr = DecomposeGEPExpression(GEP1, GEP1BaseOffset, GEP1VariableIndices, - GEP1MaxLookupReached, *DL, AC1, DT); + GEP1MaxLookupReached, DL, &AC, DT); // DecomposeGEPExpression and GetUnderlyingObject should return the // same result except when DecomposeGEPExpression has no DataLayout. + // FIXME: They always have a DataLayout so this should become an assert. if (GEP1BasePtr != UnderlyingV1) { - assert(!DL && "DecomposeGEPExpression and GetUnderlyingObject disagree!"); return MayAlias; } // If the max search depth is reached the result is undefined @@ -1039,8 +995,8 @@ const Value *V = GEP1VariableIndices[i].V; bool SignKnownZero, SignKnownOne; - ComputeSignBit(const_cast(V), SignKnownZero, SignKnownOne, *DL, - 0, AC1, nullptr, DT); + ComputeSignBit(const_cast(V), SignKnownZero, SignKnownOne, DL, + 0, &AC, nullptr, DT); // Zero-extension widens the variable, and so forces the sign // bit to zero. @@ -1075,7 +1031,7 @@ return NoAlias; if (constantOffsetHeuristic(GEP1VariableIndices, V1Size, V2Size, - GEP1BaseOffset, DL, AC1, DT)) + GEP1BaseOffset, &AC, DT)) return NoAlias; } @@ -1103,11 +1059,10 @@ /// Provides a bunch of ad-hoc rules to disambiguate a Select instruction /// against another. -AliasResult BasicAliasAnalysis::aliasSelect(const SelectInst *SI, - uint64_t SISize, - const AAMDNodes &SIAAInfo, - const Value *V2, uint64_t V2Size, - const AAMDNodes &V2AAInfo) { +AliasResult BasicAAResult::aliasSelect(const SelectInst *SI, uint64_t SISize, + const AAMDNodes &SIAAInfo, + const Value *V2, uint64_t V2Size, + const AAMDNodes &V2AAInfo) { // 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(V2)) @@ -1136,10 +1091,10 @@ /// Provide a bunch of ad-hoc rules to disambiguate a PHI instruction against /// another. -AliasResult BasicAliasAnalysis::aliasPHI(const PHINode *PN, uint64_t PNSize, - const AAMDNodes &PNAAInfo, - const Value *V2, uint64_t V2Size, - const AAMDNodes &V2AAInfo) { +AliasResult BasicAAResult::aliasPHI(const PHINode *PN, uint64_t PNSize, + const AAMDNodes &PNAAInfo, const Value *V2, + uint64_t V2Size, + const AAMDNodes &V2AAInfo) { // Track phi nodes we have visited. We use this information when we determine // value equivalence. VisitedPhiBBs.insert(PN->getParent()); @@ -1242,10 +1197,9 @@ /// Provideis a bunch of ad-hoc rules to disambiguate in common cases, such as /// array references. -AliasResult BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size, - AAMDNodes V1AAInfo, const Value *V2, - uint64_t V2Size, - AAMDNodes V2AAInfo) { +AliasResult BasicAAResult::aliasCheck(const Value *V1, uint64_t V1Size, + AAMDNodes V1AAInfo, const Value *V2, + uint64_t V2Size, AAMDNodes V2AAInfo) { // If either of the memory references is empty, it doesn't matter what the // pointer values are. if (V1Size == 0 || V2Size == 0) @@ -1273,8 +1227,8 @@ return NoAlias; // Scalars cannot alias each other // Figure out what objects these things are pointing to if we can. - const Value *O1 = GetUnderlyingObject(V1, *DL, MaxLookupSearchDepth); - const Value *O2 = GetUnderlyingObject(V2, *DL, MaxLookupSearchDepth); + const Value *O1 = GetUnderlyingObject(V1, DL, MaxLookupSearchDepth); + const Value *O2 = GetUnderlyingObject(V2, DL, MaxLookupSearchDepth); // Null values in the default address space don't point to any object, so they // don't alias any other pointer. @@ -1323,12 +1277,11 @@ // If the size of one access is larger than the entire object on the other // side, then we know such behavior is undefined and can assume no alias. - if (DL) - if ((V1Size != MemoryLocation::UnknownSize && - isObjectSmallerThan(O2, V1Size, *DL, *TLI)) || - (V2Size != MemoryLocation::UnknownSize && - isObjectSmallerThan(O1, V2Size, *DL, *TLI))) - return NoAlias; + if ((V1Size != MemoryLocation::UnknownSize && + isObjectSmallerThan(O2, V1Size, DL, TLI)) || + (V2Size != MemoryLocation::UnknownSize && + isObjectSmallerThan(O1, V2Size, DL, TLI))) + return NoAlias; // Check the cache before climbing up use-def chains. This also terminates // otherwise infinitely recursive queries. @@ -1382,16 +1335,16 @@ // If both pointers are pointing into the same object and one of them // accesses is accessing the entire object, then the accesses must // overlap in some way. - if (DL && O1 == O2) + if (O1 == O2) if ((V1Size != MemoryLocation::UnknownSize && - isObjectSize(O1, V1Size, *DL, *TLI)) || + isObjectSize(O1, V1Size, DL, TLI)) || (V2Size != MemoryLocation::UnknownSize && - isObjectSize(O2, V2Size, *DL, *TLI))) + isObjectSize(O2, V2Size, DL, TLI))) return AliasCache[Locs] = PartialAlias; AliasResult Result = - AliasAnalysis::alias(MemoryLocation(V1, V1Size, V1AAInfo), - MemoryLocation(V2, V2Size, V2AAInfo)); + AAResultBase::alias(MemoryLocation(V1, V1Size, V1AAInfo), + MemoryLocation(V2, V2Size, V2AAInfo)); return AliasCache[Locs] = Result; } @@ -1402,8 +1355,8 @@ /// visited phi nodes an making sure that the phis cannot reach the value. We /// have to do this because we are looking through phi nodes (That is we say /// noalias(V, phi(VA, VB)) if noalias(V, VA) and noalias(V, VB). -bool BasicAliasAnalysis::isValueEqualInPotentialCycles(const Value *V, - const Value *V2) { +bool BasicAAResult::isValueEqualInPotentialCycles(const Value *V, + const Value *V2) { if (V != V2) return false; @@ -1417,13 +1370,6 @@ if (VisitedPhiBBs.size() > MaxNumPhiBBsValueReachabilityCheck) return false; - // Use dominance or loop info if available. - DominatorTreeWrapperPass *DTWP = - getAnalysisIfAvailable(); - DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr; - auto *LIWP = getAnalysisIfAvailable(); - LoopInfo *LI = LIWP ? &LIWP->getLoopInfo() : nullptr; - // Make sure that the visited phis cannot reach the Value. This ensures that // the Values cannot come from different iterations of a potential cycle the // phi nodes could be involved in. @@ -1438,7 +1384,7 @@ /// /// Dest and Src are the variable indices from two decomposed GetElementPtr /// instructions GEP1 and GEP2 which have common base pointers. -void BasicAliasAnalysis::GetIndexDifference( +void BasicAAResult::GetIndexDifference( SmallVectorImpl &Dest, const SmallVectorImpl &Src) { if (Src.empty()) @@ -1474,12 +1420,12 @@ } } -bool BasicAliasAnalysis::constantOffsetHeuristic( +bool BasicAAResult::constantOffsetHeuristic( const SmallVectorImpl &VarIndices, uint64_t V1Size, - uint64_t V2Size, int64_t BaseOffset, const DataLayout *DL, - AssumptionCache *AC, DominatorTree *DT) { + uint64_t V2Size, int64_t BaseOffset, AssumptionCache *AC, + DominatorTree *DT) { if (VarIndices.size() != 2 || V1Size == MemoryLocation::UnknownSize || - V2Size == MemoryLocation::UnknownSize || !DL) + V2Size == MemoryLocation::UnknownSize) return false; const VariableGEPIndex &Var0 = VarIndices[0], &Var1 = VarIndices[1]; @@ -1499,10 +1445,10 @@ bool NSW = true, NUW = true; unsigned V0ZExtBits = 0, V0SExtBits = 0, V1ZExtBits = 0, V1SExtBits = 0; const Value *V0 = GetLinearExpression(Var0.V, V0Scale, V0Offset, V0ZExtBits, - V0SExtBits, *DL, 0, AC, DT, NSW, NUW); + V0SExtBits, DL, 0, AC, DT, NSW, NUW); NSW = true, NUW = true; const Value *V1 = GetLinearExpression(Var1.V, V1Scale, V1Offset, V1ZExtBits, - V1SExtBits, *DL, 0, AC, DT, NSW, NUW); + V1SExtBits, DL, 0, AC, DT, NSW, NUW); if (V0Scale != V1Scale || V0ZExtBits != V1ZExtBits || V0SExtBits != V1SExtBits || !isValueEqualInPotentialCycles(V0, V1)) @@ -1527,3 +1473,58 @@ return V1Size + std::abs(BaseOffset) <= MinDiffBytes && V2Size + std::abs(BaseOffset) <= MinDiffBytes; } + +//===----------------------------------------------------------------------===// +// BasicAliasAnalysis Pass +//===----------------------------------------------------------------------===// + +char BasicAA::PassID; + +BasicAAResult BasicAA::run(Function &F, AnalysisManager *AM) { + return BasicAAResult(F.getParent()->getDataLayout(), + AM->getResult(F), + AM->getResult(F), + AM->getCachedResult(F), + AM->getCachedResult(F)); +} + +char BasicAAWrapperPass::ID = 0; +void BasicAAWrapperPass::anchor() {} + +INITIALIZE_PASS_BEGIN(BasicAAWrapperPass, "basicaa", + "Basic Alias Analysis (stateless AA impl)", true, true) +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_END(BasicAAWrapperPass, "basicaa", + "Basic Alias Analysis (stateless AA impl)", true, true) + +FunctionPass *llvm::createBasicAAWrapperPass() { + return new BasicAAWrapperPass(); +} + +bool BasicAAWrapperPass::runOnFunction(Function &F) { + auto &ACT = getAnalysis(); + auto &TLIWP = getAnalysis(); + auto *DTWP = getAnalysisIfAvailable(); + auto *LIWP = getAnalysisIfAvailable(); + + Result.reset(new BasicAAResult(F.getParent()->getDataLayout(), TLIWP.getTLI(), + ACT.getAssumptionCache(F), + DTWP ? &DTWP->getDomTree() : nullptr, + LIWP ? &LIWP->getLoopInfo() : nullptr)); + + return false; +} + +void BasicAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + AU.addRequired(); +} + +BasicAAResult llvm::createLegacyPMBasicAAResult(Pass &P, Function &F) { + return BasicAAResult( + F.getParent()->getDataLayout(), + P.getAnalysis().getTLI(), + P.getAnalysis().getAssumptionCache(F)); +} Index: lib/Analysis/CFLAliasAnalysis.cpp =================================================================== --- lib/Analysis/CFLAliasAnalysis.cpp +++ lib/Analysis/CFLAliasAnalysis.cpp @@ -33,7 +33,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" -#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstVisitor.h" @@ -53,18 +53,11 @@ #define DEBUG_TYPE "cfl-aa" -// -- Setting up/registering CFLAA pass -- // -char CFLAliasAnalysis::ID = 0; - -INITIALIZE_AG_PASS(CFLAliasAnalysis, AliasAnalysis, "cfl-aa", - "CFL-Based AA implementation", false, true, false) - -ImmutablePass *llvm::createCFLAliasAnalysisPass() { - return new CFLAliasAnalysis(); -} +CFLAAResult::CFLAAResult(const TargetLibraryInfo &TLI) : AAResultBase(TLI) {} +CFLAAResult::CFLAAResult(CFLAAResult &&Arg) : AAResultBase(std::move(Arg)) {} // \brief Information we have about a function and would like to keep around -struct CFLAliasAnalysis::FunctionInfo { +struct CFLAAResult::FunctionInfo { StratifiedSets Sets; // Lots of functions have < 4 returns. Adjust as necessary. SmallVector ReturnedValues; @@ -73,22 +66,6 @@ : Sets(std::move(S)), ReturnedValues(std::move(RV)) {} }; -CFLAliasAnalysis::CFLAliasAnalysis() : ImmutablePass(ID) { - initializeCFLAliasAnalysisPass(*PassRegistry::getPassRegistry()); -} - -CFLAliasAnalysis::~CFLAliasAnalysis() {} - -void CFLAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { - AliasAnalysis::getAnalysisUsage(AU); -} - -void *CFLAliasAnalysis::getAdjustedAnalysisPointer(const void *ID) { - if (ID == &AliasAnalysis::ID) - return (AliasAnalysis *)this; - return this; -} - // Try to go from a Value* to a Function*. Never returns nullptr. static Optional parentFunctionOfValue(Value *); @@ -177,11 +154,11 @@ // \brief Gets the edges our graph should have, based on an Instruction* class GetEdgesVisitor : public InstVisitor { - CFLAliasAnalysis &AA; + CFLAAResult &AA; SmallVectorImpl &Output; public: - GetEdgesVisitor(CFLAliasAnalysis &AA, SmallVectorImpl &Output) + GetEdgesVisitor(CFLAAResult &AA, SmallVectorImpl &Output) : AA(AA), Output(Output) {} void visitInstruction(Instruction &) { @@ -669,12 +646,10 @@ static EdgeType flipWeight(EdgeType); // Gets edges of the given Instruction*, writing them to the SmallVector*. -static void argsToEdges(CFLAliasAnalysis &, Instruction *, - SmallVectorImpl &); +static void argsToEdges(CFLAAResult &, Instruction *, SmallVectorImpl &); // Gets edges of the given ConstantExpr*, writing them to the SmallVector*. -static void argsToEdges(CFLAliasAnalysis &, ConstantExpr *, - SmallVectorImpl &); +static void argsToEdges(CFLAAResult &, ConstantExpr *, SmallVectorImpl &); // Gets the "Level" that one should travel in StratifiedSets // given an EdgeType. @@ -682,13 +657,13 @@ // Builds the graph needed for constructing the StratifiedSets for the // given function -static void buildGraphFrom(CFLAliasAnalysis &, Function *, +static void buildGraphFrom(CFLAAResult &, Function *, SmallVectorImpl &, NodeMapT &, GraphT &); // Gets the edges of a ConstantExpr as if it was an Instruction. This // function also acts on any nested ConstantExprs, adding the edges // of those to the given SmallVector as well. -static void constexprToEdges(CFLAliasAnalysis &, ConstantExpr &, +static void constexprToEdges(CFLAAResult &, ConstantExpr &, SmallVectorImpl &); // Given an Instruction, this will add it to the graph, along with any @@ -697,7 +672,7 @@ // %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2 // addInstructionToGraph would add both the `load` and `getelementptr` // instructions to the graph appropriately. -static void addInstructionToGraph(CFLAliasAnalysis &, Instruction &, +static void addInstructionToGraph(CFLAAResult &, Instruction &, SmallVectorImpl &, NodeMapT &, GraphT &); @@ -777,7 +752,7 @@ llvm_unreachable("Incomplete coverage of EdgeType enum"); } -static void argsToEdges(CFLAliasAnalysis &Analysis, Instruction *Inst, +static void argsToEdges(CFLAAResult &Analysis, Instruction *Inst, SmallVectorImpl &Output) { assert(hasUsefulEdges(Inst) && "Expected instructions to have 'useful' edges"); @@ -785,7 +760,7 @@ v.visit(Inst); } -static void argsToEdges(CFLAliasAnalysis &Analysis, ConstantExpr *CE, +static void argsToEdges(CFLAAResult &Analysis, ConstantExpr *CE, SmallVectorImpl &Output) { assert(hasUsefulEdges(CE) && "Expected constant expr to have 'useful' edges"); GetEdgesVisitor v(Analysis, Output); @@ -804,7 +779,7 @@ llvm_unreachable("Incomplete switch coverage"); } -static void constexprToEdges(CFLAliasAnalysis &Analysis, +static void constexprToEdges(CFLAAResult &Analysis, ConstantExpr &CExprToCollapse, SmallVectorImpl &Results) { SmallVector Worklist; @@ -834,7 +809,7 @@ } } -static void addInstructionToGraph(CFLAliasAnalysis &Analysis, Instruction &Inst, +static void addInstructionToGraph(CFLAAResult &Analysis, Instruction &Inst, SmallVectorImpl &ReturnedValues, NodeMapT &Map, GraphT &Graph) { const auto findOrInsertNode = [&Map, &Graph](Value *Val) { @@ -897,7 +872,7 @@ // buy us much that we don't already have. I'd like to add interprocedural // analysis prior to this however, in case that somehow requires the graph // produced by this for efficient execution -static void buildGraphFrom(CFLAliasAnalysis &Analysis, Function *Fn, +static void buildGraphFrom(CFLAAResult &Analysis, Function *Fn, SmallVectorImpl &ReturnedValues, NodeMapT &Map, GraphT &Graph) { for (auto &Bb : Fn->getBasicBlockList()) @@ -928,7 +903,7 @@ } // Builds the graph + StratifiedSets for a function. -CFLAliasAnalysis::FunctionInfo CFLAliasAnalysis::buildSetsFrom(Function *Fn) { +CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) { NodeMapT Map; GraphT Graph; SmallVector ReturnedValues; @@ -1014,7 +989,7 @@ return FunctionInfo(Builder.build(), std::move(ReturnedValues)); } -void CFLAliasAnalysis::scan(Function *Fn) { +void CFLAAResult::scan(Function *Fn) { auto InsertPair = Cache.insert(std::make_pair(Fn, Optional())); (void)InsertPair; assert(InsertPair.second && @@ -1025,12 +1000,12 @@ Handles.push_front(FunctionHandle(Fn, this)); } -void CFLAliasAnalysis::evict(Function *Fn) { Cache.erase(Fn); } +void CFLAAResult::evict(Function *Fn) { Cache.erase(Fn); } /// \brief Ensures that the given function is available in the cache. /// Returns the appropriate entry from the cache. -const Optional & -CFLAliasAnalysis::ensureCached(Function *Fn) { +const Optional & +CFLAAResult::ensureCached(Function *Fn) { auto Iter = Cache.find(Fn); if (Iter == Cache.end()) { scan(Fn); @@ -1041,8 +1016,8 @@ return Iter->second; } -AliasResult CFLAliasAnalysis::query(const MemoryLocation &LocA, - const MemoryLocation &LocB) { +AliasResult CFLAAResult::query(const MemoryLocation &LocA, + const MemoryLocation &LocB) { auto *ValA = const_cast(LocA.Ptr); auto *ValB = const_cast(LocB.Ptr); @@ -1108,7 +1083,37 @@ return NoAlias; } -bool CFLAliasAnalysis::doInitialization(Module &M) { - InitializeAliasAnalysis(this, &M.getDataLayout()); - return true; +CFLAAResult CFLAA::run(Function &F, AnalysisManager *AM) { + return CFLAAResult(AM->getResult(F)); +} + +char CFLAA::PassID; + +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) + +ImmutablePass *llvm::createCFLAAWrapperPass() { return new CFLAAWrapperPass(); } + +CFLAAWrapperPass::CFLAAWrapperPass() : ImmutablePass(ID) { + initializeCFLAAWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +bool CFLAAWrapperPass::doInitialization(Module &M) { + Result.reset( + new CFLAAResult(getAnalysis().getTLI())); + return false; +} + +bool CFLAAWrapperPass::doFinalization(Module &M) { + Result.reset(); + return false; +} + +void CFLAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); } Index: lib/Analysis/CMakeLists.txt =================================================================== --- lib/Analysis/CMakeLists.txt +++ lib/Analysis/CMakeLists.txt @@ -1,6 +1,5 @@ add_llvm_library(LLVMAnalysis AliasAnalysis.cpp - AliasAnalysisCounter.cpp AliasAnalysisEvaluator.cpp AliasSetTracker.cpp Analysis.cpp @@ -48,7 +47,6 @@ MemoryDependenceAnalysis.cpp MemoryLocation.cpp ModuleDebugInfoPrinter.cpp - NoAliasAnalysis.cpp ObjCARCAliasAnalysis.cpp ObjCARCAnalysisUtils.cpp ObjCARCInstKind.cpp Index: lib/Analysis/DependenceAnalysis.cpp =================================================================== --- lib/Analysis/DependenceAnalysis.cpp +++ lib/Analysis/DependenceAnalysis.cpp @@ -118,7 +118,7 @@ "Dependence Analysis", true, true) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(DependenceAnalysis, "da", "Dependence Analysis", true, true) @@ -132,7 +132,7 @@ bool DependenceAnalysis::runOnFunction(Function &F) { this->F = &F; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); SE = &getAnalysis().getSE(); LI = &getAnalysis().getLoopInfo(); return false; @@ -145,7 +145,7 @@ void DependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequiredTransitive(); + AU.addRequiredTransitive(); AU.addRequiredTransitive(); AU.addRequiredTransitive(); } Index: lib/Analysis/GlobalsModRef.cpp =================================================================== --- lib/Analysis/GlobalsModRef.cpp +++ lib/Analysis/GlobalsModRef.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/MemoryBuiltins.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InstIterator.h" @@ -58,7 +59,7 @@ /// general and as pertains to specific globals. We only have this detailed /// information when we know *something* useful about the behavior. If we /// saturate to fully general mod/ref, we remove the info for the function. -class GlobalsModRef::FunctionInfo { +class GlobalsAAResult::FunctionInfo { typedef SmallDenseMap GlobalInfoMapType; /// Build a wrapper struct that has 8-byte alignment. All heap allocations @@ -191,56 +192,41 @@ PointerIntPair Info; }; -void GlobalsModRef::DeletionCallbackHandle::deleted() { +void GlobalsAAResult::DeletionCallbackHandle::deleted() { Value *V = getValPtr(); if (auto *F = dyn_cast(V)) - GMR.FunctionInfos.erase(F); + GAR.FunctionInfos.erase(F); if (GlobalValue *GV = dyn_cast(V)) { - if (GMR.NonAddressTakenGlobals.erase(GV)) { + if (GAR.NonAddressTakenGlobals.erase(GV)) { // This global might be an indirect global. If so, remove it and // remove any AllocRelatedValues for it. - if (GMR.IndirectGlobals.erase(GV)) { + if (GAR.IndirectGlobals.erase(GV)) { // Remove any entries in AllocsForIndirectGlobals for this global. - for (auto I = GMR.AllocsForIndirectGlobals.begin(), - E = GMR.AllocsForIndirectGlobals.end(); + for (auto I = GAR.AllocsForIndirectGlobals.begin(), + E = GAR.AllocsForIndirectGlobals.end(); I != E; ++I) if (I->second == GV) - GMR.AllocsForIndirectGlobals.erase(I); + GAR.AllocsForIndirectGlobals.erase(I); } // Scan the function info we have collected and remove this global // from all of them. - for (auto &FIPair : GMR.FunctionInfos) + for (auto &FIPair : GAR.FunctionInfos) FIPair.second.eraseModRefInfoForGlobal(*GV); } } // If this is an allocation related to an indirect global, remove it. - GMR.AllocsForIndirectGlobals.erase(V); + GAR.AllocsForIndirectGlobals.erase(V); // And clear out the handle. setValPtr(nullptr); - GMR.Handles.erase(I); + GAR.Handles.erase(I); // This object is now destroyed! } -char GlobalsModRef::ID = 0; -INITIALIZE_AG_PASS_BEGIN(GlobalsModRef, AliasAnalysis, "globalsmodref-aa", - "Simple mod/ref analysis for globals", false, true, - false) -INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) -INITIALIZE_AG_PASS_END(GlobalsModRef, AliasAnalysis, "globalsmodref-aa", - "Simple mod/ref analysis for globals", false, true, - false) - -Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); } - -GlobalsModRef::GlobalsModRef() : ModulePass(ID) { - initializeGlobalsModRefPass(*PassRegistry::getPassRegistry()); -} - -FunctionModRefBehavior GlobalsModRef::getModRefBehavior(const Function *F) { +FunctionModRefBehavior GlobalsAAResult::getModRefBehavior(const Function *F) { FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior; if (FunctionInfo *FI = getFunctionInfo(F)) { @@ -250,10 +236,11 @@ Min = FMRB_OnlyReadsMemory; } - return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min); + return FunctionModRefBehavior(AAResultBase::getModRefBehavior(F) & Min); } -FunctionModRefBehavior GlobalsModRef::getModRefBehavior(ImmutableCallSite CS) { +FunctionModRefBehavior +GlobalsAAResult::getModRefBehavior(ImmutableCallSite CS) { FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior; if (const Function *F = CS.getCalledFunction()) @@ -264,12 +251,13 @@ Min = FMRB_OnlyReadsMemory; } - return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min); + return FunctionModRefBehavior(AAResultBase::getModRefBehavior(CS) & Min); } /// Returns the function info for the function, or null if we don't have /// anything useful to say about it. -GlobalsModRef::FunctionInfo *GlobalsModRef::getFunctionInfo(const Function *F) { +GlobalsAAResult::FunctionInfo * +GlobalsAAResult::getFunctionInfo(const Function *F) { auto I = FunctionInfos.find(F); if (I != FunctionInfos.end()) return &I->second; @@ -280,7 +268,7 @@ /// GlobalValue's in the program. If none of them have their "address taken" /// (really, their address passed to something nontrivial), record this fact, /// and record the functions that they are used directly in. -void GlobalsModRef::AnalyzeGlobals(Module &M) { +void GlobalsAAResult::AnalyzeGlobals(Module &M) { SmallPtrSet TrackedFunctions; for (Function &F : M) if (F.hasLocalLinkage()) @@ -337,10 +325,10 @@ /// write to the value. /// /// If OkayStoreDest is non-null, stores into this global are allowed. -bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V, - SmallPtrSetImpl *Readers, - SmallPtrSetImpl *Writers, - GlobalValue *OkayStoreDest) { +bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V, + SmallPtrSetImpl *Readers, + SmallPtrSetImpl *Writers, + GlobalValue *OkayStoreDest) { if (!V->getType()->isPointerTy()) return true; @@ -367,7 +355,7 @@ // passing into the function. if (!CS.isCallee(&U)) { // Detect calls to free. - if (isFreeCall(I, TLI)) { + if (isFreeCall(I, &TLI)) { if (Writers) Writers->insert(CS->getParent()->getParent()); } else { @@ -392,7 +380,7 @@ /// Further, all loads out of GV must directly use the memory, not store the /// pointer somewhere. If this is true, we consider the memory pointed to by /// GV to be owned by GV and can disambiguate other pointers from it. -bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) { +bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalValue *GV) { // Keep track of values related to the allocation of the memory, f.e. the // value produced by the malloc call and any casts. std::vector AllocRelatedValues; @@ -420,7 +408,7 @@ Value *Ptr = GetUnderlyingObject(SI->getOperand(0), GV->getParent()->getDataLayout()); - if (!isAllocLikeFn(Ptr, TLI)) + if (!isAllocLikeFn(Ptr, &TLI)) return false; // Too hard to analyze. // Analyze all uses of the allocation. If any of them are used in a @@ -455,7 +443,7 @@ /// immediately stored to and read from. Propagate this information up the call /// graph to all callers and compute the mod/ref info for all memory for each /// function. -void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) { +void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) { // We do a bottom-up SCC traversal of the call graph. In other words, we // visit all callees before callers (leaf-first). for (scc_iterator I = scc_begin(&CG); !I.isAtEnd(); ++I) { @@ -538,7 +526,7 @@ // We handle calls specially because the graph-relevant aspects are // handled above. if (auto CS = CallSite(&I)) { - if (isAllocationFn(&I, TLI) || isFreeCall(&I, TLI)) { + if (isAllocationFn(&I, &TLI) || isFreeCall(&I, &TLI)) { // FIXME: It is completely unclear why this is necessary and not // handled by the above graph code. FI.addModRefInfo(MRI_ModRef); @@ -546,7 +534,7 @@ // The callgraph doesn't include intrinsic calls. if (Callee->isIntrinsic()) { FunctionModRefBehavior Behaviour = - AliasAnalysis::getModRefBehavior(Callee); + AAResultBase::getModRefBehavior(Callee); FI.addModRefInfo(ModRefInfo(Behaviour & MRI_ModRef)); } } @@ -599,8 +587,8 @@ // variables in this way to either not trust AA results while the escape is // active, or to be forced to operate as a module pass that cannot co-exist // with an alias analysis such as GMR. -bool GlobalsModRef::isNonEscapingGlobalNoAlias(const GlobalValue *GV, - const Value *V) { +bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV, + const Value *V) { // In order to know that the underlying object cannot alias the // non-addr-taken global, we must know that it would have to be an escape. // Thus if the underlying object is a function argument, a load from @@ -631,8 +619,8 @@ Type *GVType = GVar->getInitializer()->getType(); Type *InputGVType = InputGVar->getInitializer()->getType(); if (GVType->isSized() && InputGVType->isSized() && - (DL->getTypeAllocSize(GVType) > 0) && - (DL->getTypeAllocSize(InputGVType) > 0)) + (DL.getTypeAllocSize(GVType) > 0) && + (DL.getTypeAllocSize(InputGVType) > 0)) continue; } @@ -651,7 +639,7 @@ if (auto *LI = dyn_cast(Input)) { // A pointer loaded from a global would have been captured, and we know // that the global is non-escaping, so no alias. - if (isa(GetUnderlyingObject(LI->getPointerOperand(), *DL))) + if (isa(GetUnderlyingObject(LI->getPointerOperand(), DL))) continue; // Otherwise, a load could come from anywhere, so bail. @@ -665,8 +653,8 @@ if (++Depth > 4) return false; if (auto *SI = dyn_cast(Input)) { - const Value *LHS = GetUnderlyingObject(SI->getTrueValue(), *DL); - const Value *RHS = GetUnderlyingObject(SI->getFalseValue(), *DL); + const Value *LHS = GetUnderlyingObject(SI->getTrueValue(), DL); + const Value *RHS = GetUnderlyingObject(SI->getFalseValue(), DL); if (Visited.insert(LHS).second) Inputs.push_back(LHS); if (Visited.insert(RHS).second) @@ -675,7 +663,7 @@ } if (auto *PN = dyn_cast(Input)) { for (const Value *Op : PN->incoming_values()) { - Op = GetUnderlyingObject(Op, *DL); + Op = GetUnderlyingObject(Op, DL); if (Visited.insert(Op).second) Inputs.push_back(Op); } @@ -684,7 +672,7 @@ // FIXME: It would be good to handle other obvious no-alias cases here, but // it isn't clear how to do so reasonbly without building a small version - // of BasicAA into this code. We could recurse into AliasAnalysis::alias + // of BasicAA into this code. We could recurse into AAResultBase::alias // here but that seems likely to go poorly as we're inside the // implementation of such a query. Until then, just conservatievly retun // false. @@ -698,11 +686,11 @@ /// alias - If one of the pointers is to a global that we are tracking, and the /// other is some random pointer, we know there cannot be an alias, because the /// address of the global isn't taken. -AliasResult GlobalsModRef::alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) { +AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) { // Get the base object these pointers point to. - const Value *UV1 = GetUnderlyingObject(LocA.Ptr, *DL); - const Value *UV2 = GetUnderlyingObject(LocB.Ptr, *DL); + const Value *UV1 = GetUnderlyingObject(LocA.Ptr, DL); + const Value *UV2 = GetUnderlyingObject(LocB.Ptr, DL); // If either of the underlying values is a global, they may be non-addr-taken // globals, which we can answer queries about. @@ -774,16 +762,15 @@ if ((GV1 || GV2) && GV1 != GV2) return NoAlias; - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); } -ModRefInfo GlobalsModRef::getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) { +ModRefInfo GlobalsAAResult::getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) { unsigned Known = MRI_ModRef; // If we are asking for mod/ref info of a direct call with a pointer to a // global we are tracking, return information if we have it. - const DataLayout &DL = CS.getCaller()->getParent()->getDataLayout(); if (const GlobalValue *GV = dyn_cast(GetUnderlyingObject(Loc.Ptr, DL))) if (GV->hasLocalLinkage()) @@ -794,5 +781,68 @@ if (Known == MRI_NoModRef) return MRI_NoModRef; // No need to query other mod/ref analyses - return ModRefInfo(Known & AliasAnalysis::getModRefInfo(CS, Loc)); + return ModRefInfo(Known & AAResultBase::getModRefInfo(CS, Loc)); +} + +GlobalsAAResult::GlobalsAAResult(const DataLayout &DL, + const TargetLibraryInfo &TLI) + : AAResultBase(TLI), DL(DL) {} + +GlobalsAAResult::GlobalsAAResult(GlobalsAAResult &&Arg) + : AAResultBase(std::move(Arg)), DL(Arg.DL) {} + +/*static*/ GlobalsAAResult +GlobalsAAResult::analyzeModule(Module &M, const TargetLibraryInfo &TLI, + CallGraph &CG) { + GlobalsAAResult Result(M.getDataLayout(), TLI); + + // Find non-addr taken globals. + Result.AnalyzeGlobals(M); + + // Propagate on CG. + Result.AnalyzeCallGraph(CG, M); + + return Result; +} + +GlobalsAAResult GlobalsAA::run(Module &M, AnalysisManager *AM) { + return GlobalsAAResult::analyzeModule(M, + AM->getResult(M), + AM->getResult(M)); +} + +char GlobalsAA::PassID; + +char GlobalsAAWrapperPass::ID = 0; +INITIALIZE_PASS_BEGIN(GlobalsAAWrapperPass, "globals-aa", + "Globals Alias Analysis", false, true) +INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_END(GlobalsAAWrapperPass, "globals-aa", + "Globals Alias Analysis", false, true) + +ModulePass *llvm::createGlobalsAAWrapperPass() { + return new GlobalsAAWrapperPass(); +} + +GlobalsAAWrapperPass::GlobalsAAWrapperPass() : ModulePass(ID) { + initializeGlobalsAAWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +bool GlobalsAAWrapperPass::runOnModule(Module &M) { + Result.reset(new GlobalsAAResult(GlobalsAAResult::analyzeModule( + M, getAnalysis().getTLI(), + getAnalysis().getCallGraph()))); + return false; +} + +bool GlobalsAAWrapperPass::doFinalization(Module &M) { + Result.reset(); + return false; +} + +void GlobalsAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + AU.addRequired(); } Index: lib/Analysis/Lint.cpp =================================================================== --- lib/Analysis/Lint.cpp +++ lib/Analysis/Lint.cpp @@ -123,7 +123,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -167,7 +167,7 @@ INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(Lint, "lint", "Statically lint-checks LLVM IR", false, true) @@ -181,7 +181,7 @@ bool Lint::runOnFunction(Function &F) { Mod = F.getParent(); DL = &F.getParent()->getDataLayout(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); AC = &getAnalysis().getAssumptionCache(F); DT = &getAnalysis().getDomTree(); TLI = &getAnalysis().getTLI(); Index: lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- lib/Analysis/LoopAccessAnalysis.cpp +++ lib/Analysis/LoopAccessAnalysis.cpp @@ -1802,7 +1802,7 @@ SE = &getAnalysis().getSE(); auto *TLIP = getAnalysisIfAvailable(); TLI = TLIP ? &TLIP->getTLI() : nullptr; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); DT = &getAnalysis().getDomTree(); LI = &getAnalysis().getLoopInfo(); @@ -1811,7 +1811,7 @@ void LoopAccessAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -1823,7 +1823,7 @@ #define LAA_NAME "loop-accesses" INITIALIZE_PASS_BEGIN(LoopAccessAnalysis, LAA_NAME, laa_name, false, true) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) Index: lib/Analysis/MemDepPrinter.cpp =================================================================== --- lib/Analysis/MemDepPrinter.cpp +++ lib/Analysis/MemDepPrinter.cpp @@ -49,7 +49,7 @@ void print(raw_ostream &OS, const Module * = nullptr) const override; void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequiredTransitive(); + AU.addRequiredTransitive(); AU.addRequiredTransitive(); AU.setPreservesAll(); } Index: lib/Analysis/MemoryDependenceAnalysis.cpp =================================================================== --- lib/Analysis/MemoryDependenceAnalysis.cpp +++ lib/Analysis/MemoryDependenceAnalysis.cpp @@ -65,8 +65,8 @@ // Register this pass... INITIALIZE_PASS_BEGIN(MemoryDependenceAnalysis, "memdep", "Memory Dependence Analysis", false, true) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(MemoryDependenceAnalysis, "memdep", "Memory Dependence Analysis", false, true) @@ -94,12 +94,12 @@ void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); - AU.addRequiredTransitive(); + AU.addRequiredTransitive(); AU.addRequiredTransitive(); } bool MemoryDependenceAnalysis::runOnFunction(Function &F) { - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); AC = &getAnalysis().getAssumptionCache(F); DominatorTreeWrapperPass *DTWP = getAnalysisIfAvailable(); Index: lib/Analysis/NoAliasAnalysis.cpp =================================================================== --- lib/Analysis/NoAliasAnalysis.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//===- NoAliasAnalysis.cpp - Minimal Alias Analysis Impl ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the default implementation of the Alias Analysis interface -// that simply returns "I don't know" for all queries. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/Pass.h" -using namespace llvm; - -namespace { - /// NoAA - This class implements the -no-aa pass, which always returns "I - /// don't know" for alias queries. NoAA is unlike other alias analysis - /// implementations, in that it does not chain to a previous analysis. As - /// such it doesn't follow many of the rules that other alias analyses must. - /// - struct NoAA : public ImmutablePass, public AliasAnalysis { - static char ID; // Class identification, replacement for typeinfo - NoAA() : ImmutablePass(ID) { - initializeNoAAPass(*PassRegistry::getPassRegistry()); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override {} - - bool doInitialization(Module &M) override { - // Note: NoAA does not call InitializeAliasAnalysis because it's - // special and does not support chaining. - DL = &M.getDataLayout(); - return true; - } - - AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) override { - return MayAlias; - } - - FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override { - return FMRB_UnknownModRefBehavior; - } - FunctionModRefBehavior getModRefBehavior(const Function *F) override { - return FMRB_UnknownModRefBehavior; - } - - bool pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal) override { - return false; - } - ModRefInfo getArgModRefInfo(ImmutableCallSite CS, - unsigned ArgIdx) override { - return MRI_ModRef; - } - - ModRefInfo getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) override { - return MRI_ModRef; - } - ModRefInfo getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) override { - return MRI_ModRef; - } - - /// getAdjustedAnalysisPointer - This method is used when a pass implements - /// an analysis interface through multiple inheritance. If needed, it - /// should override this to adjust the this pointer as needed for the - /// specified pass info. - void *getAdjustedAnalysisPointer(const void *ID) override { - if (ID == &AliasAnalysis::ID) - return (AliasAnalysis*)this; - return this; - } - }; -} // End of anonymous namespace - -// Register this pass... -char NoAA::ID = 0; -INITIALIZE_AG_PASS(NoAA, AliasAnalysis, "no-aa", - "No Alias Analysis (always returns 'may' alias)", - true, true, true) - -ImmutablePass *llvm::createNoAAPass() { return new NoAA(); } Index: lib/Analysis/ObjCARCAliasAnalysis.cpp =================================================================== --- lib/Analysis/ObjCARCAliasAnalysis.cpp +++ lib/Analysis/ObjCARCAliasAnalysis.cpp @@ -18,6 +18,9 @@ /// used. Naive LLVM IR transformations which would otherwise be /// behavior-preserving may break these assumptions. /// +/// TODO: Theoretically we could check for dependencies between objc_* calls +/// and FMRB_OnlyAccessesArgumentPointees calls or other well-behaved calls. +/// //===----------------------------------------------------------------------===// #include "llvm/Analysis/ObjCARCAliasAnalysis.h" @@ -34,46 +37,27 @@ using namespace llvm; using namespace llvm::objcarc; -// Register this pass... -char ObjCARCAliasAnalysis::ID = 0; -INITIALIZE_AG_PASS(ObjCARCAliasAnalysis, AliasAnalysis, "objc-arc-aa", - "ObjC-ARC-Based Alias Analysis", false, true, false) - -ImmutablePass *llvm::createObjCARCAliasAnalysisPass() { - return new ObjCARCAliasAnalysis(); -} - -bool ObjCARCAliasAnalysis::doInitialization(Module &M) { - InitializeAliasAnalysis(this, &M.getDataLayout()); - return true; -} - -void ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AliasAnalysis::getAnalysisUsage(AU); -} - -AliasResult ObjCARCAliasAnalysis::alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) { +AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) { if (!EnableARCOpts) - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); // 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 = - AliasAnalysis::alias(MemoryLocation(SA, LocA.Size, LocA.AATags), - MemoryLocation(SB, LocB.Size, LocB.AATags)); + AAResultBase::alias(MemoryLocation(SA, LocA.Size, LocA.AATags), + MemoryLocation(SB, LocB.Size, LocB.AATags)); if (Result != MayAlias) return Result; // If that failed, climb to the underlying object, including climbing through // ObjC-specific no-ops, and try making an imprecise alias query. - const Value *UA = GetUnderlyingObjCPtr(SA, *DL); - const Value *UB = GetUnderlyingObjCPtr(SB, *DL); + const Value *UA = GetUnderlyingObjCPtr(SA, DL); + const Value *UB = GetUnderlyingObjCPtr(SB, DL); if (UA != SA || UB != SB) { - Result = AliasAnalysis::alias(MemoryLocation(UA), MemoryLocation(UB)); + Result = AAResultBase::alias(MemoryLocation(UA), MemoryLocation(UB)); // We can't use MustAlias or PartialAlias results here because // GetUnderlyingObjCPtr may return an offsetted pointer value. if (Result == NoAlias) @@ -85,39 +69,32 @@ return MayAlias; } -bool ObjCARCAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal) { +bool ObjCARCAAResult::pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) { if (!EnableARCOpts) - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); + return AAResultBase::pointsToConstantMemory(Loc, 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 (AliasAnalysis::pointsToConstantMemory( + if (AAResultBase::pointsToConstantMemory( MemoryLocation(S, Loc.Size, Loc.AATags), 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); + const Value *U = GetUnderlyingObjCPtr(S, DL); if (U != S) - return AliasAnalysis::pointsToConstantMemory(MemoryLocation(U), OrLocal); + return AAResultBase::pointsToConstantMemory(MemoryLocation(U), OrLocal); // If that failed, fail. We don't need to chain here, since that's covered // by the earlier precise query. return false; } -FunctionModRefBehavior -ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { - // We have nothing to do. Just chain to the next AliasAnalysis. - return AliasAnalysis::getModRefBehavior(CS); -} - -FunctionModRefBehavior -ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) { +FunctionModRefBehavior ObjCARCAAResult::getModRefBehavior(const Function *F) { if (!EnableARCOpts) - return AliasAnalysis::getModRefBehavior(F); + return AAResultBase::getModRefBehavior(F); switch (GetFunctionClass(F)) { case ARCInstKind::NoopCast: @@ -126,13 +103,13 @@ break; } - return AliasAnalysis::getModRefBehavior(F); + return AAResultBase::getModRefBehavior(F); } -ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) { +ModRefInfo ObjCARCAAResult::getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) { if (!EnableARCOpts) - return AliasAnalysis::getModRefInfo(CS, Loc); + return AAResultBase::getModRefInfo(CS, Loc); switch (GetBasicARCInstKind(CS.getInstruction())) { case ARCInstKind::Retain: @@ -151,12 +128,43 @@ break; } - return AliasAnalysis::getModRefInfo(CS, Loc); + return AAResultBase::getModRefInfo(CS, Loc); +} + +ObjCARCAAResult ObjCARCAA::run(Function &F, AnalysisManager *AM) { + return ObjCARCAAResult(F.getParent()->getDataLayout(), + AM->getResult(F)); } -ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) { - // TODO: Theoretically we could check for dependencies between objc_* calls - // and FMRB_OnlyAccessesArgumentPointees calls or other well-behaved calls. - return AliasAnalysis::getModRefInfo(CS1, CS2); +char ObjCARCAA::PassID; + +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) + +ImmutablePass *llvm::createObjCARCAAWrapperPass() { + return new ObjCARCAAWrapperPass(); +} + +ObjCARCAAWrapperPass::ObjCARCAAWrapperPass() : ImmutablePass(ID) { + initializeObjCARCAAWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +bool ObjCARCAAWrapperPass::doInitialization(Module &M) { + Result.reset(new ObjCARCAAResult( + M.getDataLayout(), getAnalysis().getTLI())); + return false; +} + +bool ObjCARCAAWrapperPass::doFinalization(Module &M) { + Result.reset(); + return false; +} + +void ObjCARCAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); } Index: lib/Analysis/ScalarEvolutionAliasAnalysis.cpp =================================================================== --- lib/Analysis/ScalarEvolutionAliasAnalysis.cpp +++ lib/Analysis/ScalarEvolutionAliasAnalysis.cpp @@ -20,66 +20,20 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" +#include "llvm/Analysis/TargetLibraryInfo.h" using namespace llvm; -// Register this pass... -char ScalarEvolutionAliasAnalysis::ID = 0; -INITIALIZE_AG_PASS_BEGIN(ScalarEvolutionAliasAnalysis, AliasAnalysis, "scev-aa", - "ScalarEvolution-based Alias Analysis", false, true, - false) -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) -INITIALIZE_AG_PASS_END(ScalarEvolutionAliasAnalysis, AliasAnalysis, "scev-aa", - "ScalarEvolution-based Alias Analysis", false, true, - false) - -FunctionPass *llvm::createScalarEvolutionAliasAnalysisPass() { - return new ScalarEvolutionAliasAnalysis(); -} - -void ScalarEvolutionAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredTransitive(); - AU.setPreservesAll(); - AliasAnalysis::getAnalysisUsage(AU); -} - -bool ScalarEvolutionAliasAnalysis::runOnFunction(Function &F) { - InitializeAliasAnalysis(this, &F.getParent()->getDataLayout()); - SE = &getAnalysis().getSE(); - return false; -} - -/// Given an expression, try to find a base value. -/// -/// Returns null if none was found. -Value *ScalarEvolutionAliasAnalysis::GetBaseValue(const SCEV *S) { - if (const SCEVAddRecExpr *AR = dyn_cast(S)) { - // In an addrec, assume that the base will be in the start, rather - // than the step. - return GetBaseValue(AR->getStart()); - } else if (const SCEVAddExpr *A = dyn_cast(S)) { - // If there's a pointer operand, it'll be sorted at the end of the list. - const SCEV *Last = A->getOperand(A->getNumOperands() - 1); - if (Last->getType()->isPointerTy()) - return GetBaseValue(Last); - } else if (const SCEVUnknown *U = dyn_cast(S)) { - // This is a leaf node. - return U->getValue(); - } - // No Identified object found. - return nullptr; -} - -AliasResult ScalarEvolutionAliasAnalysis::alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) { +AliasResult SCEVAAResult::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) { // 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. if (LocA.Size == 0 || LocB.Size == 0) return NoAlias; - // This is ScalarEvolutionAliasAnalysis. Get the SCEVs! - const SCEV *AS = SE->getSCEV(const_cast(LocA.Ptr)); - const SCEV *BS = SE->getSCEV(const_cast(LocB.Ptr)); + // This is SCEVAAResult. Get the SCEVs! + const SCEV *AS = SE.getSCEV(const_cast(LocA.Ptr)); + const SCEV *BS = SE.getSCEV(const_cast(LocB.Ptr)); // If they evaluate to the same expression, it's a MustAlias. if (AS == BS) @@ -87,20 +41,20 @@ // If something is known about the difference between the two addresses, // see if it's enough to prove a NoAlias. - if (SE->getEffectiveSCEVType(AS->getType()) == - SE->getEffectiveSCEVType(BS->getType())) { - unsigned BitWidth = SE->getTypeSizeInBits(AS->getType()); + if (SE.getEffectiveSCEVType(AS->getType()) == + SE.getEffectiveSCEVType(BS->getType())) { + unsigned BitWidth = SE.getTypeSizeInBits(AS->getType()); APInt ASizeInt(BitWidth, LocA.Size); APInt BSizeInt(BitWidth, LocB.Size); // Compute the difference between the two pointers. - const SCEV *BA = SE->getMinusSCEV(BS, AS); + const SCEV *BA = SE.getMinusSCEV(BS, AS); // Test whether the difference is known to be great enough that memory of // the given sizes don't overlap. This assumes that ASizeInt and BSizeInt // are non-zero, which is special-cased above. - if (ASizeInt.ule(SE->getUnsignedRange(BA).getUnsignedMin()) && - (-BSizeInt).uge(SE->getUnsignedRange(BA).getUnsignedMax())) + if (ASizeInt.ule(SE.getUnsignedRange(BA).getUnsignedMin()) && + (-BSizeInt).uge(SE.getUnsignedRange(BA).getUnsignedMax())) return NoAlias; // Folding the subtraction while preserving range information can be tricky @@ -108,13 +62,13 @@ // and try again to see if things fold better that way. // Compute the difference between the two pointers. - const SCEV *AB = SE->getMinusSCEV(AS, BS); + const SCEV *AB = SE.getMinusSCEV(AS, BS); // Test whether the difference is known to be great enough that memory of // the given sizes don't overlap. This assumes that ASizeInt and BSizeInt // are non-zero, which is special-cased above. - if (BSizeInt.ule(SE->getUnsignedRange(AB).getUnsignedMin()) && - (-ASizeInt).uge(SE->getUnsignedRange(AB).getUnsignedMax())) + if (BSizeInt.ule(SE.getUnsignedRange(AB).getUnsignedMin()) && + (-ASizeInt).uge(SE.getUnsignedRange(AB).getUnsignedMax())) return NoAlias; } @@ -133,5 +87,62 @@ return NoAlias; // Forward the query to the next analysis. - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); +} + +/// Given an expression, try to find a base value. +/// +/// Returns null if none was found. +Value *SCEVAAResult::GetBaseValue(const SCEV *S) { + if (const SCEVAddRecExpr *AR = dyn_cast(S)) { + // In an addrec, assume that the base will be in the start, rather + // than the step. + return GetBaseValue(AR->getStart()); + } else if (const SCEVAddExpr *A = dyn_cast(S)) { + // If there's a pointer operand, it'll be sorted at the end of the list. + const SCEV *Last = A->getOperand(A->getNumOperands() - 1); + if (Last->getType()->isPointerTy()) + return GetBaseValue(Last); + } else if (const SCEVUnknown *U = dyn_cast(S)) { + // This is a leaf node. + return U->getValue(); + } + // No Identified object found. + return nullptr; +} + +SCEVAAResult SCEVAA::run(Function &F, AnalysisManager *AM) { + return SCEVAAResult(AM->getResult(F), + AM->getResult(F)); +} + +char SCEVAA::PassID; + +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) + +FunctionPass *llvm::createSCEVAAWrapperPass() { + return new SCEVAAWrapperPass(); +} + +SCEVAAWrapperPass::SCEVAAWrapperPass() : FunctionPass(ID) { + initializeSCEVAAWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +bool SCEVAAWrapperPass::runOnFunction(Function &F) { + Result.reset( + new SCEVAAResult(getAnalysis().getTLI(), + getAnalysis().getSE())); + return false; +} + +void SCEVAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + AU.addRequired(); } Index: lib/Analysis/ScopedNoAliasAA.cpp =================================================================== --- lib/Analysis/ScopedNoAliasAA.cpp +++ lib/Analysis/ScopedNoAliasAA.cpp @@ -34,7 +34,7 @@ #include "llvm/Analysis/ScopedNoAliasAA.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" @@ -72,26 +72,62 @@ }; } // End of anonymous namespace -// Register this pass... -char ScopedNoAliasAA::ID = 0; -INITIALIZE_AG_PASS(ScopedNoAliasAA, AliasAnalysis, "scoped-noalias", - "Scoped NoAlias Alias Analysis", false, true, false) +AliasResult ScopedNoAliasAAResult::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) { + if (!EnableScopedNoAlias) + return AAResultBase::alias(LocA, LocB); + + // Get the attached MDNodes. + const MDNode *AScopes = LocA.AATags.Scope, *BScopes = LocB.AATags.Scope; + + const MDNode *ANoAlias = LocA.AATags.NoAlias, *BNoAlias = LocB.AATags.NoAlias; + + if (!mayAliasInScopes(AScopes, BNoAlias)) + return NoAlias; + + if (!mayAliasInScopes(BScopes, ANoAlias)) + return NoAlias; -ImmutablePass *llvm::createScopedNoAliasAAPass() { - return new ScopedNoAliasAA(); + // If they may alias, chain to the next AliasAnalysis. + return AAResultBase::alias(LocA, LocB); } -bool ScopedNoAliasAA::doInitialization(Module &M) { - InitializeAliasAnalysis(this, &M.getDataLayout()); - return true; +ModRefInfo ScopedNoAliasAAResult::getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) { + if (!EnableScopedNoAlias) + return AAResultBase::getModRefInfo(CS, Loc); + + if (!mayAliasInScopes(Loc.AATags.Scope, CS.getInstruction()->getMetadata( + LLVMContext::MD_noalias))) + return MRI_NoModRef; + + if (!mayAliasInScopes( + CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), + Loc.AATags.NoAlias)) + return MRI_NoModRef; + + return AAResultBase::getModRefInfo(CS, Loc); } -void ScopedNoAliasAA::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AliasAnalysis::getAnalysisUsage(AU); +ModRefInfo ScopedNoAliasAAResult::getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) { + if (!EnableScopedNoAlias) + return AAResultBase::getModRefInfo(CS1, CS2); + + if (!mayAliasInScopes( + CS1.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), + CS2.getInstruction()->getMetadata(LLVMContext::MD_noalias))) + return MRI_NoModRef; + + if (!mayAliasInScopes( + CS2.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), + CS1.getInstruction()->getMetadata(LLVMContext::MD_noalias))) + return MRI_NoModRef; + + return AAResultBase::getModRefInfo(CS1, CS2); } -void ScopedNoAliasAA::collectMDInDomain( +void ScopedNoAliasAAResult::collectMDInDomain( const MDNode *List, const MDNode *Domain, SmallPtrSetImpl &Nodes) const { for (unsigned i = 0, ie = List->getNumOperands(); i != ie; ++i) @@ -100,8 +136,8 @@ Nodes.insert(MD); } -bool ScopedNoAliasAA::mayAliasInScopes(const MDNode *Scopes, - const MDNode *NoAlias) const { +bool ScopedNoAliasAAResult::mayAliasInScopes(const MDNode *Scopes, + const MDNode *NoAlias) const { if (!Scopes || !NoAlias) return true; @@ -136,72 +172,40 @@ return true; } -AliasResult ScopedNoAliasAA::alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) { - if (!EnableScopedNoAlias) - return AliasAnalysis::alias(LocA, LocB); - - // Get the attached MDNodes. - const MDNode *AScopes = LocA.AATags.Scope, *BScopes = LocB.AATags.Scope; - - const MDNode *ANoAlias = LocA.AATags.NoAlias, *BNoAlias = LocB.AATags.NoAlias; +ScopedNoAliasAAResult ScopedNoAliasAA::run(Function &F, + AnalysisManager *AM) { + return ScopedNoAliasAAResult(AM->getResult(F)); +} - if (!mayAliasInScopes(AScopes, BNoAlias)) - return NoAlias; +char ScopedNoAliasAA::PassID; - if (!mayAliasInScopes(BScopes, ANoAlias)) - return NoAlias; +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) - // If they may alias, chain to the next AliasAnalysis. - return AliasAnalysis::alias(LocA, LocB); -} - -bool ScopedNoAliasAA::pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal) { - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); +ImmutablePass *llvm::createScopedNoAliasAAWrapperPass() { + return new ScopedNoAliasAAWrapperPass(); } -FunctionModRefBehavior -ScopedNoAliasAA::getModRefBehavior(ImmutableCallSite CS) { - return AliasAnalysis::getModRefBehavior(CS); +ScopedNoAliasAAWrapperPass::ScopedNoAliasAAWrapperPass() : ImmutablePass(ID) { + initializeScopedNoAliasAAWrapperPassPass(*PassRegistry::getPassRegistry()); } -FunctionModRefBehavior ScopedNoAliasAA::getModRefBehavior(const Function *F) { - return AliasAnalysis::getModRefBehavior(F); +bool ScopedNoAliasAAWrapperPass::doInitialization(Module &M) { + Result.reset(new ScopedNoAliasAAResult( + getAnalysis().getTLI())); + return false; } -ModRefInfo ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) { - if (!EnableScopedNoAlias) - return AliasAnalysis::getModRefInfo(CS, Loc); - - if (!mayAliasInScopes(Loc.AATags.Scope, CS.getInstruction()->getMetadata( - LLVMContext::MD_noalias))) - return MRI_NoModRef; - - if (!mayAliasInScopes( - CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), - Loc.AATags.NoAlias)) - return MRI_NoModRef; - - return AliasAnalysis::getModRefInfo(CS, Loc); +bool ScopedNoAliasAAWrapperPass::doFinalization(Module &M) { + Result.reset(); + return false; } -ModRefInfo ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) { - if (!EnableScopedNoAlias) - return AliasAnalysis::getModRefInfo(CS1, CS2); - - if (!mayAliasInScopes( - CS1.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), - CS2.getInstruction()->getMetadata(LLVMContext::MD_noalias))) - return MRI_NoModRef; - - if (!mayAliasInScopes( - CS2.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), - CS1.getInstruction()->getMetadata(LLVMContext::MD_noalias))) - return MRI_NoModRef; - - return AliasAnalysis::getModRefInfo(CS1, CS2); +void ScopedNoAliasAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); } - Index: lib/Analysis/TypeBasedAliasAnalysis.cpp =================================================================== --- lib/Analysis/TypeBasedAliasAnalysis.cpp +++ lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -122,6 +122,7 @@ //===----------------------------------------------------------------------===// #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" @@ -269,25 +270,6 @@ }; } -// Register this pass... -char TypeBasedAliasAnalysis::ID = 0; -INITIALIZE_AG_PASS(TypeBasedAliasAnalysis, AliasAnalysis, "tbaa", - "Type-Based Alias Analysis", false, true, false) - -ImmutablePass *llvm::createTypeBasedAliasAnalysisPass() { - return new TypeBasedAliasAnalysis(); -} - -bool TypeBasedAliasAnalysis::doInitialization(Module &M) { - InitializeAliasAnalysis(this, &M.getDataLayout()); - return true; -} - -void TypeBasedAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AliasAnalysis::getAnalysisUsage(AU); -} - /// Check the first operand of the tbaa tag node, if it is a MDNode, we treat /// it as struct-path aware TBAA format, otherwise, we treat it as scalar TBAA /// format. @@ -297,145 +279,36 @@ return isa(MD->getOperand(0)) && MD->getNumOperands() >= 3; } -/// Aliases - Test whether the type represented by A may alias the -/// type represented by B. -bool TypeBasedAliasAnalysis::Aliases(const MDNode *A, const MDNode *B) const { - // Make sure that both MDNodes are struct-path aware. - if (isStructPathTBAA(A) && isStructPathTBAA(B)) - return PathAliases(A, B); - - // Keep track of the root node for A and B. - TBAANode RootA, RootB; - - // Climb the tree from A to see if we reach B. - for (TBAANode T(A);;) { - if (T.getNode() == B) - // B is an ancestor of A. - return true; - - RootA = T; - T = T.getParent(); - if (!T.getNode()) - break; - } - - // Climb the tree from B to see if we reach A. - for (TBAANode T(B);;) { - if (T.getNode() == A) - // A is an ancestor of B. - return true; - - RootB = T; - T = T.getParent(); - if (!T.getNode()) - break; - } - - // Neither node is an ancestor of the other. - - // If they have different roots, they're part of different potentially - // unrelated type systems, so we must be conservative. - if (RootA.getNode() != RootB.getNode()) - return true; - - // If they have the same root, then we've proved there's no alias. - return false; -} - -/// Test whether the struct-path tag represented by A may alias the -/// struct-path tag represented by B. -bool TypeBasedAliasAnalysis::PathAliases(const MDNode *A, - const MDNode *B) const { - // Verify that both input nodes are struct-path aware. - assert(isStructPathTBAA(A) && "MDNode A is not struct-path aware."); - assert(isStructPathTBAA(B) && "MDNode B is not struct-path aware."); - - // Keep track of the root node for A and B. - TBAAStructTypeNode RootA, RootB; - TBAAStructTagNode TagA(A), TagB(B); - - // TODO: We need to check if AccessType of TagA encloses AccessType of - // TagB to support aggregate AccessType. If yes, return true. - - // Start from the base type of A, follow the edge with the correct offset in - // the type DAG and adjust the offset until we reach the base type of B or - // until we reach the Root node. - // Compare the adjusted offset once we have the same base. - - // Climb the type DAG from base type of A to see if we reach base type of B. - const MDNode *BaseA = TagA.getBaseType(); - const MDNode *BaseB = TagB.getBaseType(); - uint64_t OffsetA = TagA.getOffset(), OffsetB = TagB.getOffset(); - for (TBAAStructTypeNode T(BaseA);;) { - if (T.getNode() == BaseB) - // Base type of A encloses base type of B, check if the offsets match. - return OffsetA == OffsetB; - - RootA = T; - // Follow the edge with the correct offset, OffsetA will be adjusted to - // be relative to the field type. - T = T.getParent(OffsetA); - if (!T.getNode()) - break; - } - - // Reset OffsetA and climb the type DAG from base type of B to see if we reach - // base type of A. - OffsetA = TagA.getOffset(); - for (TBAAStructTypeNode T(BaseB);;) { - if (T.getNode() == BaseA) - // Base type of B encloses base type of A, check if the offsets match. - return OffsetA == OffsetB; - - RootB = T; - // Follow the edge with the correct offset, OffsetB will be adjusted to - // be relative to the field type. - T = T.getParent(OffsetB); - if (!T.getNode()) - break; - } - - // Neither node is an ancestor of the other. - - // If they have different roots, they're part of different potentially - // unrelated type systems, so we must be conservative. - if (RootA.getNode() != RootB.getNode()) - return true; - - // If they have the same root, then we've proved there's no alias. - return false; -} - -AliasResult TypeBasedAliasAnalysis::alias(const MemoryLocation &LocA, - const MemoryLocation &LocB) { +AliasResult TypeBasedAAResult::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) { if (!EnableTBAA) - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); // Get the attached MDNodes. If either value lacks a tbaa MDNode, we must // be conservative. const MDNode *AM = LocA.AATags.TBAA; if (!AM) - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); const MDNode *BM = LocB.AATags.TBAA; if (!BM) - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); // If they may alias, chain to the next AliasAnalysis. if (Aliases(AM, BM)) - return AliasAnalysis::alias(LocA, LocB); + return AAResultBase::alias(LocA, LocB); // Otherwise return a definitive result. return NoAlias; } -bool TypeBasedAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal) { +bool TypeBasedAAResult::pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) { if (!EnableTBAA) - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); const MDNode *M = Loc.AATags.TBAA; if (!M) - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); // If this is an "immutable" type, we can assume the pointer is pointing // to constant memory. @@ -443,13 +316,13 @@ (isStructPathTBAA(M) && TBAAStructTagNode(M).TypeIsImmutable())) return true; - return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); } FunctionModRefBehavior -TypeBasedAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { +TypeBasedAAResult::getModRefBehavior(ImmutableCallSite CS) { if (!EnableTBAA) - return AliasAnalysis::getModRefBehavior(CS); + return AAResultBase::getModRefBehavior(CS); FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior; @@ -460,19 +333,18 @@ (isStructPathTBAA(M) && TBAAStructTagNode(M).TypeIsImmutable())) Min = FMRB_OnlyReadsMemory; - return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min); + return FunctionModRefBehavior(AAResultBase::getModRefBehavior(CS) & Min); } -FunctionModRefBehavior -TypeBasedAliasAnalysis::getModRefBehavior(const Function *F) { +FunctionModRefBehavior TypeBasedAAResult::getModRefBehavior(const Function *F) { // Functions don't have metadata. Just chain to the next implementation. - return AliasAnalysis::getModRefBehavior(F); + return AAResultBase::getModRefBehavior(F); } -ModRefInfo TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) { +ModRefInfo TypeBasedAAResult::getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) { if (!EnableTBAA) - return AliasAnalysis::getModRefInfo(CS, Loc); + return AAResultBase::getModRefInfo(CS, Loc); if (const MDNode *L = Loc.AATags.TBAA) if (const MDNode *M = @@ -480,13 +352,13 @@ if (!Aliases(L, M)) return MRI_NoModRef; - return AliasAnalysis::getModRefInfo(CS, Loc); + return AAResultBase::getModRefInfo(CS, Loc); } -ModRefInfo TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) { +ModRefInfo TypeBasedAAResult::getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) { if (!EnableTBAA) - return AliasAnalysis::getModRefInfo(CS1, CS2); + return AAResultBase::getModRefInfo(CS1, CS2); if (const MDNode *M1 = CS1.getInstruction()->getMetadata(LLVMContext::MD_tbaa)) @@ -495,7 +367,7 @@ if (!Aliases(M1, M2)) return MRI_NoModRef; - return AliasAnalysis::getModRefInfo(CS1, CS2); + return AAResultBase::getModRefInfo(CS1, CS2); } bool MDNode::isTBAAVtableAccess() const { @@ -604,3 +476,147 @@ N.NoAlias = getMetadata(LLVMContext::MD_noalias); } +/// Aliases - Test whether the type represented by A may alias the +/// type represented by B. +bool TypeBasedAAResult::Aliases(const MDNode *A, const MDNode *B) const { + // Make sure that both MDNodes are struct-path aware. + if (isStructPathTBAA(A) && isStructPathTBAA(B)) + return PathAliases(A, B); + + // Keep track of the root node for A and B. + TBAANode RootA, RootB; + + // Climb the tree from A to see if we reach B. + for (TBAANode T(A);;) { + if (T.getNode() == B) + // B is an ancestor of A. + return true; + + RootA = T; + T = T.getParent(); + if (!T.getNode()) + break; + } + + // Climb the tree from B to see if we reach A. + for (TBAANode T(B);;) { + if (T.getNode() == A) + // A is an ancestor of B. + return true; + + RootB = T; + T = T.getParent(); + if (!T.getNode()) + break; + } + + // Neither node is an ancestor of the other. + + // If they have different roots, they're part of different potentially + // unrelated type systems, so we must be conservative. + if (RootA.getNode() != RootB.getNode()) + return true; + + // If they have the same root, then we've proved there's no alias. + return false; +} + +/// Test whether the struct-path tag represented by A may alias the +/// struct-path tag represented by B. +bool TypeBasedAAResult::PathAliases(const MDNode *A, const MDNode *B) const { + // Verify that both input nodes are struct-path aware. + assert(isStructPathTBAA(A) && "MDNode A is not struct-path aware."); + assert(isStructPathTBAA(B) && "MDNode B is not struct-path aware."); + + // Keep track of the root node for A and B. + TBAAStructTypeNode RootA, RootB; + TBAAStructTagNode TagA(A), TagB(B); + + // TODO: We need to check if AccessType of TagA encloses AccessType of + // TagB to support aggregate AccessType. If yes, return true. + + // Start from the base type of A, follow the edge with the correct offset in + // the type DAG and adjust the offset until we reach the base type of B or + // until we reach the Root node. + // Compare the adjusted offset once we have the same base. + + // Climb the type DAG from base type of A to see if we reach base type of B. + const MDNode *BaseA = TagA.getBaseType(); + const MDNode *BaseB = TagB.getBaseType(); + uint64_t OffsetA = TagA.getOffset(), OffsetB = TagB.getOffset(); + for (TBAAStructTypeNode T(BaseA);;) { + if (T.getNode() == BaseB) + // Base type of A encloses base type of B, check if the offsets match. + return OffsetA == OffsetB; + + RootA = T; + // Follow the edge with the correct offset, OffsetA will be adjusted to + // be relative to the field type. + T = T.getParent(OffsetA); + if (!T.getNode()) + break; + } + + // Reset OffsetA and climb the type DAG from base type of B to see if we reach + // base type of A. + OffsetA = TagA.getOffset(); + for (TBAAStructTypeNode T(BaseB);;) { + if (T.getNode() == BaseA) + // Base type of B encloses base type of A, check if the offsets match. + return OffsetA == OffsetB; + + RootB = T; + // Follow the edge with the correct offset, OffsetB will be adjusted to + // be relative to the field type. + T = T.getParent(OffsetB); + if (!T.getNode()) + break; + } + + // Neither node is an ancestor of the other. + + // If they have different roots, they're part of different potentially + // unrelated type systems, so we must be conservative. + if (RootA.getNode() != RootB.getNode()) + return true; + + // If they have the same root, then we've proved there's no alias. + return false; +} + +TypeBasedAAResult TypeBasedAA::run(Function &F, AnalysisManager *AM) { + return TypeBasedAAResult(AM->getResult(F)); +} + +char TypeBasedAA::PassID; + +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) + +ImmutablePass *llvm::createTypeBasedAAWrapperPass() { + return new TypeBasedAAWrapperPass(); +} + +TypeBasedAAWrapperPass::TypeBasedAAWrapperPass() : ImmutablePass(ID) { + initializeTypeBasedAAWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +bool TypeBasedAAWrapperPass::doInitialization(Module &M) { + Result.reset(new TypeBasedAAResult( + getAnalysis().getTLI())); + return false; +} + +bool TypeBasedAAWrapperPass::doFinalization(Module &M) { + Result.reset(); + return false; +} + +void TypeBasedAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); +} Index: lib/CodeGen/InlineSpiller.cpp =================================================================== --- lib/CodeGen/InlineSpiller.cpp +++ lib/CodeGen/InlineSpiller.cpp @@ -141,7 +141,7 @@ InlineSpiller(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm) : MF(mf), LIS(pass.getAnalysis()), LSS(pass.getAnalysis()), - AA(&pass.getAnalysis()), + AA(&pass.getAnalysis().getAAResults()), MDT(pass.getAnalysis()), Loops(pass.getAnalysis()), VRM(vrm), MFI(*mf.getFrameInfo()), MRI(mf.getRegInfo()), Index: lib/CodeGen/LiveIntervalAnalysis.cpp =================================================================== --- lib/CodeGen/LiveIntervalAnalysis.cpp +++ lib/CodeGen/LiveIntervalAnalysis.cpp @@ -48,7 +48,7 @@ char &llvm::LiveIntervalsID = LiveIntervals::ID; INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals", "Live Interval Analysis", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(LiveVariables) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_DEPENDENCY(SlotIndexes) @@ -76,8 +76,8 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); - AU.addRequired(); - AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); // LiveVariables isn't really required by this analysis, it is only required // here to make sure it is live during TwoAddressInstructionPass and // PHIElimination. This is temporary. @@ -124,7 +124,7 @@ MRI = &MF->getRegInfo(); TRI = MF->getSubtarget().getRegisterInfo(); TII = MF->getSubtarget().getInstrInfo(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); Indexes = &getAnalysis(); DomTree = &getAnalysis(); Index: lib/CodeGen/MachineCSE.cpp =================================================================== --- lib/CodeGen/MachineCSE.cpp +++ lib/CodeGen/MachineCSE.cpp @@ -57,7 +57,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); MachineFunctionPass::getAnalysisUsage(AU); - AU.addRequired(); + AU.addRequired(); AU.addPreservedID(MachineLoopInfoID); AU.addRequired(); AU.addPreserved(); @@ -111,7 +111,7 @@ INITIALIZE_PASS_BEGIN(MachineCSE, "machine-cse", "Machine Common Subexpression Elimination", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(MachineCSE, "machine-cse", "Machine Common Subexpression Elimination", false, false) @@ -714,7 +714,7 @@ TII = MF.getSubtarget().getInstrInfo(); TRI = MF.getSubtarget().getRegisterInfo(); MRI = &MF.getRegInfo(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); DT = &getAnalysis(); LookAheadLimit = TII->getMachineCSELookAheadLimit(); return PerformCSE(DT->getRootNode()); Index: lib/CodeGen/MachineFunctionPass.cpp =================================================================== --- lib/CodeGen/MachineFunctionPass.cpp +++ lib/CodeGen/MachineFunctionPass.cpp @@ -13,11 +13,14 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/DominanceFrontier.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/IVUsers.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/CodeGen/MachineFunctionAnalysis.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/StackProtector.h" @@ -49,13 +52,16 @@ // passes explicitly. This does not include setPreservesCFG, // because CodeGen overloads that to mean preserving the MachineBasicBlock // CFG in addition to the LLVM IR CFG. - AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); FunctionPass::getAnalysisUsage(AU); Index: lib/CodeGen/MachineLICM.cpp =================================================================== --- lib/CodeGen/MachineLICM.cpp +++ lib/CodeGen/MachineLICM.cpp @@ -138,7 +138,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addPreserved(); AU.addPreserved(); MachineFunctionPass::getAnalysisUsage(AU); @@ -315,7 +315,7 @@ "Machine Loop Invariant Code Motion", false, false) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(MachineLICM, "machinelicm", "Machine Loop Invariant Code Motion", false, false) @@ -367,7 +367,7 @@ // Get our Loop information... MLI = &getAnalysis(); DT = &getAnalysis(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); SmallVector Worklist(MLI->begin(), MLI->end()); while (!Worklist.empty()) { Index: lib/CodeGen/MachineScheduler.cpp =================================================================== --- lib/CodeGen/MachineScheduler.cpp +++ lib/CodeGen/MachineScheduler.cpp @@ -146,7 +146,7 @@ INITIALIZE_PASS_BEGIN(MachineScheduler, "machine-scheduler", "Machine Instruction Scheduler", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(SlotIndexes) INITIALIZE_PASS_DEPENDENCY(LiveIntervals) INITIALIZE_PASS_END(MachineScheduler, "machine-scheduler", @@ -161,7 +161,7 @@ AU.setPreservesCFG(); AU.addRequiredID(MachineDominatorsID); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addPreserved(); @@ -322,7 +322,7 @@ MLI = &getAnalysis(); MDT = &getAnalysis(); PassConfig = &getAnalysis(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); LIS = &getAnalysis(); Index: lib/CodeGen/MachineSink.cpp =================================================================== --- lib/CodeGen/MachineSink.cpp +++ lib/CodeGen/MachineSink.cpp @@ -87,7 +87,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); MachineFunctionPass::getAnalysisUsage(AU); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -150,7 +150,7 @@ "Machine code sinking", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(MachineSinking, "machine-sink", "Machine code sinking", false, false) @@ -268,7 +268,7 @@ PDT = &getAnalysis(); LI = &getAnalysis(); MBFI = UseBlockFreqInfo ? &getAnalysis() : nullptr; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); bool EverMadeChange = false; Index: lib/CodeGen/Passes.cpp =================================================================== --- lib/CodeGen/Passes.cpp +++ lib/CodeGen/Passes.cpp @@ -226,6 +226,10 @@ // including this pass itself. initializeCodeGen(*PassRegistry::getPassRegistry()); + // Also register alias analysis passes required by codegen passes. + initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry()); + initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry()); + // Substitute Pseudo Pass IDs for real ones. substitutePass(&EarlyTailDuplicateID, &TailDuplicateID); substitutePass(&PostRAMachineLICMID, &MachineLICMID); @@ -381,10 +385,10 @@ // BasicAliasAnalysis wins if they disagree. This is intended to help // support "obvious" type-punning idioms. if (UseCFLAA) - addPass(createCFLAliasAnalysisPass()); - addPass(createTypeBasedAliasAnalysisPass()); - addPass(createScopedNoAliasAAPass()); - addPass(createBasicAliasAnalysisPass()); + addPass(createCFLAAWrapperPass()); + addPass(createTypeBasedAAWrapperPass()); + addPass(createScopedNoAliasAAWrapperPass()); + addPass(createBasicAAWrapperPass()); // Before running any passes, run the verifier to determine if the input // coming from the front-end and/or optimizer is valid. Index: lib/CodeGen/PostRASchedulerList.cpp =================================================================== --- lib/CodeGen/PostRASchedulerList.cpp +++ lib/CodeGen/PostRASchedulerList.cpp @@ -87,7 +87,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addPreserved(); @@ -267,7 +267,7 @@ TII = Fn.getSubtarget().getInstrInfo(); MachineLoopInfo &MLI = getAnalysis(); - AliasAnalysis *AA = &getAnalysis(); + AliasAnalysis *AA = &getAnalysis().getAAResults(); TargetPassConfig *PassConfig = &getAnalysis(); RegClassInfo.runOnMachineFunction(Fn); Index: lib/CodeGen/ProcessImplicitDefs.cpp =================================================================== --- lib/CodeGen/ProcessImplicitDefs.cpp +++ lib/CodeGen/ProcessImplicitDefs.cpp @@ -58,7 +58,7 @@ void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); - AU.addPreserved(); + AU.addPreserved(); MachineFunctionPass::getAnalysisUsage(AU); } Index: lib/CodeGen/RegAllocBasic.cpp =================================================================== --- lib/CodeGen/RegAllocBasic.cpp +++ lib/CodeGen/RegAllocBasic.cpp @@ -133,8 +133,8 @@ void RABasic::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); - AU.addRequired(); - AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); Index: lib/CodeGen/RegAllocGreedy.cpp =================================================================== --- lib/CodeGen/RegAllocGreedy.cpp +++ lib/CodeGen/RegAllocGreedy.cpp @@ -461,8 +461,8 @@ AU.setPreservesCFG(); AU.addRequired(); AU.addPreserved(); - AU.addRequired(); - AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); Index: lib/CodeGen/RegAllocPBQP.cpp =================================================================== --- lib/CodeGen/RegAllocPBQP.cpp +++ lib/CodeGen/RegAllocPBQP.cpp @@ -497,8 +497,8 @@ void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const { au.setPreservesCFG(); - au.addRequired(); - au.addPreserved(); + au.addRequired(); + au.addPreserved(); au.addRequired(); au.addPreserved(); au.addRequired(); Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -275,7 +275,7 @@ INITIALIZE_PASS_DEPENDENCY(LiveIntervals) INITIALIZE_PASS_DEPENDENCY(SlotIndexes) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing", "Simple Register Coalescing", false, false) @@ -453,7 +453,7 @@ void RegisterCoalescer::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); @@ -2943,7 +2943,7 @@ TRI = STI.getRegisterInfo(); TII = STI.getInstrInfo(); LIS = &getAnalysis(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); Loops = &getAnalysis(); if (EnableGlobalCopies == cl::BOU_UNSET) JoinGlobalCopies = STI.enableJoinGlobalCopies(); Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -17,6 +17,7 @@ #include "StatepointLowering.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAGNodes.h" @@ -30,7 +31,6 @@ namespace llvm { class AddrSpaceCastInst; -class AliasAnalysis; class AllocaInst; class BasicBlock; class BitCastInst; Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -356,9 +356,9 @@ OptLevel(OL), DAGSize(0) { initializeGCModuleInfoPass(*PassRegistry::getPassRegistry()); - initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry()); initializeBranchProbabilityInfoWrapperPassPass( *PassRegistry::getPassRegistry()); + initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry()); initializeTargetLibraryInfoWrapperPassPass( *PassRegistry::getPassRegistry()); } @@ -370,8 +370,7 @@ } void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.addPreserved(); + AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); @@ -444,7 +443,7 @@ TII = MF->getSubtarget().getInstrInfo(); TLI = MF->getSubtarget().getTargetLowering(); RegInfo = &MF->getRegInfo(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); LibInfo = &getAnalysis().getTLI(); GFI = Fn.hasGC() ? &getAnalysis().getFunctionInfo(Fn) : nullptr; Index: lib/CodeGen/TwoAddressInstructionPass.cpp =================================================================== --- lib/CodeGen/TwoAddressInstructionPass.cpp +++ lib/CodeGen/TwoAddressInstructionPass.cpp @@ -151,7 +151,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); - AU.addRequired(); + AU.addRequired(); AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); @@ -168,7 +168,7 @@ char TwoAddressInstructionPass::ID = 0; INITIALIZE_PASS_BEGIN(TwoAddressInstructionPass, "twoaddressinstruction", "Two-Address instruction pass", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(TwoAddressInstructionPass, "twoaddressinstruction", "Two-Address instruction pass", false, false) @@ -1599,7 +1599,7 @@ InstrItins = MF->getSubtarget().getInstrItineraryData(); LV = getAnalysisIfAvailable(); LIS = getAnalysisIfAvailable(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); OptLevel = TM.getOptLevel(); bool MadeChange = false; Index: lib/LTO/LTOCodeGenerator.cpp =================================================================== --- lib/LTO/LTOCodeGenerator.cpp +++ lib/LTO/LTOCodeGenerator.cpp @@ -101,7 +101,7 @@ initializeSROA_DTPass(R); initializeSROA_SSAUpPass(R); initializeFunctionAttrsPass(R); - initializeGlobalsModRefPass(R); + initializeGlobalsAAWrapperPassPass(R); initializeLICMPass(R); initializeMergedLoadStoreMotionPass(R); initializeGVNPass(R); Index: lib/Target/Hexagon/HexagonVLIWPacketizer.cpp =================================================================== --- lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -177,7 +177,7 @@ INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer", false, false) Index: lib/Target/PowerPC/PPCLoopDataPrefetch.cpp =================================================================== --- lib/Target/PowerPC/PPCLoopDataPrefetch.cpp +++ lib/Target/PowerPC/PPCLoopDataPrefetch.cpp @@ -21,6 +21,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/TargetTransformInfo.h" Index: lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- lib/Transforms/IPO/ArgumentPromotion.cpp +++ lib/Transforms/IPO/ArgumentPromotion.cpp @@ -34,8 +34,11 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CallGraphSCCPass.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/CFG.h" #include "llvm/IR/CallSite.h" @@ -63,7 +66,8 @@ /// struct ArgPromotion : public CallGraphSCCPass { void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); + AU.addRequired(); CallGraphSCCPass::getAnalysisUsage(AU); } @@ -81,7 +85,8 @@ bool isDenselyPacked(Type *type, const DataLayout &DL); bool canPaddingBeAccessed(Argument *Arg); CallGraphNode *PromoteArguments(CallGraphNode *CGN); - bool isSafeToPromoteArgument(Argument *Arg, bool isByVal) const; + bool isSafeToPromoteArgument(Argument *Arg, bool isByVal, + AAResults &AAR) const; CallGraphNode *DoPromotion(Function *F, SmallPtrSetImpl &ArgsToPromote, SmallPtrSetImpl &ByValArgsToTransform); @@ -97,8 +102,9 @@ char ArgPromotion::ID = 0; INITIALIZE_PASS_BEGIN(ArgPromotion, "argpromotion", "Promote 'by reference' arguments to scalars", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(ArgPromotion, "argpromotion", "Promote 'by reference' arguments to scalars", false, false) @@ -237,6 +243,14 @@ const DataLayout &DL = F->getParent()->getDataLayout(); + // We need to manually construct BasicAA directly in order to disable its use + // of other function analyses. + BasicAAResult BAR(createLegacyPMBasicAAResult(*this, *F)); + + // Construct our own AA results for this function. We do this manually to + // work around the limitations of the legacy pass manager. + AAResults AAR(createLegacyPMAAResults(*this, *F, BAR)); + // Check to see which arguments are promotable. If an argument is promotable, // add it to ArgsToPromote. SmallPtrSet ArgsToPromote; @@ -315,7 +329,7 @@ } // Otherwise, see if we can promote the pointer to its value. - if (isSafeToPromoteArgument(PtrArg, PtrArg->hasByValOrInAllocaAttr())) + if (isSafeToPromoteArgument(PtrArg, PtrArg->hasByValOrInAllocaAttr(), AAR)) ArgsToPromote.insert(PtrArg); } @@ -416,7 +430,8 @@ /// elements of the aggregate in order to avoid exploding the number of /// arguments passed in. bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, - bool isByValOrInAlloca) const { + bool isByValOrInAlloca, + AAResults &AAR) const { typedef std::set GEPIndicesSet; // Quick exit for unused arguments @@ -505,7 +520,7 @@ // TODO: This runs the above loop over and over again for dead GEPs // Couldn't we just do increment the UI iterator earlier and erase the // use? - return isSafeToPromoteArgument(Arg, isByValOrInAlloca); + return isSafeToPromoteArgument(Arg, isByValOrInAlloca, AAR); } // Ensure that all of the indices are constants. @@ -562,8 +577,6 @@ // blocks we know to be transparent to the load. SmallPtrSet TranspBlocks; - AliasAnalysis &AA = getAnalysis(); - for (unsigned i = 0, e = Loads.size(); i != e; ++i) { // Check to see if the load is invalidated from the start of the block to // the load itself. @@ -571,7 +584,7 @@ BasicBlock *BB = Load->getParent(); MemoryLocation Loc = MemoryLocation::get(Load); - if (AA.canInstructionRangeModRef(BB->front(), *Load, Loc, MRI_Mod)) + if (AAR.canInstructionRangeModRef(BB->front(), *Load, Loc, MRI_Mod)) return false; // Pointer is invalidated! // Now check every path from the entry block to the load for transparency. @@ -579,7 +592,7 @@ // loading block. for (BasicBlock *P : predecessors(BB)) { for (BasicBlock *TranspBB : inverse_depth_first_ext(P, TranspBlocks)) - if (AA.canBasicBlockModify(*TranspBB, Loc)) + if (AAR.canBasicBlockModify(*TranspBB, Loc)) return false; } } Index: lib/Transforms/IPO/FunctionAttrs.cpp =================================================================== --- lib/Transforms/IPO/FunctionAttrs.cpp +++ lib/Transforms/IPO/FunctionAttrs.cpp @@ -24,9 +24,12 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/CaptureTracking.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstIterator.h" @@ -51,7 +54,7 @@ namespace { struct FunctionAttrs : public CallGraphSCCPass { static char ID; // Pass identification, replacement for typeid - FunctionAttrs() : CallGraphSCCPass(ID), AA(nullptr) { + FunctionAttrs() : CallGraphSCCPass(ID) { initializeFunctionAttrsPass(*PassRegistry::getPassRegistry()); } @@ -134,13 +137,12 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); CallGraphSCCPass::getAnalysisUsage(AU); } private: - AliasAnalysis *AA; TargetLibraryInfo *TLI; }; } @@ -148,7 +150,7 @@ char FunctionAttrs::ID = 0; INITIALIZE_PASS_BEGIN(FunctionAttrs, "functionattrs", "Deduce function attributes", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(FunctionAttrs, "functionattrs", @@ -177,7 +179,15 @@ // memory and give up. return false; - FunctionModRefBehavior MRB = AA->getModRefBehavior(F); + // We need to manually construct BasicAA directly in order to disable its + // use of other function analyses. + BasicAAResult BAR(createLegacyPMBasicAAResult(*this, *F)); + + // Construct our own AA results for this function. We do this manually to + // work around the limitations of the legacy pass manager. + AAResults AAR(createLegacyPMAAResults(*this, *F, BAR)); + + FunctionModRefBehavior MRB = AAR.getModRefBehavior(F); if (MRB == FMRB_DoesNotAccessMemory) // Already perfect! continue; @@ -204,7 +214,7 @@ // Ignore calls to functions in the same SCC. if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction())) continue; - FunctionModRefBehavior MRB = AA->getModRefBehavior(CS); + FunctionModRefBehavior MRB = AAR.getModRefBehavior(CS); // If the call doesn't access arbitrary memory, we may be able to // figure out something. if (AliasAnalysis::onlyAccessesArgPointees(MRB)) { @@ -220,7 +230,7 @@ I->getAAMetadata(AAInfo); MemoryLocation Loc(Arg, MemoryLocation::UnknownSize, AAInfo); - if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) { + if (!AAR.pointsToConstantMemory(Loc, /*OrLocal=*/true)) { if (MRB & MRI_Mod) // Writes non-local memory. Give up. return false; @@ -243,20 +253,20 @@ // Ignore non-volatile loads from local memory. (Atomic is okay here.) if (!LI->isVolatile()) { MemoryLocation Loc = MemoryLocation::get(LI); - if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) + if (AAR.pointsToConstantMemory(Loc, /*OrLocal=*/true)) continue; } } else if (StoreInst *SI = dyn_cast(I)) { // Ignore non-volatile stores to local memory. (Atomic is okay here.) if (!SI->isVolatile()) { MemoryLocation Loc = MemoryLocation::get(SI); - if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) + if (AAR.pointsToConstantMemory(Loc, /*OrLocal=*/true)) continue; } } else if (VAArgInst *VI = dyn_cast(I)) { // Ignore vaargs on local memory. MemoryLocation Loc = MemoryLocation::get(VI); - if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) + if (AAR.pointsToConstantMemory(Loc, /*OrLocal=*/true)) continue; } @@ -1848,7 +1858,6 @@ } bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) { - AA = &getAnalysis(); TLI = &getAnalysis().getTLI(); bool Changed = annotateLibraryCalls(SCC); Index: lib/Transforms/IPO/InlineAlways.cpp =================================================================== --- lib/Transforms/IPO/InlineAlways.cpp +++ lib/Transforms/IPO/InlineAlways.cpp @@ -14,10 +14,10 @@ #include "llvm/Transforms/IPO.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/DataLayout.h" @@ -67,10 +67,10 @@ char AlwaysInliner::ID = 0; INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", "Inliner for always_inline functions", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(AlwaysInliner, "always-inline", "Inliner for always_inline functions", false, false) Index: lib/Transforms/IPO/InlineSimple.cpp =================================================================== --- lib/Transforms/IPO/InlineSimple.cpp +++ lib/Transforms/IPO/InlineSimple.cpp @@ -12,10 +12,10 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" -#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/DataLayout.h" @@ -75,10 +75,10 @@ char SimpleInliner::ID = 0; INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", "Function Integration/Inlining", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(SimpleInliner, "inline", "Function Integration/Inlining", false, false) Index: lib/Transforms/IPO/Inliner.cpp =================================================================== --- lib/Transforms/IPO/Inliner.cpp +++ lib/Transforms/IPO/Inliner.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -76,8 +77,8 @@ /// If the derived class implements this method, it should /// always explicitly call the implementation here. void Inliner::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); AU.addRequired(); + AU.addRequired(); CallGraphSCCPass::getAnalysisUsage(AU); } @@ -126,15 +127,23 @@ /// available from other functions inlined into the caller. If we are able to /// inline this call site we attempt to reuse already available allocas or add /// any new allocas to the set if not possible. -static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI, +static bool InlineCallIfPossible(Pass &P, CallSite CS, InlineFunctionInfo &IFI, InlinedArrayAllocasTy &InlinedArrayAllocas, int InlineHistory, bool InsertLifetime) { Function *Callee = CS.getCalledFunction(); Function *Caller = CS.getCaller(); + // We need to manually construct BasicAA directly in order to disable + // its use of other function analyses. + BasicAAResult BAR(createLegacyPMBasicAAResult(P, *Callee)); + + // Construct our own AA results for this function. We do this manually to + // work around the limitations of the legacy pass manager. + AAResults AAR(createLegacyPMAAResults(P, *Callee, BAR)); + // Try to inline the function. Get the list of static allocas that were // inlined. - if (!InlineFunction(CS, IFI, InsertLifetime)) + if (!InlineFunction(CS, IFI, &AAR, InsertLifetime)) return false; AdjustCallerSSPLevel(Caller, Callee); @@ -432,9 +441,7 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { CallGraph &CG = getAnalysis().getCallGraph(); AssumptionCacheTracker *ACT = &getAnalysis(); - auto *TLIP = getAnalysisIfAvailable(); - const TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI() : nullptr; - AliasAnalysis *AA = &getAnalysis(); + auto &TLI = getAnalysis().getTLI(); SmallPtrSet SCCFunctions; DEBUG(dbgs() << "Inliner visiting SCC:"); @@ -494,7 +501,7 @@ InlinedArrayAllocasTy InlinedArrayAllocas; - InlineFunctionInfo InlineInfo(&CG, AA, ACT); + InlineFunctionInfo InlineInfo(&CG, ACT); // Now that we have all of the call sites, loop over them and inline them if // it looks profitable to do so. @@ -515,7 +522,7 @@ // just delete the call instead of trying to inline it, regardless of // size. This happens because IPSCCP propagates the result out of the // call and then we're left with the dead call. - if (isInstructionTriviallyDead(CS.getInstruction(), TLI)) { + if (isInstructionTriviallyDead(CS.getInstruction(), &TLI)) { DEBUG(dbgs() << " -> Deleting dead call: " << *CS.getInstruction() << "\n"); // Update the call graph by deleting the edge from Callee to Caller. @@ -552,7 +559,7 @@ } // Attempt to inline the function. - if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas, + if (!InlineCallIfPossible(*this, CS, InlineInfo, InlinedArrayAllocas, InlineHistoryID, InsertLifetime)) { emitOptimizationRemarkMissed(CallerCtx, DEBUG_TYPE, *Caller, DLoc, Twine(Callee->getName() + Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -153,10 +153,9 @@ // BasicAliasAnalysis wins if they disagree. This is intended to help // support "obvious" type-punning idioms. if (UseCFLAA) - PM.add(createCFLAliasAnalysisPass()); - PM.add(createTypeBasedAliasAnalysisPass()); - PM.add(createScopedNoAliasAAPass()); - PM.add(createBasicAliasAnalysisPass()); + PM.add(createCFLAAWrapperPass()); + PM.add(createTypeBasedAAWrapperPass()); + PM.add(createScopedNoAliasAAWrapperPass()); } void PassManagerBuilder::populateFunctionPassManager( @@ -227,7 +226,7 @@ // We add a module alias analysis pass here. In part due to bugs in the // analysis infrastructure this "works" in that the analysis stays alive // for the entire SCC pass run below. - MPM.add(createGlobalsModRefPass()); + MPM.add(createGlobalsAAWrapperPass()); // Start of CallGraph SCC passes. if (!DisableUnitAtATime) @@ -347,7 +346,7 @@ // this to work. Fortunately, it is trivial to preserve AliasAnalysis // (doing nothing preserves it as it is required to be conservatively // correct in the face of IR changes). - MPM.add(createGlobalsModRefPass()); + MPM.add(createGlobalsAAWrapperPass()); if (RunFloat2Int) MPM.add(createFloat2IntPass()); @@ -517,7 +516,7 @@ // Run a few AA driven optimizations here and now, to cleanup the code. PM.add(createFunctionAttrsPass()); // Add nocapture. - PM.add(createGlobalsModRefPass()); // IP alias analysis. + PM.add(createGlobalsAAWrapperPass()); // IP alias analysis. PM.add(createLICMPass()); // Hoist loop invariants. if (EnableMLSM) Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -42,6 +42,7 @@ #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CFG.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LibCallSemantics.h" #include "llvm/Analysis/LoopInfo.h" @@ -3071,11 +3072,12 @@ void InstructionCombiningPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addPreserved(); + AU.addPreserved(); } bool InstructionCombiningPass::runOnFunction(Function &F) { @@ -3083,7 +3085,7 @@ return false; // Required analyses. - auto AA = &getAnalysis(); + auto AA = &getAnalysis().getAAResults(); auto &AC = getAnalysis().getAssumptionCache(F); auto &TLI = getAnalysis().getTLI(); auto &DT = getAnalysis().getDomTree(); @@ -3101,7 +3103,8 @@ INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_END(InstructionCombiningPass, "instcombine", "Combine redundant instructions", false, false) Index: lib/Transforms/Instrumentation/SafeStack.cpp =================================================================== --- lib/Transforms/Instrumentation/SafeStack.cpp +++ lib/Transforms/Instrumentation/SafeStack.cpp @@ -221,7 +221,7 @@ } virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); + AU.addRequired(); } virtual bool doInitialization(Module &M) { @@ -513,7 +513,7 @@ } bool SafeStack::runOnFunction(Function &F) { - auto AA = &getAnalysis(); + auto AA = &getAnalysis().getAAResults(); DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n"); Index: lib/Transforms/ObjCARC/ObjCARC.cpp =================================================================== --- lib/Transforms/ObjCARC/ObjCARC.cpp +++ lib/Transforms/ObjCARC/ObjCARC.cpp @@ -29,7 +29,7 @@ /// initializeObjCARCOptsPasses - Initialize all passes linked into the /// ObjCARCOpts library. void llvm::initializeObjCARCOpts(PassRegistry &Registry) { - initializeObjCARCAliasAnalysisPass(Registry); + initializeObjCARCAAWrapperPassPass(Registry); initializeObjCARCAPElimPass(Registry); initializeObjCARCExpandPass(Registry); initializeObjCARCContractPass(Registry); Index: lib/Transforms/ObjCARC/ObjCARCContract.cpp =================================================================== --- lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -511,10 +511,10 @@ return false; Changed = false; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); DT = &getAnalysis().getDomTree(); - PA.setAA(&getAnalysis()); + PA.setAA(&getAnalysis().getAAResults()); DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n"); @@ -629,13 +629,13 @@ char ObjCARCContract::ID = 0; INITIALIZE_PASS_BEGIN(ObjCARCContract, "objc-arc-contract", "ObjC ARC contraction", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_END(ObjCARCContract, "objc-arc-contract", "ObjC ARC contraction", false, false) void ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.setPreservesCFG(); } Index: lib/Transforms/ObjCARC/ObjCARCOpts.cpp =================================================================== --- lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -556,7 +556,7 @@ char ObjCARCOpt::ID = 0; INITIALIZE_PASS_BEGIN(ObjCARCOpt, "objc-arc", "ObjC ARC optimization", false, false) -INITIALIZE_PASS_DEPENDENCY(ObjCARCAliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(ObjCARCAAWrapperPass) INITIALIZE_PASS_END(ObjCARCOpt, "objc-arc", "ObjC ARC optimization", false, false) @@ -565,8 +565,8 @@ } void ObjCARCOpt::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.addRequired(); + AU.addRequired(); + AU.addRequired(); // ARC optimization doesn't currently split critical edges. AU.setPreservesCFG(); } @@ -2192,7 +2192,7 @@ DEBUG(dbgs() << "<<< ObjCARCOpt: Visiting Function: " << F.getName() << " >>>" "\n"); - PA.setAA(&getAnalysis()); + PA.setAA(&getAnalysis().getAAResults()); #ifndef NDEBUG if (AreStatisticsEnabled()) { Index: lib/Transforms/ObjCARC/ProvenanceAnalysis.h =================================================================== --- lib/Transforms/ObjCARC/ProvenanceAnalysis.h +++ lib/Transforms/ObjCARC/ProvenanceAnalysis.h @@ -26,10 +26,10 @@ #define LLVM_LIB_TRANSFORMS_OBJCARC_PROVENANCEANALYSIS_H #include "llvm/ADT/DenseMap.h" +#include "llvm/Analysis/AliasAnalysis.h" namespace llvm { class Value; - class AliasAnalysis; class DataLayout; class PHINode; class SelectInst; Index: lib/Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp =================================================================== --- lib/Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp +++ lib/Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp @@ -35,7 +35,7 @@ PAEval::PAEval() : FunctionPass(ID) {} void PAEval::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); + AU.addRequired(); } static StringRef getName(Value *V) { @@ -65,7 +65,7 @@ } ProvenanceAnalysis PA; - PA.setAA(&getAnalysis()); + PA.setAA(&getAnalysis().getAAResults()); const DataLayout &DL = F.getParent()->getDataLayout(); for (Value *V1 : Values) { @@ -89,6 +89,6 @@ INITIALIZE_PASS_BEGIN(PAEval, "pa-eval", "Evaluate ProvenanceAnalysis on all pairs", false, true) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(PAEval, "pa-eval", "Evaluate ProvenanceAnalysis on all pairs", false, true) Index: lib/Transforms/Scalar/DeadStoreElimination.cpp =================================================================== --- lib/Transforms/Scalar/DeadStoreElimination.cpp +++ lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CaptureTracking.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -60,7 +61,7 @@ if (skipOptnoneFunction(F)) return false; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); MD = &getAnalysis(); DT = &getAnalysis().getDomTree(); TLI = &getAnalysis().getTLI(); @@ -87,11 +88,11 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); - AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); } }; @@ -99,8 +100,9 @@ char DSE::ID = 0; INITIALIZE_PASS_BEGIN(DSE, "dse", "Dead Store Elimination", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(DSE, "dse", "Dead Store Elimination", false, false) Index: lib/Transforms/Scalar/FlattenCFGPass.cpp =================================================================== --- lib/Transforms/Scalar/FlattenCFGPass.cpp +++ lib/Transforms/Scalar/FlattenCFGPass.cpp @@ -30,7 +30,7 @@ bool runOnFunction(Function &F) override; void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); } private: @@ -41,7 +41,7 @@ char FlattenCFGPass::ID = 0; INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, false) @@ -69,7 +69,7 @@ } bool FlattenCFGPass::runOnFunction(Function &F) { - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); bool EverChanged = false; // iterativelyFlattenCFG can make some blocks dead. while (iterativelyFlattenCFG(F, AA)) { Index: lib/Transforms/Scalar/Float2Int.cpp =================================================================== --- lib/Transforms/Scalar/Float2Int.cpp +++ lib/Transforms/Scalar/Float2Int.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/IRBuilder.h" @@ -61,7 +62,7 @@ bool runOnFunction(Function &F) override; void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); - AU.addPreserved(); + AU.addPreserved(); } void findRoots(Function &F, SmallPtrSet &Roots); @@ -84,7 +85,9 @@ } char Float2Int::ID = 0; -INITIALIZE_PASS(Float2Int, "float2int", "Float to int", false, false) +INITIALIZE_PASS_BEGIN(Float2Int, "float2int", "Float to int", false, false) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) +INITIALIZE_PASS_END(Float2Int, "float2int", "Float to int", false, false) // Given a FCmp predicate, return a matching ICmp predicate if one // exists, otherwise return BAD_ICMP_PREDICATE. Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp +++ lib/Transforms/Scalar/GVN.cpp @@ -28,6 +28,7 @@ #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CFG.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/MemoryBuiltins.h" @@ -689,10 +690,10 @@ AU.addRequired(); if (!NoLoads) AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addPreserved(); - AU.addPreserved(); + AU.addPreserved(); } @@ -738,7 +739,8 @@ INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_END(GVN, "gvn", "Global Value Numbering", false, false) #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) @@ -2314,7 +2316,7 @@ DT = &getAnalysis().getDomTree(); AC = &getAnalysis().getAssumptionCache(F); TLI = &getAnalysis().getTLI(); - VN.setAliasAnalysis(&getAnalysis()); + VN.setAliasAnalysis(&getAnalysis().getAAResults()); VN.setMemDep(MD); VN.setDomTree(DT); Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -31,6 +31,7 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpander.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/BasicBlock.h" Index: lib/Transforms/Scalar/LICM.cpp =================================================================== --- lib/Transforms/Scalar/LICM.cpp +++ lib/Transforms/Scalar/LICM.cpp @@ -34,10 +34,13 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasSetTracker.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/CFG.h" @@ -118,9 +121,12 @@ AU.addPreservedID(LoopSimplifyID); AU.addRequiredID(LCSSAID); AU.addPreservedID(LCSSAID); - AU.addRequired(); - AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); AU.addRequired(); } @@ -166,7 +172,10 @@ INITIALIZE_PASS_DEPENDENCY(LCSSA) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) INITIALIZE_PASS_END(LICM, "licm", "Loop Invariant Code Motion", false, false) Pass *llvm::createLICMPass() { return new LICM(); } @@ -183,7 +192,7 @@ // Get our Loop and Alias Analysis information... LI = &getAnalysis().getLoopInfo(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); DT = &getAnalysis().getDomTree(); TLI = &getAnalysis().getTLI(); Index: lib/Transforms/Scalar/LoadCombine.cpp =================================================================== --- lib/Transforms/Scalar/LoadCombine.cpp +++ lib/Transforms/Scalar/LoadCombine.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasSetTracker.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/TargetFolder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" @@ -223,7 +224,7 @@ if (skipOptnoneFunction(BB)) return false; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); IRBuilder TheBuilder( BB.getContext(), TargetFolder(BB.getModule()->getDataLayout())); @@ -262,8 +263,8 @@ void LoadCombine::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); - AU.addRequired(); - AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); } char LoadCombine::ID = 0; @@ -274,7 +275,8 @@ INITIALIZE_PASS_BEGIN(LoadCombine, "load-combine", "Combine Adjacent Loads", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_END(LoadCombine, "load-combine", "Combine Adjacent Loads", false, false) Index: lib/Transforms/Scalar/LoopIdiomRecognize.cpp =================================================================== --- lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -44,8 +44,11 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpander.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -94,14 +97,17 @@ AU.addPreservedID(LoopSimplifyID); AU.addRequiredID(LCSSAID); AU.addPreservedID(LCSSAID); - AU.addRequired(); - AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); - AU.addPreserved(); + AU.addPreserved(); AU.addRequired(); + AU.addPreserved(); AU.addRequired(); AU.addRequired(); + AU.addPreserved(); + AU.addPreserved(); } private: @@ -148,7 +154,10 @@ INITIALIZE_PASS_DEPENDENCY(LCSSA) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_END(LoopIdiomRecognize, "loop-idiom", "Recognize loop idioms", false, false) @@ -189,7 +198,7 @@ if (Name == "memset" || Name == "memcpy") return false; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); DT = &getAnalysis().getDomTree(); LI = &getAnalysis().getLoopInfo(); SE = &getAnalysis().getSE(); Index: lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- lib/Transforms/Scalar/LoopInterchange.cpp +++ lib/Transforms/Scalar/LoopInterchange.cpp @@ -438,7 +438,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -1286,7 +1286,7 @@ char LoopInterchange::ID = 0; INITIALIZE_PASS_BEGIN(LoopInterchange, "loop-interchange", "Interchanges loops for cache reuse", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(DependenceAnalysis) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) Index: lib/Transforms/Scalar/LoopRerollPass.cpp =================================================================== --- lib/Transforms/Scalar/LoopRerollPass.cpp +++ lib/Transforms/Scalar/LoopRerollPass.cpp @@ -147,7 +147,7 @@ bool runOnLoop(Loop *L, LPPassManager &LPM) override; void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); @@ -449,7 +449,7 @@ char LoopReroll::ID = 0; INITIALIZE_PASS_BEGIN(LoopReroll, "loop-reroll", "Reroll loops", false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) @@ -1466,7 +1466,7 @@ if (skipOptnoneFunction(L)) return false; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); LI = &getAnalysis().getLoopInfo(); SE = &getAnalysis().getSE(); TLI = &getAnalysis().getTLI(); Index: lib/Transforms/Scalar/LoopRotation.cpp =================================================================== --- lib/Transforms/Scalar/LoopRotation.cpp +++ lib/Transforms/Scalar/LoopRotation.cpp @@ -14,11 +14,14 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/CFG.h" @@ -57,7 +60,7 @@ // LCSSA form makes instruction renaming easier. void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addPreserved(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); @@ -67,7 +70,10 @@ AU.addRequiredID(LCSSAID); AU.addPreservedID(LCSSAID); AU.addPreserved(); + AU.addPreserved(); AU.addRequired(); + AU.addPreserved(); + AU.addPreserved(); } bool runOnLoop(Loop *L, LPPassManager &LPM) override; @@ -90,6 +96,9 @@ INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopSimplify) INITIALIZE_PASS_DEPENDENCY(LCSSA) +INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_END(LoopRotate, "loop-rotate", "Rotate Loops", false, false) Pass *llvm::createLoopRotatePass(int MaxHeaderSize) { Index: lib/Transforms/Scalar/MemCpyOptimizer.cpp =================================================================== --- lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" @@ -324,9 +325,9 @@ AU.addRequired(); AU.addRequired(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); - AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); } @@ -359,7 +360,8 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_END(MemCpyOpt, "memcpyopt", "MemCpy Optimization", false, false) @@ -502,7 +504,7 @@ if (C) { // Check that nothing touches the dest of the "copy" between // the call and the store. - AliasAnalysis &AA = getAnalysis(); + AliasAnalysis &AA = getAnalysis().getAAResults(); MemoryLocation StoreLoc = MemoryLocation::get(SI); for (BasicBlock::iterator I = --BasicBlock::iterator(SI), E = C; I != E; --I) { @@ -703,7 +705,7 @@ // unexpected manner, for example via a global, which we deduce from // the use analysis, we also need to know that it does not sneakily // access dest. We rely on AA to figure this out for us. - AliasAnalysis &AA = getAnalysis(); + AliasAnalysis &AA = getAnalysis().getAAResults(); ModRefInfo MR = AA.getModRefInfo(C, cpyDest, srcSize); // If necessary, perform additional analysis. if (MR != MRI_NoModRef) @@ -779,7 +781,7 @@ if (!MDepLen || !MLen || MDepLen->getZExtValue() < MLen->getZExtValue()) return false; - AliasAnalysis &AA = getAnalysis(); + AliasAnalysis &AA = getAnalysis().getAAResults(); // Verify that the copied-from memory doesn't change in between the two // transfers. For example, in: @@ -1031,7 +1033,7 @@ /// Transforms memmove calls to memcpy calls when the src/dst are guaranteed /// not to alias. bool MemCpyOpt::processMemMove(MemMoveInst *M) { - AliasAnalysis &AA = getAnalysis(); + AliasAnalysis &AA = getAnalysis().getAAResults(); if (!TLI->has(LibFunc::memmove)) return false; Index: lib/Transforms/Scalar/MergedLoadStoreMotion.cpp =================================================================== --- lib/Transforms/Scalar/MergedLoadStoreMotion.cpp +++ lib/Transforms/Scalar/MergedLoadStoreMotion.cpp @@ -78,6 +78,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CFG.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" @@ -117,9 +118,9 @@ // This transformation requires dominator postdominator info void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); - AU.addRequired(); + AU.addRequired(); + AU.addPreserved(); AU.addPreserved(); - AU.addPreserved(); } // Helper routines @@ -169,7 +170,8 @@ "MergedLoadStoreMotion", false, false) INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_END(MergedLoadStoreMotion, "mldst-motion", "MergedLoadStoreMotion", false, false) @@ -564,7 +566,7 @@ /// bool MergedLoadStoreMotion::runOnFunction(Function &F) { MD = getAnalysisIfAvailable(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); bool Changed = false; DEBUG(dbgs() << "Instruction Merger\n"); Index: lib/Transforms/Scalar/Scalar.cpp =================================================================== --- lib/Transforms/Scalar/Scalar.cpp +++ lib/Transforms/Scalar/Scalar.cpp @@ -227,15 +227,15 @@ } void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createTypeBasedAliasAnalysisPass()); + unwrap(PM)->add(createTypeBasedAAWrapperPass()); } void LLVMAddScopedNoAliasAAPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createScopedNoAliasAAPass()); + unwrap(PM)->add(createScopedNoAliasAAWrapperPass()); } void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createBasicAliasAnalysisPass()); + unwrap(PM)->add(createBasicAAWrapperPass()); } void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM) { Index: lib/Transforms/Scalar/Sink.cpp =================================================================== --- lib/Transforms/Scalar/Sink.cpp +++ lib/Transforms/Scalar/Sink.cpp @@ -48,7 +48,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); FunctionPass::getAnalysisUsage(AU); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addPreserved(); @@ -66,7 +66,7 @@ INITIALIZE_PASS_BEGIN(Sinking, "sink", "Code sinking", false, false) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(Sinking, "sink", "Code sinking", false, false) FunctionPass *llvm::createSinkingPass() { return new Sinking(); } @@ -99,7 +99,7 @@ bool Sinking::runOnFunction(Function &F) { DT = &getAnalysis().getDomTree(); LI = &getAnalysis().getLoopInfo(); - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); bool MadeChange, EverMadeChange = false; Index: lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- lib/Transforms/Utils/InlineFunction.cpp +++ lib/Transforms/Utils/InlineFunction.cpp @@ -54,12 +54,12 @@ cl::desc("Convert align attributes to assumptions during inlining.")); bool llvm::InlineFunction(CallInst *CI, InlineFunctionInfo &IFI, - bool InsertLifetime) { - return InlineFunction(CallSite(CI), IFI, InsertLifetime); + AAResults *CalleeAAR, bool InsertLifetime) { + return InlineFunction(CallSite(CI), IFI, CalleeAAR, InsertLifetime); } bool llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, - bool InsertLifetime) { - return InlineFunction(CallSite(II), IFI, InsertLifetime); + AAResults *CalleeAAR, bool InsertLifetime) { + return InlineFunction(CallSite(II), IFI, CalleeAAR, InsertLifetime); } namespace { @@ -484,7 +484,7 @@ /// parameters with noalias metadata specifying the new scope, and tag all /// non-derived loads, stores and memory intrinsics with the new alias scopes. static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, - const DataLayout &DL, AliasAnalysis *AA) { + const DataLayout &DL, AAResults *CalleeAAR) { if (!EnableNoAliasConversion) return; @@ -569,8 +569,8 @@ continue; IsFuncCall = true; - if (AA) { - FunctionModRefBehavior MRB = AA->getModRefBehavior(ICS); + if (CalleeAAR) { + FunctionModRefBehavior MRB = CalleeAAR->getModRefBehavior(ICS); if (MRB == FMRB_OnlyAccessesArgumentPointees || MRB == FMRB_OnlyReadsArgumentPointees) IsArgMemOnlyCall = true; @@ -1005,7 +1005,7 @@ /// exists in the instruction stream. Similarly this will inline a recursive /// function by one level. bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, - bool InsertLifetime) { + AAResults *CalleeAAR, bool InsertLifetime) { Instruction *TheCall = CS.getInstruction(); assert(TheCall->getParent() && TheCall->getParent()->getParent() && "Instruction not in function!"); @@ -1130,7 +1130,7 @@ CloneAliasScopeMetadata(CS, VMap); // Add noalias metadata if necessary. - AddAliasScopeMetadata(CS, VMap, DL, IFI.AA); + AddAliasScopeMetadata(CS, VMap, DL, CalleeAAR); // FIXME: We could register any cloned assumptions instead of clearing the // whole function's cache. Index: lib/Transforms/Utils/LCSSA.cpp =================================================================== --- lib/Transforms/Utils/LCSSA.cpp +++ lib/Transforms/Utils/LCSSA.cpp @@ -31,8 +31,10 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" @@ -297,8 +299,10 @@ AU.addRequired(); AU.addRequired(); AU.addPreservedID(LoopSimplifyID); - AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); } }; } @@ -307,6 +311,8 @@ INITIALIZE_PASS_BEGIN(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) INITIALIZE_PASS_END(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false) Pass *llvm::createLCSSAPass() { return new LCSSA(); } Index: lib/Transforms/Utils/LoopSimplify.cpp =================================================================== --- lib/Transforms/Utils/LoopSimplify.cpp +++ lib/Transforms/Utils/LoopSimplify.cpp @@ -44,11 +44,14 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/DependenceAnalysis.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -759,8 +762,11 @@ AU.addRequired(); AU.addPreserved(); - AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); AU.addPreservedID(BreakCriticalEdgesID); // No critical edges added. } @@ -776,6 +782,9 @@ INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) INITIALIZE_PASS_END(LoopSimplify, "loop-simplify", "Canonicalize natural loops", false, false) Index: lib/Transforms/Vectorize/BBVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/BBVectorize.cpp +++ lib/Transforms/Vectorize/BBVectorize.cpp @@ -25,7 +25,9 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasSetTracker.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -205,7 +207,7 @@ BBVectorize(Pass *P, Function &F, const VectorizeConfig &C) : BasicBlockPass(ID), Config(C) { - AA = &P->getAnalysis(); + AA = &P->getAnalysis().getAAResults(); DT = &P->getAnalysis().getDomTree(); SE = &P->getAnalysis().getSE(); TLI = &P->getAnalysis().getTLI(); @@ -440,7 +442,7 @@ bool runOnBasicBlock(BasicBlock &BB) override { // OptimizeNone check deferred to vectorizeBB(). - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); DT = &getAnalysis().getDomTree(); SE = &getAnalysis().getSE(); TLI = &getAnalysis().getTLI(); @@ -454,14 +456,15 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { BasicBlockPass::getAnalysisUsage(AU); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); - AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); AU.setPreservesCFG(); } @@ -3196,11 +3199,14 @@ char BBVectorize::ID = 0; static const char bb_vectorize_name[] = "Basic-Block Vectorization"; INITIALIZE_PASS_BEGIN(BBVectorize, BBV_NAME, bb_vectorize_name, false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) INITIALIZE_PASS_END(BBVectorize, BBV_NAME, bb_vectorize_name, false, false) BasicBlockPass *llvm::createBBVectorizePass(const VectorizeConfig &C) { Index: lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/LoopVectorize.cpp +++ lib/Transforms/Vectorize/LoopVectorize.cpp @@ -58,10 +58,12 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/CodeMetrics.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopAccessAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopIterator.h" @@ -1514,7 +1516,7 @@ BFI = &getAnalysis().getBFI(); auto *TLIP = getAnalysisIfAvailable(); TLI = TLIP ? &TLIP->getTLI() : nullptr; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); AC = &getAnalysis().getAssumptionCache(F); LAA = &getAnalysis(); @@ -1815,11 +1817,13 @@ AU.addRequired(); AU.addRequired(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); - AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); } }; @@ -5360,7 +5364,9 @@ static const char lv_name[] = "Loop Vectorization"; INITIALIZE_PASS_BEGIN(LoopVectorize, LV_NAME, lv_name, false, false) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) Index: lib/Transforms/Vectorize/SLPVectorizer.cpp =================================================================== --- lib/Transforms/Vectorize/SLPVectorizer.cpp +++ lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -3083,7 +3083,7 @@ TTI = &getAnalysis().getTTI(F); auto *TLIP = getAnalysisIfAvailable(); TLI = TLIP ? &TLIP->getTLI() : nullptr; - AA = &getAnalysis(); + AA = &getAnalysis().getAAResults(); LI = &getAnalysis().getLoopInfo(); DT = &getAnalysis().getDomTree(); AC = &getAnalysis().getAssumptionCache(F); @@ -3145,7 +3145,7 @@ FunctionPass::getAnalysisUsage(AU); AU.addRequired(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -4053,7 +4053,7 @@ char SLPVectorizer::ID = 0; static const char lv_name[] = "SLP Vectorizer"; INITIALIZE_PASS_BEGIN(SLPVectorizer, SV_NAME, lv_name, false, false) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) Index: test/Analysis/BasicAA/full-store-partial-alias.ll =================================================================== --- test/Analysis/BasicAA/full-store-partial-alias.ll +++ test/Analysis/BasicAA/full-store-partial-alias.ll @@ -1,5 +1,5 @@ -; RUN: opt -S -tbaa -basicaa -gvn < %s | FileCheck -check-prefix=BASICAA %s -; RUN: opt -S -tbaa -gvn < %s | FileCheck %s +; RUN: opt -S -tbaa -gvn < %s | FileCheck -check-prefix=BASICAA %s +; RUN: opt -S -tbaa -disable-basicaa -gvn < %s | FileCheck %s ; rdar://8875631, rdar://8875069 ; BasicAA should notice that the store stores to the entire %u object, Index: test/Analysis/CFLAliasAnalysis/arguments-globals.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/arguments-globals.ll +++ test/Analysis/CFLAliasAnalysis/arguments-globals.ll @@ -3,7 +3,7 @@ ; (Everything should alias everything, because args can alias globals, so the ; aliasing sets should of args+alloca+global should be combined) -; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s ; CHECK: Function: test Index: test/Analysis/CFLAliasAnalysis/basic-interproc.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/basic-interproc.ll +++ test/Analysis/CFLAliasAnalysis/basic-interproc.ll @@ -1,7 +1,7 @@ ; This testcase ensures that CFL AA gives conservative answers on variables ; that involve arguments. -; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s ; CHECK: Function: test ; CHECK: 2 Total Alias Queries Performed Index: test/Analysis/CFLAliasAnalysis/branch-alias.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/branch-alias.ll +++ test/Analysis/CFLAliasAnalysis/branch-alias.ll @@ -13,7 +13,7 @@ ; int* ShouldAliasA = *AliasA1; ; } -; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s ; CHECK: Function: ptr_test define void @ptr_test() #0 { Index: test/Analysis/CFLAliasAnalysis/const-expr-gep.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/const-expr-gep.ll +++ test/Analysis/CFLAliasAnalysis/const-expr-gep.ll @@ -2,7 +2,7 @@ ; resolvable by cfl-aa, but require analysis of getelementptr constant exprs. ; Derived from BasicAA/2003-12-11-ConstExprGEP.ll -; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s %T = type { i32, [10 x i8] } Index: test/Analysis/CFLAliasAnalysis/full-store-partial-alias.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/full-store-partial-alias.ll +++ test/Analysis/CFLAliasAnalysis/full-store-partial-alias.ll @@ -1,5 +1,5 @@ -; RUN: opt -S -tbaa -cfl-aa -gvn < %s | FileCheck -check-prefix=CFLAA %s -; RUN: opt -S -tbaa -gvn < %s | FileCheck %s +; RUN: opt -S -disable-basicaa -tbaa -cfl-aa -gvn < %s | FileCheck -check-prefix=CFLAA %s +; RUN: opt -S -disable-basicaa -tbaa -gvn < %s | FileCheck %s ; Adapted from the BasicAA full-store-partial-alias.ll test. ; CFL AA could notice that the store stores to the entire %u object, Index: test/Analysis/CFLAliasAnalysis/gep-signed-arithmetic.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/gep-signed-arithmetic.ll +++ test/Analysis/CFLAliasAnalysis/gep-signed-arithmetic.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -cfl-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s ; Derived from BasicAA/2010-09-15-GEP-SignedArithmetic.ll target datalayout = "e-p:32:32:32" Index: test/Analysis/CFLAliasAnalysis/multilevel-combine.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/multilevel-combine.ll +++ test/Analysis/CFLAliasAnalysis/multilevel-combine.ll @@ -8,7 +8,7 @@ ; } ; -; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s %T = type { i32, [10 x i8] } Index: test/Analysis/CFLAliasAnalysis/must-and-partial.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/must-and-partial.ll +++ test/Analysis/CFLAliasAnalysis/must-and-partial.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -cfl-aa -aa-eval -print-all-alias-modref-info 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-all-alias-modref-info 2>&1 | FileCheck %s ; When merging MustAlias and PartialAlias, merge to PartialAlias ; instead of MayAlias. Index: test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll +++ test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll @@ -2,7 +2,7 @@ ; its own stratified set. This would make cases like the one in @test say that ; nothing (except %Escapes and %Arg) can alias -; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s ; CHECK: Function: test ; CHECK: MayAlias: i8* %Arg, i8* %Escapes Index: test/Analysis/CFLAliasAnalysis/va.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/va.ll +++ test/Analysis/CFLAliasAnalysis/va.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s ; CHECK-LABEL: Function: test1 ; CHECK: 0 no alias responses Index: test/Analysis/DependenceAnalysis/PR21585.ll =================================================================== --- test/Analysis/DependenceAnalysis/PR21585.ll +++ test/Analysis/DependenceAnalysis/PR21585.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -analyze -basicaa -globalsmodref-aa -da | FileCheck %s +; RUN: opt < %s -analyze -basicaa -globals-aa -da | FileCheck %s define void @i32_subscript(i32* %a) { entry: br label %for.body Index: test/Analysis/GlobalsModRef/2008-09-03-ReadGlobals.ll =================================================================== --- test/Analysis/GlobalsModRef/2008-09-03-ReadGlobals.ll +++ test/Analysis/GlobalsModRef/2008-09-03-ReadGlobals.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -globalsmodref-aa -gvn -S | FileCheck %s +; RUN: opt < %s -globals-aa -gvn -S | FileCheck %s @g = internal global i32 0 ; [#uses=2] Index: test/Analysis/GlobalsModRef/aliastest.ll =================================================================== --- test/Analysis/GlobalsModRef/aliastest.ll +++ test/Analysis/GlobalsModRef/aliastest.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -basicaa -globalsmodref-aa -gvn -S -enable-unsafe-globalsmodref-alias-results | FileCheck %s +; RUN: opt < %s -basicaa -globals-aa -gvn -S -enable-unsafe-globalsmodref-alias-results | FileCheck %s ; ; Note that this test relies on an unsafe feature of GlobalsModRef. While this ; test is correct and safe, GMR's technique for handling this isn't generally. Index: test/Analysis/GlobalsModRef/atomic-instrs.ll =================================================================== --- test/Analysis/GlobalsModRef/atomic-instrs.ll +++ test/Analysis/GlobalsModRef/atomic-instrs.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -globalsmodref-aa -gvn -S | FileCheck %s +; RUN: opt < %s -globals-aa -gvn -S | FileCheck %s @X = internal global i32 4 Index: test/Analysis/GlobalsModRef/chaining-analysis.ll =================================================================== --- test/Analysis/GlobalsModRef/chaining-analysis.ll +++ test/Analysis/GlobalsModRef/chaining-analysis.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -basicaa -globalsmodref-aa -gvn -S | FileCheck %s +; RUN: opt < %s -basicaa -globals-aa -gvn -S | FileCheck %s ; This test requires the use of previous analyses to determine that ; doesnotmodX does not modify X (because 'sin' doesn't). Index: test/Analysis/GlobalsModRef/indirect-global.ll =================================================================== --- test/Analysis/GlobalsModRef/indirect-global.ll +++ test/Analysis/GlobalsModRef/indirect-global.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -basicaa -globalsmodref-aa -gvn -instcombine -S -enable-unsafe-globalsmodref-alias-results | FileCheck %s +; RUN: opt < %s -basicaa -globals-aa -gvn -instcombine -S -enable-unsafe-globalsmodref-alias-results | FileCheck %s ; ; Note that this test relies on an unsafe feature of GlobalsModRef. While this ; test is correct and safe, GMR's technique for handling this isn't generally. Index: test/Analysis/GlobalsModRef/modreftest.ll =================================================================== --- test/Analysis/GlobalsModRef/modreftest.ll +++ test/Analysis/GlobalsModRef/modreftest.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -basicaa -globalsmodref-aa -gvn -S | FileCheck %s +; RUN: opt < %s -basicaa -globals-aa -gvn -S | FileCheck %s @X = internal global i32 4 ; [#uses=2] Index: test/Analysis/GlobalsModRef/nonescaping-noalias.ll =================================================================== --- test/Analysis/GlobalsModRef/nonescaping-noalias.ll +++ test/Analysis/GlobalsModRef/nonescaping-noalias.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -globalsmodref-aa -gvn -S | FileCheck %s +; RUN: opt < %s -globals-aa -gvn -S | FileCheck %s ; ; This tests the safe no-alias conclusions of GMR -- when there is ; a non-escaping global as one indentified underlying object and some pointer Index: test/Analysis/GlobalsModRef/pr12351.ll =================================================================== --- test/Analysis/GlobalsModRef/pr12351.ll +++ test/Analysis/GlobalsModRef/pr12351.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -basicaa -globalsmodref-aa -gvn -S | FileCheck %s +; RUN: opt < %s -basicaa -globals-aa -gvn -S | FileCheck %s declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) define void @foo(i8* %x, i8* %y) { Index: test/Analysis/GlobalsModRef/purecse.ll =================================================================== --- test/Analysis/GlobalsModRef/purecse.ll +++ test/Analysis/GlobalsModRef/purecse.ll @@ -1,5 +1,5 @@ ; Test that pure functions are cse'd away -; RUN: opt < %s -globalsmodref-aa -gvn -instcombine -S | FileCheck %s +; RUN: opt < %s -disable-basicaa -globals-aa -gvn -instcombine -S | FileCheck %s define i32 @pure(i32 %X) { %Y = add i32 %X, 1 ; [#uses=1] Index: test/Analysis/ScalarEvolution/scev-aa.ll =================================================================== --- test/Analysis/ScalarEvolution/scev-aa.ll +++ test/Analysis/ScalarEvolution/scev-aa.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -scev-aa -aa-eval -print-all-alias-modref-info \ +; RUN: opt -disable-output < %s -disable-basicaa -scev-aa -aa-eval -print-all-alias-modref-info \ ; RUN: 2>&1 | FileCheck %s ; At the time of this writing, -basicaa misses the example of the form Index: test/Analysis/TypeBasedAliasAnalysis/precedence.ll =================================================================== --- test/Analysis/TypeBasedAliasAnalysis/precedence.ll +++ test/Analysis/TypeBasedAliasAnalysis/precedence.ll @@ -1,9 +1,9 @@ -; RUN: opt -basicaa -tbaa -gvn -instcombine -S < %s | FileCheck %s --check-prefix=TBAA -; RUN: opt -tbaa -basicaa -gvn -instcombine -S < %s | FileCheck %s --check-prefix=BASICAA +; RUN: opt -tbaa -disable-basicaa -gvn -instcombine -S < %s | FileCheck %s --check-prefix=TBAA +; RUN: opt -tbaa -gvn -instcombine -S < %s | FileCheck %s --check-prefix=BASICAA ; According to the TBAA metadata the load and store don't alias. However, -; according to the actual code, they do. The order of the alias analysis -; passes should determine which of these takes precedence. +; according to the actual code, they do. Disabling basicaa shows the raw TBAA +; results. target datalayout = "e-p:64:64:64" Index: test/Transforms/BBVectorize/X86/wr-aliases.ll =================================================================== --- test/Transforms/BBVectorize/X86/wr-aliases.ll +++ test/Transforms/BBVectorize/X86/wr-aliases.ll @@ -1,4 +1,4 @@ -; RUN: opt -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7-avx -bb-vectorize -S < %s | FileCheck %s +; RUN: opt -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7-avx -disable-basicaa -bb-vectorize -S < %s | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" Index: test/Transforms/GVN/crash-no-aa.ll =================================================================== --- test/Transforms/GVN/crash-no-aa.ll +++ test/Transforms/GVN/crash-no-aa.ll @@ -1,4 +1,4 @@ -; RUN: opt -no-aa -gvn -S < %s +; RUN: opt -disable-basicaa -gvn -S < %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-unknown-freebsd8.0" Index: test/Transforms/GVN/pr14166.ll =================================================================== --- test/Transforms/GVN/pr14166.ll +++ test/Transforms/GVN/pr14166.ll @@ -1,4 +1,4 @@ -; RUN: opt -gvn -S < %s | FileCheck %s +; RUN: opt -disable-basicaa -gvn -S < %s | FileCheck %s target datalayout = "e-p:32:32:32" target triple = "i386-pc-linux-gnu" define <2 x i32> @test1() { Index: test/Transforms/LICM/2004-09-14-AliasAnalysisInvalidate.ll =================================================================== --- test/Transforms/LICM/2004-09-14-AliasAnalysisInvalidate.ll +++ test/Transforms/LICM/2004-09-14-AliasAnalysisInvalidate.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -globalsmodref-aa -licm -disable-output +; RUN: opt < %s -globals-aa -licm -disable-output @PL_regcomp_parse = internal global i8* null ; [#uses=2] Index: test/Transforms/LICM/hoist-invariant-load.ll =================================================================== --- test/Transforms/LICM/hoist-invariant-load.ll +++ test/Transforms/LICM/hoist-invariant-load.ll @@ -1,5 +1,5 @@ ; REQUIRES: asserts -; RUN: opt < %s -licm -stats -S 2>&1 | grep "1 licm" +; RUN: opt < %s -licm -disable-basicaa -stats -S 2>&1 | grep "1 licm" @"\01L_OBJC_METH_VAR_NAME_" = internal global [4 x i8] c"foo\00", section "__TEXT,__objc_methname,cstring_literals", align 1 @"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" Index: test/Transforms/LoopVectorize/X86/reduction-crash.ll =================================================================== --- test/Transforms/LoopVectorize/X86/reduction-crash.ll +++ test/Transforms/LoopVectorize/X86/reduction-crash.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -loop-vectorize -mcpu=prescott < %s | FileCheck %s +; RUN: opt -S -loop-vectorize -mcpu=prescott -disable-basicaa < %s | FileCheck %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" target triple = "i386-apple-darwin" Index: test/Transforms/ObjCARC/provenance.ll =================================================================== --- test/Transforms/ObjCARC/provenance.ll +++ test/Transforms/ObjCARC/provenance.ll @@ -1,4 +1,4 @@ -; RUN: opt -disable-output -pa-eval %s 2>&1 | FileCheck %s +; RUN: opt -disable-output -disable-basicaa -pa-eval %s 2>&1 | FileCheck %s @"\01l_objc_msgSend_fixup_" = global i8 0 @g1 = global i8 0, section "__OBJC,__message_refs,literal_pointers,no_dead_strip" Index: unittests/Analysis/AliasAnalysisTest.cpp =================================================================== --- unittests/Analysis/AliasAnalysisTest.cpp +++ unittests/Analysis/AliasAnalysisTest.cpp @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/BasicAliasAnalysis.h" -#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/Support/CommandLine.h" #include "gtest/gtest.h" @@ -23,49 +23,27 @@ class AliasAnalysisTest : public testing::Test { protected: - AliasAnalysisTest() : M("AliasAnalysisTBAATest", C) {} - - // This is going to check that calling getModRefInfo without a location, and - // with a default location, first, doesn't crash, and second, gives the right - // answer. - void CheckModRef(Instruction *I, ModRefInfo Result) { - static char ID; - class CheckModRefTestPass : public FunctionPass { - public: - CheckModRefTestPass(Instruction *I, ModRefInfo Result) - : FunctionPass(ID), ExpectResult(Result), I(I) {} - static int initialize() { - PassInfo *PI = new PassInfo("CheckModRef testing pass", "", &ID, - nullptr, true, true); - PassRegistry::getPassRegistry()->registerPass(*PI, false); - initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry()); - initializeBasicAliasAnalysisPass(*PassRegistry::getPassRegistry()); - return 0; - } - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesAll(); - AU.addRequiredTransitive(); - } - bool runOnFunction(Function &) override { - AliasAnalysis &AA = getAnalysis(); - EXPECT_EQ(AA.getModRefInfo(I, MemoryLocation()), ExpectResult); - EXPECT_EQ(AA.getModRefInfo(I), ExpectResult); - return false; - } - ModRefInfo ExpectResult; - Instruction *I; - }; - static int initialize = CheckModRefTestPass::initialize(); - (void)initialize; - CheckModRefTestPass *P = new CheckModRefTestPass(I, Result); - legacy::PassManager PM; - PM.add(createBasicAliasAnalysisPass()); - PM.add(P); - PM.run(M); - } - LLVMContext C; Module M; + TargetLibraryInfoImpl TLII; + TargetLibraryInfo TLI; + std::unique_ptr AC; + std::unique_ptr BAR; + std::unique_ptr AAR; + + AliasAnalysisTest() : M("AliasAnalysisTest", C), TLI(TLII) {} + + AAResults &getAAResults(Function &F) { + // Reset the Function AA results first to clear out any references. + AAR.reset(new AAResults()); + + // Build the various AA results and register them. + AC.reset(new AssumptionCache(F)); + BAR.reset(new BasicAAResult(M.getDataLayout(), TLI, *AC)); + AAR->addAAResult(*BAR); + + return *AAR; + } }; TEST_F(AliasAnalysisTest, getModRefInfo) { @@ -92,13 +70,21 @@ ReturnInst::Create(C, nullptr, BB); + auto &AA = getAAResults(*F); + // Check basic results - CheckModRef(Store1, MRI_Mod); - CheckModRef(Load1, MRI_Ref); - CheckModRef(Add1, MRI_NoModRef); - CheckModRef(VAArg1, MRI_ModRef); - CheckModRef(CmpXChg1, MRI_ModRef); - CheckModRef(AtomicRMW, MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(Store1, MemoryLocation()), MRI_Mod); + EXPECT_EQ(AA.getModRefInfo(Store1), MRI_Mod); + EXPECT_EQ(AA.getModRefInfo(Load1, MemoryLocation()), MRI_Ref); + EXPECT_EQ(AA.getModRefInfo(Load1), MRI_Ref); + EXPECT_EQ(AA.getModRefInfo(Add1, MemoryLocation()), MRI_NoModRef); + EXPECT_EQ(AA.getModRefInfo(Add1), MRI_NoModRef); + EXPECT_EQ(AA.getModRefInfo(VAArg1, MemoryLocation()), MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(VAArg1), MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(CmpXChg1, MemoryLocation()), MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(CmpXChg1), MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(AtomicRMW, MemoryLocation()), MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(AtomicRMW), MRI_ModRef); } } // end anonymous namspace Index: unittests/Analysis/MixedTBAATest.cpp =================================================================== --- unittests/Analysis/MixedTBAATest.cpp +++ unittests/Analysis/MixedTBAATest.cpp @@ -68,7 +68,7 @@ // because the AA eval pass only runs one test per store-pair. const char* args[] = { "MixedTBAATest", "-evaluate-aa-metadata" }; cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char*), args); - PM.add(createTypeBasedAliasAnalysisPass()); + PM.add(createTypeBasedAAWrapperPass()); PM.add(createAAEvalPass()); PM.run(M); } Index: unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h =================================================================== --- unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h +++ unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h @@ -17,6 +17,8 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/InitializePasses.h" #include "llvm/Support/Host.h" #include "llvm/Support/TargetSelect.h" @@ -39,6 +41,10 @@ InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); + // FIXME: It isn't at all clear why this is necesasry, but without it we + // fail to initialize the AssumptionCacheTracker. + initializeAssumptionCacheTrackerPass(*PassRegistry::getPassRegistry()); + #ifdef LLVM_ON_WIN32 // On Windows, generate ELF objects by specifying "-elf" in triple HostTriple += "-elf";