541 changes: 501 additions & 40 deletions llvm/include/llvm/Analysis/AliasAnalysis.h

Large diffs are not rendered by default.

65 changes: 0 additions & 65 deletions llvm/include/llvm/Analysis/AliasAnalysisCounter.h

This file was deleted.

2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/AliasSetTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <vector>

namespace llvm {

class AliasAnalysis;
class LoadInst;
class StoreInst;
class VAArgInst;
Expand Down
129 changes: 87 additions & 42 deletions llvm/include/llvm/Analysis/BasicAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<BasicAAResult> {
friend AAResultBase<BasicAAResult>;

const DataLayout &DL;
AssumptionCache &AC;
DominatorTree *DT;
LoopInfo *LI;

#ifndef NDEBUG
static const Function *getParent(const Value *V) {
Expand All @@ -52,23 +64,34 @@ struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis {
}
#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<AliasAnalysis>();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
/// 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 {
assert(AliasCache.empty() && "AliasCache must be cleared after use!");
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
assert(notDifferentParent(LocA.Ptr, LocB.Ptr) &&
"BasicAliasAnalysis doesn't support interprocedural queries.");

// If we have a directly cached entry for these locations, we have recursed
// through this once, so just return the cached results. Notably, when this
// happens, we don't clear the cache.
auto CacheIt = AliasCache.find(LocPair(LocA, LocB));
if (CacheIt != AliasCache.end())
return CacheIt->second;

AliasResult Alias = aliasCheck(LocA.Ptr, LocA.Size, LocA.AATags, LocB.Ptr,
LocB.Size, LocB.AATags);
// AliasCache rarely has more than 1 or 2 elements, always use
Expand All @@ -80,33 +103,22 @@ struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis {
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,
Expand Down Expand Up @@ -181,8 +193,7 @@ struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis {
bool
constantOffsetHeuristic(const SmallVectorImpl<VariableGEPIndex> &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);

Expand All @@ -206,13 +217,47 @@ struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis {
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<Function> *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<BasicAAResult> 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
126 changes: 80 additions & 46 deletions llvm/include/llvm/Analysis/CFLAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<CFLAAResult> {
friend AAResultBase<CFLAAResult>;

void removeSelfFromCache() {
assert(CFLAA != nullptr);
auto *Val = getValPtr();
CFLAA->evict(cast<Function>(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<Function *, Optional<FunctionInfo>> Cache;
std::forward_list<FunctionHandle> 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);
Expand All @@ -79,8 +51,7 @@ class CFLAliasAnalysis : public ImmutablePass, public AliasAnalysis {

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;
Expand All @@ -96,29 +67,92 @@ class CFLAliasAnalysis : public ImmutablePass, public AliasAnalysis {
// one Value tied to a Function, and neither GlobalValues nor ConstantExprs
// are.
if (isa<Constant>(LocA.Ptr) && isa<Constant>(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<Function>(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<Function *, Optional<FunctionInfo>> Cache;
std::forward_list<FunctionHandle> 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<Function> *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<CFLAAResult> 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
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/DependenceAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
103 changes: 59 additions & 44 deletions llvm/include/llvm/Analysis/GlobalsModRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<GlobalsAAResult> {
friend AAResultBase<GlobalsAAResult>;

class FunctionInfo;

const DataLayout &DL;

/// The globals that do not have their addresses taken.
SmallPtrSet<const GlobalValue *, 8> NonAddressTakenGlobals;

Expand All @@ -45,11 +52,11 @@ class GlobalsModRef : public ModulePass, public AliasAnalysis {

/// Handle to clear this analysis on deletion of values.
struct DeletionCallbackHandle final : CallbackVH {
GlobalsModRef &GMR;
GlobalsAAResult &GAR;
std::list<DeletionCallbackHandle>::iterator I;

DeletionCallbackHandle(GlobalsModRef &GMR, Value *V)
: CallbackVH(V), GMR(GMR) {}
DeletionCallbackHandle(GlobalsAAResult &GAR, Value *V)
: CallbackVH(V), GAR(GAR) {}

void deleted() override;
};
Expand All @@ -60,56 +67,31 @@ class GlobalsModRef : public ModulePass, public AliasAnalysis {
/// could perform to the memory utilization here if this becomes a problem.
std::list<DeletionCallbackHandle> 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<CallGraphWrapperPass>().getCallGraph(), M);
return false;
}

void getAnalysisUsage(AnalysisUsage &AU) const override {
AliasAnalysis::getAnalysisUsage(AU);
AU.addRequired<CallGraphWrapperPass>();
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);
Expand All @@ -125,13 +107,46 @@ class GlobalsModRef : public ModulePass, public AliasAnalysis {
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<Module> *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<GlobalsAAResult> 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
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/Loads.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
1 change: 0 additions & 1 deletion llvm/include/llvm/Analysis/LoopAccessAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ namespace llvm {

class Value;
class DataLayout;
class AliasAnalysis;
class ScalarEvolution;
class Loop;
class SCEV;
Expand Down
1 change: 0 additions & 1 deletion llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ namespace llvm {
class FunctionPass;
class Instruction;
class CallSite;
class AliasAnalysis;
class AssumptionCache;
class MemoryDependenceAnalysis;
class PredIteratorCache;
Expand Down
76 changes: 53 additions & 23 deletions llvm/include/llvm/Analysis/ObjCARCAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -35,35 +36,64 @@ namespace objcarc {
/// 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<ObjCARCAAResult> {
friend AAResultBase<ObjCARCAAResult>;

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<Function> *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<AliasAnalysis *>(this);
return this;
}
/// Legacy wrapper pass to provide the ObjCARCAAResult object.
class ObjCARCAAWrapperPass : public ImmutablePass {
std::unique_ptr<ObjCARCAAResult> 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
Expand Down
10 changes: 2 additions & 8 deletions llvm/include/llvm/Analysis/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,10 @@ namespace llvm {

//===--------------------------------------------------------------------===//
//
// 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();

Expand Down
67 changes: 42 additions & 25 deletions llvm/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,55 @@ namespace llvm {

/// A simple alias analysis implementation that uses ScalarEvolution to answer
/// queries.
class ScalarEvolutionAliasAnalysis : public FunctionPass, public AliasAnalysis {
ScalarEvolution *SE;
class SCEVAAResult : public AAResultBase<SCEVAAResult> {
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<Function> *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<SCEVAAResult> 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();

}

Expand Down
81 changes: 50 additions & 31 deletions llvm/include/llvm/Analysis/ScopedNoAliasAA.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<ScopedNoAliasAAResult> {
friend AAResultBase<ScopedNoAliasAAResult>;

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<const MDNode *> &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<Function> *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<ScopedNoAliasAAResult> 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
80 changes: 51 additions & 29 deletions llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<TypeBasedAAResult> {
friend AAResultBase<TypeBasedAAResult>;

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<Function> *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<TypeBasedAAResult> 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
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -36,7 +37,6 @@ namespace llvm {

extern cl::opt<bool> UseSegmentSetForPhysRegs;

class AliasAnalysis;
class BitVector;
class BlockFrequency;
class LiveRangeCalc;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/LiveRangeEdit.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
#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"
#include "llvm/Target/TargetSubtargetInfo.h"

namespace llvm {

class AliasAnalysis;
class LiveIntervals;
class MachineBlockFrequencyInfo;
class MachineLoopInfo;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/MachineInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -34,7 +35,6 @@
namespace llvm {

template <typename T> class SmallVectorImpl;
class AliasAnalysis;
class TargetInstrInfo;
class TargetRegisterClass;
class TargetRegisterInfo;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/MachineScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -87,7 +88,6 @@ namespace llvm {
extern cl::opt<bool> ForceTopDown;
extern cl::opt<bool> ForceBottomUp;

class AliasAnalysis;
class LiveIntervals;
class MachineDominatorTree;
class MachineLoopInfo;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/ScheduleDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -31,7 +32,6 @@

namespace llvm {

class AliasAnalysis;
class MachineConstantPoolValue;
class MachineFunction;
class MDNode;
Expand Down
17 changes: 8 additions & 9 deletions llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,14 @@ void initializeAAEvalPass(PassRegistry&);
void initializeAddDiscriminatorsPass(PassRegistry&);
void initializeADCEPass(PassRegistry&);
void initializeBDCEPass(PassRegistry&);
void initializeAliasAnalysisAnalysisGroup(PassRegistry&);
void initializeAliasAnalysisCounterPass(PassRegistry&);
void initializeAliasSetPrinterPass(PassRegistry&);
void initializeAlwaysInlinerPass(PassRegistry&);
void initializeArgPromotionPass(PassRegistry&);
void initializeAtomicExpandPass(PassRegistry&);
void initializeSampleProfileLoaderPass(PassRegistry&);
void initializeAlignmentFromAssumptionsPass(PassRegistry&);
void initializeBarrierNoopPass(PassRegistry&);
void initializeBasicAliasAnalysisPass(PassRegistry&);
void initializeBasicAAWrapperPassPass(PassRegistry&);
void initializeCallGraphWrapperPassPass(PassRegistry &);
void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyInfoWrapperPassPass(PassRegistry&);
Expand All @@ -86,7 +84,7 @@ void initializeCFGOnlyPrinterPass(PassRegistry&);
void initializeCFGOnlyViewerPass(PassRegistry&);
void initializeCFGPrinterPass(PassRegistry&);
void initializeCFGSimplifyPassPass(PassRegistry&);
void initializeCFLAliasAnalysisPass(PassRegistry&);
void initializeCFLAAWrapperPassPass(PassRegistry&);
void initializeForwardControlFlowIntegrityPass(PassRegistry&);
void initializeFlattenCFGPassPass(PassRegistry&);
void initializeStructurizeCFGPass(PassRegistry&);
Expand Down Expand Up @@ -116,6 +114,7 @@ void initializeDominatorTreeWrapperPassPass(PassRegistry&);
void initializeEarlyIfConverterPass(PassRegistry&);
void initializeEdgeBundlesPass(PassRegistry&);
void initializeExpandPostRAPass(PassRegistry&);
void initializeAAResultsWrapperPassPass(PassRegistry &);
void initializeGCOVProfilerPass(PassRegistry&);
void initializeInstrProfilingPass(PassRegistry&);
void initializeAddressSanitizerPass(PassRegistry&);
Expand All @@ -134,7 +133,7 @@ void initializeGCModuleInfoPass(PassRegistry&);
void initializeGVNPass(PassRegistry&);
void initializeGlobalDCEPass(PassRegistry&);
void initializeGlobalOptPass(PassRegistry&);
void initializeGlobalsModRefPass(PassRegistry&);
void initializeGlobalsAAWrapperPassPass(PassRegistry&);
void initializeIPCPPass(PassRegistry&);
void initializeIPSCCPPass(PassRegistry&);
void initializeIVUsersPass(PassRegistry&);
Expand Down Expand Up @@ -205,7 +204,7 @@ void initializeMergeFunctionsPass(PassRegistry&);
void initializeModuleDebugInfoPrinterPass(PassRegistry&);
void initializeNaryReassociatePass(PassRegistry&);
void initializeNoAAPass(PassRegistry&);
void initializeObjCARCAliasAnalysisPass(PassRegistry&);
void initializeObjCARCAAWrapperPassPass(PassRegistry&);
void initializeObjCARCAPElimPass(PassRegistry&);
void initializeObjCARCExpandPass(PassRegistry&);
void initializeObjCARCContractPass(PassRegistry&);
Expand Down Expand Up @@ -243,7 +242,7 @@ void initializeSCCPPass(PassRegistry&);
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&);
Expand Down Expand Up @@ -271,8 +270,8 @@ void initializeTargetTransformInfoWrapperPassPass(PassRegistry &);
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&);
Expand Down
17 changes: 7 additions & 10 deletions llvm/include/llvm/LinkAllPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -59,19 +58,18 @@ namespace {
(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();
Expand All @@ -92,7 +90,7 @@ namespace {
(void) llvm::createAlwaysInlinerPass();
(void) llvm::createGlobalDCEPass();
(void) llvm::createGlobalOptimizerPass();
(void) llvm::createGlobalsModRefPass();
(void) llvm::createGlobalsAAWrapperPass();
(void) llvm::createIPConstantPropagationPass();
(void) llvm::createIPSCCPPass();
(void) llvm::createInductiveRangeCheckEliminationPass();
Expand All @@ -115,8 +113,7 @@ namespace {
(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();
Expand Down
12 changes: 5 additions & 7 deletions llvm/include/llvm/Transforms/Utils/Cloning.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -44,7 +45,6 @@ class DataLayout;
class Loop;
class LoopInfo;
class AllocaInst;
class AliasAnalysis;
class AssumptionCacheTracker;
class DominatorTree;

Expand Down Expand Up @@ -202,14 +202,12 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
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
Expand Down Expand Up @@ -237,11 +235,11 @@ class InlineFunctionInfo {
/// 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.
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Transforms/Utils/Local.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -40,7 +41,6 @@ class DataLayout;
class TargetLibraryInfo;
class TargetTransformInfo;
class DIBuilder;
class AliasAnalysis;
class DominatorTree;

template<typename T> class SmallVectorImpl;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Transforms/Utils/LoopUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
441 changes: 234 additions & 207 deletions llvm/lib/Analysis/AliasAnalysis.cpp

Large diffs are not rendered by default.

165 changes: 0 additions & 165 deletions llvm/lib/Analysis/AliasAnalysisCounter.cpp

This file was deleted.

6 changes: 3 additions & 3 deletions llvm/lib/Analysis/AliasAnalysisEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace {
}

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<AliasAnalysis>();
AU.addRequired<AAResultsWrapperPass>();
AU.setPreservesAll();
}

Expand All @@ -83,7 +83,7 @@ namespace {
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)

Expand Down Expand Up @@ -142,7 +142,7 @@ static inline bool isInterestingPointer(Value *V) {

bool AAEval::runOnFunction(Function &F) {
const DataLayout &DL = F.getParent()->getDataLayout();
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();

SetVector<Value *> Pointers;
SetVector<CallSite> CallSites;
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Analysis/AliasSetTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,11 +649,12 @@ namespace {

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
AU.addRequired<AliasAnalysis>();
AU.addRequired<AAResultsWrapperPass>();
}

bool runOnFunction(Function &F) override {
Tracker = new AliasSetTracker(getAnalysis<AliasAnalysis>());
auto &AAWP = getAnalysis<AAResultsWrapperPass>();
Tracker = new AliasSetTracker(AAWP.getAAResults());

for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
Tracker->add(&*I);
Expand All @@ -667,6 +668,6 @@ namespace {
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)
18 changes: 8 additions & 10 deletions llvm/lib/Analysis/Analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@ using namespace llvm;

/// 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);
Expand All @@ -36,7 +33,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeCFGPrinterPass(Registry);
initializeCFGOnlyViewerPass(Registry);
initializeCFGOnlyPrinterPass(Registry);
initializeCFLAliasAnalysisPass(Registry);
initializeCFLAAWrapperPassPass(Registry);
initializeDependenceAnalysisPass(Registry);
initializeDelinearizationPass(Registry);
initializeDemandedBitsPass(Registry);
Expand All @@ -50,7 +47,8 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializePostDomPrinterPass(Registry);
initializePostDomOnlyViewerPass(Registry);
initializePostDomOnlyPrinterPass(Registry);
initializeGlobalsModRefPass(Registry);
initializeAAResultsWrapperPassPass(Registry);
initializeGlobalsAAWrapperPassPass(Registry);
initializeIVUsersPass(Registry);
initializeInstCountPass(Registry);
initializeIntervalPartitionPass(Registry);
Expand All @@ -61,18 +59,18 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
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) {
Expand Down
276 changes: 139 additions & 137 deletions llvm/lib/Analysis/BasicAliasAnalysis.cpp

Large diffs are not rendered by default.

107 changes: 56 additions & 51 deletions llvm/lib/Analysis/CFLAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -53,18 +53,11 @@ using namespace llvm;

#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<Value *> Sets;
// Lots of functions have < 4 returns. Adjust as necessary.
SmallVector<Value *, 4> ReturnedValues;
Expand All @@ -73,22 +66,6 @@ struct CFLAliasAnalysis::FunctionInfo {
: 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<Function *> parentFunctionOfValue(Value *);

Expand Down Expand Up @@ -177,11 +154,11 @@ struct Edge {

// \brief Gets the edges our graph should have, based on an Instruction*
class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
CFLAliasAnalysis &AA;
CFLAAResult &AA;
SmallVectorImpl<Edge> &Output;

public:
GetEdgesVisitor(CFLAliasAnalysis &AA, SmallVectorImpl<Edge> &Output)
GetEdgesVisitor(CFLAAResult &AA, SmallVectorImpl<Edge> &Output)
: AA(AA), Output(Output) {}

void visitInstruction(Instruction &) {
Expand Down Expand Up @@ -669,26 +646,24 @@ static Optional<StratifiedAttr> valueToAttrIndex(Value *Val);
static EdgeType flipWeight(EdgeType);

// Gets edges of the given Instruction*, writing them to the SmallVector*.
static void argsToEdges(CFLAliasAnalysis &, Instruction *,
SmallVectorImpl<Edge> &);
static void argsToEdges(CFLAAResult &, Instruction *, SmallVectorImpl<Edge> &);

// Gets edges of the given ConstantExpr*, writing them to the SmallVector*.
static void argsToEdges(CFLAliasAnalysis &, ConstantExpr *,
SmallVectorImpl<Edge> &);
static void argsToEdges(CFLAAResult &, ConstantExpr *, SmallVectorImpl<Edge> &);

// Gets the "Level" that one should travel in StratifiedSets
// given an EdgeType.
static Level directionOfEdgeType(EdgeType);

// Builds the graph needed for constructing the StratifiedSets for the
// given function
static void buildGraphFrom(CFLAliasAnalysis &, Function *,
static void buildGraphFrom(CFLAAResult &, Function *,
SmallVectorImpl<Value *> &, 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<Edge> &);

// Given an Instruction, this will add it to the graph, along with any
Expand All @@ -697,7 +672,7 @@ static void constexprToEdges(CFLAliasAnalysis &, ConstantExpr &,
// %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<Value *> &, NodeMapT &,
GraphT &);

Expand Down Expand Up @@ -777,15 +752,15 @@ static EdgeType flipWeight(EdgeType Initial) {
llvm_unreachable("Incomplete coverage of EdgeType enum");
}

static void argsToEdges(CFLAliasAnalysis &Analysis, Instruction *Inst,
static void argsToEdges(CFLAAResult &Analysis, Instruction *Inst,
SmallVectorImpl<Edge> &Output) {
assert(hasUsefulEdges(Inst) &&
"Expected instructions to have 'useful' edges");
GetEdgesVisitor v(Analysis, Output);
v.visit(Inst);
}

static void argsToEdges(CFLAliasAnalysis &Analysis, ConstantExpr *CE,
static void argsToEdges(CFLAAResult &Analysis, ConstantExpr *CE,
SmallVectorImpl<Edge> &Output) {
assert(hasUsefulEdges(CE) && "Expected constant expr to have 'useful' edges");
GetEdgesVisitor v(Analysis, Output);
Expand All @@ -804,7 +779,7 @@ static Level directionOfEdgeType(EdgeType Weight) {
llvm_unreachable("Incomplete switch coverage");
}

static void constexprToEdges(CFLAliasAnalysis &Analysis,
static void constexprToEdges(CFLAAResult &Analysis,
ConstantExpr &CExprToCollapse,
SmallVectorImpl<Edge> &Results) {
SmallVector<ConstantExpr *, 4> Worklist;
Expand Down Expand Up @@ -834,7 +809,7 @@ static void constexprToEdges(CFLAliasAnalysis &Analysis,
}
}

static void addInstructionToGraph(CFLAliasAnalysis &Analysis, Instruction &Inst,
static void addInstructionToGraph(CFLAAResult &Analysis, Instruction &Inst,
SmallVectorImpl<Value *> &ReturnedValues,
NodeMapT &Map, GraphT &Graph) {
const auto findOrInsertNode = [&Map, &Graph](Value *Val) {
Expand Down Expand Up @@ -897,7 +872,7 @@ static void addInstructionToGraph(CFLAliasAnalysis &Analysis, Instruction &Inst,
// 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<Value *> &ReturnedValues,
NodeMapT &Map, GraphT &Graph) {
for (auto &Bb : Fn->getBasicBlockList())
Expand Down Expand Up @@ -928,7 +903,7 @@ static bool canSkipAddingToSets(Value *Val) {
}

// Builds the graph + StratifiedSets for a function.
CFLAliasAnalysis::FunctionInfo CFLAliasAnalysis::buildSetsFrom(Function *Fn) {
CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
NodeMapT Map;
GraphT Graph;
SmallVector<Value *, 4> ReturnedValues;
Expand Down Expand Up @@ -1014,7 +989,7 @@ CFLAliasAnalysis::FunctionInfo CFLAliasAnalysis::buildSetsFrom(Function *Fn) {
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<FunctionInfo>()));
(void)InsertPair;
assert(InsertPair.second &&
Expand All @@ -1025,12 +1000,12 @@ void CFLAliasAnalysis::scan(Function *Fn) {
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::FunctionInfo> &
CFLAliasAnalysis::ensureCached(Function *Fn) {
const Optional<CFLAAResult::FunctionInfo> &
CFLAAResult::ensureCached(Function *Fn) {
auto Iter = Cache.find(Fn);
if (Iter == Cache.end()) {
scan(Fn);
Expand All @@ -1041,8 +1016,8 @@ CFLAliasAnalysis::ensureCached(Function *Fn) {
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<Value *>(LocA.Ptr);
auto *ValB = const_cast<Value *>(LocB.Ptr);

Expand Down Expand Up @@ -1108,7 +1083,37 @@ AliasResult CFLAliasAnalysis::query(const MemoryLocation &LocA,
return NoAlias;
}

bool CFLAliasAnalysis::doInitialization(Module &M) {
InitializeAliasAnalysis(this, &M.getDataLayout());
return true;
CFLAAResult CFLAA::run(Function &F, AnalysisManager<Function> *AM) {
return CFLAAResult(AM->getResult<TargetLibraryAnalysis>(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<TargetLibraryInfoWrapperPass>().getTLI()));
return false;
}

bool CFLAAWrapperPass::doFinalization(Module &M) {
Result.reset();
return false;
}

void CFLAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
2 changes: 0 additions & 2 deletions llvm/lib/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
add_llvm_library(LLVMAnalysis
AliasAnalysis.cpp
AliasAnalysisCounter.cpp
AliasAnalysisEvaluator.cpp
AliasSetTracker.cpp
Analysis.cpp
Expand Down Expand Up @@ -48,7 +47,6 @@ add_llvm_library(LLVMAnalysis
MemoryDependenceAnalysis.cpp
MemoryLocation.cpp
ModuleDebugInfoPrinter.cpp
NoAliasAnalysis.cpp
ObjCARCAliasAnalysis.cpp
ObjCARCAnalysisUtils.cpp
ObjCARCInstKind.cpp
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Analysis/DependenceAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ INITIALIZE_PASS_BEGIN(DependenceAnalysis, "da",
"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)

Expand All @@ -132,7 +132,7 @@ FunctionPass *llvm::createDependenceAnalysisPass() {

bool DependenceAnalysis::runOnFunction(Function &F) {
this->F = &F;
AA = &getAnalysis<AliasAnalysis>();
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
return false;
Expand All @@ -145,7 +145,7 @@ void DependenceAnalysis::releaseMemory() {

void DependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequiredTransitive<AliasAnalysis>();
AU.addRequiredTransitive<AAResultsWrapperPass>();
AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
AU.addRequiredTransitive<LoopInfoWrapperPass>();
}
Expand Down
170 changes: 110 additions & 60 deletions llvm/lib/Analysis/GlobalsModRef.cpp

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions llvm/lib/Analysis/Lint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ namespace {

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
AU.addRequired<AliasAnalysis>();
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
Expand Down Expand Up @@ -167,7 +167,7 @@ INITIALIZE_PASS_BEGIN(Lint, "lint", "Statically lint-checks LLVM IR",
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)

Expand All @@ -181,7 +181,7 @@ INITIALIZE_PASS_END(Lint, "lint", "Statically lint-checks LLVM IR",
bool Lint::runOnFunction(Function &F) {
Mod = F.getParent();
DL = &F.getParent()->getDataLayout();
AA = &getAnalysis<AliasAnalysis>();
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Analysis/LoopAccessAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1802,7 +1802,7 @@ bool LoopAccessAnalysis::runOnFunction(Function &F) {
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
TLI = TLIP ? &TLIP->getTLI() : nullptr;
AA = &getAnalysis<AliasAnalysis>();
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();

Expand All @@ -1811,7 +1811,7 @@ bool LoopAccessAnalysis::runOnFunction(Function &F) {

void LoopAccessAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<ScalarEvolutionWrapperPass>();
AU.addRequired<AliasAnalysis>();
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<LoopInfoWrapperPass>();

Expand All @@ -1823,7 +1823,7 @@ static const char laa_name[] = "Loop Access Analysis";
#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)
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Analysis/MemDepPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace {
void print(raw_ostream &OS, const Module * = nullptr) const override;

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequiredTransitive<AliasAnalysis>();
AU.addRequiredTransitive<AAResultsWrapperPass>();
AU.addRequiredTransitive<MemoryDependenceAnalysis>();
AU.setPreservesAll();
}
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ char MemoryDependenceAnalysis::ID = 0;
// 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)
Expand Down Expand Up @@ -94,12 +94,12 @@ void MemoryDependenceAnalysis::releaseMemory() {
void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequiredTransitive<AliasAnalysis>();
AU.addRequiredTransitive<AAResultsWrapperPass>();
AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
}

bool MemoryDependenceAnalysis::runOnFunction(Function &F) {
AA = &getAnalysis<AliasAnalysis>();
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
Expand Down
92 changes: 0 additions & 92 deletions llvm/lib/Analysis/NoAliasAnalysis.cpp

This file was deleted.

112 changes: 60 additions & 52 deletions llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
Expand All @@ -85,39 +69,32 @@ AliasResult ObjCARCAliasAnalysis::alias(const MemoryLocation &LocA,
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:
Expand All @@ -126,13 +103,13 @@ ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
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:
Expand All @@ -151,12 +128,43 @@ ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
break;
}

return AliasAnalysis::getModRefInfo(CS, Loc);
return AAResultBase::getModRefInfo(CS, Loc);
}

ObjCARCAAResult ObjCARCAA::run(Function &F, AnalysisManager<Function> *AM) {
return ObjCARCAAResult(F.getParent()->getDataLayout(),
AM->getResult<TargetLibraryAnalysis>(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<TargetLibraryInfoWrapperPass>().getTLI()));
return false;
}

bool ObjCARCAAWrapperPass::doFinalization(Module &M) {
Result.reset();
return false;
}

void ObjCARCAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
135 changes: 73 additions & 62 deletions llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,101 +20,55 @@
//===----------------------------------------------------------------------===//

#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<ScalarEvolutionWrapperPass>();
AU.setPreservesAll();
AliasAnalysis::getAnalysisUsage(AU);
}

bool ScalarEvolutionAliasAnalysis::runOnFunction(Function &F) {
InitializeAliasAnalysis(this, &F.getParent()->getDataLayout());
SE = &getAnalysis<ScalarEvolutionWrapperPass>().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<SCEVAddRecExpr>(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<SCEVAddExpr>(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<SCEVUnknown>(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<Value *>(LocA.Ptr));
const SCEV *BS = SE->getSCEV(const_cast<Value *>(LocB.Ptr));
// This is SCEVAAResult. Get the SCEVs!
const SCEV *AS = SE.getSCEV(const_cast<Value *>(LocA.Ptr));
const SCEV *BS = SE.getSCEV(const_cast<Value *>(LocB.Ptr));

// If they evaluate to the same expression, it's a MustAlias.
if (AS == BS)
return MustAlias;

// 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
// (because of INT_MIN, etc.); if the prior test failed, swap AS and BS
// 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;
}

Expand All @@ -133,5 +87,62 @@ AliasResult ScalarEvolutionAliasAnalysis::alias(const MemoryLocation &LocA,
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<SCEVAddRecExpr>(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<SCEVAddExpr>(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<SCEVUnknown>(S)) {
// This is a leaf node.
return U->getValue();
}
// No Identified object found.
return nullptr;
}

SCEVAAResult SCEVAA::run(Function &F, AnalysisManager<Function> *AM) {
return SCEVAAResult(AM->getResult<TargetLibraryAnalysis>(F),
AM->getResult<ScalarEvolutionAnalysis>(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<TargetLibraryInfoWrapperPass>().getTLI(),
getAnalysis<ScalarEvolutionWrapperPass>().getSE()));
return false;
}

void SCEVAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<ScalarEvolutionWrapperPass>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
150 changes: 77 additions & 73 deletions llvm/lib/Analysis/ScopedNoAliasAA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -72,26 +72,62 @@ class AliasScopeNode {
};
} // 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<const MDNode *> &Nodes) const {
for (unsigned i = 0, ie = List->getNumOperands(); i != ie; ++i)
Expand All @@ -100,8 +136,8 @@ void ScopedNoAliasAA::collectMDInDomain(
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;

Expand Down Expand Up @@ -136,72 +172,40 @@ bool ScopedNoAliasAA::mayAliasInScopes(const MDNode *Scopes,
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<Function> *AM) {
return ScopedNoAliasAAResult(AM->getResult<TargetLibraryAnalysis>(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<TargetLibraryInfoWrapperPass>().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<TargetLibraryInfoWrapperPass>();
}

Loading