//===- AliasAnalysis.cpp - Generic Alias Analysis Interface Implementation -==//
//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
// This file implements the generic AliasAnalysis interface which is used as the
// common interface used by all clients and implementations of alias analysis.
//
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/iMemory.h"
-#include "llvm/iOther.h"
-#include "llvm/Constants.h"
-#include "llvm/ConstantHandling.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetLibraryInfo.h"
+using namespace llvm;
// Register the AliasAnalysis interface, providing a nice name to refer to.
-namespace {
- RegisterAnalysisGroup<AliasAnalysis> Z("Alias Analysis");
+INITIALIZE_ANALYSIS_GROUP(AliasAnalysis, "Alias Analysis", NoAA)
+char AliasAnalysis::ID = 0;
+
+//===----------------------------------------------------------------------===//
+// Default chaining methods
+//===----------------------------------------------------------------------===//
+
+AliasAnalysis::AliasResult
+AliasAnalysis::alias(const Location &LocA, const Location &LocB) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->alias(LocA, LocB);
+}
+
+bool AliasAnalysis::pointsToConstantMemory(const Location &Loc,
+ bool OrLocal) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->pointsToConstantMemory(Loc, OrLocal);
+}
+
+AliasAnalysis::Location
+AliasAnalysis::getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
+ AliasAnalysis::ModRefResult &Mask) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->getArgLocation(CS, ArgIdx, Mask);
+}
+
+void AliasAnalysis::deleteValue(Value *V) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ AA->deleteValue(V);
+}
+
+void AliasAnalysis::copyValue(Value *From, Value *To) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ AA->copyValue(From, To);
+}
+
+void AliasAnalysis::addEscapingUse(Use &U) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ AA->addEscapingUse(U);
+}
+
+
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const Location &Loc) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+
+ ModRefBehavior MRB = getModRefBehavior(CS);
+ if (MRB == DoesNotAccessMemory)
+ return NoModRef;
+
+ ModRefResult Mask = ModRef;
+ if (onlyReadsMemory(MRB))
+ Mask = Ref;
+
+ if (onlyAccessesArgPointees(MRB)) {
+ bool doesAlias = false;
+ ModRefResult AllArgsMask = NoModRef;
+ if (doesAccessArgPointees(MRB)) {
+ for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
+ AI != AE; ++AI) {
+ const Value *Arg = *AI;
+ if (!Arg->getType()->isPointerTy())
+ continue;
+ ModRefResult ArgMask;
+ Location CSLoc =
+ getArgLocation(CS, (unsigned) std::distance(CS.arg_begin(), AI),
+ ArgMask);
+ if (!isNoAlias(CSLoc, Loc)) {
+ doesAlias = true;
+ AllArgsMask = ModRefResult(AllArgsMask | ArgMask);
+ }
+ }
+ }
+ if (!doesAlias)
+ return NoModRef;
+ Mask = ModRefResult(Mask & AllArgsMask);
+ }
+
+ // If Loc is a constant memory location, the call definitely could not
+ // modify the memory location.
+ if ((Mask & Mod) && pointsToConstantMemory(Loc))
+ Mask = ModRefResult(Mask & ~Mod);
+
+ // If this is the end of the chain, don't forward.
+ if (!AA) return Mask;
+
+ // Otherwise, fall back to the next AA in the chain. But we can merge
+ // in any mask we've managed to compute.
+ return ModRefResult(AA->getModRefInfo(CS, Loc) & Mask);
+}
+
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+
+ // If CS1 or CS2 are readnone, they don't interact.
+ ModRefBehavior CS1B = getModRefBehavior(CS1);
+ if (CS1B == DoesNotAccessMemory) return NoModRef;
+
+ ModRefBehavior CS2B = getModRefBehavior(CS2);
+ if (CS2B == DoesNotAccessMemory) return NoModRef;
+
+ // If they both only read from memory, there is no dependence.
+ if (onlyReadsMemory(CS1B) && onlyReadsMemory(CS2B))
+ return NoModRef;
+
+ AliasAnalysis::ModRefResult Mask = ModRef;
+
+ // If CS1 only reads memory, the only dependence on CS2 can be
+ // from CS1 reading memory written by CS2.
+ if (onlyReadsMemory(CS1B))
+ Mask = ModRefResult(Mask & Ref);
+
+ // If CS2 only access memory through arguments, accumulate the mod/ref
+ // information from CS1's references to the memory referenced by
+ // CS2's arguments.
+ if (onlyAccessesArgPointees(CS2B)) {
+ AliasAnalysis::ModRefResult R = NoModRef;
+ if (doesAccessArgPointees(CS2B)) {
+ for (ImmutableCallSite::arg_iterator
+ I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
+ const Value *Arg = *I;
+ if (!Arg->getType()->isPointerTy())
+ continue;
+ ModRefResult ArgMask;
+ Location CS2Loc =
+ getArgLocation(CS2, (unsigned) std::distance(CS2.arg_begin(), I),
+ ArgMask);
+ // ArgMask indicates what CS2 might do to CS2Loc, and the dependence of
+ // CS1 on that location is the inverse.
+ if (ArgMask == Mod)
+ ArgMask = ModRef;
+ else if (ArgMask == Ref)
+ ArgMask = Mod;
+
+ R = ModRefResult((R | (getModRefInfo(CS1, CS2Loc) & ArgMask)) & Mask);
+ if (R == Mask)
+ break;
+ }
+ }
+ return R;
+ }
+
+ // If CS1 only accesses memory through arguments, check if CS2 references
+ // any of the memory referenced by CS1's arguments. If not, return NoModRef.
+ if (onlyAccessesArgPointees(CS1B)) {
+ AliasAnalysis::ModRefResult R = NoModRef;
+ if (doesAccessArgPointees(CS1B)) {
+ for (ImmutableCallSite::arg_iterator
+ I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) {
+ const Value *Arg = *I;
+ if (!Arg->getType()->isPointerTy())
+ continue;
+ ModRefResult ArgMask;
+ Location CS1Loc =
+ getArgLocation(CS1, (unsigned) std::distance(CS1.arg_begin(), I),
+ ArgMask);
+ // ArgMask indicates what CS1 might do to CS1Loc; if CS1 might Mod
+ // CS1Loc, then we care about either a Mod or a Ref by CS2. If CS1
+ // might Ref, then we care only about a Mod by CS2.
+ ModRefResult ArgR = getModRefInfo(CS2, CS1Loc);
+ if (((ArgMask & Mod) != NoModRef && (ArgR & ModRef) != NoModRef) ||
+ ((ArgMask & Ref) != NoModRef && (ArgR & Mod) != NoModRef))
+ R = ModRefResult((R | ArgMask) & Mask);
+
+ if (R == Mask)
+ break;
+ }
+ }
+ return R;
+ }
+
+ // If this is the end of the chain, don't forward.
+ if (!AA) return Mask;
+
+ // Otherwise, fall back to the next AA in the chain. But we can merge
+ // in any mask we've managed to compute.
+ return ModRefResult(AA->getModRefInfo(CS1, CS2) & Mask);
+}
+
+AliasAnalysis::ModRefBehavior
+AliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+
+ ModRefBehavior Min = UnknownModRefBehavior;
+
+ // Call back into the alias analysis with the other form of getModRefBehavior
+ // to see if it can give a better response.
+ if (const Function *F = CS.getCalledFunction())
+ Min = getModRefBehavior(F);
+
+ // If this is the end of the chain, don't forward.
+ if (!AA) return Min;
+
+ // Otherwise, fall back to the next AA in the chain. But we can merge
+ // in any result we've managed to compute.
+ return ModRefBehavior(AA->getModRefBehavior(CS) & Min);
+}
+
+AliasAnalysis::ModRefBehavior
+AliasAnalysis::getModRefBehavior(const Function *F) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->getModRefBehavior(F);
+}
+
+//===----------------------------------------------------------------------===//
+// AliasAnalysis non-virtual helper method implementation
+//===----------------------------------------------------------------------===//
+
+AliasAnalysis::Location AliasAnalysis::getLocation(const LoadInst *LI) {
+ AAMDNodes AATags;
+ LI->getAAMetadata(AATags);
+
+ return Location(LI->getPointerOperand(),
+ getTypeStoreSize(LI->getType()), AATags);
+}
+
+AliasAnalysis::Location AliasAnalysis::getLocation(const StoreInst *SI) {
+ AAMDNodes AATags;
+ SI->getAAMetadata(AATags);
+
+ return Location(SI->getPointerOperand(),
+ getTypeStoreSize(SI->getValueOperand()->getType()), AATags);
+}
+
+AliasAnalysis::Location AliasAnalysis::getLocation(const VAArgInst *VI) {
+ AAMDNodes AATags;
+ VI->getAAMetadata(AATags);
+
+ return Location(VI->getPointerOperand(), UnknownSize, AATags);
+}
+
+AliasAnalysis::Location
+AliasAnalysis::getLocation(const AtomicCmpXchgInst *CXI) {
+ AAMDNodes AATags;
+ CXI->getAAMetadata(AATags);
+
+ return Location(CXI->getPointerOperand(),
+ getTypeStoreSize(CXI->getCompareOperand()->getType()),
+ AATags);
+}
+
+AliasAnalysis::Location
+AliasAnalysis::getLocation(const AtomicRMWInst *RMWI) {
+ AAMDNodes AATags;
+ RMWI->getAAMetadata(AATags);
+
+ return Location(RMWI->getPointerOperand(),
+ getTypeStoreSize(RMWI->getValOperand()->getType()), AATags);
+}
+
+AliasAnalysis::Location
+AliasAnalysis::getLocationForSource(const MemTransferInst *MTI) {
+ uint64_t Size = UnknownSize;
+ if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength()))
+ Size = C->getValue().getZExtValue();
+
+ // memcpy/memmove can have AA tags. For memcpy, they apply
+ // to both the source and the destination.
+ AAMDNodes AATags;
+ MTI->getAAMetadata(AATags);
+
+ return Location(MTI->getRawSource(), Size, AATags);
+}
+
+AliasAnalysis::Location
+AliasAnalysis::getLocationForDest(const MemIntrinsic *MTI) {
+ uint64_t Size = UnknownSize;
+ if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength()))
+ Size = C->getValue().getZExtValue();
+
+ // memcpy/memmove can have AA tags. For memcpy, they apply
+ // to both the source and the destination.
+ AAMDNodes AATags;
+ MTI->getMetadata(AATags);
+
+ return Location(MTI->getRawDest(), Size, AATags);
+}
+
+
+
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) {
+ // Be conservative in the face of volatile/atomic.
+ if (!L->isUnordered())
+ return ModRef;
+
+ // If the load address doesn't alias the given address, it doesn't read
+ // or write the specified memory.
+ if (!alias(getLocation(L), Loc))
+ return NoModRef;
+
+ // Otherwise, a load just reads.
+ return Ref;
}
AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(LoadInst *L, Value *P, unsigned Size) {
- return alias(L->getOperand(0), TD->getTypeSize(L->getType()),
- P, Size) ? Ref : NoModRef;
+AliasAnalysis::getModRefInfo(const StoreInst *S, const Location &Loc) {
+ // Be conservative in the face of volatile/atomic.
+ if (!S->isUnordered())
+ return ModRef;
+
+ // If the store address cannot alias the pointer in question, then the
+ // specified memory cannot be modified by the store.
+ if (!alias(getLocation(S), Loc))
+ return NoModRef;
+
+ // If the pointer is a pointer to constant memory, then it could not have been
+ // modified by this store.
+ if (pointsToConstantMemory(Loc))
+ return NoModRef;
+
+ // Otherwise, a store just writes.
+ return Mod;
}
AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
- return alias(S->getOperand(1), TD->getTypeSize(S->getOperand(0)->getType()),
- P, Size) ? Mod : NoModRef;
+AliasAnalysis::getModRefInfo(const VAArgInst *V, const Location &Loc) {
+ // If the va_arg address cannot alias the pointer in question, then the
+ // specified memory cannot be accessed by the va_arg.
+ if (!alias(getLocation(V), Loc))
+ return NoModRef;
+
+ // If the pointer is a pointer to constant memory, then it could not have been
+ // modified by this va_arg.
+ if (pointsToConstantMemory(Loc))
+ return NoModRef;
+
+ // Otherwise, a va_arg reads and writes.
+ return ModRef;
}
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc) {
+ // Acquire/Release cmpxchg has properties that matter for arbitrary addresses.
+ if (CX->getSuccessOrdering() > Monotonic)
+ return ModRef;
+
+ // If the cmpxchg address does not alias the location, it does not access it.
+ if (!alias(getLocation(CX), Loc))
+ return NoModRef;
+
+ return ModRef;
+}
+
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc) {
+ // Acquire/Release atomicrmw has properties that matter for arbitrary addresses.
+ if (RMW->getOrdering() > Monotonic)
+ return ModRef;
+
+ // If the atomicrmw address does not alias the location, it does not access it.
+ if (!alias(getLocation(RMW), Loc))
+ return NoModRef;
+
+ return ModRef;
+}
+
+// FIXME: this is really just shoring-up a deficiency in alias analysis.
+// BasicAA isn't willing to spend linear time determining whether an alloca
+// was captured before or after this particular call, while we are. However,
+// with a smarter AA in place, this test is just wasting compile time.
+AliasAnalysis::ModRefResult
+AliasAnalysis::callCapturesBefore(const Instruction *I,
+ const AliasAnalysis::Location &MemLoc,
+ DominatorTree *DT) {
+ if (!DT || !DL) return AliasAnalysis::ModRef;
+
+ const Value *Object = GetUnderlyingObject(MemLoc.Ptr, DL);
+ if (!isIdentifiedObject(Object) || isa<GlobalValue>(Object) ||
+ isa<Constant>(Object))
+ return AliasAnalysis::ModRef;
+
+ ImmutableCallSite CS(I);
+ if (!CS.getInstruction() || CS.getInstruction() == Object)
+ return AliasAnalysis::ModRef;
+
+ if (llvm::PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true,
+ /* StoreCaptures */ true, I, DT,
+ /* include Object */ true))
+ return AliasAnalysis::ModRef;
+
+ unsigned ArgNo = 0;
+ AliasAnalysis::ModRefResult R = AliasAnalysis::NoModRef;
+ for (ImmutableCallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
+ CI != CE; ++CI, ++ArgNo) {
+ // Only look at the no-capture or byval pointer arguments. If this
+ // pointer were passed to arguments that were neither of these, then it
+ // couldn't be no-capture.
+ if (!(*CI)->getType()->isPointerTy() ||
+ (!CS.doesNotCapture(ArgNo) && !CS.isByValArgument(ArgNo)))
+ continue;
+
+ // If this is a no-capture pointer argument, see if we can tell that it
+ // is impossible to alias the pointer we're checking. If not, we have to
+ // assume that the call could touch the pointer, even though it doesn't
+ // escape.
+ if (isNoAlias(AliasAnalysis::Location(*CI),
+ AliasAnalysis::Location(Object)))
+ continue;
+ if (CS.doesNotAccessMemory(ArgNo))
+ continue;
+ if (CS.onlyReadsMemory(ArgNo)) {
+ R = AliasAnalysis::Ref;
+ continue;
+ }
+ return AliasAnalysis::ModRef;
+ }
+ return R;
+}
// AliasAnalysis destructor: DO NOT move this to the header file for
// AliasAnalysis or else clients of the AliasAnalysis class may not depend on
//
AliasAnalysis::~AliasAnalysis() {}
-/// setTargetData - Subclasses must call this method to initialize the
+/// InitializeAliasAnalysis - Subclasses must call this method to initialize the
/// AliasAnalysis interface before any other methods are called.
///
void AliasAnalysis::InitializeAliasAnalysis(Pass *P) {
- TD = &P->getAnalysis<TargetData>();
+ DataLayoutPass *DLP = P->getAnalysisIfAvailable<DataLayoutPass>();
+ DL = DLP ? &DLP->getDataLayout() : nullptr;
+ TLI = P->getAnalysisIfAvailable<TargetLibraryInfo>();
+ AA = &P->getAnalysis<AliasAnalysis>();
}
// getAnalysisUsage - All alias analysis implementations should invoke this
-// directly (using AliasAnalysis::getAnalysisUsage(AU)) to make sure that
-// TargetData is required by the pass.
+// directly (using AliasAnalysis::getAnalysisUsage(AU)).
void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetData>(); // All AA's need TargetData.
+ AU.addRequired<AliasAnalysis>(); // All AA's chain
+}
+
+/// getTypeStoreSize - Return the DataLayout store size for the given type,
+/// if known, or a conservative value otherwise.
+///
+uint64_t AliasAnalysis::getTypeStoreSize(Type *Ty) {
+ return DL ? DL->getTypeStoreSize(Ty) : UnknownSize;
}
/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
- const Value *Ptr, unsigned Size) {
- return canInstructionRangeModify(BB.front(), BB.back(), Ptr, Size);
+ const Location &Loc) {
+ return canInstructionRangeModify(BB.front(), BB.back(), Loc);
}
/// canInstructionRangeModify - Return true if it is possible for the execution
///
bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
const Instruction &I2,
- const Value *Ptr, unsigned Size) {
+ const Location &Loc) {
assert(I1.getParent() == I2.getParent() &&
"Instructions not in same basic block!");
- BasicBlock::iterator I = const_cast<Instruction*>(&I1);
- BasicBlock::iterator E = const_cast<Instruction*>(&I2);
+ BasicBlock::const_iterator I = &I1;
+ BasicBlock::const_iterator E = &I2;
++E; // Convert from inclusive to exclusive range.
for (; I != E; ++I) // Check every instruction in range
- if (getModRefInfo(I, const_cast<Value*>(Ptr), Size) & Mod)
+ if (getModRefInfo(I, Loc) & Mod)
return true;
return false;
}
-//===----------------------------------------------------------------------===//
-// BasicAliasAnalysis Pass Implementation
-//===----------------------------------------------------------------------===//
-//
-// Because of the way .a files work, the implementation of the
-// BasicAliasAnalysis class MUST be in the AliasAnalysis file itself, or else we
-// run the risk of AliasAnalysis being used, but the default implementation not
-// being linked into the tool that uses it. As such, we register and implement
-// the class here.
-//
-namespace {
- // Register this pass...
- RegisterOpt<BasicAliasAnalysis>
- X("basicaa", "Basic Alias Analysis (default AA impl)");
-
- // Declare that we implement the AliasAnalysis interface
- RegisterAnalysisGroup<AliasAnalysis, BasicAliasAnalysis, true> Y;
-} // End of anonymous namespace
-
-void BasicAliasAnalysis::initializePass() {
- InitializeAliasAnalysis(this);
-}
-
-
-
-// hasUniqueAddress - Return true if the
-static inline bool hasUniqueAddress(const Value *V) {
- return isa<GlobalValue>(V) || isa<MallocInst>(V) || isa<AllocaInst>(V);
+/// isNoAliasCall - Return true if this pointer is returned by a noalias
+/// function.
+bool llvm::isNoAliasCall(const Value *V) {
+ if (isa<CallInst>(V) || isa<InvokeInst>(V))
+ return ImmutableCallSite(cast<Instruction>(V))
+ .paramHasAttr(0, Attribute::NoAlias);
+ return false;
}
-static const Value *getUnderlyingObject(const Value *V) {
- if (!isa<PointerType>(V->getType())) return 0;
-
- // If we are at some type of object... return it.
- if (hasUniqueAddress(V)) return V;
-
- // Traverse through different addressing mechanisms...
- if (const Instruction *I = dyn_cast<Instruction>(V)) {
- if (isa<CastInst>(I) || isa<GetElementPtrInst>(I))
- return getUnderlyingObject(I->getOperand(0));
- }
- return 0;
+/// isNoAliasArgument - Return true if this is an argument with the noalias
+/// attribute.
+bool llvm::isNoAliasArgument(const Value *V)
+{
+ if (const Argument *A = dyn_cast<Argument>(V))
+ return A->hasNoAliasAttr();
+ return false;
}
-
-// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
-// as array references. Note that this function is heavily tail recursive.
-// Hopefully we have a smart C++ compiler. :)
-//
-AliasAnalysis::AliasResult
-BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
- const Value *V2, unsigned V2Size) {
- // Strip off constant pointer refs if they exist
- if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V1))
- V1 = CPR->getValue();
- if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V2))
- V2 = CPR->getValue();
-
- // Are we checking for alias of the same value?
- if (V1 == V2) return MustAlias;
-
- if ((!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType())) &&
- V1->getType() != Type::LongTy && V2->getType() != Type::LongTy)
- return NoAlias; // Scalars cannot alias each other
-
- // Strip off cast instructions...
- if (const Instruction *I = dyn_cast<CastInst>(V1))
- return alias(I->getOperand(0), V1Size, V2, V2Size);
- if (const Instruction *I = dyn_cast<CastInst>(V2))
- return alias(V1, V1Size, I->getOperand(0), V2Size);
-
- // Figure out what objects these things are pointing to if we can...
- const Value *O1 = getUnderlyingObject(V1);
- const Value *O2 = getUnderlyingObject(V2);
-
- // Pointing at a discernable object?
- if (O1 && O2) {
- // If they are two different objects, we know that we have no alias...
- if (O1 != O2) return NoAlias;
-
- // If they are the same object, they we can look at the indexes. If they
- // index off of the object is the same for both pointers, they must alias.
- // If they are provably different, they must not alias. Otherwise, we can't
- // tell anything.
- } else if (O1 && isa<ConstantPointerNull>(V2)) {
- return NoAlias; // Unique values don't alias null
- } else if (O2 && isa<ConstantPointerNull>(V1)) {
- return NoAlias; // Unique values don't alias null
- }
-
- // If we have two gep instructions with identical indices, return an alias
- // result equal to the alias result of the original pointer...
- //
- if (const GetElementPtrInst *GEP1 = dyn_cast<GetElementPtrInst>(V1))
- if (const GetElementPtrInst *GEP2 = dyn_cast<GetElementPtrInst>(V2))
- if (GEP1->getNumOperands() == GEP2->getNumOperands() &&
- GEP1->getOperand(0)->getType() == GEP2->getOperand(0)->getType()) {
- AliasResult GAlias =
- CheckGEPInstructions((GetElementPtrInst*)GEP1, V1Size,
- (GetElementPtrInst*)GEP2, V2Size);
- if (GAlias != MayAlias)
- return GAlias;
- }
-
- // Check to see if these two pointers are related by a getelementptr
- // instruction. If one pointer is a GEP with a non-zero index of the other
- // pointer, we know they cannot alias.
- //
- if (isa<GetElementPtrInst>(V2)) {
- std::swap(V1, V2);
- std::swap(V1Size, V2Size);
- }
-
- if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V1))
- if (GEP->getOperand(0) == V2) {
- // If there is at least one non-zero constant index, we know they cannot
- // alias.
- for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
- if (const Constant *C = dyn_cast<Constant>(GEP->getOperand(i)))
- if (!C->isNullValue())
- return NoAlias;
- }
-
- return MayAlias;
+/// isIdentifiedObject - Return true if this pointer refers to a distinct and
+/// identifiable object. This returns true for:
+/// Global Variables and Functions (but not Global Aliases)
+/// Allocas and Mallocs
+/// ByVal and NoAlias Arguments
+/// NoAlias returns
+///
+bool llvm::isIdentifiedObject(const Value *V) {
+ if (isa<AllocaInst>(V))
+ return true;
+ if (isa<GlobalValue>(V) && !isa<GlobalAlias>(V))
+ return true;
+ if (isNoAliasCall(V))
+ return true;
+ if (const Argument *A = dyn_cast<Argument>(V))
+ return A->hasNoAliasAttr() || A->hasByValAttr();
+ return false;
}
-// CheckGEPInstructions - Check two GEP instructions of compatible types and
-// equal number of arguments. This checks to see if the index expressions
-// preclude the pointers from aliasing...
-//
-AliasAnalysis::AliasResult
-BasicAliasAnalysis::CheckGEPInstructions(GetElementPtrInst *GEP1, unsigned G1S,
- GetElementPtrInst *GEP2, unsigned G2S){
- // Do the base pointers alias?
- AliasResult BaseAlias = alias(GEP1->getOperand(0), G1S,
- GEP2->getOperand(0), G2S);
- if (BaseAlias != MustAlias) // No or May alias: We cannot add anything...
- return BaseAlias;
-
- // Find the (possibly empty) initial sequence of equal values...
- unsigned NumGEPOperands = GEP1->getNumOperands();
- unsigned UnequalOper = 1;
- while (UnequalOper != NumGEPOperands &&
- GEP1->getOperand(UnequalOper) == GEP2->getOperand(UnequalOper))
- ++UnequalOper;
-
- // If all operands equal each other, then the derived pointers must
- // alias each other...
- if (UnequalOper == NumGEPOperands) return MustAlias;
-
- // So now we know that the indexes derived from the base pointers,
- // which are known to alias, are different. We can still determine a
- // no-alias result if there are differing constant pairs in the index
- // chain. For example:
- // A[i][0] != A[j][1] iff (&A[0][1]-&A[0][0] >= std::max(G1S, G2S))
- //
- unsigned SizeMax = std::max(G1S, G2S);
- if (SizeMax == ~0U) return MayAlias; // Avoid frivolous work...
-
- // Scan for the first operand that is constant and unequal in the
- // two getelemenptrs...
- unsigned FirstConstantOper = UnequalOper;
- for (; FirstConstantOper != NumGEPOperands; ++FirstConstantOper) {
- const Value *G1Oper = GEP1->getOperand(FirstConstantOper);
- const Value *G2Oper = GEP2->getOperand(FirstConstantOper);
- if (G1Oper != G2Oper && // Found non-equal constant indexes...
- isa<Constant>(G1Oper) && isa<Constant>(G2Oper)) {
- // Make sure they are comparable... and make sure the GEP with
- // the smaller leading constant is GEP1.
- ConstantBool *Compare =
- *cast<Constant>(GEP1->getOperand(FirstConstantOper)) >
- *cast<Constant>(GEP2->getOperand(FirstConstantOper));
- if (Compare) { // If they are comparable...
- if (Compare->getValue())
- std::swap(GEP1, GEP2); // Make GEP1 < GEP2
- break;
- }
- }
- }
-
- // No constant operands, we cannot tell anything...
- if (FirstConstantOper == NumGEPOperands) return MayAlias;
-
- // If there are non-equal constants arguments, then we can figure
- // out a minimum known delta between the two index expressions... at
- // this point we know that the first constant index of GEP1 is less
- // than the first constant index of GEP2.
- //
- std::vector<Value*> Indices1;
- Indices1.reserve(NumGEPOperands-1);
- for (unsigned i = 1; i != FirstConstantOper; ++i)
- Indices1.push_back(Constant::getNullValue(GEP1->getOperand(i)
- ->getType()));
- std::vector<Value*> Indices2;
- Indices2.reserve(NumGEPOperands-1);
- Indices2 = Indices1; // Copy the zeros prefix...
-
- // Add the two known constant operands...
- Indices1.push_back((Value*)GEP1->getOperand(FirstConstantOper));
- Indices2.push_back((Value*)GEP2->getOperand(FirstConstantOper));
-
- const Type *GEPPointerTy = GEP1->getOperand(0)->getType();
-
- // Loop over the rest of the operands...
- for (unsigned i = FirstConstantOper+1; i!=NumGEPOperands; ++i){
- const Value *Op1 = GEP1->getOperand(i);
- const Value *Op2 = GEP1->getOperand(i);
- if (Op1 == Op2) { // If they are equal, use a zero index...
- Indices1.push_back(Constant::getNullValue(Op1->getType()));
- Indices2.push_back(Indices1.back());
- } else {
- if (isa<Constant>(Op1))
- Indices1.push_back((Value*)Op1);
- else {
- // GEP1 is known to produce a value less than GEP2. To be
- // conservatively correct, we must assume the largest
- // possible constant is used in this position. This cannot
- // be the initial index to the GEP instructions (because we
- // know we have at least one element before this one with
- // the different constant arguments), so we know that the
- // current index must be into either a struct or array.
- // Because of this, we can calculate the maximum value
- // possible.
- //
- const Type *ElTy = GEP1->getIndexedType(GEPPointerTy,
- Indices1, true);
- if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
- Indices1.push_back(ConstantUInt::get(Type::UByteTy,
- STy->getNumContainedTypes()));
- } else {
- Indices1.push_back(ConstantSInt::get(Type::LongTy,
- cast<ArrayType>(ElTy)->getNumElements()));
- }
- }
-
- if (isa<Constant>(Op2))
- Indices2.push_back((Value*)Op2);
- else // Conservatively assume the minimum value for this index
- Indices2.push_back(Constant::getNullValue(Op1->getType()));
- }
- }
-
- unsigned Offset1 = getTargetData().getIndexedOffset(GEPPointerTy, Indices1);
- unsigned Offset2 = getTargetData().getIndexedOffset(GEPPointerTy, Indices2);
- assert(Offset1 < Offset2 &&"There is at least one different constant here!");
-
- if (Offset2-Offset1 >= SizeMax) {
- //std::cerr << "Determined that these two GEP's don't alias ["
- // << SizeMax << " bytes]: \n" << *GEP1 << *GEP2;
- return NoAlias;
- }
- return MayAlias;
+/// isIdentifiedFunctionLocal - Return true if V is umabigously identified
+/// at the function-level. Different IdentifiedFunctionLocals can't alias.
+/// Further, an IdentifiedFunctionLocal can not alias with any function
+/// arguments other than itself, which is not necessarily true for
+/// IdentifiedObjects.
+bool llvm::isIdentifiedFunctionLocal(const Value *V)
+{
+ return isa<AllocaInst>(V) || isNoAliasCall(V) || isNoAliasArgument(V);
}