//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/Passes.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryBuiltins.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include <algorithm>
using namespace llvm;
+/// Enable analysis of recursive PHI nodes.
+static cl::opt<bool> EnableRecPhiAnalysis("basicaa-recphi", cl::Hidden,
+ cl::init(false));
+
+/// SearchLimitReached / SearchTimes shows how often the limit of
+/// to decompose GEPs is reached. It will affect the precision
+/// of basic alias analysis.
+#define DEBUG_TYPE "basicaa"
+STATISTIC(SearchLimitReached, "Number of times the limit to "
+ "decompose GEPs is reached");
+STATISTIC(SearchTimes, "Number of times a GEP is decomposed");
+
/// Cutoff after which to stop analysing a set of phi nodes potentially involved
/// in a cycle. Because we are analysing 'through' phi nodes we need to be
/// careful with value equivalence. We use reachability to make sure a value
// Useful predicates
//===----------------------------------------------------------------------===//
-/// isNonEscapingLocalObject - Return true if the pointer is to a function-local
-/// object that never escapes from the function.
+/// Returns true if the pointer is to a function-local object that never
+/// escapes from the function.
static bool isNonEscapingLocalObject(const Value *V) {
// If this is a local allocation, check to see if it escapes.
if (isa<AllocaInst>(V) || isNoAliasCall(V))
return false;
}
-/// isEscapeSource - Return true if the pointer is one which would have
-/// been considered an escape by isNonEscapingLocalObject.
+/// Returns true if the pointer is one which would have been considered an
+/// escape by isNonEscapingLocalObject.
static bool isEscapeSource(const Value *V) {
if (isa<CallInst>(V) || isa<InvokeInst>(V) || isa<Argument>(V))
return true;
return false;
}
-/// getObjectSize - Return the size of the object specified by V, or
-/// UnknownSize if unknown.
+/// Returns the size of the object specified by V, or UnknownSize if unknown.
static uint64_t getObjectSize(const Value *V, const DataLayout &DL,
const TargetLibraryInfo &TLI,
bool RoundToAlign = false) {
return MemoryLocation::UnknownSize;
}
-/// isObjectSmallerThan - Return true if we can prove that the object specified
-/// by V is smaller than Size.
+/// Returns true if we can prove that the object specified by V is smaller than
+/// Size.
static bool isObjectSmallerThan(const Value *V, uint64_t Size,
const DataLayout &DL,
const TargetLibraryInfo &TLI) {
// This function needs to use the aligned object size because we allow
// reads a bit past the end given sufficient alignment.
- uint64_t ObjectSize = getObjectSize(V, DL, TLI, /*RoundToAlign*/true);
+ uint64_t ObjectSize = getObjectSize(V, DL, TLI, /*RoundToAlign*/ true);
return ObjectSize != MemoryLocation::UnknownSize && ObjectSize < Size;
}
-/// isObjectSize - Return true if we can prove that the object specified
-/// by V has size Size.
-static bool isObjectSize(const Value *V, uint64_t Size,
- const DataLayout &DL, const TargetLibraryInfo &TLI) {
+/// Returns true if we can prove that the object specified by V has size Size.
+static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL,
+ const TargetLibraryInfo &TLI) {
uint64_t ObjectSize = getObjectSize(V, DL, TLI);
return ObjectSize != MemoryLocation::UnknownSize && ObjectSize == Size;
}
// 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);
- }
- };
-} // namespace
-
-
-/// GetLinearExpression - Analyze the specified value as a linear expression:
-/// "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
-/// through any sign or zero extends. The incoming Value is known to have
-/// IntegerType and it may already be sign or zero extended.
+/// Analyzes the specified value as a linear expression: "A*V + B", where A and
+/// B are constant integers.
+///
+/// Returns the scale and offset values as APInts and return V as a Value*, and
+/// return whether we looked through any sign or zero extends. The incoming
+/// Value is known to have IntegerType and it may already be sign or zero
+/// extended.
///
/// Note that this looks through extends, so the high bits may not be
/// represented in the result.
-static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
- ExtensionKind &Extension,
- const DataLayout &DL, unsigned Depth,
- AssumptionCache *AC, DominatorTree *DT) {
+/*static*/ Value *BasicAliasAnalysis::GetLinearExpression(
+ Value *V, APInt &Scale, APInt &Offset, ExtensionKind &Extension,
+ const DataLayout &DL, unsigned Depth, AssumptionCache *AC,
+ DominatorTree *DT) {
assert(V->getType()->isIntegerTy() && "Not an integer value");
// Limit our recursion depth.
if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(V)) {
if (ConstantInt *RHSC = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
switch (BOp->getOpcode()) {
- default: break;
+ default:
+ break;
case Instruction::Or:
// X|C == X+C if all the bits in C are unset in X. Otherwise we can't
// analyze it.
if (!MaskedValueIsZero(BOp->getOperand(0), RHSC->getValue(), DL, 0, AC,
BOp, DT))
break;
- // FALL THROUGH.
+ // FALL THROUGH.
case Instruction::Add:
V = GetLinearExpression(BOp->getOperand(0), Scale, Offset, Extension,
DL, Depth + 1, AC, DT);
return V;
}
-/// DecomposeGEPExpression - If V is a symbolic pointer expression, decompose it
-/// into a base pointer with a constant offset and a number of scaled symbolic
-/// offsets.
+/// If V is a symbolic pointer expression, decompose it into a base pointer
+/// with a constant offset and a number of scaled symbolic offsets.
///
-/// The scaled symbolic offsets (represented by pairs of a Value* and a scale in
-/// the VarIndices vector) are Value*'s that are known to be scaled by the
-/// specified amount, but which may have other unrepresented high bits. As such,
-/// the gep cannot necessarily be reconstructed from its decomposed form.
+/// The scaled symbolic offsets (represented by pairs of a Value* and a scale
+/// in the VarIndices vector) are Value*'s that are known to be scaled by the
+/// specified amount, but which may have other unrepresented high bits. As
+/// such, the gep cannot necessarily be reconstructed from its decomposed form.
///
/// When DataLayout is around, this function is capable of analyzing everything
/// that GetUnderlyingObject can look through. To be able to do that
/// GetUnderlyingObject and DecomposeGEPExpression must use the same search
-/// depth (MaxLookupSearchDepth).
-/// When DataLayout not is around, it just looks through pointer casts.
-///
-static const Value *
-DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
- SmallVectorImpl<VariableGEPIndex> &VarIndices,
- bool &MaxLookupReached, const DataLayout &DL,
- AssumptionCache *AC, DominatorTree *DT) {
+/// depth (MaxLookupSearchDepth). When DataLayout not is around, it just looks
+/// through pointer casts.
+/*static*/ const Value *BasicAliasAnalysis::DecomposeGEPExpression(
+ const Value *V, int64_t &BaseOffs,
+ SmallVectorImpl<VariableGEPIndex> &VarIndices, bool &MaxLookupReached,
+ const DataLayout &DL, AssumptionCache *AC, DominatorTree *DT) {
// Limit recursion depth to limit compile time in crazy cases.
unsigned MaxLookup = MaxLookupSearchDepth;
MaxLookupReached = false;
+ SearchTimes++;
BaseOffs = 0;
do {
// updated when GetUnderlyingObject is updated). TLI should be
// provided also.
if (const Value *Simplified =
- SimplifyInstruction(const_cast<Instruction *>(I), DL)) {
+ SimplifyInstruction(const_cast<Instruction *>(I), DL)) {
V = Simplified;
continue;
}
unsigned AS = GEPOp->getPointerAddressSpace();
// Walk the indices of the GEP, accumulating them into BaseOff/VarIndices.
gep_type_iterator GTI = gep_type_begin(GEPOp);
- for (User::const_op_iterator I = GEPOp->op_begin()+1,
- E = GEPOp->op_end(); I != E; ++I) {
+ for (User::const_op_iterator I = GEPOp->op_begin() + 1, E = GEPOp->op_end();
+ I != E; ++I) {
Value *Index = *I;
// Compute the (potentially symbolic) offset in bytes for this index.
if (StructType *STy = dyn_cast<StructType>(*GTI++)) {
// For a struct, add the member offset.
unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();
- if (FieldNo == 0) continue;
+ if (FieldNo == 0)
+ continue;
BaseOffs += DL.getStructLayout(STy)->getElementOffset(FieldNo);
continue;
// For an array/pointer, add the element offset, explicitly scaled.
if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Index)) {
- if (CIdx->isZero()) continue;
+ if (CIdx->isZero())
+ continue;
BaseOffs += DL.getTypeAllocSize(*GTI) * CIdx->getSExtValue();
continue;
}
// The GEP index scale ("Scale") scales C1*V+C2, yielding (C1*V+C2)*Scale.
// This gives us an aggregate computation of (C1*Scale)*V + C2*Scale.
- BaseOffs += IndexOffset.getSExtValue()*Scale;
+ BaseOffs += IndexOffset.getSExtValue() * Scale;
Scale *= IndexScale.getSExtValue();
// If we already had an occurrence of this index variable, merge this
// A[x][x] -> x*16 + x*4 -> x*20
// This also ensures that 'x' only appears in the index list once.
for (unsigned i = 0, e = VarIndices.size(); i != e; ++i) {
- if (VarIndices[i].V == Index &&
- VarIndices[i].Extension == Extension) {
+ if (VarIndices[i].V == Index && VarIndices[i].Extension == Extension) {
Scale += VarIndices[i].Scale;
- VarIndices.erase(VarIndices.begin()+i);
+ VarIndices.erase(VarIndices.begin() + i);
break;
}
}
// If the chain of expressions is too deep, just return early.
MaxLookupReached = true;
+ SearchLimitReached++;
return V;
}
// BasicAliasAnalysis Pass
//===----------------------------------------------------------------------===//
-#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
-
-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;
- }
-
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
-
- ModRefResult 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.
- ModRefResult getArgModRefInfo(ImmutableCallSite CS,
- unsigned ArgIdx) override;
-
- /// getModRefBehavior - Return the behavior when calling the given
- /// call site.
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
-
- /// getModRefBehavior - Return the behavior when calling the given function.
- /// For use when the call site is not known.
- ModRefBehavior 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...
+// Register the pass...
char BasicAliasAnalysis::ID = 0;
INITIALIZE_AG_PASS_BEGIN(BasicAliasAnalysis, AliasAnalysis, "basicaa",
- "Basic Alias Analysis (stateless AA impl)",
- false, true, false)
+ "Basic Alias Analysis (stateless AA impl)", false,
+ true, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_AG_PASS_END(BasicAliasAnalysis, AliasAnalysis, "basicaa",
- "Basic Alias Analysis (stateless AA impl)",
- false, true, false)
-
+ "Basic Alias Analysis (stateless AA impl)", false, true,
+ false)
ImmutablePass *llvm::createBasicAliasAnalysisPass() {
return new BasicAliasAnalysis();
}
-/// pointsToConstantMemory - Returns whether the given pointer value
-/// points to memory that is local to the function, with global constants being
-/// considered local to all functions.
+/// Returns whether the given pointer value points to memory that is local to
+/// the function, with global constants being considered local to all
+/// functions.
bool BasicAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) {
assert(Visited.empty() && "Visited must be cleared after use!");
return false;
}
-/// getModRefBehavior - Return the behavior when calling the given call site.
-AliasAnalysis::ModRefBehavior
+/// Returns the behavior when calling the given call site.
+FunctionModRefBehavior
BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
if (CS.doesNotAccessMemory())
// Can't do better than this.
- return DoesNotAccessMemory;
+ return FMRB_DoesNotAccessMemory;
- ModRefBehavior Min = UnknownModRefBehavior;
+ FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
// If the callsite knows it only reads memory, don't return worse
// than that.
if (CS.onlyReadsMemory())
- Min = OnlyReadsMemory;
+ Min = FMRB_OnlyReadsMemory;
+
+ if (CS.onlyAccessesArgMemory())
+ Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
// The AliasAnalysis base class has some smarts, lets use them.
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
+ return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
}
-/// getModRefBehavior - Return the behavior when calling the given function.
-/// For use when the call site is not known.
-AliasAnalysis::ModRefBehavior
+/// Returns the behavior when calling the given function. For use when the call
+/// site is not known.
+FunctionModRefBehavior
BasicAliasAnalysis::getModRefBehavior(const Function *F) {
// If the function declares it doesn't access memory, we can't do better.
if (F->doesNotAccessMemory())
- return DoesNotAccessMemory;
+ return FMRB_DoesNotAccessMemory;
- // For intrinsics, we can check the table.
- if (Intrinsic::ID iid = F->getIntrinsicID()) {
-#define GET_INTRINSIC_MODREF_BEHAVIOR
-#include "llvm/IR/Intrinsics.gen"
-#undef GET_INTRINSIC_MODREF_BEHAVIOR
- }
-
- ModRefBehavior Min = UnknownModRefBehavior;
+ FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
// If the function declares it only reads memory, go with that.
if (F->onlyReadsMemory())
- Min = OnlyReadsMemory;
+ Min = FMRB_OnlyReadsMemory;
+
+ if (F->onlyAccessesArgMemory())
+ Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
const TargetLibraryInfo &TLI =
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
if (isMemsetPattern16(F, TLI))
- Min = OnlyAccessesArgumentPointees;
+ Min = FMRB_OnlyAccessesArgumentPointees;
// Otherwise be conservative.
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
+ return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
}
-AliasAnalysis::ModRefResult
-BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
+ModRefInfo BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS,
+ unsigned ArgIdx) {
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction()))
switch (II->getIntrinsicID()) {
default:
case Intrinsic::memmove:
assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memory intrinsic");
- return ArgIdx ? Ref : Mod;
+ return ArgIdx ? MRI_Ref : MRI_Mod;
}
// We can bound the aliasing properties of memset_pattern16 just as we can
isMemsetPattern16(CS.getCalledFunction(), *TLI)) {
assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memset_pattern16");
- return ArgIdx ? Ref : Mod;
+ return ArgIdx ? MRI_Ref : MRI_Mod;
}
// FIXME: Handle memset_pattern4 and memset_pattern8 also.
return true;
}
-/// getModRefInfo - Check to see if the specified callsite can clobber the
-/// specified memory object. Since we only look at local properties of this
-/// function, we really can't say much about this query. We do, however, use
-/// simple "address taken" analysis on local objects.
-AliasAnalysis::ModRefResult
-BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) {
+/// Checks to see if the specified callsite can clobber the specified memory
+/// object.
+///
+/// Since we only look at local properties of this function, we really can't
+/// say much about this query. We do, however, use simple "address taken"
+/// analysis on local objects.
+ModRefInfo BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
assert(notDifferentParent(CS.getInstruction(), Loc.Ptr) &&
"AliasAnalysis query involving multiple functions!");
if (isa<AllocaInst>(Object))
if (const CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
if (CI->isTailCall())
- return NoModRef;
+ return MRI_NoModRef;
// If the pointer is to a locally allocated object that does not escape,
// then the call can not mod/ref the pointer unless the call takes the pointer
}
if (!PassedAsArg)
- return NoModRef;
+ return MRI_NoModRef;
}
// While the assume intrinsic is marked as arbitrarily writing so that
// proper control dependencies will be maintained, it never aliases any
// particular memory location.
if (isAssumeIntrinsic(CS))
- return NoModRef;
+ return MRI_NoModRef;
// The AliasAnalysis base class has some smarts, lets use them.
return AliasAnalysis::getModRefInfo(CS, Loc);
}
-AliasAnalysis::ModRefResult
-BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) {
+ModRefInfo BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
// While the assume intrinsic is marked as arbitrarily writing so that
// proper control dependencies will be maintained, it never aliases any
// particular memory location.
if (isAssumeIntrinsic(CS1) || isAssumeIntrinsic(CS2))
- return NoModRef;
+ return MRI_NoModRef;
// The AliasAnalysis base class has some smarts, lets use them.
return AliasAnalysis::getModRefInfo(CS1, CS2);
}
-/// \brief Provide ad-hoc rules to disambiguate accesses through two GEP
-/// operators, both having the exact same pointer operand.
-static AliasAnalysis::AliasResult
-aliasSameBasePointerGEPs(const GEPOperator *GEP1, uint64_t V1Size,
- const GEPOperator *GEP2, uint64_t V2Size,
- const DataLayout &DL) {
+/// Provide ad-hoc rules to disambiguate accesses through two GEP operators,
+/// both having the exact same pointer operand.
+static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1,
+ uint64_t V1Size,
+ const GEPOperator *GEP2,
+ uint64_t V2Size,
+ const DataLayout &DL) {
assert(GEP1->getPointerOperand() == GEP2->getPointerOperand() &&
"Expected GEPs with the same pointer operand");
// We also need at least two indices (the pointer, and the struct field).
if (GEP1->getNumIndices() != GEP2->getNumIndices() ||
GEP1->getNumIndices() < 2)
- return AliasAnalysis::MayAlias;
+ return MayAlias;
// If we don't know the size of the accesses through both GEPs, we can't
// determine whether the struct fields accessed can't alias.
if (V1Size == MemoryLocation::UnknownSize ||
V2Size == MemoryLocation::UnknownSize)
- return AliasAnalysis::MayAlias;
+ return MayAlias;
ConstantInt *C1 =
dyn_cast<ConstantInt>(GEP1->getOperand(GEP1->getNumOperands() - 1));
// If they're identical, the other indices might be also be dynamically
// equal, so the GEPs can alias.
if (!C1 || !C2 || C1 == C2)
- return AliasAnalysis::MayAlias;
+ return MayAlias;
// Find the last-indexed type of the GEP, i.e., the type you'd get if
// you stripped the last index.
for (unsigned i = 1, e = GEP1->getNumIndices() - 1; i != e; ++i) {
if (!isa<ArrayType>(GetElementPtrInst::getIndexedType(
GEP1->getSourceElementType(), IntermediateIndices)))
- return AliasAnalysis::MayAlias;
+ return MayAlias;
IntermediateIndices.push_back(GEP1->getOperand(i + 1));
}
GEP1->getSourceElementType(), IntermediateIndices));
if (!LastIndexedStruct)
- return AliasAnalysis::MayAlias;
+ return MayAlias;
// We know that:
// - both GEPs begin indexing from the exact same pointer;
if (EltsDontOverlap(V1Off, V1Size, V2Off, V2Size) ||
EltsDontOverlap(V2Off, V2Size, V1Off, V1Size))
- return AliasAnalysis::NoAlias;
+ return NoAlias;
- return AliasAnalysis::MayAlias;
+ return MayAlias;
}
-/// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction
-/// against another pointer. We know that V1 is a GEP, but we don't know
-/// anything about V2. UnderlyingV1 is GetUnderlyingObject(GEP1, DL),
-/// UnderlyingV2 is the same for V2.
+/// Provides a bunch of ad-hoc rules to disambiguate a GEP instruction against
+/// another pointer.
///
-AliasAnalysis::AliasResult
-BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
- const AAMDNodes &V1AAInfo,
- const Value *V2, uint64_t V2Size,
- const AAMDNodes &V2AAInfo,
- const Value *UnderlyingV1,
- const Value *UnderlyingV2) {
+/// We know that V1 is a GEP, but we don't know anything about V2.
+/// UnderlyingV1 is GetUnderlyingObject(GEP1, DL), UnderlyingV2 is the same for
+/// V2.
+AliasResult BasicAliasAnalysis::aliasGEP(
+ const GEPOperator *GEP1, uint64_t V1Size, const AAMDNodes &V1AAInfo,
+ const Value *V2, uint64_t V2Size, const AAMDNodes &V2AAInfo,
+ const Value *UnderlyingV1, const Value *UnderlyingV2) {
int64_t GEP1BaseOffset;
bool GEP1MaxLookupReached;
SmallVector<VariableGEPIndex, 4> GEP1VariableIndices;
// identical.
if ((BaseAlias == MayAlias) && V1Size == V2Size) {
// Do the base pointers alias assuming type and size.
- AliasResult PreciseBaseAlias = aliasCheck(UnderlyingV1, V1Size,
- V1AAInfo, UnderlyingV2,
- V2Size, V2AAInfo);
+ AliasResult PreciseBaseAlias = aliasCheck(UnderlyingV1, V1Size, V1AAInfo,
+ UnderlyingV2, V2Size, V2AAInfo);
if (PreciseBaseAlias == NoAlias) {
// See if the computed offset from the common pointer tells us about the
// relation of the resulting pointer.
// If we get a No or May, then return it immediately, no amount of analysis
// will improve this situation.
- if (BaseAlias != MustAlias) return BaseAlias;
+ if (BaseAlias != MustAlias)
+ return BaseAlias;
// Otherwise, we have a MustAlias. Since the base pointers alias each other
// exactly, see if the computed offset from the common pointer tells us
// DecomposeGEPExpression and GetUnderlyingObject should return the
// same result except when DecomposeGEPExpression has no DataLayout.
if (GEP1BasePtr != UnderlyingV1 || GEP2BasePtr != UnderlyingV2) {
- assert(!DL &&
- "DecomposeGEPExpression and GetUnderlyingObject disagree!");
+ assert(!DL && "DecomposeGEPExpression and GetUnderlyingObject disagree!");
return MayAlias;
}
// DecomposeGEPExpression and GetUnderlyingObject should return the
// same result except when DecomposeGEPExpression has no DataLayout.
if (GEP1BasePtr != UnderlyingV1) {
- assert(!DL &&
- "DecomposeGEPExpression and GetUnderlyingObject disagree!");
+ assert(!DL && "DecomposeGEPExpression and GetUnderlyingObject disagree!");
return MayAlias;
}
// If the max search depth is reached the result is undefined
// Grab the least significant bit set in any of the scales. We
// don't need std::abs here (even if the scale's negative) as we'll
// be ^'ing Modulo with itself later.
- Modulo |= (uint64_t) GEP1VariableIndices[i].Scale;
+ Modulo |= (uint64_t)GEP1VariableIndices[i].Scale;
if (AllPositive) {
// If the Value could change between cycles, then any reasoning about
// unsigned.
int64_t Scale = GEP1VariableIndices[i].Scale;
AllPositive =
- (SignKnownZero && Scale >= 0) ||
- (SignKnownOne && Scale < 0);
+ (SignKnownZero && Scale >= 0) || (SignKnownOne && Scale < 0);
}
}
// If we know all the variables are positive, then GEP1 >= GEP1BasePtr.
// If GEP1BasePtr > V2 (GEP1BaseOffset > 0) then we know the pointers
// don't alias if V2Size can fit in the gap between V2 and GEP1BasePtr.
- if (AllPositive && GEP1BaseOffset > 0 && V2Size <= (uint64_t) GEP1BaseOffset)
+ if (AllPositive && GEP1BaseOffset > 0 && V2Size <= (uint64_t)GEP1BaseOffset)
return NoAlias;
}
return PartialAlias;
}
-static AliasAnalysis::AliasResult
-MergeAliasResults(AliasAnalysis::AliasResult A, AliasAnalysis::AliasResult B) {
+static AliasResult MergeAliasResults(AliasResult A, AliasResult B) {
// If the results agree, take it.
if (A == B)
return A;
// A mix of PartialAlias and MustAlias is PartialAlias.
- if ((A == AliasAnalysis::PartialAlias && B == AliasAnalysis::MustAlias) ||
- (B == AliasAnalysis::PartialAlias && A == AliasAnalysis::MustAlias))
- return AliasAnalysis::PartialAlias;
+ if ((A == PartialAlias && B == MustAlias) ||
+ (B == PartialAlias && A == MustAlias))
+ return PartialAlias;
// Otherwise, we don't know anything.
- return AliasAnalysis::MayAlias;
+ return MayAlias;
}
-/// aliasSelect - Provide a bunch of ad-hoc rules to disambiguate a Select
-/// instruction against another.
-AliasAnalysis::AliasResult
-BasicAliasAnalysis::aliasSelect(const SelectInst *SI, uint64_t SISize,
- const AAMDNodes &SIAAInfo,
- const Value *V2, uint64_t V2Size,
- const AAMDNodes &V2AAInfo) {
+/// Provides a bunch of ad-hoc rules to disambiguate a Select instruction
+/// against another.
+AliasResult BasicAliasAnalysis::aliasSelect(const SelectInst *SI,
+ uint64_t SISize,
+ const AAMDNodes &SIAAInfo,
+ const Value *V2, uint64_t V2Size,
+ const AAMDNodes &V2AAInfo) {
// If the values are Selects with the same condition, we can do a more precise
// check: just check for aliases between the values on corresponding arms.
if (const SelectInst *SI2 = dyn_cast<SelectInst>(V2))
if (SI->getCondition() == SI2->getCondition()) {
- AliasResult Alias =
- aliasCheck(SI->getTrueValue(), SISize, SIAAInfo,
- SI2->getTrueValue(), V2Size, V2AAInfo);
+ AliasResult Alias = aliasCheck(SI->getTrueValue(), SISize, SIAAInfo,
+ SI2->getTrueValue(), V2Size, V2AAInfo);
if (Alias == MayAlias)
return MayAlias;
AliasResult ThisAlias =
- aliasCheck(SI->getFalseValue(), SISize, SIAAInfo,
- SI2->getFalseValue(), V2Size, V2AAInfo);
+ aliasCheck(SI->getFalseValue(), SISize, SIAAInfo,
+ SI2->getFalseValue(), V2Size, V2AAInfo);
return MergeAliasResults(ThisAlias, Alias);
}
// If both arms of the Select node NoAlias or MustAlias V2, then returns
// NoAlias / MustAlias. Otherwise, returns MayAlias.
AliasResult Alias =
- aliasCheck(V2, V2Size, V2AAInfo, SI->getTrueValue(), SISize, SIAAInfo);
+ aliasCheck(V2, V2Size, V2AAInfo, SI->getTrueValue(), SISize, SIAAInfo);
if (Alias == MayAlias)
return MayAlias;
AliasResult ThisAlias =
- aliasCheck(V2, V2Size, V2AAInfo, SI->getFalseValue(), SISize, SIAAInfo);
+ aliasCheck(V2, V2Size, V2AAInfo, SI->getFalseValue(), SISize, SIAAInfo);
return MergeAliasResults(ThisAlias, Alias);
}
-// aliasPHI - Provide a bunch of ad-hoc rules to disambiguate a PHI instruction
-// against another.
-AliasAnalysis::AliasResult
-BasicAliasAnalysis::aliasPHI(const PHINode *PN, uint64_t PNSize,
- const AAMDNodes &PNAAInfo,
- const Value *V2, uint64_t V2Size,
- const AAMDNodes &V2AAInfo) {
+/// Provide a bunch of ad-hoc rules to disambiguate a PHI instruction against
+/// another.
+AliasResult BasicAliasAnalysis::aliasPHI(const PHINode *PN, uint64_t PNSize,
+ const AAMDNodes &PNAAInfo,
+ const Value *V2, uint64_t V2Size,
+ const AAMDNodes &V2AAInfo) {
// Track phi nodes we have visited. We use this information when we determine
// value equivalence.
VisitedPhiBBs.insert(PN->getParent());
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
AliasResult ThisAlias =
- aliasCheck(PN->getIncomingValue(i), PNSize, PNAAInfo,
- PN2->getIncomingValueForBlock(PN->getIncomingBlock(i)),
- V2Size, V2AAInfo);
+ aliasCheck(PN->getIncomingValue(i), PNSize, PNAAInfo,
+ PN2->getIncomingValueForBlock(PN->getIncomingBlock(i)),
+ V2Size, V2AAInfo);
Alias = MergeAliasResults(ThisAlias, Alias);
if (Alias == MayAlias)
break;
return Alias;
}
- SmallPtrSet<Value*, 4> UniqueSrc;
- SmallVector<Value*, 4> V1Srcs;
+ SmallPtrSet<Value *, 4> UniqueSrc;
+ SmallVector<Value *, 4> V1Srcs;
+ bool isRecursive = false;
for (Value *PV1 : PN->incoming_values()) {
if (isa<PHINode>(PV1))
// If any of the source itself is a PHI, return MayAlias conservatively
// sides are PHI nodes. In which case, this is O(m x n) time where 'm'
// and 'n' are the number of PHI sources.
return MayAlias;
+
+ if (EnableRecPhiAnalysis)
+ if (GEPOperator *PV1GEP = dyn_cast<GEPOperator>(PV1)) {
+ // Check whether the incoming value is a GEP that advances the pointer
+ // result of this PHI node (e.g. in a loop). If this is the case, we
+ // would recurse and always get a MayAlias. Handle this case specially
+ // below.
+ if (PV1GEP->getPointerOperand() == PN && PV1GEP->getNumIndices() == 1 &&
+ isa<ConstantInt>(PV1GEP->idx_begin())) {
+ isRecursive = true;
+ continue;
+ }
+ }
+
if (UniqueSrc.insert(PV1).second)
V1Srcs.push_back(PV1);
}
- AliasResult Alias = aliasCheck(V2, V2Size, V2AAInfo,
- V1Srcs[0], PNSize, PNAAInfo);
+ // If this PHI node is recursive, set the size of the accessed memory to
+ // unknown to represent all the possible values the GEP could advance the
+ // pointer to.
+ if (isRecursive)
+ PNSize = MemoryLocation::UnknownSize;
+
+ AliasResult Alias =
+ aliasCheck(V2, V2Size, V2AAInfo, V1Srcs[0], PNSize, PNAAInfo);
+
// Early exit if the check of the first PHI source against V2 is MayAlias.
// Other results are not possible.
if (Alias == MayAlias)
for (unsigned i = 1, e = V1Srcs.size(); i != e; ++i) {
Value *V = V1Srcs[i];
- AliasResult ThisAlias = aliasCheck(V2, V2Size, V2AAInfo,
- V, PNSize, PNAAInfo);
+ AliasResult ThisAlias =
+ aliasCheck(V2, V2Size, V2AAInfo, V, PNSize, PNAAInfo);
Alias = MergeAliasResults(ThisAlias, Alias);
if (Alias == MayAlias)
break;
return Alias;
}
-// aliasCheck - Provide a bunch of ad-hoc rules to disambiguate in common cases,
-// such as array references.
-//
-AliasAnalysis::AliasResult
-BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size,
- AAMDNodes V1AAInfo,
- const Value *V2, uint64_t V2Size,
- AAMDNodes V2AAInfo) {
+/// Provideis a bunch of ad-hoc rules to disambiguate in common cases, such as
+/// array references.
+AliasResult BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size,
+ AAMDNodes V1AAInfo, const Value *V2,
+ uint64_t V2Size,
+ AAMDNodes V2AAInfo) {
// If either of the memory references is empty, it doesn't matter what the
// pointer values are.
if (V1Size == 0 || V2Size == 0)
return MustAlias;
if (!V1->getType()->isPointerTy() || !V2->getType()->isPointerTy())
- return NoAlias; // Scalars cannot alias each other
+ return NoAlias; // Scalars cannot alias each other
// Figure out what objects these things are pointing to if we can.
const Value *O1 = GetUnderlyingObject(V1, *DL, MaxLookupSearchDepth);
if (V1 > V2)
std::swap(Locs.first, Locs.second);
std::pair<AliasCacheTy::iterator, bool> Pair =
- AliasCache.insert(std::make_pair(Locs, MayAlias));
+ AliasCache.insert(std::make_pair(Locs, MayAlias));
if (!Pair.second)
return Pair.first->second;
std::swap(V1AAInfo, V2AAInfo);
}
if (const GEPOperator *GV1 = dyn_cast<GEPOperator>(V1)) {
- AliasResult Result = aliasGEP(GV1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O1, O2);
- if (Result != MayAlias) return AliasCache[Locs] = Result;
+ AliasResult Result =
+ aliasGEP(GV1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O1, O2);
+ if (Result != MayAlias)
+ return AliasCache[Locs] = Result;
}
if (isa<PHINode>(V2) && !isa<PHINode>(V1)) {
std::swap(V1AAInfo, V2AAInfo);
}
if (const PHINode *PN = dyn_cast<PHINode>(V1)) {
- AliasResult Result = aliasPHI(PN, V1Size, V1AAInfo,
- V2, V2Size, V2AAInfo);
- if (Result != MayAlias) return AliasCache[Locs] = Result;
+ AliasResult Result = aliasPHI(PN, V1Size, V1AAInfo, V2, V2Size, V2AAInfo);
+ if (Result != MayAlias)
+ return AliasCache[Locs] = Result;
}
if (isa<SelectInst>(V2) && !isa<SelectInst>(V1)) {
std::swap(V1AAInfo, V2AAInfo);
}
if (const SelectInst *S1 = dyn_cast<SelectInst>(V1)) {
- AliasResult Result = aliasSelect(S1, V1Size, V1AAInfo,
- V2, V2Size, V2AAInfo);
- if (Result != MayAlias) return AliasCache[Locs] = Result;
+ AliasResult Result =
+ aliasSelect(S1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo);
+ if (Result != MayAlias)
+ return AliasCache[Locs] = Result;
}
// If both pointers are pointing into the same object and one of them
return AliasCache[Locs] = Result;
}
+/// 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 BasicAliasAnalysis::isValueEqualInPotentialCycles(const Value *V,
const Value *V2) {
if (V != V2)
return true;
}
-/// GetIndexDifference - 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.
+/// Computes the symbolic difference between two de-composed GEPs.
+///
+/// Dest and Src are the variable indices from two decomposed GetElementPtr
+/// instructions GEP1 and GEP2 which have common base pointers.
void BasicAliasAnalysis::GetIndexDifference(
SmallVectorImpl<VariableGEPIndex> &Dest,
const SmallVectorImpl<VariableGEPIndex> &Src) {
// If we didn't consume this entry, add it to the end of the Dest list.
if (Scale) {
- VariableGEPIndex Entry = { V, Extension, -Scale };
+ VariableGEPIndex Entry = {V, Extension, -Scale};
Dest.push_back(Entry);
}
}