//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/Pass.h"
#include "llvm/BasicBlock.h"
#include "llvm/Function.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Instructions.h"
#include "llvm/Type.h"
#include "llvm/Target/TargetData.h"
using namespace llvm;
// Register the AliasAnalysis interface, providing a nice name to refer to.
-namespace {
- RegisterAnalysisGroup<AliasAnalysis> Z("Alias Analysis");
-}
+static RegisterAnalysisGroup<AliasAnalysis> Z("Alias Analysis");
char AliasAnalysis::ID = 0;
//===----------------------------------------------------------------------===//
return AA->alias(V1, V1Size, V2, V2Size);
}
-void AliasAnalysis::getMustAliases(Value *P, std::vector<Value*> &RetVals) {
- assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
- return AA->getMustAliases(P, RetVals);
-}
-
bool AliasAnalysis::pointsToConstantMemory(const Value *P) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
return AA->pointsToConstantMemory(P);
}
-AliasAnalysis::ModRefBehavior
-AliasAnalysis::getModRefBehavior(Function *F, CallSite CS,
- std::vector<PointerAccessInfo> *Info) {
- assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
- return AA->getModRefBehavior(F, CS, Info);
-}
-
-bool AliasAnalysis::hasNoModRefInfoForCalls() const {
- assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
- return AA->hasNoModRefInfoForCalls();
-}
-
void AliasAnalysis::deleteValue(Value *V) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
AA->deleteValue(V);
AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(LoadInst *L, Value *P, unsigned Size) {
- return alias(L->getOperand(0), TD->getTypeStoreSize(L->getType()),
+ return alias(L->getOperand(0), getTypeStoreSize(L->getType()),
P, Size) ? Ref : NoModRef;
}
// If the stored address cannot alias the pointer in question, then the
// pointer cannot be modified by the store.
if (!alias(S->getOperand(1),
- TD->getTypeStoreSize(S->getOperand(0)->getType()), P, Size))
+ getTypeStoreSize(S->getOperand(0)->getType()), P, Size))
return NoModRef;
// If the pointer is a pointer to constant memory, then it could not have been
AliasAnalysis::ModRefBehavior
AliasAnalysis::getModRefBehavior(CallSite CS,
std::vector<PointerAccessInfo> *Info) {
- if (CS.paramHasAttr(0, ParamAttr::ReadNone))
+ if (CS.doesNotAccessMemory())
// Can't do better than this.
return DoesNotAccessMemory;
- ModRefBehavior MRB = UnknownModRefBehavior;
- if (Function *F = CS.getCalledFunction())
- MRB = getModRefBehavior(F, CS, Info);
- if (MRB != DoesNotAccessMemory && CS.paramHasAttr(0, ParamAttr::ReadOnly))
+ ModRefBehavior MRB = getModRefBehavior(CS.getCalledFunction(), Info);
+ if (MRB != DoesNotAccessMemory && CS.onlyReadsMemory())
return OnlyReadsMemory;
return MRB;
}
AliasAnalysis::ModRefBehavior
AliasAnalysis::getModRefBehavior(Function *F,
std::vector<PointerAccessInfo> *Info) {
- if (F->paramHasAttr(0, ParamAttr::ReadNone))
- // Can't do better than this.
- return DoesNotAccessMemory;
- ModRefBehavior MRB = getModRefBehavior(F, CallSite(), Info);
- if (MRB != DoesNotAccessMemory && F->paramHasAttr(0, ParamAttr::ReadOnly))
- return OnlyReadsMemory;
- return MRB;
+ if (F) {
+ if (F->doesNotAccessMemory())
+ // Can't do better than this.
+ return DoesNotAccessMemory;
+ if (F->onlyReadsMemory())
+ return OnlyReadsMemory;
+ if (unsigned id = F->getIntrinsicID())
+ return getModRefBehavior(id);
+ }
+ return UnknownModRefBehavior;
+}
+
+AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(unsigned iid) {
+#define GET_INTRINSIC_MODREF_BEHAVIOR
+#include "llvm/Intrinsics.gen"
+#undef GET_INTRINSIC_MODREF_BEHAVIOR
}
AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
- ModRefResult Mask = ModRef;
ModRefBehavior MRB = getModRefBehavior(CS);
+ if (MRB == DoesNotAccessMemory)
+ return NoModRef;
+
+ ModRefResult Mask = ModRef;
if (MRB == OnlyReadsMemory)
Mask = Ref;
- else if (MRB == DoesNotAccessMemory)
- return NoModRef;
+ else if (MRB == AliasAnalysis::AccessesArguments) {
+ bool doesAlias = false;
+ for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
+ AI != AE; ++AI)
+ if (!isNoAlias(*AI, ~0U, P, Size)) {
+ doesAlias = true;
+ break;
+ }
+
+ if (!doesAlias)
+ return NoModRef;
+ }
if (!AA) return Mask;
//
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>();
+ TD = P->getAnalysisIfAvailable<TargetData>();
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 TargetData store size for the given type,
+/// if known, or a conservative value otherwise.
+///
+unsigned AliasAnalysis::getTypeStoreSize(const Type *Ty) {
+ return TD ? TD->getTypeStoreSize(Ty) : ~0u;
+}
+
/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
///
return false;
}
+/// 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 CallSite(const_cast<Instruction*>(cast<Instruction>(V)))
+ .paramHasAttr(0, Attribute::NoAlias);
+ return false;
+}
+
+/// 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;
+}
+
// Because of the way .a files work, we must force the BasicAA implementation to
// be pulled in if the AliasAnalysis classes are pulled in. Otherwise we run
// the risk of AliasAnalysis being used, but the default implementation not