#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/ManagedStatic.h"
#include <algorithm>
using namespace llvm;
/// implementations, in that it does not chain to a previous analysis. As
/// such it doesn't follow many of the rules that other alias analyses must.
///
- struct NoAA : public ImmutablePass, public AliasAnalysis {
+ struct VISIBILITY_HIDDEN NoAA : public ImmutablePass, public AliasAnalysis {
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetData>();
}
};
// Register this pass...
- RegisterOpt<NoAA>
+ RegisterPass<NoAA>
U("no-aa", "No Alias Analysis (always returns 'may' alias)");
// Declare that we implement the AliasAnalysis interface
- RegisterAnalysisGroup<AliasAnalysis, NoAA> V;
+ RegisterAnalysisGroup<AliasAnalysis> V(U);
} // End of anonymous namespace
ImmutablePass *llvm::createNoAAPass() { return new NoAA(); }
/// BasicAliasAnalysis - This is the default alias analysis implementation.
/// Because it doesn't chain to a previous alias analysis (like -no-aa), it
/// derives from the NoAA class.
- struct BasicAliasAnalysis : public NoAA {
+ struct VISIBILITY_HIDDEN BasicAliasAnalysis : public NoAA {
AliasResult alias(const Value *V1, unsigned V1Size,
const Value *V2, unsigned V2Size);
};
// Register this pass...
- RegisterOpt<BasicAliasAnalysis>
+ RegisterPass<BasicAliasAnalysis>
X("basicaa", "Basic Alias Analysis (default AA impl)");
// Declare that we implement the AliasAnalysis interface
- RegisterAnalysisGroup<AliasAnalysis, BasicAliasAnalysis, true> Y;
+ RegisterAnalysisGroup<AliasAnalysis, true> Y(X);
} // End of anonymous namespace
ImmutablePass *llvm::createBasicAliasAnalysisPass() {
return new BasicAliasAnalysis();
}
-// hasUniqueAddress - Return true if the specified value points to something
-// with a unique, discernable, address.
-static inline bool hasUniqueAddress(const Value *V) {
- return isa<GlobalValue>(V) || isa<AllocationInst>(V);
-}
-
// getUnderlyingObject - This traverses the use chain to figure out what object
// the specified value points to. If the value points to, or is derived from, a
// unique object or an argument, return it.
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) || isa<Argument>(V)) return V;
+ // If we are at some type of object, return it. GlobalValues and Allocations
+ // have unique addresses.
+ if (isa<GlobalValue>(V) || isa<AllocationInst>(V) || isa<Argument>(V))
+ return V;
// Traverse through different addressing mechanisms...
if (const Instruction *I = dyn_cast<Instruction>(V)) {
- if (isa<CastInst>(I) || isa<GetElementPtrInst>(I))
+ if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I))
return getUnderlyingObject(I->getOperand(0));
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
- if (CE->getOpcode() == Instruction::Cast ||
+ if (CE->getOpcode() == Instruction::BitCast ||
CE->getOpcode() == Instruction::GetElementPtr)
return getUnderlyingObject(CE->getOperand(0));
- } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
- return GV;
}
return 0;
}
return false;
}
+// 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;
+ case Instruction::Load:
+ break; //next use.
case Instruction::Store:
if (I->getOperand(0) == V)
return true; // Escapes if the pointer is stored.
- break;
+ break; // next use.
case Instruction::GetElementPtr:
- if (AddressMightEscape(I)) return true;
- break;
- case Instruction::Cast:
+ if (AddressMightEscape(I))
+ return true;
+ case Instruction::BitCast:
if (!isa<PointerType>(I->getType()))
return true;
- if (AddressMightEscape(I)) return true;
- break;
+ 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;
+ break; // next use
default:
return true;
}
const Value *V2, unsigned V2Size) {
// Strip off any constant expression casts if they exist
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V1))
- if (CE->getOpcode() == Instruction::Cast &&
- isa<PointerType>(CE->getOperand(0)->getType()))
+ if (CE->isCast() && isa<PointerType>(CE->getOperand(0)->getType()))
V1 = CE->getOperand(0);
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V2))
- if (CE->getOpcode() == Instruction::Cast &&
- isa<PointerType>(CE->getOperand(0)->getType()))
+ if (CE->isCast() && isa<PointerType>(CE->getOperand(0)->getType()))
V2 = CE->getOperand(0);
// 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)
+ V1->getType() != Type::Int64Ty && V2->getType() != Type::Int64Ty)
return NoAlias; // Scalars cannot alias each other
// Strip off cast instructions...
- if (const Instruction *I = dyn_cast<CastInst>(V1))
+ if (const BitCastInst *I = dyn_cast<BitCastInst>(V1))
if (isa<PointerType>(I->getOperand(0)->getType()))
return alias(I->getOperand(0), V1Size, V2, V2Size);
- if (const Instruction *I = dyn_cast<CastInst>(V2))
+ if (const BitCastInst *I = dyn_cast<BitCastInst>(V2))
if (isa<PointerType>(I->getOperand(0)->getType()))
return alias(V1, V1Size, I->getOperand(0), V2Size);
}
if (V1Size != ~0U && V2Size != ~0U)
- if (const User *GEP = isGEP(V1)) {
+ if (isGEP(V1)) {
std::vector<Value*> GEPOperands;
const Value *BasePtr = GetGEPOperands(V1, GEPOperands);
return MayAlias;
}
-static bool ValuesEqual(Value *V1, Value *V2) {
+// This function is used to determin if the indices of two GEP instructions are
+// equal. V1 and V2 are the indices.
+static bool IndexOperandsEqual(Value *V1, Value *V2) {
if (V1->getType() == V2->getType())
return V1 == V2;
if (Constant *C1 = dyn_cast<Constant>(V1))
if (Constant *C2 = dyn_cast<Constant>(V2)) {
- // Sign extend the constants to long types.
- C1 = ConstantExpr::getSignExtend(C1, Type::LongTy);
- C2 = ConstantExpr::getSignExtend(C2, Type::LongTy);
+ // Sign extend the constants to long types, if necessary
+ if (C1->getType() != Type::Int64Ty)
+ C1 = ConstantExpr::getSExt(C1, Type::Int64Ty);
+ if (C2->getType() != Type::Int64Ty)
+ C2 = ConstantExpr::getSExt(C2, Type::Int64Ty);
return C1 == C2;
}
return false;
/// CheckGEPInstructions - Check two GEP instructions with known must-aliasing
/// base pointers. This checks to see if the index expressions preclude the
/// pointers from aliasing...
-AliasAnalysis::AliasResult BasicAliasAnalysis::
-CheckGEPInstructions(const Type* BasePtr1Ty, std::vector<Value*> &GEP1Ops,
- unsigned G1S,
- const Type *BasePtr2Ty, std::vector<Value*> &GEP2Ops,
- unsigned G2S) {
+AliasAnalysis::AliasResult
+BasicAliasAnalysis::CheckGEPInstructions(
+ const Type* BasePtr1Ty, std::vector<Value*> &GEP1Ops, unsigned G1S,
+ const Type *BasePtr2Ty, std::vector<Value*> &GEP2Ops, unsigned G2S) {
// We currently can't handle the case when the base pointers have different
// primitive types. Since this is uncommon anyway, we are happy being
// extremely conservative.
unsigned MaxOperands = std::max(NumGEP1Operands, NumGEP2Operands);
unsigned UnequalOper = 0;
while (UnequalOper != MinOperands &&
- ValuesEqual(GEP1Ops[UnequalOper], GEP2Ops[UnequalOper])) {
+ IndexOperandsEqual(GEP1Ops[UnequalOper], GEP2Ops[UnequalOper])) {
// Advance through the type as we go...
++UnequalOper;
if (const CompositeType *CT = dyn_cast<CompositeType>(BasePtr1Ty))
if (Constant *G2OC = dyn_cast<ConstantInt>(const_cast<Value*>(G2Oper))){
if (G1OC->getType() != G2OC->getType()) {
// Sign extend both operands to long.
- G1OC = ConstantExpr::getSignExtend(G1OC, Type::LongTy);
- G2OC = ConstantExpr::getSignExtend(G2OC, Type::LongTy);
+ if (G1OC->getType() != Type::Int64Ty)
+ G1OC = ConstantExpr::getSExt(G1OC, Type::Int64Ty);
+ if (G2OC->getType() != Type::Int64Ty)
+ G2OC = ConstantExpr::getSExt(G2OC, Type::Int64Ty);
GEP1Ops[FirstConstantOper] = G1OC;
GEP2Ops[FirstConstantOper] = G2OC;
}
if (G1OC != G2OC) {
- // Handle the "be careful" case above: if this is an array
+ // Handle the "be careful" case above: if this is an array/packed
// subscript, scan for a subsequent variable array index.
- if (isa<ArrayType>(BasePtr1Ty)) {
- const Type *NextTy =cast<ArrayType>(BasePtr1Ty)->getElementType();
+ if (isa<SequentialType>(BasePtr1Ty)) {
+ const Type *NextTy =
+ cast<SequentialType>(BasePtr1Ty)->getElementType();
bool isBadCase = false;
for (unsigned Idx = FirstConstantOper+1;
- Idx != MinOperands && isa<ArrayType>(NextTy); ++Idx) {
+ Idx != MinOperands && isa<SequentialType>(NextTy); ++Idx) {
const Value *V1 = GEP1Ops[Idx], *V2 = GEP2Ops[Idx];
if (!isa<Constant>(V1) || !isa<Constant>(V2)) {
isBadCase = true;
break;
}
- NextTy = cast<ArrayType>(NextTy)->getElementType();
+ NextTy = cast<SequentialType>(NextTy)->getElementType();
}
if (isBadCase) G1OC = 0;
// Make sure they are comparable (ie, not constant expressions), and
// make sure the GEP with the smaller leading constant is GEP1.
if (G1OC) {
- Constant *Compare = ConstantExpr::getSetGT(G1OC, G2OC);
- if (ConstantBool *CV = dyn_cast<ConstantBool>(Compare)) {
- if (CV->getValue()) // If they are comparable and G2 > G1
+ Constant *Compare = ConstantExpr::getICmp(ICmpInst::ICMP_SGT,
+ G1OC, G2OC);
+ if (ConstantInt *CV = dyn_cast<ConstantInt>(Compare)) {
+ if (CV->getZExtValue()) // If they are comparable and G2 > G1
std::swap(GEP1Ops, GEP2Ops); // Make GEP1 < GEP2
break;
}
// Is there anything to check?
if (GEP1Ops.size() > MinOperands) {
for (unsigned i = FirstConstantOper; i != MaxOperands; ++i)
- if (isa<ConstantInt>(GEP1Ops[i]) &&
+ if (isa<ConstantInt>(GEP1Ops[i]) &&
!cast<Constant>(GEP1Ops[i])->isNullValue()) {
// Yup, there's a constant in the tail. Set all variables to
// constants in the GEP instruction to make it suiteable for
const Type *ZeroIdxTy = GEPPointerTy;
for (unsigned i = 0; i != FirstConstantOper; ++i) {
if (!isa<StructType>(ZeroIdxTy))
- GEP1Ops[i] = GEP2Ops[i] = Constant::getNullValue(Type::UIntTy);
+ GEP1Ops[i] = GEP2Ops[i] = Constant::getNullValue(Type::Int32Ty);
if (const CompositeType *CT = dyn_cast<CompositeType>(ZeroIdxTy))
ZeroIdxTy = CT->getTypeAtIndex(GEP1Ops[i]);
if (Op1) {
if (const ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
// If this is an array index, make sure the array element is in range.
- if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty))
- if (Op1C->getRawValue() >= AT->getNumElements())
+ if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty)) {
+ if (Op1C->getZExtValue() >= AT->getNumElements())
return MayAlias; // Be conservative with out-of-range accesses
-
+ } else if (const PackedType *PT = dyn_cast<PackedType>(BasePtr1Ty)) {
+ if (Op1C->getZExtValue() >= PT->getNumElements())
+ return MayAlias; // Be conservative with out-of-range accesses
+ }
+
} else {
// GEP1 is known to produce a value less than GEP2. To be
// conservatively correct, we must assume the largest possible
// value possible.
//
if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty))
- GEP1Ops[i] = ConstantSInt::get(Type::LongTy,AT->getNumElements()-1);
+ GEP1Ops[i] = ConstantInt::get(Type::Int64Ty, AT->getNumElements()-1);
+ else if (const PackedType *PT = dyn_cast<PackedType>(BasePtr1Ty))
+ GEP1Ops[i] = ConstantInt::get(Type::Int64Ty, PT->getNumElements()-1);
+
}
}
if (Op2) {
if (const ConstantInt *Op2C = dyn_cast<ConstantInt>(Op2)) {
// If this is an array index, make sure the array element is in range.
- if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty))
- if (Op2C->getRawValue() >= AT->getNumElements())
+ if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty)) {
+ if (Op2C->getZExtValue() >= AT->getNumElements())
+ return MayAlias; // Be conservative with out-of-range accesses
+ } else if (const PackedType *PT = dyn_cast<PackedType>(BasePtr1Ty)) {
+ if (Op2C->getZExtValue() >= PT->getNumElements())
return MayAlias; // Be conservative with out-of-range accesses
+ }
} else { // Conservatively assume the minimum value for this index
GEP2Ops[i] = Constant::getNullValue(Op2->getType());
}
assert(Offset1<Offset2 && "There is at least one different constant here!");
if ((uint64_t)(Offset2-Offset1) >= SizeMax) {
- //std::cerr << "Determined that these two GEP's don't alias ["
- // << SizeMax << " bytes]: \n" << *GEP1 << *GEP2;
+ //cerr << "Determined that these two GEP's don't alias ["
+ // << SizeMax << " bytes]: \n" << *GEP1 << *GEP2;
return NoAlias;
}
}
"feof_unlocked", "ferror_unlocked", "fileno_unlocked"
};
+static ManagedStatic<std::vector<const char*> > NoMemoryTable;
+static ManagedStatic<std::vector<const char*> > OnlyReadsMemoryTable;
+
+
AliasAnalysis::ModRefBehavior
BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS,
std::vector<PointerAccessInfo> *Info) {
if (!F->isExternal()) return UnknownModRefBehavior;
- static std::vector<const char*> NoMemoryTable, OnlyReadsMemoryTable;
-
static bool Initialized = false;
if (!Initialized) {
- NoMemoryTable.insert(NoMemoryTable.end(),
- DoesntAccessMemoryFns,
- DoesntAccessMemoryFns+
+ NoMemoryTable->insert(NoMemoryTable->end(),
+ DoesntAccessMemoryFns,
+ DoesntAccessMemoryFns+
sizeof(DoesntAccessMemoryFns)/sizeof(DoesntAccessMemoryFns[0]));
- OnlyReadsMemoryTable.insert(OnlyReadsMemoryTable.end(),
+ OnlyReadsMemoryTable->insert(OnlyReadsMemoryTable->end(),
OnlyReadsMemoryFns,
OnlyReadsMemoryFns+
sizeof(OnlyReadsMemoryFns)/sizeof(OnlyReadsMemoryFns[0]));
#undef GET_MODREF_BEHAVIOR
// Sort the table the first time through.
- std::sort(NoMemoryTable.begin(), NoMemoryTable.end(), StringCompare());
- std::sort(OnlyReadsMemoryTable.begin(), OnlyReadsMemoryTable.end(),
+ std::sort(NoMemoryTable->begin(), NoMemoryTable->end(), StringCompare());
+ std::sort(OnlyReadsMemoryTable->begin(), OnlyReadsMemoryTable->end(),
StringCompare());
Initialized = true;
}
std::vector<const char*>::iterator Ptr =
- std::lower_bound(NoMemoryTable.begin(), NoMemoryTable.end(),
+ std::lower_bound(NoMemoryTable->begin(), NoMemoryTable->end(),
F->getName().c_str(), StringCompare());
- if (Ptr != NoMemoryTable.end() && *Ptr == F->getName())
+ if (Ptr != NoMemoryTable->end() && *Ptr == F->getName())
return DoesNotAccessMemory;
- Ptr = std::lower_bound(OnlyReadsMemoryTable.begin(),
- OnlyReadsMemoryTable.end(),
+ Ptr = std::lower_bound(OnlyReadsMemoryTable->begin(),
+ OnlyReadsMemoryTable->end(),
F->getName().c_str(), StringCompare());
- if (Ptr != OnlyReadsMemoryTable.end() && *Ptr == F->getName())
+ if (Ptr != OnlyReadsMemoryTable->end() && *Ptr == F->getName())
return OnlyReadsMemory;
return UnknownModRefBehavior;