mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-25 15:41:05 +00:00
[PM/AA] Hoist the interface for BasicAA into a header file.
This is the first mechanical step in preparation for making this and all the other alias analysis passes available to the new pass manager. I'm factoring out all the totally boring changes I can so I'm moving code around here with no other changes. I've even minimized the formatting churn. I'll reformat and freshen comments on the interface now that its located in the right place so that the substantive changes don't triger this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244197 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f4fa49e750
commit
734c778cb2
@ -1,3 +1,4 @@
|
|||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/Passes.h"
|
||||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/Passes.h"
|
||||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/Passes.h"
|
||||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/Passes.h"
|
||||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||||
|
223
include/llvm/Analysis/BasicAliasAnalysis.h
Normal file
223
include/llvm/Analysis/BasicAliasAnalysis.h
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
//===- BasicAliasAnalysis.h - Stateless, local Alias Analysis ---*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
/// \file
|
||||||
|
/// This is the interface for LLVM's primary stateless and local alias analysis.
|
||||||
|
///
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_ANALYSIS_BASICALIASANALYSIS_H
|
||||||
|
#define LLVM_ANALYSIS_BASICALIASANALYSIS_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
|
#include "llvm/Analysis/AssumptionCache.h"
|
||||||
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||||
|
#include "llvm/IR/Function.h"
|
||||||
|
#include "llvm/IR/GetElementPtrTypeIterator.h"
|
||||||
|
#include "llvm/IR/Instruction.h"
|
||||||
|
#include "llvm/IR/LLVMContext.h"
|
||||||
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/// BasicAliasAnalysis - This is the primary alias analysis implementation.
|
||||||
|
struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis {
|
||||||
|
static char ID; // Class identification, replacement for typeinfo
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
static const Function *getParent(const Value *V) {
|
||||||
|
if (const Instruction *inst = dyn_cast<Instruction>(V))
|
||||||
|
return inst->getParent()->getParent();
|
||||||
|
|
||||||
|
if (const Argument *arg = dyn_cast<Argument>(V))
|
||||||
|
return arg->getParent();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool notDifferentParent(const Value *O1, const Value *O2) {
|
||||||
|
|
||||||
|
const Function *F1 = getParent(O1);
|
||||||
|
const Function *F2 = getParent(O2);
|
||||||
|
|
||||||
|
return !F1 || !F2 || F1 == F2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BasicAliasAnalysis() : ImmutablePass(ID) {
|
||||||
|
initializeBasicAliasAnalysisPass(*PassRegistry::getPassRegistry());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool doInitialization(Module &M) override;
|
||||||
|
|
||||||
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||||
|
AU.addRequired<AliasAnalysis>();
|
||||||
|
AU.addRequired<AssumptionCacheTracker>();
|
||||||
|
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||||
|
}
|
||||||
|
|
||||||
|
AliasResult alias(const MemoryLocation &LocA,
|
||||||
|
const MemoryLocation &LocB) override {
|
||||||
|
assert(AliasCache.empty() && "AliasCache must be cleared after use!");
|
||||||
|
assert(notDifferentParent(LocA.Ptr, LocB.Ptr) &&
|
||||||
|
"BasicAliasAnalysis doesn't support interprocedural queries.");
|
||||||
|
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
|
||||||
|
// shrink_and_clear so it quickly returns to the inline capacity of the
|
||||||
|
// SmallDenseMap if it ever grows larger.
|
||||||
|
// FIXME: This should really be shrink_to_inline_capacity_and_clear().
|
||||||
|
AliasCache.shrink_and_clear();
|
||||||
|
VisitedPhiBBs.clear();
|
||||||
|
return Alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModRefInfo getModRefInfo(ImmutableCallSite CS,
|
||||||
|
const MemoryLocation &Loc) override;
|
||||||
|
|
||||||
|
ModRefInfo getModRefInfo(ImmutableCallSite CS1,
|
||||||
|
ImmutableCallSite CS2) override;
|
||||||
|
|
||||||
|
/// pointsToConstantMemory - Chase pointers until we find a (constant
|
||||||
|
/// global) or not.
|
||||||
|
bool pointsToConstantMemory(const MemoryLocation &Loc,
|
||||||
|
bool OrLocal) override;
|
||||||
|
|
||||||
|
/// Get the location associated with a pointer argument of a callsite.
|
||||||
|
ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override;
|
||||||
|
|
||||||
|
/// getModRefBehavior - Return the behavior when calling the given
|
||||||
|
/// call site.
|
||||||
|
FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
|
||||||
|
|
||||||
|
/// getModRefBehavior - Return the behavior when calling the given function.
|
||||||
|
/// For use when the call site is not known.
|
||||||
|
FunctionModRefBehavior getModRefBehavior(const Function *F) 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(const void *ID) override {
|
||||||
|
if (ID == &AliasAnalysis::ID)
|
||||||
|
return (AliasAnalysis*)this;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum ExtensionKind {
|
||||||
|
EK_NotExtended,
|
||||||
|
EK_SignExt,
|
||||||
|
EK_ZeroExt
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VariableGEPIndex {
|
||||||
|
const Value *V;
|
||||||
|
ExtensionKind Extension;
|
||||||
|
int64_t Scale;
|
||||||
|
|
||||||
|
bool operator==(const VariableGEPIndex &Other) const {
|
||||||
|
return V == Other.V && Extension == Other.Extension &&
|
||||||
|
Scale == Other.Scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const VariableGEPIndex &Other) const {
|
||||||
|
return !operator==(Other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// AliasCache - Track alias queries to guard against recursion.
|
||||||
|
typedef std::pair<MemoryLocation, MemoryLocation> LocPair;
|
||||||
|
typedef SmallDenseMap<LocPair, AliasResult, 8> AliasCacheTy;
|
||||||
|
AliasCacheTy AliasCache;
|
||||||
|
|
||||||
|
/// \brief Track phi nodes we have visited. When interpret "Value" pointer
|
||||||
|
/// equality as value equality we need to make sure that the "Value" is not
|
||||||
|
/// part of a cycle. Otherwise, two uses could come from different
|
||||||
|
/// "iterations" of a cycle and see different values for the same "Value"
|
||||||
|
/// pointer.
|
||||||
|
/// The following example shows the problem:
|
||||||
|
/// %p = phi(%alloca1, %addr2)
|
||||||
|
/// %l = load %ptr
|
||||||
|
/// %addr1 = gep, %alloca2, 0, %l
|
||||||
|
/// %addr2 = gep %alloca2, 0, (%l + 1)
|
||||||
|
/// alias(%p, %addr1) -> MayAlias !
|
||||||
|
/// store %l, ...
|
||||||
|
SmallPtrSet<const BasicBlock*, 8> VisitedPhiBBs;
|
||||||
|
|
||||||
|
// Visited - Track instructions visited by pointsToConstantMemory.
|
||||||
|
SmallPtrSet<const Value*, 16> Visited;
|
||||||
|
|
||||||
|
static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
|
||||||
|
ExtensionKind &Extension,
|
||||||
|
const DataLayout &DL, unsigned Depth,
|
||||||
|
AssumptionCache *AC, DominatorTree *DT);
|
||||||
|
|
||||||
|
static const Value *
|
||||||
|
DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
|
||||||
|
SmallVectorImpl<VariableGEPIndex> &VarIndices,
|
||||||
|
bool &MaxLookupReached, const DataLayout &DL,
|
||||||
|
AssumptionCache *AC, DominatorTree *DT);
|
||||||
|
|
||||||
|
/// \brief Check whether two Values can be considered equivalent.
|
||||||
|
///
|
||||||
|
/// In addition to pointer equivalence of \p V1 and \p V2 this checks
|
||||||
|
/// whether they can not be part of a cycle in the value graph by looking at
|
||||||
|
/// all 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 isValueEqualInPotentialCycles(const Value *V1, const Value *V2);
|
||||||
|
|
||||||
|
/// \brief Dest and Src are the variable indices from two decomposed
|
||||||
|
/// GetElementPtr instructions GEP1 and GEP2 which have common base
|
||||||
|
/// pointers. Subtract the GEP2 indices from GEP1 to find the symbolic
|
||||||
|
/// difference between the two pointers.
|
||||||
|
void GetIndexDifference(SmallVectorImpl<VariableGEPIndex> &Dest,
|
||||||
|
const SmallVectorImpl<VariableGEPIndex> &Src);
|
||||||
|
|
||||||
|
// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP
|
||||||
|
// instruction against another.
|
||||||
|
AliasResult aliasGEP(const GEPOperator *V1, uint64_t V1Size,
|
||||||
|
const AAMDNodes &V1AAInfo,
|
||||||
|
const Value *V2, uint64_t V2Size,
|
||||||
|
const AAMDNodes &V2AAInfo,
|
||||||
|
const Value *UnderlyingV1, const Value *UnderlyingV2);
|
||||||
|
|
||||||
|
// aliasPHI - Provide a bunch of ad-hoc rules to disambiguate a PHI
|
||||||
|
// instruction against another.
|
||||||
|
AliasResult aliasPHI(const PHINode *PN, uint64_t PNSize,
|
||||||
|
const AAMDNodes &PNAAInfo,
|
||||||
|
const Value *V2, uint64_t V2Size,
|
||||||
|
const AAMDNodes &V2AAInfo);
|
||||||
|
|
||||||
|
/// aliasSelect - Disambiguate a Select instruction against another value.
|
||||||
|
AliasResult aliasSelect(const SelectInst *SI, uint64_t SISize,
|
||||||
|
const AAMDNodes &SIAAInfo,
|
||||||
|
const Value *V2, uint64_t V2Size,
|
||||||
|
const AAMDNodes &V2AAInfo);
|
||||||
|
|
||||||
|
AliasResult aliasCheck(const Value *V1, uint64_t V1Size,
|
||||||
|
AAMDNodes V1AATag,
|
||||||
|
const Value *V2, uint64_t V2Size,
|
||||||
|
AAMDNodes V2AATag);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// createBasicAliasAnalysisPass - This pass implements the stateless alias
|
||||||
|
// analysis.
|
||||||
|
//
|
||||||
|
ImmutablePass *createBasicAliasAnalysisPass();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -57,13 +57,6 @@ namespace llvm {
|
|||||||
//
|
//
|
||||||
ImmutablePass *createNoAAPass();
|
ImmutablePass *createNoAAPass();
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// createBasicAliasAnalysisPass - This pass implements the stateless alias
|
|
||||||
// analysis.
|
|
||||||
//
|
|
||||||
ImmutablePass *createBasicAliasAnalysisPass();
|
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// createCFLAliasAnalysisPass - This pass implements a set-based approach to
|
// createCFLAliasAnalysisPass - This pass implements a set-based approach to
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/Analysis/AliasSetTracker.h"
|
#include "llvm/Analysis/AliasSetTracker.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/CallPrinter.h"
|
#include "llvm/Analysis/CallPrinter.h"
|
||||||
#include "llvm/Analysis/DomPrinter.h"
|
#include "llvm/Analysis/DomPrinter.h"
|
||||||
#include "llvm/Analysis/IntervalPartition.h"
|
#include "llvm/Analysis/IntervalPartition.h"
|
||||||
|
@ -13,25 +13,20 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/Analysis/AssumptionCache.h"
|
|
||||||
#include "llvm/Analysis/CFG.h"
|
#include "llvm/Analysis/CFG.h"
|
||||||
#include "llvm/Analysis/CaptureTracking.h"
|
#include "llvm/Analysis/CaptureTracking.h"
|
||||||
#include "llvm/Analysis/InstructionSimplify.h"
|
#include "llvm/Analysis/InstructionSimplify.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/Analysis/MemoryBuiltins.h"
|
#include "llvm/Analysis/MemoryBuiltins.h"
|
||||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
|
||||||
#include "llvm/Analysis/ValueTracking.h"
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/DataLayout.h"
|
#include "llvm/IR/DataLayout.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
#include "llvm/IR/Dominators.h"
|
#include "llvm/IR/Dominators.h"
|
||||||
#include "llvm/IR/Function.h"
|
|
||||||
#include "llvm/IR/GetElementPtrTypeIterator.h"
|
|
||||||
#include "llvm/IR/GlobalAlias.h"
|
#include "llvm/IR/GlobalAlias.h"
|
||||||
#include "llvm/IR/GlobalVariable.h"
|
#include "llvm/IR/GlobalVariable.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
@ -174,30 +169,6 @@ static bool isObjectSize(const Value *V, uint64_t Size,
|
|||||||
// GetElementPtr Instruction Decomposition and Analysis
|
// GetElementPtr Instruction Decomposition and Analysis
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
namespace {
|
|
||||||
enum ExtensionKind {
|
|
||||||
EK_NotExtended,
|
|
||||||
EK_SignExt,
|
|
||||||
EK_ZeroExt
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VariableGEPIndex {
|
|
||||||
const Value *V;
|
|
||||||
ExtensionKind Extension;
|
|
||||||
int64_t Scale;
|
|
||||||
|
|
||||||
bool operator==(const VariableGEPIndex &Other) const {
|
|
||||||
return V == Other.V && Extension == Other.Extension &&
|
|
||||||
Scale == Other.Scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const VariableGEPIndex &Other) const {
|
|
||||||
return !operator==(Other);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// GetLinearExpression - Analyze the specified value as a linear expression:
|
/// GetLinearExpression - Analyze the specified value as a linear expression:
|
||||||
/// "A*V + B", where A and B are constant integers. Return the scale and offset
|
/// "A*V + B", where A and B are constant integers. Return the scale and offset
|
||||||
/// values as APInts and return V as a Value*, and return whether we looked
|
/// values as APInts and return V as a Value*, and return whether we looked
|
||||||
@ -206,10 +177,10 @@ namespace {
|
|||||||
///
|
///
|
||||||
/// Note that this looks through extends, so the high bits may not be
|
/// Note that this looks through extends, so the high bits may not be
|
||||||
/// represented in the result.
|
/// represented in the result.
|
||||||
static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
|
/*static*/ Value *BasicAliasAnalysis::GetLinearExpression(
|
||||||
ExtensionKind &Extension,
|
Value *V, APInt &Scale, APInt &Offset, ExtensionKind &Extension,
|
||||||
const DataLayout &DL, unsigned Depth,
|
const DataLayout &DL, unsigned Depth, AssumptionCache *AC,
|
||||||
AssumptionCache *AC, DominatorTree *DT) {
|
DominatorTree *DT) {
|
||||||
assert(V->getType()->isIntegerTy() && "Not an integer value");
|
assert(V->getType()->isIntegerTy() && "Not an integer value");
|
||||||
|
|
||||||
// Limit our recursion depth.
|
// Limit our recursion depth.
|
||||||
@ -302,11 +273,10 @@ static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
|
|||||||
/// depth (MaxLookupSearchDepth).
|
/// depth (MaxLookupSearchDepth).
|
||||||
/// When DataLayout not is around, it just looks through pointer casts.
|
/// When DataLayout not is around, it just looks through pointer casts.
|
||||||
///
|
///
|
||||||
static const Value *
|
/*static*/ const Value *BasicAliasAnalysis::DecomposeGEPExpression(
|
||||||
DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
|
const Value *V, int64_t &BaseOffs,
|
||||||
SmallVectorImpl<VariableGEPIndex> &VarIndices,
|
SmallVectorImpl<VariableGEPIndex> &VarIndices, bool &MaxLookupReached,
|
||||||
bool &MaxLookupReached, const DataLayout &DL,
|
const DataLayout &DL, AssumptionCache *AC, DominatorTree *DT) {
|
||||||
AssumptionCache *AC, DominatorTree *DT) {
|
|
||||||
// Limit recursion depth to limit compile time in crazy cases.
|
// Limit recursion depth to limit compile time in crazy cases.
|
||||||
unsigned MaxLookup = MaxLookupSearchDepth;
|
unsigned MaxLookup = MaxLookupSearchDepth;
|
||||||
MaxLookupReached = false;
|
MaxLookupReached = false;
|
||||||
@ -438,158 +408,7 @@ DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
|
|||||||
// BasicAliasAnalysis Pass
|
// BasicAliasAnalysis Pass
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef NDEBUG
|
// Register the pass...
|
||||||
static const Function *getParent(const Value *V) {
|
|
||||||
if (const Instruction *inst = dyn_cast<Instruction>(V))
|
|
||||||
return inst->getParent()->getParent();
|
|
||||||
|
|
||||||
if (const Argument *arg = dyn_cast<Argument>(V))
|
|
||||||
return arg->getParent();
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool notDifferentParent(const Value *O1, const Value *O2) {
|
|
||||||
|
|
||||||
const Function *F1 = getParent(O1);
|
|
||||||
const Function *F2 = getParent(O2);
|
|
||||||
|
|
||||||
return !F1 || !F2 || F1 == F2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
/// BasicAliasAnalysis - This is the primary alias analysis implementation.
|
|
||||||
struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis {
|
|
||||||
static char ID; // Class identification, replacement for typeinfo
|
|
||||||
BasicAliasAnalysis() : ImmutablePass(ID) {
|
|
||||||
initializeBasicAliasAnalysisPass(*PassRegistry::getPassRegistry());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool doInitialization(Module &M) override;
|
|
||||||
|
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
||||||
AU.addRequired<AliasAnalysis>();
|
|
||||||
AU.addRequired<AssumptionCacheTracker>();
|
|
||||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
|
||||||
}
|
|
||||||
|
|
||||||
AliasResult alias(const MemoryLocation &LocA,
|
|
||||||
const MemoryLocation &LocB) override {
|
|
||||||
assert(AliasCache.empty() && "AliasCache must be cleared after use!");
|
|
||||||
assert(notDifferentParent(LocA.Ptr, LocB.Ptr) &&
|
|
||||||
"BasicAliasAnalysis doesn't support interprocedural queries.");
|
|
||||||
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
|
|
||||||
// shrink_and_clear so it quickly returns to the inline capacity of the
|
|
||||||
// SmallDenseMap if it ever grows larger.
|
|
||||||
// FIXME: This should really be shrink_to_inline_capacity_and_clear().
|
|
||||||
AliasCache.shrink_and_clear();
|
|
||||||
VisitedPhiBBs.clear();
|
|
||||||
return Alias;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModRefInfo getModRefInfo(ImmutableCallSite CS,
|
|
||||||
const MemoryLocation &Loc) override;
|
|
||||||
|
|
||||||
ModRefInfo getModRefInfo(ImmutableCallSite CS1,
|
|
||||||
ImmutableCallSite CS2) override;
|
|
||||||
|
|
||||||
/// pointsToConstantMemory - Chase pointers until we find a (constant
|
|
||||||
/// global) or not.
|
|
||||||
bool pointsToConstantMemory(const MemoryLocation &Loc,
|
|
||||||
bool OrLocal) override;
|
|
||||||
|
|
||||||
/// Get the location associated with a pointer argument of a callsite.
|
|
||||||
ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override;
|
|
||||||
|
|
||||||
/// getModRefBehavior - Return the behavior when calling the given
|
|
||||||
/// call site.
|
|
||||||
FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
|
|
||||||
|
|
||||||
/// getModRefBehavior - Return the behavior when calling the given function.
|
|
||||||
/// For use when the call site is not known.
|
|
||||||
FunctionModRefBehavior getModRefBehavior(const Function *F) 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(const void *ID) override {
|
|
||||||
if (ID == &AliasAnalysis::ID)
|
|
||||||
return (AliasAnalysis*)this;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// AliasCache - Track alias queries to guard against recursion.
|
|
||||||
typedef std::pair<MemoryLocation, MemoryLocation> LocPair;
|
|
||||||
typedef SmallDenseMap<LocPair, AliasResult, 8> AliasCacheTy;
|
|
||||||
AliasCacheTy AliasCache;
|
|
||||||
|
|
||||||
/// \brief Track phi nodes we have visited. When interpret "Value" pointer
|
|
||||||
/// equality as value equality we need to make sure that the "Value" is not
|
|
||||||
/// part of a cycle. Otherwise, two uses could come from different
|
|
||||||
/// "iterations" of a cycle and see different values for the same "Value"
|
|
||||||
/// pointer.
|
|
||||||
/// The following example shows the problem:
|
|
||||||
/// %p = phi(%alloca1, %addr2)
|
|
||||||
/// %l = load %ptr
|
|
||||||
/// %addr1 = gep, %alloca2, 0, %l
|
|
||||||
/// %addr2 = gep %alloca2, 0, (%l + 1)
|
|
||||||
/// alias(%p, %addr1) -> MayAlias !
|
|
||||||
/// store %l, ...
|
|
||||||
SmallPtrSet<const BasicBlock*, 8> VisitedPhiBBs;
|
|
||||||
|
|
||||||
// Visited - Track instructions visited by pointsToConstantMemory.
|
|
||||||
SmallPtrSet<const Value*, 16> Visited;
|
|
||||||
|
|
||||||
/// \brief Check whether two Values can be considered equivalent.
|
|
||||||
///
|
|
||||||
/// In addition to pointer equivalence of \p V1 and \p V2 this checks
|
|
||||||
/// whether they can not be part of a cycle in the value graph by looking at
|
|
||||||
/// all 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 isValueEqualInPotentialCycles(const Value *V1, const Value *V2);
|
|
||||||
|
|
||||||
/// \brief Dest and Src are the variable indices from two decomposed
|
|
||||||
/// GetElementPtr instructions GEP1 and GEP2 which have common base
|
|
||||||
/// pointers. Subtract the GEP2 indices from GEP1 to find the symbolic
|
|
||||||
/// difference between the two pointers.
|
|
||||||
void GetIndexDifference(SmallVectorImpl<VariableGEPIndex> &Dest,
|
|
||||||
const SmallVectorImpl<VariableGEPIndex> &Src);
|
|
||||||
|
|
||||||
// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP
|
|
||||||
// instruction against another.
|
|
||||||
AliasResult aliasGEP(const GEPOperator *V1, uint64_t V1Size,
|
|
||||||
const AAMDNodes &V1AAInfo,
|
|
||||||
const Value *V2, uint64_t V2Size,
|
|
||||||
const AAMDNodes &V2AAInfo,
|
|
||||||
const Value *UnderlyingV1, const Value *UnderlyingV2);
|
|
||||||
|
|
||||||
// aliasPHI - Provide a bunch of ad-hoc rules to disambiguate a PHI
|
|
||||||
// instruction against another.
|
|
||||||
AliasResult aliasPHI(const PHINode *PN, uint64_t PNSize,
|
|
||||||
const AAMDNodes &PNAAInfo,
|
|
||||||
const Value *V2, uint64_t V2Size,
|
|
||||||
const AAMDNodes &V2AAInfo);
|
|
||||||
|
|
||||||
/// aliasSelect - Disambiguate a Select instruction against another value.
|
|
||||||
AliasResult aliasSelect(const SelectInst *SI, uint64_t SISize,
|
|
||||||
const AAMDNodes &SIAAInfo,
|
|
||||||
const Value *V2, uint64_t V2Size,
|
|
||||||
const AAMDNodes &V2AAInfo);
|
|
||||||
|
|
||||||
AliasResult aliasCheck(const Value *V1, uint64_t V1Size,
|
|
||||||
AAMDNodes V1AATag,
|
|
||||||
const Value *V2, uint64_t V2Size,
|
|
||||||
AAMDNodes V2AATag);
|
|
||||||
};
|
|
||||||
} // End of anonymous namespace
|
|
||||||
|
|
||||||
// Register this pass...
|
|
||||||
char BasicAliasAnalysis::ID = 0;
|
char BasicAliasAnalysis::ID = 0;
|
||||||
INITIALIZE_AG_PASS_BEGIN(BasicAliasAnalysis, AliasAnalysis, "basicaa",
|
INITIALIZE_AG_PASS_BEGIN(BasicAliasAnalysis, AliasAnalysis, "basicaa",
|
||||||
"Basic Alias Analysis (stateless AA impl)",
|
"Basic Alias Analysis (stateless AA impl)",
|
||||||
@ -600,7 +419,6 @@ INITIALIZE_AG_PASS_END(BasicAliasAnalysis, AliasAnalysis, "basicaa",
|
|||||||
"Basic Alias Analysis (stateless AA impl)",
|
"Basic Alias Analysis (stateless AA impl)",
|
||||||
false, true, false)
|
false, true, false)
|
||||||
|
|
||||||
|
|
||||||
ImmutablePass *llvm::createBasicAliasAnalysisPass() {
|
ImmutablePass *llvm::createBasicAliasAnalysisPass() {
|
||||||
return new BasicAliasAnalysis();
|
return new BasicAliasAnalysis();
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
//===---------------------------------------------------------------------===//
|
//===---------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/CodeGen/Passes.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/Passes.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/CodeGen/RegAllocRegistry.h"
|
#include "llvm/CodeGen/RegAllocRegistry.h"
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "llvm/IR/LegacyPassManager.h"
|
#include "llvm/IR/LegacyPassManager.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Transforms/IPO.h"
|
#include "llvm/Transforms/IPO.h"
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm-c/Initialization.h"
|
#include "llvm-c/Initialization.h"
|
||||||
#include "llvm-c/Transforms/Scalar.h"
|
#include "llvm-c/Transforms/Scalar.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/Passes.h"
|
||||||
#include "llvm/IR/DataLayout.h"
|
#include "llvm/IR/DataLayout.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/Passes.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user