+//===----------------------------------------------------------------------===//
+// Useful predicates
+//===----------------------------------------------------------------------===//
+
+// Determine if an AllocationInst instruction escapes from the function it is
+// contained in. If it does not escape, there is no way for another function to
+// mod/ref it. We do this by looking at its uses and determining if the uses
+// can escape (recursively).
+static bool AddressMightEscape(const Value *V) {
+ for (Value::use_const_iterator UI = V->use_begin(), E = V->use_end();
+ UI != E; ++UI) {
+ const Instruction *I = cast<Instruction>(*UI);
+ switch (I->getOpcode()) {
+ case Instruction::Load:
+ break; //next use.
+ case Instruction::Store:
+ if (I->getOperand(0) == V)
+ return true; // Escapes if the pointer is stored.
+ break; // next use.
+ case Instruction::GetElementPtr:
+ if (AddressMightEscape(I))
+ return true;
+ break; // next use.
+ case Instruction::BitCast:
+ if (AddressMightEscape(I))
+ return true;
+ break; // next use
+ case Instruction::Ret:
+ // If returned, the address will escape to calling functions, but no
+ // callees could modify it.
+ break; // next use
+ case Instruction::Call:
+ // If the call is to a few known safe intrinsics, we know that it does
+ // not escape.
+ // TODO: Eventually just check the 'nocapture' attribute.
+ if (!isa<MemIntrinsic>(I))
+ return true;
+ break; // next use
+ default:
+ return true;
+ }
+ }
+ return false;
+}
+
+static const User *isGEP(const Value *V) {
+ if (isa<GetElementPtrInst>(V) ||
+ (isa<ConstantExpr>(V) &&
+ cast<ConstantExpr>(V)->getOpcode() == Instruction::GetElementPtr))
+ return cast<User>(V);
+ return 0;
+}
+
+static const Value *GetGEPOperands(const Value *V,
+ SmallVector<Value*, 16> &GEPOps){
+ assert(GEPOps.empty() && "Expect empty list to populate!");
+ GEPOps.insert(GEPOps.end(), cast<User>(V)->op_begin()+1,
+ cast<User>(V)->op_end());
+
+ // Accumulate all of the chained indexes into the operand array
+ V = cast<User>(V)->getOperand(0);
+
+ while (const User *G = isGEP(V)) {
+ if (!isa<Constant>(GEPOps[0]) || isa<GlobalValue>(GEPOps[0]) ||
+ !cast<Constant>(GEPOps[0])->isNullValue())
+ break; // Don't handle folding arbitrary pointer offsets yet...
+ GEPOps.erase(GEPOps.begin()); // Drop the zero index
+ GEPOps.insert(GEPOps.begin(), G->op_begin()+1, G->op_end());
+ V = G->getOperand(0);
+ }
+ return V;
+}
+
+/// isNoAliasCall - Return true if this pointer is returned by a noalias
+/// function.
+static bool 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
+/// Allocas and Mallocs
+/// ByVal and NoAlias Arguments
+/// NoAlias returns
+///
+static bool isIdentifiedObject(const Value *V) {
+ if (isa<GlobalValue>(V) || isa<AllocationInst>(V) || isNoAliasCall(V))
+ return true;
+ if (const Argument *A = dyn_cast<Argument>(V))
+ return A->hasNoAliasAttr() || A->hasByValAttr();
+ return false;
+}
+
+/// isKnownNonNull - Return true if we know that the specified value is never
+/// null.
+static bool isKnownNonNull(const Value *V) {
+ // Alloca never returns null, malloc might.
+ if (isa<AllocaInst>(V)) return true;
+
+ // A byval argument is never null.
+ if (const Argument *A = dyn_cast<Argument>(V))
+ return A->hasByValAttr();
+
+ // Global values are not null unless extern weak.
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
+ return !GV->hasExternalWeakLinkage();
+ return false;
+}
+
+/// isNonEscapingLocalObject - Return 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<AllocationInst>(V) || isNoAliasCall(V))
+ return !AddressMightEscape(V);
+
+ // If this is an argument that corresponds to a byval or noalias argument,
+ // it can't escape either.
+ if (const Argument *A = dyn_cast<Argument>(V))
+ if (A->hasByValAttr() || A->hasNoAliasAttr())
+ return !AddressMightEscape(V);
+ return false;
+}
+
+
+/// isObjectSmallerThan - Return true if we can prove that the object specified
+/// by V is smaller than Size.
+static bool isObjectSmallerThan(const Value *V, unsigned Size,
+ const TargetData &TD) {
+ const Type *AccessTy;
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
+ AccessTy = GV->getType()->getElementType();
+ } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(V)) {
+ if (!AI->isArrayAllocation())
+ AccessTy = AI->getType()->getElementType();
+ else
+ return false;
+ } else if (const Argument *A = dyn_cast<Argument>(V)) {
+ if (A->hasByValAttr())
+ AccessTy = cast<PointerType>(A->getType())->getElementType();
+ else
+ return false;
+ } else {
+ return false;
+ }
+
+ if (AccessTy->isSized())
+ return TD.getABITypeSize(AccessTy) < Size;
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// NoAA Pass
+//===----------------------------------------------------------------------===//
+