///
struct NoAA : public ImmutablePass, public AliasAnalysis {
static char ID; // Class identification, replacement for typeinfo
- NoAA() : ImmutablePass(&ID) {}
- explicit NoAA(void *PID) : ImmutablePass(PID) { }
+ NoAA() : ImmutablePass(ID) {}
+ explicit NoAA(char &PID) : ImmutablePass(PID) { }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
}
return MayAlias;
}
- virtual void getArgumentAccesses(Function *F, CallSite CS,
- std::vector<PointerAccessInfo> &Info) {
- llvm_unreachable("This method may not be called on this function!");
- }
-
virtual bool pointsToConstantMemory(const Value *P) { return false; }
- virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
+ const Value *P, unsigned Size) {
return ModRef;
}
- virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
+ virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
return ModRef;
}
virtual void copyValue(Value *From, Value *To) {}
/// getAdjustedAnalysisPointer - This method is used when a pass implements
- /// an analysis interface through multiple inheritance. If needed, it should
- /// override this to adjust the this pointer as needed for the specified pass
- /// info.
- virtual void *getAdjustedAnalysisPointer(const StaticPassInfo *PI) {
- if (PI->isPassID(&AliasAnalysis::ID))
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
+ if (PI == &AliasAnalysis::ID)
return (AliasAnalysis*)this;
return this;
}
// Register this pass...
char NoAA::ID = 0;
-static RegisterPass<NoAA>
-U("no-aa", "No Alias Analysis (always returns 'may' alias)", true, true);
-
-// Declare that we implement the AliasAnalysis interface
-static RegisterAnalysisGroup<AliasAnalysis> V(U);
+INITIALIZE_AG_PASS(NoAA, AliasAnalysis, "no-aa",
+ "No Alias Analysis (always returns 'may' alias)",
+ true, true, false);
ImmutablePass *llvm::createNoAAPass() { return new NoAA(); }
/// derives from the NoAA class.
struct BasicAliasAnalysis : public NoAA {
static char ID; // Class identification, replacement for typeinfo
- BasicAliasAnalysis() : NoAA(&ID) {}
+ BasicAliasAnalysis() : NoAA(ID) {}
AliasResult alias(const Value *V1, unsigned V1Size,
const Value *V2, unsigned V2Size) {
return Alias;
}
- ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
- ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
+ ModRefResult getModRefInfo(ImmutableCallSite CS,
+ const Value *P, unsigned Size);
+ ModRefResult getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2);
/// pointsToConstantMemory - Chase pointers until we find a (constant
/// global) or not.
bool pointsToConstantMemory(const Value *P);
/// getAdjustedAnalysisPointer - This method is used when a pass implements
- /// an analysis interface through multiple inheritance. If needed, it should
- /// override this to adjust the this pointer as needed for the specified pass
- /// info.
- virtual void *getAdjustedAnalysisPointer(const StaticPassInfo *PI) {
- if (PI->isPassID(&AliasAnalysis::ID))
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
+ if (PI == &AliasAnalysis::ID)
return (AliasAnalysis*)this;
return this;
}
// Register this pass...
char BasicAliasAnalysis::ID = 0;
-static RegisterPass<BasicAliasAnalysis>
-X("basicaa", "Basic Alias Analysis (default AA impl)", false, true);
-
-// Declare that we implement the AliasAnalysis interface
-static RegisterAnalysisGroup<AliasAnalysis, true> Y(X);
+INITIALIZE_AG_PASS(BasicAliasAnalysis, AliasAnalysis, "basicaa",
+ "Basic Alias Analysis (default AA impl)",
+ false, true, true);
ImmutablePass *llvm::createBasicAliasAnalysisPass() {
return new BasicAliasAnalysis();
/// 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(CallSite CS, Value *P, unsigned Size) {
+BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const Value *P, unsigned Size) {
assert(notDifferentParent(CS.getInstruction(), P) &&
"AliasAnalysis query involving multiple functions!");
// the current function not to the current function, and a tail callee
// may reference them.
if (isa<AllocaInst>(Object))
- if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
+ if (const CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
if (CI->isTailCall())
return NoModRef;
isNonEscapingLocalObject(Object)) {
bool PassedAsArg = false;
unsigned ArgNo = 0;
- for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
+ for (ImmutableCallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
CI != CE; ++CI, ++ArgNo) {
// Only look at the no-capture pointer arguments.
if (!(*CI)->getType()->isPointerTy() ||
// 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(cast<Value>(CI), ~0U, P, ~0U)) {
+ if (!isNoAlias(cast<Value>(CI), UnknownSize, P, UnknownSize)) {
PassedAsArg = true;
break;
}
}
// Finally, handle specific knowledge of intrinsics.
- IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction());
+ const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction());
if (II == 0)
return AliasAnalysis::getModRefInfo(CS, P, Size);
default: break;
case Intrinsic::memcpy:
case Intrinsic::memmove: {
- unsigned Len = ~0U;
+ unsigned Len = UnknownSize;
if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
Len = LenCI->getZExtValue();
Value *Dest = II->getArgOperand(0);
AliasAnalysis::ModRefResult
-BasicAliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) {
+BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
// If CS1 or CS2 are readnone, they don't interact.
ModRefBehavior CS1B = AliasAnalysis::getModRefBehavior(CS1);
if (CS1B == DoesNotAccessMemory) return NoModRef;
ModRefBehavior CS2B = AliasAnalysis::getModRefBehavior(CS2);
if (CS2B == DoesNotAccessMemory) return NoModRef;
- // If they both only read from memory, just return ref.
+ // If they both only read from memory, there is no dependence.
if (CS1B == OnlyReadsMemory && CS2B == OnlyReadsMemory)
- return Ref;
+ 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 (CS1B == OnlyReadsMemory)
+ 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 (CS2B == AccessesArguments) {
+ AliasAnalysis::ModRefResult R = NoModRef;
+ for (ImmutableCallSite::arg_iterator
+ I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
+ R = ModRefResult((R | getModRefInfo(CS1, *I, UnknownSize)) & 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 (CS1B == AccessesArguments) {
+ AliasAnalysis::ModRefResult R = NoModRef;
+ for (ImmutableCallSite::arg_iterator
+ I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I)
+ if (getModRefInfo(CS2, *I, UnknownSize) != NoModRef) {
+ R = Mask;
+ break;
+ }
+ if (R == NoModRef)
+ return R;
+ }
+
// Otherwise, fall back to NoAA (mod+ref).
- return NoAA::getModRefInfo(CS1, CS2);
+ return ModRefResult(NoAA::getModRefInfo(CS1, CS2) & Mask);
}
-/// GetIndiceDifference - Dest and Src are the variable indices from two
+/// GetIndexDifference - Dest and Src are the variable indices from two
/// decomposed GetElementPtr instructions GEP1 and GEP2 which have common base
/// pointers. Subtract the GEP2 indices from GEP1 to find the symbolic
/// difference between the two pointers.
-static void GetIndiceDifference(
+static void GetIndexDifference(
SmallVectorImpl<std::pair<const Value*, int64_t> > &Dest,
const SmallVectorImpl<std::pair<const Value*, int64_t> > &Src) {
if (Src.empty()) return;
// out if the indexes to the GEP tell us anything about the derived pointer.
if (const GEPOperator *GEP2 = dyn_cast<GEPOperator>(V2)) {
// Do the base pointers alias?
- AliasResult BaseAlias = aliasCheck(UnderlyingV1, ~0U, UnderlyingV2, ~0U);
+ AliasResult BaseAlias = aliasCheck(UnderlyingV1, UnknownSize,
+ UnderlyingV2, UnknownSize);
// If we get a No or May, then return it immediately, no amount of analysis
// will improve this situation.
// Subtract the GEP2 pointer from the GEP1 pointer to find out their
// symbolic difference.
GEP1BaseOffset -= GEP2BaseOffset;
- GetIndiceDifference(GEP1VariableIndices, GEP2VariableIndices);
+ GetIndexDifference(GEP1VariableIndices, GEP2VariableIndices);
} else {
// Check to see if these two pointers are related by the getelementptr
// pointer, we know they cannot alias.
// If both accesses are unknown size, we can't do anything useful here.
- if (V1Size == ~0U && V2Size == ~0U)
+ if (V1Size == UnknownSize && V2Size == UnknownSize)
return MayAlias;
- AliasResult R = aliasCheck(UnderlyingV1, ~0U, V2, V2Size);
+ AliasResult R = aliasCheck(UnderlyingV1, UnknownSize, V2, V2Size);
if (R != MustAlias)
// If V2 may alias GEP base pointer, conservatively returns MayAlias.
// If V2 is known not to alias GEP base pointer, then the two values
// If the size of one access is larger than the entire object on the other
// side, then we know such behavior is undefined and can assume no alias.
if (TD)
- if ((V1Size != ~0U && isObjectSmallerThan(O2, V1Size, *TD)) ||
- (V2Size != ~0U && isObjectSmallerThan(O1, V2Size, *TD)))
+ if ((V1Size != UnknownSize && isObjectSmallerThan(O2, V1Size, *TD)) ||
+ (V2Size != UnknownSize && isObjectSmallerThan(O1, V2Size, *TD)))
return NoAlias;
// FIXME: This isn't aggressively handling alias(GEP, PHI) for example: if the