#include <algorithm>
using namespace llvm;
+/// Enable analysis of recursive PHI nodes.
+static cl::opt<bool> EnableRecPhiAnalysis("basicaa-recphi",
+ cl::Hidden, cl::init(false));
+
/// 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
return !operator==(Other);
}
};
-} // namespace
+}
/// GetLinearExpression - Analyze the specified value as a linear expression:
return Alias;
}
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override;
/// pointsToConstantMemory - Chase pointers until we find a (constant
/// global) or not.
bool OrLocal) override;
/// Get the location associated with a pointer argument of a callsite.
- ModRefResult getArgModRefInfo(ImmutableCallSite CS,
- unsigned ArgIdx) override;
+ ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override;
/// getModRefBehavior - Return the behavior when calling the given
/// call site.
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
+ FunctionModRefBehavior 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;
+ FunctionModRefBehavior getModRefBehavior(const Function *F) override;
/// getAdjustedAnalysisPointer - This method is used when a pass implements
/// an analysis interface through multiple inheritance. If needed, it
}
/// getModRefBehavior - Return the behavior when calling the given call site.
-AliasAnalysis::ModRefBehavior
+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
+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()) {
#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.
/// 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) {
+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) {
+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
/// anything about V2. UnderlyingV1 is GetUnderlyingObject(GEP1, DL),
/// UnderlyingV2 is the same for V2.
///
-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) {
+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;
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) {
+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))
// 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) {
+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());
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);
}
+ // 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)
// 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) {
+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)