MustAlias,
};
+/// Flags indicating whether a memory access modifies or references memory.
+///
+/// This is no access at all, a modification, a reference, or both
+/// a modification and a reference. These are specifically structured such that
+/// they form a two bit matrix and bit-tests for 'mod' or 'ref' work with any
+/// of the possible values.
+enum ModRefInfo {
+ /// The access neither references nor modifies the value stored in memory.
+ MRI_NoModRef = 0,
+ /// The access references the value stored in memory.
+ MRI_Ref = 1,
+ /// The access modifies the value stored in memory.
+ MRI_Mod = 2,
+ /// The access both references and modifies the value stored in memory.
+ MRI_ModRef = MRI_Ref | MRI_Mod
+};
+
+/// The locations at which a function might access memory.
+///
+/// These are primarily used in conjunction with the \c AccessKind bits to
+/// describe both the nature of access and the locations of access for a
+/// function call.
+enum FunctionModRefLocation {
+ /// Base case is no access to memory.
+ FMRL_Nowhere = 0,
+ /// Access to memory via argument pointers.
+ FMRL_ArgumentPointees = 4,
+ /// Access to any memory.
+ FMRL_Anywhere = 8 | FMRL_ArgumentPointees
+};
+
+/// Summary of how a function affects memory in the program.
+///
+/// Loads from constant globals are not considered memory accesses for this
+/// interface. Also, functions may freely modify stack space local to their
+/// invocation without having to report it through these interfaces.
+enum FunctionModRefBehavior {
+ /// This function does not perform any non-local loads or stores to memory.
+ ///
+ /// This property corresponds to the GCC 'const' attribute.
+ /// This property corresponds to the LLVM IR 'readnone' attribute.
+ /// This property corresponds to the IntrNoMem LLVM intrinsic flag.
+ FMRB_DoesNotAccessMemory = FMRL_Nowhere | MRI_NoModRef,
+
+ /// The only memory references in this function (if it has any) are
+ /// non-volatile loads from objects pointed to by its pointer-typed
+ /// arguments, with arbitrary offsets.
+ ///
+ /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
+ FMRB_OnlyReadsArgumentPointees = FMRL_ArgumentPointees | MRI_Ref,
+
+ /// The only memory references in this function (if it has any) are
+ /// non-volatile loads and stores from objects pointed to by its
+ /// pointer-typed arguments, with arbitrary offsets.
+ ///
+ /// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag.
+ FMRB_OnlyAccessesArgumentPointees = FMRL_ArgumentPointees | MRI_ModRef,
+
+ /// This function does not perform any non-local stores or volatile loads,
+ /// but may read from any memory location.
+ ///
+ /// This property corresponds to the GCC 'pure' attribute.
+ /// This property corresponds to the LLVM IR 'readonly' attribute.
+ /// This property corresponds to the IntrReadMem LLVM intrinsic flag.
+ FMRB_OnlyReadsMemory = FMRL_Anywhere | MRI_Ref,
+
+ /// This indicates that the function could not be classified into one of the
+ /// behaviors above.
+ FMRB_UnknownModRefBehavior = FMRL_Anywhere | MRI_ModRef
+};
+
class AliasAnalysis {
protected:
const DataLayout *DL;
/// Simple mod/ref information...
///
- /// ModRefResult - Represent the result of a mod/ref query. Mod and Ref are
- /// bits which may be or'd together.
- ///
- enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 };
-
- /// These values define additional bits used to define the
- /// ModRefBehavior values.
- enum { Nowhere = 0, ArgumentPointees = 4, Anywhere = 8 | ArgumentPointees };
-
- /// ModRefBehavior - Summary of how a function affects memory in the program.
- /// Loads from constant globals are not considered memory accesses for this
- /// interface. Also, functions may freely modify stack space local to their
- /// invocation without having to report it through these interfaces.
- enum ModRefBehavior {
- /// DoesNotAccessMemory - This function does not perform any non-local loads
- /// or stores to memory.
- ///
- /// This property corresponds to the GCC 'const' attribute.
- /// This property corresponds to the LLVM IR 'readnone' attribute.
- /// This property corresponds to the IntrNoMem LLVM intrinsic flag.
- DoesNotAccessMemory = Nowhere | NoModRef,
-
- /// OnlyReadsArgumentPointees - The only memory references in this function
- /// (if it has any) are non-volatile loads from objects pointed to by its
- /// pointer-typed arguments, with arbitrary offsets.
- ///
- /// This property corresponds to the LLVM IR 'argmemonly' attribute combined
- /// with 'readonly' attribute.
- /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
- OnlyReadsArgumentPointees = ArgumentPointees | Ref,
-
- /// OnlyAccessesArgumentPointees - The only memory references in this
- /// function (if it has any) are non-volatile loads and stores from objects
- /// pointed to by its pointer-typed arguments, with arbitrary offsets.
- ///
- /// This property corresponds to the LLVM IR 'argmemonly' attribute.
- /// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag.
- OnlyAccessesArgumentPointees = ArgumentPointees | ModRef,
-
- /// OnlyReadsMemory - This function does not perform any non-local stores or
- /// volatile loads, but may read from any memory location.
- ///
- /// This property corresponds to the GCC 'pure' attribute.
- /// This property corresponds to the LLVM IR 'readonly' attribute.
- /// This property corresponds to the IntrReadMem LLVM intrinsic flag.
- OnlyReadsMemory = Anywhere | Ref,
-
- /// UnknownModRefBehavior - This indicates that the function could not be
- /// classified into one of the behaviors above.
- UnknownModRefBehavior = Anywhere | ModRef
- };
-
/// Get the ModRef info associated with a pointer argument of a callsite. The
/// result's bits are set to indicate the allowed aliasing ModRef kinds. Note
/// that these bits do not necessarily account for the overall behavior of
/// the function, but rather only provide additional per-argument
/// information.
- virtual ModRefResult getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx);
+ virtual ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx);
/// getModRefBehavior - Return the behavior when calling the given call site.
- virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
+ virtual FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS);
/// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known.
- virtual ModRefBehavior getModRefBehavior(const Function *F);
+ virtual FunctionModRefBehavior getModRefBehavior(const Function *F);
/// doesNotAccessMemory - If the specified call is known to never read or
/// write memory, return true. If the call only reads from known-constant
/// This property corresponds to the GCC 'const' attribute.
///
bool doesNotAccessMemory(ImmutableCallSite CS) {
- return getModRefBehavior(CS) == DoesNotAccessMemory;
+ return getModRefBehavior(CS) == FMRB_DoesNotAccessMemory;
}
/// doesNotAccessMemory - If the specified function is known to never read or
/// write memory, return true. For use when the call site is not known.
///
bool doesNotAccessMemory(const Function *F) {
- return getModRefBehavior(F) == DoesNotAccessMemory;
+ return getModRefBehavior(F) == FMRB_DoesNotAccessMemory;
}
/// onlyReadsMemory - If the specified call is known to only read from
/// onlyReadsMemory - Return true if functions with the specified behavior are
/// known to only read from non-volatile memory (or not access memory at all).
///
- static bool onlyReadsMemory(ModRefBehavior MRB) {
- return !(MRB & Mod);
+ static bool onlyReadsMemory(FunctionModRefBehavior MRB) {
+ return !(MRB & MRI_Mod);
}
/// onlyAccessesArgPointees - Return true if functions with the specified
/// behavior are known to read and write at most from objects pointed to by
/// their pointer-typed arguments (with arbitrary offsets).
///
- static bool onlyAccessesArgPointees(ModRefBehavior MRB) {
- return !(MRB & Anywhere & ~ArgumentPointees);
+ static bool onlyAccessesArgPointees(FunctionModRefBehavior MRB) {
+ return !(MRB & FMRL_Anywhere & ~FMRL_ArgumentPointees);
}
/// doesAccessArgPointees - Return true if functions with the specified
/// behavior are known to potentially read or write from objects pointed
/// to be their pointer-typed arguments (with arbitrary offsets).
///
- static bool doesAccessArgPointees(ModRefBehavior MRB) {
- return (MRB & ModRef) && (MRB & ArgumentPointees);
+ static bool doesAccessArgPointees(FunctionModRefBehavior MRB) {
+ return (MRB & MRI_ModRef) && (MRB & FMRL_ArgumentPointees);
}
/// getModRefInfo - Return information about whether or not an
/// instruction may read or write memory (without regard to a
/// specific location)
- ModRefResult getModRefInfo(const Instruction *I) {
+ ModRefInfo getModRefInfo(const Instruction *I) {
if (auto CS = ImmutableCallSite(I)) {
auto MRB = getModRefBehavior(CS);
- if (MRB & ModRef)
- return ModRef;
- else if (MRB & Ref)
- return Ref;
- else if (MRB & Mod)
- return Mod;
- return NoModRef;
+ if (MRB & MRI_ModRef)
+ return MRI_ModRef;
+ else if (MRB & MRI_Ref)
+ return MRI_Ref;
+ else if (MRB & MRI_Mod)
+ return MRI_Mod;
+ return MRI_NoModRef;
}
return getModRefInfo(I, MemoryLocation());
/// getModRefInfo - Return information about whether or not an instruction may
/// read or write the specified memory location. An instruction
/// that doesn't read or write memory may be trivially LICM'd for example.
- ModRefResult getModRefInfo(const Instruction *I, const MemoryLocation &Loc) {
+ ModRefInfo getModRefInfo(const Instruction *I, const MemoryLocation &Loc) {
switch (I->getOpcode()) {
case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc);
case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc);
return getModRefInfo((const AtomicRMWInst*)I, Loc);
case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc);
case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
- default: return NoModRef;
+ default:
+ return MRI_NoModRef;
}
}
/// getModRefInfo - A convenience wrapper.
- ModRefResult getModRefInfo(const Instruction *I,
- const Value *P, uint64_t Size) {
+ ModRefInfo getModRefInfo(const Instruction *I, const Value *P,
+ uint64_t Size) {
return getModRefInfo(I, MemoryLocation(P, Size));
}
/// getModRefInfo (for call sites) - Return information about whether
/// a particular call site modifies or reads the specified memory location.
- virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc);
+ virtual ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc);
/// getModRefInfo (for call sites) - A convenience wrapper.
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const Value *P, uint64_t Size) {
+ ModRefInfo getModRefInfo(ImmutableCallSite CS, const Value *P,
+ uint64_t Size) {
return getModRefInfo(CS, MemoryLocation(P, Size));
}
/// getModRefInfo (for calls) - Return information about whether
/// a particular call modifies or reads the specified memory location.
- ModRefResult getModRefInfo(const CallInst *C, const MemoryLocation &Loc) {
+ ModRefInfo getModRefInfo(const CallInst *C, const MemoryLocation &Loc) {
return getModRefInfo(ImmutableCallSite(C), Loc);
}
/// getModRefInfo (for calls) - A convenience wrapper.
- ModRefResult getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) {
+ ModRefInfo getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) {
return getModRefInfo(C, MemoryLocation(P, Size));
}
/// getModRefInfo (for invokes) - Return information about whether
/// a particular invoke modifies or reads the specified memory location.
- ModRefResult getModRefInfo(const InvokeInst *I, const MemoryLocation &Loc) {
+ ModRefInfo getModRefInfo(const InvokeInst *I, const MemoryLocation &Loc) {
return getModRefInfo(ImmutableCallSite(I), Loc);
}
/// getModRefInfo (for invokes) - A convenience wrapper.
- ModRefResult getModRefInfo(const InvokeInst *I,
- const Value *P, uint64_t Size) {
+ ModRefInfo getModRefInfo(const InvokeInst *I, const Value *P, uint64_t Size) {
return getModRefInfo(I, MemoryLocation(P, Size));
}
/// getModRefInfo (for loads) - Return information about whether
/// a particular load modifies or reads the specified memory location.
- ModRefResult getModRefInfo(const LoadInst *L, const MemoryLocation &Loc);
+ ModRefInfo getModRefInfo(const LoadInst *L, const MemoryLocation &Loc);
/// getModRefInfo (for loads) - A convenience wrapper.
- ModRefResult getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) {
+ ModRefInfo getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) {
return getModRefInfo(L, MemoryLocation(P, Size));
}
/// getModRefInfo (for stores) - Return information about whether
/// a particular store modifies or reads the specified memory location.
- ModRefResult getModRefInfo(const StoreInst *S, const MemoryLocation &Loc);
+ ModRefInfo getModRefInfo(const StoreInst *S, const MemoryLocation &Loc);
/// getModRefInfo (for stores) - A convenience wrapper.
- ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size){
+ ModRefInfo getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size) {
return getModRefInfo(S, MemoryLocation(P, Size));
}
/// getModRefInfo (for fences) - Return information about whether
/// a particular store modifies or reads the specified memory location.
- ModRefResult getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) {
+ ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) {
// Conservatively correct. (We could possibly be a bit smarter if
// Loc is a alloca that doesn't escape.)
- return ModRef;
+ return MRI_ModRef;
}
/// getModRefInfo (for fences) - A convenience wrapper.
- ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size){
+ ModRefInfo getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size) {
return getModRefInfo(S, MemoryLocation(P, Size));
}
/// getModRefInfo (for cmpxchges) - Return information about whether
/// a particular cmpxchg modifies or reads the specified memory location.
- ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX,
- const MemoryLocation &Loc);
+ ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX,
+ const MemoryLocation &Loc);
/// getModRefInfo (for cmpxchges) - A convenience wrapper.
- ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX,
- const Value *P, unsigned Size) {
+ ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX, const Value *P,
+ unsigned Size) {
return getModRefInfo(CX, MemoryLocation(P, Size));
}
/// getModRefInfo (for atomicrmws) - Return information about whether
/// a particular atomicrmw modifies or reads the specified memory location.
- ModRefResult getModRefInfo(const AtomicRMWInst *RMW,
- const MemoryLocation &Loc);
+ ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc);
/// getModRefInfo (for atomicrmws) - A convenience wrapper.
- ModRefResult getModRefInfo(const AtomicRMWInst *RMW,
- const Value *P, unsigned Size) {
+ ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const Value *P,
+ unsigned Size) {
return getModRefInfo(RMW, MemoryLocation(P, Size));
}
/// getModRefInfo (for va_args) - Return information about whether
/// a particular va_arg modifies or reads the specified memory location.
- ModRefResult getModRefInfo(const VAArgInst *I, const MemoryLocation &Loc);
+ ModRefInfo getModRefInfo(const VAArgInst *I, const MemoryLocation &Loc);
/// getModRefInfo (for va_args) - A convenience wrapper.
- ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){
+ ModRefInfo getModRefInfo(const VAArgInst *I, const Value *P, uint64_t Size) {
return getModRefInfo(I, MemoryLocation(P, Size));
}
/// getModRefInfo - Return information about whether a call and an instruction
/// may refer to the same memory locations.
- ModRefResult getModRefInfo(Instruction *I,
- ImmutableCallSite Call);
+ ModRefInfo getModRefInfo(Instruction *I, ImmutableCallSite Call);
/// getModRefInfo - Return information about whether two call sites may refer
/// to the same set of memory locations. See
/// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
/// for details.
- virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2);
+ virtual ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2);
/// callCapturesBefore - Return information about whether a particular call
/// site modifies or reads the specified memory location.
- ModRefResult callCapturesBefore(const Instruction *I,
- const MemoryLocation &MemLoc,
- DominatorTree *DT);
+ ModRefInfo callCapturesBefore(const Instruction *I,
+ const MemoryLocation &MemLoc,
+ DominatorTree *DT);
/// callCapturesBefore - A convenience wrapper.
- ModRefResult callCapturesBefore(const Instruction *I, const Value *P,
- uint64_t Size, DominatorTree *DT) {
+ ModRefInfo callCapturesBefore(const Instruction *I, const Value *P,
+ uint64_t Size, DominatorTree *DT) {
return callCapturesBefore(I, MemoryLocation(P, Size), DT);
}
/// I1 and I2 must be in the same basic block.
bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2,
const MemoryLocation &Loc,
- const ModRefResult Mode);
+ const ModRefInfo Mode);
/// canInstructionRangeModRef - A convenience wrapper.
- bool canInstructionRangeModRef(const Instruction &I1,
- const Instruction &I2, const Value *Ptr,
- uint64_t Size, const ModRefResult Mode) {
+ bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2,
+ const Value *Ptr, uint64_t Size,
+ const ModRefInfo Mode) {
return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode);
}
};
}
~LibCallAliasAnalysis() override;
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override {
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override {
// TODO: Could compare two direct calls against each other if we cared to.
return AliasAnalysis::getModRefInfo(CS1, CS2);
}
}
private:
- ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
- ImmutableCallSite CS,
- const MemoryLocation &Loc);
+ ModRefInfo AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
+ ImmutableCallSite CS,
+ const MemoryLocation &Loc);
};
} // End of llvm namespace
/// any specific context knowledge. For example, if the function is known
/// to be readonly, this would be set to 'ref'. If known to be readnone,
/// this is set to NoModRef.
- AliasAnalysis::ModRefResult UniversalBehavior;
-
+ ModRefInfo UniversalBehavior;
+
/// LocationMRInfo - This pair captures info about whether a specific
/// location is modified or referenced by a libcall.
struct LocationMRInfo {
/// LocationID - ID # of the accessed location or ~0U for array end.
unsigned LocationID;
/// MRInfo - Mod/Ref info for this location.
- AliasAnalysis::ModRefResult MRInfo;
+ ModRefInfo MRInfo;
};
/// DetailsType - Indicate the sense of the LocationDetails array. This
return AA->pointsToConstantMemory(Loc, OrLocal);
}
-AliasAnalysis::ModRefResult
-AliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
+ModRefInfo AliasAnalysis::getArgModRefInfo(ImmutableCallSite CS,
+ unsigned ArgIdx) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
return AA->getArgModRefInfo(CS, ArgIdx);
}
-AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(Instruction *I, ImmutableCallSite Call) {
+ModRefInfo AliasAnalysis::getModRefInfo(Instruction *I,
+ ImmutableCallSite Call) {
// We may have two calls
if (auto CS = ImmutableCallSite(I)) {
// Check if the two calls modify the same memory
// is that if the call references what this instruction
// defines, it must be clobbered by this location.
const MemoryLocation DefLoc = MemoryLocation::get(I);
- if (getModRefInfo(Call, DefLoc) != AliasAnalysis::NoModRef)
- return AliasAnalysis::ModRef;
+ if (getModRefInfo(Call, DefLoc) != MRI_NoModRef)
+ return MRI_ModRef;
}
- return AliasAnalysis::NoModRef;
+ return MRI_NoModRef;
}
-AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
+ModRefInfo AliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
- ModRefBehavior MRB = getModRefBehavior(CS);
- if (MRB == DoesNotAccessMemory)
- return NoModRef;
+ auto MRB = getModRefBehavior(CS);
+ if (MRB == FMRB_DoesNotAccessMemory)
+ return MRI_NoModRef;
- ModRefResult Mask = ModRef;
+ ModRefInfo Mask = MRI_ModRef;
if (onlyReadsMemory(MRB))
- Mask = Ref;
+ Mask = MRI_Ref;
if (onlyAccessesArgPointees(MRB)) {
bool doesAlias = false;
- ModRefResult AllArgsMask = NoModRef;
+ ModRefInfo AllArgsMask = MRI_NoModRef;
if (doesAccessArgPointees(MRB)) {
for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
AI != AE; ++AI) {
MemoryLocation ArgLoc =
MemoryLocation::getForArgument(CS, ArgIdx, *TLI);
if (!isNoAlias(ArgLoc, Loc)) {
- ModRefResult ArgMask = getArgModRefInfo(CS, ArgIdx);
+ ModRefInfo ArgMask = getArgModRefInfo(CS, ArgIdx);
doesAlias = true;
- AllArgsMask = ModRefResult(AllArgsMask | ArgMask);
+ AllArgsMask = ModRefInfo(AllArgsMask | ArgMask);
}
}
}
if (!doesAlias)
- return NoModRef;
- Mask = ModRefResult(Mask & AllArgsMask);
+ return MRI_NoModRef;
+ Mask = ModRefInfo(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 ((Mask & MRI_Mod) && pointsToConstantMemory(Loc))
+ Mask = ModRefInfo(Mask & ~MRI_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);
+ return ModRefInfo(AA->getModRefInfo(CS, Loc) & Mask);
}
-AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
+ModRefInfo 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;
+ auto CS1B = getModRefBehavior(CS1);
+ if (CS1B == FMRB_DoesNotAccessMemory)
+ return MRI_NoModRef;
- ModRefBehavior CS2B = getModRefBehavior(CS2);
- if (CS2B == DoesNotAccessMemory) return NoModRef;
+ auto CS2B = getModRefBehavior(CS2);
+ if (CS2B == FMRB_DoesNotAccessMemory)
+ return MRI_NoModRef;
// If they both only read from memory, there is no dependence.
if (onlyReadsMemory(CS1B) && onlyReadsMemory(CS2B))
- return NoModRef;
+ return MRI_NoModRef;
- AliasAnalysis::ModRefResult Mask = ModRef;
+ ModRefInfo Mask = MRI_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);
+ Mask = ModRefInfo(Mask & MRI_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;
+ ModRefInfo R = MRI_NoModRef;
if (doesAccessArgPointees(CS2B)) {
for (ImmutableCallSite::arg_iterator
I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
// ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence of
// CS1 on that location is the inverse.
- ModRefResult ArgMask = getArgModRefInfo(CS2, CS2ArgIdx);
- if (ArgMask == Mod)
- ArgMask = ModRef;
- else if (ArgMask == Ref)
- ArgMask = Mod;
+ ModRefInfo ArgMask = getArgModRefInfo(CS2, CS2ArgIdx);
+ if (ArgMask == MRI_Mod)
+ ArgMask = MRI_ModRef;
+ else if (ArgMask == MRI_Ref)
+ ArgMask = MRI_Mod;
- R = ModRefResult((R | (getModRefInfo(CS1, CS2ArgLoc) & ArgMask)) & Mask);
+ R = ModRefInfo((R | (getModRefInfo(CS1, CS2ArgLoc) & ArgMask)) & Mask);
if (R == Mask)
break;
}
// 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;
+ ModRefInfo R = MRI_NoModRef;
if (doesAccessArgPointees(CS1B)) {
for (ImmutableCallSite::arg_iterator
I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) {
// ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod
// CS1ArgLoc, 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 ArgMask = getArgModRefInfo(CS1, CS1ArgIdx);
- ModRefResult ArgR = getModRefInfo(CS2, CS1ArgLoc);
- if (((ArgMask & Mod) != NoModRef && (ArgR & ModRef) != NoModRef) ||
- ((ArgMask & Ref) != NoModRef && (ArgR & Mod) != NoModRef))
- R = ModRefResult((R | ArgMask) & Mask);
+ ModRefInfo ArgMask = getArgModRefInfo(CS1, CS1ArgIdx);
+ ModRefInfo ArgR = getModRefInfo(CS2, CS1ArgLoc);
+ if (((ArgMask & MRI_Mod) != MRI_NoModRef &&
+ (ArgR & MRI_ModRef) != MRI_NoModRef) ||
+ ((ArgMask & MRI_Ref) != MRI_NoModRef &&
+ (ArgR & MRI_Mod) != MRI_NoModRef))
+ R = ModRefInfo((R | ArgMask) & Mask);
if (R == Mask)
break;
// 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);
+ return ModRefInfo(AA->getModRefInfo(CS1, CS2) & Mask);
}
-AliasAnalysis::ModRefBehavior
-AliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
+FunctionModRefBehavior AliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
- ModRefBehavior Min = UnknownModRefBehavior;
+ auto Min = FMRB_UnknownModRefBehavior;
// Call back into the alias analysis with the other form of getModRefBehavior
// to see if it can give a better response.
// 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);
+ return FunctionModRefBehavior(AA->getModRefBehavior(CS) & Min);
}
-AliasAnalysis::ModRefBehavior
-AliasAnalysis::getModRefBehavior(const Function *F) {
+FunctionModRefBehavior 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::ModRefResult
-AliasAnalysis::getModRefInfo(const LoadInst *L, const MemoryLocation &Loc) {
+ModRefInfo AliasAnalysis::getModRefInfo(const LoadInst *L,
+ const MemoryLocation &Loc) {
// Be conservative in the face of volatile/atomic.
if (!L->isUnordered())
- return ModRef;
+ return MRI_ModRef;
// If the load address doesn't alias the given address, it doesn't read
// or write the specified memory.
if (Loc.Ptr && !alias(MemoryLocation::get(L), Loc))
- return NoModRef;
+ return MRI_NoModRef;
// Otherwise, a load just reads.
- return Ref;
+ return MRI_Ref;
}
-AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(const StoreInst *S, const MemoryLocation &Loc) {
+ModRefInfo AliasAnalysis::getModRefInfo(const StoreInst *S,
+ const MemoryLocation &Loc) {
// Be conservative in the face of volatile/atomic.
if (!S->isUnordered())
- return ModRef;
+ return MRI_ModRef;
if (Loc.Ptr) {
// If the store address cannot alias the pointer in question, then the
// specified memory cannot be modified by the store.
if (!alias(MemoryLocation::get(S), Loc))
- return NoModRef;
+ return MRI_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;
-
+ return MRI_NoModRef;
}
// Otherwise, a store just writes.
- return Mod;
+ return MRI_Mod;
}
-AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc) {
+ModRefInfo AliasAnalysis::getModRefInfo(const VAArgInst *V,
+ const MemoryLocation &Loc) {
if (Loc.Ptr) {
// If the va_arg address cannot alias the pointer in question, then the
// specified memory cannot be accessed by the va_arg.
if (!alias(MemoryLocation::get(V), Loc))
- return NoModRef;
+ return MRI_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;
+ return MRI_NoModRef;
}
// Otherwise, a va_arg reads and writes.
- return ModRef;
+ return MRI_ModRef;
}
-AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX,
- const MemoryLocation &Loc) {
+ModRefInfo AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX,
+ const MemoryLocation &Loc) {
// Acquire/Release cmpxchg has properties that matter for arbitrary addresses.
if (CX->getSuccessOrdering() > Monotonic)
- return ModRef;
+ return MRI_ModRef;
// If the cmpxchg address does not alias the location, it does not access it.
if (Loc.Ptr && !alias(MemoryLocation::get(CX), Loc))
- return NoModRef;
+ return MRI_NoModRef;
- return ModRef;
+ return MRI_ModRef;
}
-AliasAnalysis::ModRefResult
-AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW,
- const MemoryLocation &Loc) {
+ModRefInfo AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW,
+ const MemoryLocation &Loc) {
// Acquire/Release atomicrmw has properties that matter for arbitrary addresses.
if (RMW->getOrdering() > Monotonic)
- return ModRef;
+ return MRI_ModRef;
// If the atomicrmw address does not alias the location, it does not access it.
if (Loc.Ptr && !alias(MemoryLocation::get(RMW), Loc))
- return NoModRef;
+ return MRI_NoModRef;
- return ModRef;
+ return MRI_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 MemoryLocation &MemLoc, DominatorTree *DT) {
+ModRefInfo AliasAnalysis::callCapturesBefore(const Instruction *I,
+ const MemoryLocation &MemLoc,
+ DominatorTree *DT) {
if (!DT)
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
const Value *Object = GetUnderlyingObject(MemLoc.Ptr, *DL);
if (!isIdentifiedObject(Object) || isa<GlobalValue>(Object) ||
isa<Constant>(Object))
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
ImmutableCallSite CS(I);
if (!CS.getInstruction() || CS.getInstruction() == Object)
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
if (llvm::PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true,
/* StoreCaptures */ true, I, DT,
/* include Object */ true))
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
unsigned ArgNo = 0;
- AliasAnalysis::ModRefResult R = AliasAnalysis::NoModRef;
+ ModRefInfo R = MRI_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
if (CS.doesNotAccessMemory(ArgNo))
continue;
if (CS.onlyReadsMemory(ArgNo)) {
- R = AliasAnalysis::Ref;
+ R = MRI_Ref;
continue;
}
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
}
return R;
}
///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
const MemoryLocation &Loc) {
- return canInstructionRangeModRef(BB.front(), BB.back(), Loc, Mod);
+ return canInstructionRangeModRef(BB.front(), BB.back(), Loc, MRI_Mod);
}
/// canInstructionRangeModRef - Return true if it is possible for the
bool AliasAnalysis::canInstructionRangeModRef(const Instruction &I1,
const Instruction &I2,
const MemoryLocation &Loc,
- const ModRefResult Mode) {
+ const ModRefInfo Mode) {
assert(I1.getParent() == I2.getParent() &&
"Instructions not in same basic block!");
BasicBlock::const_iterator I = &I1;
<< Must*100/AASum<<"%\n\n";
}
- errs() << " " << MRSum << " Total Mod/Ref Queries Performed\n";
+ errs() << " " << MRSum << " Total MRI_Mod/MRI_Ref Queries Performed\n";
if (MRSum) {
printLine("no mod/ref", NoMR, MRSum);
printLine("ref", JustRef, MRSum);
printLine("mod", JustMod, MRSum);
printLine("mod/ref", MR, MRSum);
- errs() << " Mod/Ref Analysis Counter Summary: " <<NoMR*100/MRSum
- << "%/" << JustRef*100/MRSum << "%/" << JustMod*100/MRSum
- << "%/" << MR*100/MRSum <<"%\n\n";
+ errs() << " MRI_Mod/MRI_Ref Analysis Counter Summary: "
+ << NoMR * 100 / MRSum << "%/" << JustRef * 100 / MRSum << "%/"
+ << JustMod * 100 / MRSum << "%/" << MR * 100 / MRSum
+ << "%\n\n";
}
}
}
AliasResult alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override {
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override {
return AliasAnalysis::getModRefInfo(CS1,CS2);
}
};
return R;
}
-AliasAnalysis::ModRefResult
-AliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) {
- ModRefResult R = getAnalysis<AliasAnalysis>().getModRefInfo(CS, Loc);
+ModRefInfo AliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
+ ModRefInfo R = getAnalysis<AliasAnalysis>().getModRefInfo(CS, Loc);
const char *MRString = nullptr;
switch (R) {
- case NoModRef: NoMR++; MRString = "NoModRef"; break;
- case Ref: JustRef++; MRString = "JustRef"; break;
- case Mod: JustMod++; MRString = "JustMod"; break;
- case ModRef: MR++; MRString = "ModRef"; break;
+ case MRI_NoModRef:
+ NoMR++;
+ MRString = "MRI_NoModRef";
+ break;
+ case MRI_Ref:
+ JustRef++;
+ MRString = "JustRef";
+ break;
+ case MRI_Mod:
+ JustMod++;
+ MRString = "JustMod";
+ break;
+ case MRI_ModRef:
+ MR++;
+ MRString = "MRI_ModRef";
+ break;
}
- if (PrintAll || (PrintAllFailures && R == ModRef)) {
+ if (PrintAll || (PrintAllFailures && R == MRI_ModRef)) {
errs() << MRString << ": Ptr: ";
errs() << "[" << Loc.Size << "B] ";
Loc.Ptr->printAsOperand(errs(), true, M);
if (ElTy->isSized()) Size = AA.getTypeStoreSize(ElTy);
switch (AA.getModRefInfo(*C, *V, Size)) {
- case AliasAnalysis::NoModRef:
+ case MRI_NoModRef:
PrintModRefResults("NoModRef", PrintNoModRef, I, *V, F.getParent());
++NoModRefCount;
break;
- case AliasAnalysis::Mod:
+ case MRI_Mod:
PrintModRefResults("Just Mod", PrintMod, I, *V, F.getParent());
++ModCount;
break;
- case AliasAnalysis::Ref:
+ case MRI_Ref:
PrintModRefResults("Just Ref", PrintRef, I, *V, F.getParent());
++RefCount;
break;
- case AliasAnalysis::ModRef:
+ case MRI_ModRef:
PrintModRefResults("Both ModRef", PrintModRef, I, *V, F.getParent());
++ModRefCount;
break;
if (D == C)
continue;
switch (AA.getModRefInfo(*C, *D)) {
- case AliasAnalysis::NoModRef:
+ case MRI_NoModRef:
PrintModRefResults("NoModRef", PrintNoModRef, *C, *D, F.getParent());
++NoModRefCount;
break;
- case AliasAnalysis::Mod:
+ case MRI_Mod:
PrintModRefResults("Just Mod", PrintMod, *C, *D, F.getParent());
++ModCount;
break;
- case AliasAnalysis::Ref:
+ case MRI_Ref:
PrintModRefResults("Just Ref", PrintRef, *C, *D, F.getParent());
++RefCount;
break;
- case AliasAnalysis::ModRef:
+ case MRI_ModRef:
PrintModRefResults("Both ModRef", PrintModRef, *C, *D, F.getParent());
++ModRefCount;
break;
return AliasAnalysis::alias(LocA, LocB);
}
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override {
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override {
assert(Vals.find(Loc.Ptr) != Vals.end() && "Never seen value in AA before");
return AliasAnalysis::getModRefInfo(CS, Loc);
}
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override {
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override {
return AliasAnalysis::getModRefInfo(CS1,CS2);
}
if (!UnknownInsts.empty()) {
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
if (AA.getModRefInfo(UnknownInsts[i],
- MemoryLocation(Ptr, Size, AAInfo)) !=
- AliasAnalysis::NoModRef)
+ MemoryLocation(Ptr, Size, AAInfo)) != MRI_NoModRef)
return true;
}
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
ImmutableCallSite C1(getUnknownInst(i)), C2(Inst);
- if (!C1 || !C2 ||
- AA.getModRefInfo(C1, C2) != AliasAnalysis::NoModRef ||
- AA.getModRefInfo(C2, C1) != AliasAnalysis::NoModRef)
+ if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef ||
+ AA.getModRefInfo(C2, C1) != MRI_NoModRef)
return true;
}
for (iterator I = begin(), E = end(); I != E; ++I)
- if (AA.getModRefInfo(
- Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())) !=
- AliasAnalysis::NoModRef)
+ if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(),
+ I.getAAInfo())) != MRI_NoModRef)
return true;
return false;
return Alias;
}
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override;
/// pointsToConstantMemory - Chase pointers until we find a (constant
/// global) or not.
bool OrLocal) override;
/// Get the location associated with a pointer argument of a callsite.
- ModRefResult getArgModRefInfo(ImmutableCallSite CS,
- unsigned ArgIdx) override;
+ ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override;
/// getModRefBehavior - Return the behavior when calling the given
/// call site.
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
+ FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
/// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known.
- ModRefBehavior getModRefBehavior(const Function *F) override;
+ FunctionModRefBehavior getModRefBehavior(const Function *F) override;
/// getAdjustedAnalysisPointer - This method is used when a pass implements
/// an analysis interface through multiple inheritance. If needed, it
}
/// getModRefBehavior - Return the behavior when calling the given call site.
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
if (CS.doesNotAccessMemory())
// Can't do better than this.
- return DoesNotAccessMemory;
+ return FMRB_DoesNotAccessMemory;
- ModRefBehavior Min = UnknownModRefBehavior;
+ FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
// If the callsite knows it only reads memory, don't return worse
// than that.
if (CS.onlyReadsMemory())
- Min = OnlyReadsMemory;
+ Min = FMRB_OnlyReadsMemory;
if (CS.onlyAccessesArgMemory())
- Min = ModRefBehavior(Min & OnlyAccessesArgumentPointees);
+ Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
// The AliasAnalysis base class has some smarts, lets use them.
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
+ return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
}
/// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known.
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
BasicAliasAnalysis::getModRefBehavior(const Function *F) {
// If the function declares it doesn't access memory, we can't do better.
if (F->doesNotAccessMemory())
- return DoesNotAccessMemory;
+ return FMRB_DoesNotAccessMemory;
// For intrinsics, we can check the table.
if (Intrinsic::ID iid = F->getIntrinsicID()) {
#undef GET_INTRINSIC_MODREF_BEHAVIOR
}
- ModRefBehavior Min = UnknownModRefBehavior;
+ FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
// If the function declares it only reads memory, go with that.
if (F->onlyReadsMemory())
- Min = OnlyReadsMemory;
+ Min = FMRB_OnlyReadsMemory;
if (F->onlyAccessesArgMemory())
- Min = ModRefBehavior(Min & OnlyAccessesArgumentPointees);
+ Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
const TargetLibraryInfo &TLI =
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
if (isMemsetPattern16(F, TLI))
- Min = OnlyAccessesArgumentPointees;
+ Min = FMRB_OnlyAccessesArgumentPointees;
// Otherwise be conservative.
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
+ return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
}
-AliasAnalysis::ModRefResult
-BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
+ModRefInfo BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS,
+ unsigned ArgIdx) {
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction()))
switch (II->getIntrinsicID()) {
default:
case Intrinsic::memmove:
assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memory intrinsic");
- return ArgIdx ? Ref : Mod;
+ return ArgIdx ? MRI_Ref : MRI_Mod;
}
// We can bound the aliasing properties of memset_pattern16 just as we can
isMemsetPattern16(CS.getCalledFunction(), *TLI)) {
assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memset_pattern16");
- return ArgIdx ? Ref : Mod;
+ return ArgIdx ? MRI_Ref : MRI_Mod;
}
// FIXME: Handle memset_pattern4 and memset_pattern8 also.
/// specified memory object. Since we only look at local properties of this
/// 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(ImmutableCallSite CS,
- const MemoryLocation &Loc) {
+ModRefInfo BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
assert(notDifferentParent(CS.getInstruction(), Loc.Ptr) &&
"AliasAnalysis query involving multiple functions!");
if (isa<AllocaInst>(Object))
if (const CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
if (CI->isTailCall())
- return NoModRef;
+ return MRI_NoModRef;
// If the pointer is to a locally allocated object that does not escape,
// then the call can not mod/ref the pointer unless the call takes the pointer
}
if (!PassedAsArg)
- return NoModRef;
+ return MRI_NoModRef;
}
// While the assume intrinsic is marked as arbitrarily writing so that
// proper control dependencies will be maintained, it never aliases any
// particular memory location.
if (isAssumeIntrinsic(CS))
- return NoModRef;
+ return MRI_NoModRef;
// The AliasAnalysis base class has some smarts, lets use them.
return AliasAnalysis::getModRefInfo(CS, Loc);
}
-AliasAnalysis::ModRefResult
-BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) {
+ModRefInfo BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
// While the assume intrinsic is marked as arbitrarily writing so that
// proper control dependencies will be maintained, it never aliases any
// particular memory location.
if (isAssumeIntrinsic(CS1) || isAssumeIntrinsic(CS2))
- return NoModRef;
+ return MRI_NoModRef;
// The AliasAnalysis base class has some smarts, lets use them.
return AliasAnalysis::getModRefInfo(CS1, CS2);
bool MayReadAnyGlobal;
unsigned getInfoForGlobal(const GlobalValue *GV) const {
- unsigned Effect = MayReadAnyGlobal ? AliasAnalysis::Ref : 0;
+ unsigned Effect = MayReadAnyGlobal ? MRI_Ref : 0;
std::map<const GlobalValue *, unsigned>::const_iterator I =
GlobalInfo.find(GV);
if (I != GlobalInfo.end())
AU.setPreservesAll(); // Does not transform code
}
+ /// 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.
+ void *getAdjustedAnalysisPointer(AnalysisID PI) override {
+ if (PI == &AliasAnalysis::ID)
+ return (AliasAnalysis *)this;
+ return this;
+ }
+
//------------------------------------------------
// Implement the AliasAnalysis API
//
AliasResult alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override {
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override {
return AliasAnalysis::getModRefInfo(CS1, CS2);
}
/// getModRefBehavior - Return the behavior of the specified function if
/// called from the specified call site. The call site may be null in which
/// case the most generic behavior of this function should be returned.
- ModRefBehavior getModRefBehavior(const Function *F) override {
- ModRefBehavior Min = UnknownModRefBehavior;
+ FunctionModRefBehavior getModRefBehavior(const Function *F) override {
+ FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
if (FunctionRecord *FR = getFunctionInfo(F)) {
if (FR->FunctionEffect == 0)
- Min = DoesNotAccessMemory;
- else if ((FR->FunctionEffect & Mod) == 0)
- Min = OnlyReadsMemory;
+ Min = FMRB_DoesNotAccessMemory;
+ else if ((FR->FunctionEffect & MRI_Mod) == 0)
+ Min = FMRB_OnlyReadsMemory;
}
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
+ return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
}
/// getModRefBehavior - Return the behavior of the specified function if
/// called from the specified call site. The call site may be null in which
/// case the most generic behavior of this function should be returned.
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override {
- ModRefBehavior Min = UnknownModRefBehavior;
+ FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override {
+ FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
if (const Function *F = CS.getCalledFunction())
if (FunctionRecord *FR = getFunctionInfo(F)) {
if (FR->FunctionEffect == 0)
- Min = DoesNotAccessMemory;
- else if ((FR->FunctionEffect & Mod) == 0)
- Min = OnlyReadsMemory;
+ Min = FMRB_DoesNotAccessMemory;
+ else if ((FR->FunctionEffect & MRI_Mod) == 0)
+ Min = FMRB_OnlyReadsMemory;
}
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
- }
-
- /// 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.
- void *getAdjustedAnalysisPointer(AnalysisID PI) override {
- if (PI == &AliasAnalysis::ID)
- return (AliasAnalysis *)this;
- return this;
+ return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
}
private:
Handles.front().I = Handles.begin();
for (Function *Reader : Readers)
- FunctionInfo[Reader].GlobalInfo[&GV] |= Ref;
+ FunctionInfo[Reader].GlobalInfo[&GV] |= MRI_Ref;
if (!GV.isConstant()) // No need to keep track of writers to constants
for (Function *Writer : Writers)
- FunctionInfo[Writer].GlobalInfo[&GV] |= Mod;
+ FunctionInfo[Writer].GlobalInfo[&GV] |= MRI_Mod;
++NumNonAddrTakenGlobalVars;
// If this global holds a pointer type, see if it is an indirect global.
if (F->doesNotAccessMemory()) {
// Can't do better than that!
} else if (F->onlyReadsMemory()) {
- FunctionEffect |= Ref;
+ FunctionEffect |= MRI_Ref;
if (!F->isIntrinsic())
// This function might call back into the module and read a global -
// consider every global as possibly being read by this function.
FR.MayReadAnyGlobal = true;
} else {
- FunctionEffect |= ModRef;
+ FunctionEffect |= MRI_ModRef;
// Can't say anything useful unless it's an intrinsic - they don't
// read or write global variables of the kind considered here.
KnowNothing = !F->isIntrinsic();
// Scan the function bodies for explicit loads or stores.
for (auto *Node : SCC) {
- if (FunctionEffect == ModRef)
+ if (FunctionEffect == MRI_ModRef)
break; // The mod/ref lattice saturates here.
for (Instruction &I : inst_range(Node->getFunction())) {
- if (FunctionEffect == ModRef)
+ if (FunctionEffect == MRI_ModRef)
break; // The mod/ref lattice saturates here.
// We handle calls specially because the graph-relevant aspects are
if (isAllocationFn(&I, TLI) || isFreeCall(&I, TLI)) {
// FIXME: It is completely unclear why this is necessary and not
// handled by the above graph code.
- FunctionEffect |= ModRef;
+ FunctionEffect |= MRI_ModRef;
} else if (Function *Callee = CS.getCalledFunction()) {
// The callgraph doesn't include intrinsic calls.
if (Callee->isIntrinsic()) {
- ModRefBehavior Behaviour =
+ FunctionModRefBehavior Behaviour =
AliasAnalysis::getModRefBehavior(Callee);
- FunctionEffect |= (Behaviour & ModRef);
+ FunctionEffect |= (Behaviour & MRI_ModRef);
}
}
continue;
// All non-call instructions we use the primary predicates for whether
// thay read or write memory.
if (I.mayReadFromMemory())
- FunctionEffect |= Ref;
+ FunctionEffect |= MRI_Ref;
if (I.mayWriteToMemory())
- FunctionEffect |= Mod;
+ FunctionEffect |= MRI_Mod;
}
}
- if ((FunctionEffect & Mod) == 0)
+ if ((FunctionEffect & MRI_Mod) == 0)
++NumReadMemFunctions;
if (FunctionEffect == 0)
++NumNoMemFunctions;
return AliasAnalysis::alias(LocA, LocB);
}
-AliasAnalysis::ModRefResult
-GlobalsModRef::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
- unsigned Known = ModRef;
+ModRefInfo GlobalsModRef::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
+ unsigned Known = MRI_ModRef;
// If we are asking for mod/ref info of a direct call with a pointer to a
// global we are tracking, return information if we have it.
if (const FunctionRecord *FR = getFunctionInfo(F))
Known = FR->getInfoForGlobal(GV);
- if (Known == NoModRef)
- return NoModRef; // No need to query other mod/ref analyses
- return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, Loc));
+ if (Known == MRI_NoModRef)
+ return MRI_NoModRef; // No need to query other mod/ref analyses
+ return ModRefInfo(Known & AliasAnalysis::getModRefInfo(CS, Loc));
}
/// AnalyzeLibCallDetails - Given a call to a function with the specified
/// LibCallFunctionInfo, see if we can improve the mod/ref footprint of the call
/// vs the specified pointer/size.
-AliasAnalysis::ModRefResult
+ModRefInfo
LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
ImmutableCallSite CS,
const MemoryLocation &Loc) {
// If we have a function, check to see what kind of mod/ref effects it
// has. Start by including any info globally known about the function.
- AliasAnalysis::ModRefResult MRInfo = FI->UniversalBehavior;
- if (MRInfo == NoModRef) return MRInfo;
-
+ ModRefInfo MRInfo = FI->UniversalBehavior;
+ if (MRInfo == MRI_NoModRef)
+ return MRInfo;
+
// If that didn't tell us that the function is 'readnone', check to see
// if we have detailed info and if 'P' is any of the locations we know
// about.
// If we find a match against a location that we 'do not' interact with,
// learn this info into MRInfo.
- return ModRefResult(MRInfo & ~Details[i].MRInfo);
+ return ModRefInfo(MRInfo & ~Details[i].MRInfo);
}
return MRInfo;
}
// If the details are of the 'DoesOnly' sort, we know something if the pointer
// is a match for one of the locations in 'Details'. Also, if we can prove
// that the pointers is *not* one of the locations in 'Details', we know that
- // the call is NoModRef.
+ // the call is MRI_NoModRef.
assert(FI->DetailsType == LibCallFunctionInfo::DoesOnly);
// Find out if the pointer refers to a known location.
// If we know that this pointer definitely is pointing into the location,
// merge in this information.
- return ModRefResult(MRInfo & Details[i].MRInfo);
+ return ModRefInfo(MRInfo & Details[i].MRInfo);
}
// If we found that the pointer is guaranteed to not match any of the
// locations in our 'DoesOnly' rule, then we know that the pointer must point
// to some other location. Since the libcall doesn't mod/ref any other
- // locations, return NoModRef.
+ // locations, return MRI_NoModRef.
if (NoneMatch)
- return NoModRef;
-
+ return MRI_NoModRef;
+
// Otherwise, return any other info gained so far.
return MRInfo;
}
// getModRefInfo - Check to see if the specified callsite can clobber the
// specified memory object.
//
-AliasAnalysis::ModRefResult
-LibCallAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) {
- ModRefResult MRInfo = ModRef;
-
+ModRefInfo LibCallAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
+ ModRefInfo MRInfo = MRI_ModRef;
+
// If this is a direct call to a function that LCI knows about, get the
// information about the runtime function.
if (LCI) {
if (const Function *F = CS.getCalledFunction()) {
if (const LibCallFunctionInfo *FI = LCI->getFunctionInfo(F)) {
- MRInfo = ModRefResult(MRInfo & AnalyzeLibCallDetails(FI, CS, Loc));
- if (MRInfo == NoModRef) return NoModRef;
+ MRInfo = ModRefInfo(MRInfo & AnalyzeLibCallDetails(FI, CS, Loc));
+ if (MRInfo == MRI_NoModRef)
+ return MRI_NoModRef;
}
}
}
// The AliasAnalysis base class has some smarts, lets use them.
- return (ModRefResult)(MRInfo | AliasAnalysis::getModRefInfo(CS, Loc));
+ return (ModRefInfo)(MRInfo | AliasAnalysis::getModRefInfo(CS, Loc));
}
// If we have alias analysis and it says the store won't modify the loaded
// value, ignore the store.
- if (AA &&
- (AA->getModRefInfo(SI, StrippedPtr, AccessSize) &
- AliasAnalysis::Mod) == 0)
+ if (AA && (AA->getModRefInfo(SI, StrippedPtr, AccessSize) & MRI_Mod) == 0)
continue;
// Otherwise the store that may or may not alias the pointer, bail out.
// If alias analysis claims that it really won't modify the load,
// ignore it.
if (AA &&
- (AA->getModRefInfo(Inst, StrippedPtr, AccessSize) &
- AliasAnalysis::Mod) == 0)
+ (AA->getModRefInfo(Inst, StrippedPtr, AccessSize) & MRI_Mod) == 0)
continue;
// May modify the pointer, bail out.
/// location, fill in Loc with the details, otherwise set Loc.Ptr to null.
/// Return a ModRefInfo value describing the general behavior of the
/// instruction.
-static AliasAnalysis::ModRefResult
-GetLocation(const Instruction *Inst, MemoryLocation &Loc, AliasAnalysis *AA) {
+static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,
+ AliasAnalysis *AA) {
if (const LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
if (LI->isUnordered()) {
Loc = MemoryLocation::get(LI);
- return AliasAnalysis::Ref;
+ return MRI_Ref;
}
if (LI->getOrdering() == Monotonic) {
Loc = MemoryLocation::get(LI);
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
}
Loc = MemoryLocation();
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
}
if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
if (SI->isUnordered()) {
Loc = MemoryLocation::get(SI);
- return AliasAnalysis::Mod;
+ return MRI_Mod;
}
if (SI->getOrdering() == Monotonic) {
Loc = MemoryLocation::get(SI);
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
}
Loc = MemoryLocation();
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
}
if (const VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
Loc = MemoryLocation::get(V);
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
}
if (const CallInst *CI = isFreeCall(Inst, AA->getTargetLibraryInfo())) {
// calls to free() deallocate the entire structure
Loc = MemoryLocation(CI->getArgOperand(0));
- return AliasAnalysis::Mod;
+ return MRI_Mod;
}
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AAInfo);
// These intrinsics don't really modify the memory, but returning Mod
// will allow them to be handled conservatively.
- return AliasAnalysis::Mod;
+ return MRI_Mod;
case Intrinsic::invariant_end:
II->getAAMetadata(AAInfo);
Loc = MemoryLocation(
cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AAInfo);
// These intrinsics don't really modify the memory, but returning Mod
// will allow them to be handled conservatively.
- return AliasAnalysis::Mod;
+ return MRI_Mod;
default:
break;
}
// Otherwise, just do the coarse-grained thing that always works.
if (Inst->mayWriteToMemory())
- return AliasAnalysis::ModRef;
+ return MRI_ModRef;
if (Inst->mayReadFromMemory())
- return AliasAnalysis::Ref;
- return AliasAnalysis::NoModRef;
+ return MRI_Ref;
+ return MRI_NoModRef;
}
/// getCallSiteDependencyFrom - Private helper for finding the local
// If this inst is a memory op, get the pointer it accessed
MemoryLocation Loc;
- AliasAnalysis::ModRefResult MR = GetLocation(Inst, Loc, AA);
+ ModRefInfo MR = GetLocation(Inst, Loc, AA);
if (Loc.Ptr) {
// A simple instruction.
- if (AA->getModRefInfo(CS, Loc) != AliasAnalysis::NoModRef)
+ if (AA->getModRefInfo(CS, Loc) != MRI_NoModRef)
return MemDepResult::getClobber(Inst);
continue;
}
if (isa<DbgInfoIntrinsic>(Inst)) continue;
// If these two calls do not interfere, look past it.
switch (AA->getModRefInfo(CS, InstCS)) {
- case AliasAnalysis::NoModRef:
+ case MRI_NoModRef:
// If the two calls are the same, return InstCS as a Def, so that
// CS can be found redundant and eliminated.
- if (isReadOnlyCall && !(MR & AliasAnalysis::Mod) &&
+ if (isReadOnlyCall && !(MR & MRI_Mod) &&
CS.getInstruction()->isIdenticalToWhenDefined(Inst))
return MemDepResult::getDef(Inst);
// If we could not obtain a pointer for the instruction and the instruction
// touches memory then assume that this is a dependency.
- if (MR != AliasAnalysis::NoModRef)
+ if (MR != MRI_NoModRef)
return MemDepResult::getClobber(Inst);
}
// If alias analysis can tell that this store is guaranteed to not modify
// the query pointer, ignore it. Use getModRefInfo to handle cases where
// the query pointer points to constant memory etc.
- if (AA->getModRefInfo(SI, MemLoc) == AliasAnalysis::NoModRef)
+ if (AA->getModRefInfo(SI, MemLoc) == MRI_NoModRef)
continue;
// Ok, this store might clobber the query pointer. Check to see if it is
continue;
// See if this instruction (e.g. a call or vaarg) mod/ref's the pointer.
- AliasAnalysis::ModRefResult MR = AA->getModRefInfo(Inst, MemLoc);
+ ModRefInfo MR = AA->getModRefInfo(Inst, MemLoc);
// If necessary, perform additional analysis.
- if (MR == AliasAnalysis::ModRef)
+ if (MR == MRI_ModRef)
MR = AA->callCapturesBefore(Inst, MemLoc, DT);
switch (MR) {
- case AliasAnalysis::NoModRef:
+ case MRI_NoModRef:
// If the call has no effect on the queried pointer, just ignore it.
continue;
- case AliasAnalysis::Mod:
+ case MRI_Mod:
return MemDepResult::getClobber(Inst);
- case AliasAnalysis::Ref:
+ case MRI_Ref:
// If the call is known to never store to the pointer, and if this is a
// load query, we can safely ignore it (scan past it).
if (isLoad)
LocalCache = MemDepResult::getNonFuncLocal();
} else {
MemoryLocation MemLoc;
- AliasAnalysis::ModRefResult MR = GetLocation(QueryInst, MemLoc, AA);
+ ModRefInfo MR = GetLocation(QueryInst, MemLoc, AA);
if (MemLoc.Ptr) {
// If we can do a pointer scan, make it happen.
- bool isLoad = !(MR & AliasAnalysis::Mod);
+ bool isLoad = !(MR & MRI_Mod);
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(QueryInst))
isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_start;
return MayAlias;
}
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override {
- return UnknownModRefBehavior;
+ FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override {
+ return FMRB_UnknownModRefBehavior;
}
- ModRefBehavior getModRefBehavior(const Function *F) override {
- return UnknownModRefBehavior;
+ FunctionModRefBehavior getModRefBehavior(const Function *F) override {
+ return FMRB_UnknownModRefBehavior;
}
bool pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) override {
return false;
}
- ModRefResult getArgModRefInfo(ImmutableCallSite CS,
- unsigned ArgIdx) override {
- return ModRef;
+ ModRefInfo getArgModRefInfo(ImmutableCallSite CS,
+ unsigned ArgIdx) override {
+ return MRI_ModRef;
}
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override {
- return ModRef;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override {
+ return MRI_ModRef;
}
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override {
- return ModRef;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override {
+ return MRI_ModRef;
}
/// getAdjustedAnalysisPointer - This method is used when a pass implements
AliasResult alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) override;
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override;
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
- ModRefBehavior getModRefBehavior(const Function *F) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override;
+ FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
+ FunctionModRefBehavior getModRefBehavior(const Function *F) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override;
};
} // End of anonymous namespace
return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
}
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
ScopedNoAliasAA::getModRefBehavior(ImmutableCallSite CS) {
return AliasAnalysis::getModRefBehavior(CS);
}
-AliasAnalysis::ModRefBehavior
-ScopedNoAliasAA::getModRefBehavior(const Function *F) {
+FunctionModRefBehavior ScopedNoAliasAA::getModRefBehavior(const Function *F) {
return AliasAnalysis::getModRefBehavior(F);
}
-AliasAnalysis::ModRefResult
-ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) {
+ModRefInfo ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
if (!EnableScopedNoAlias)
return AliasAnalysis::getModRefInfo(CS, Loc);
if (!mayAliasInScopes(Loc.AATags.Scope, CS.getInstruction()->getMetadata(
LLVMContext::MD_noalias)))
- return NoModRef;
+ return MRI_NoModRef;
if (!mayAliasInScopes(
CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
Loc.AATags.NoAlias))
- return NoModRef;
+ return MRI_NoModRef;
return AliasAnalysis::getModRefInfo(CS, Loc);
}
-AliasAnalysis::ModRefResult
-ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
+ModRefInfo ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
if (!EnableScopedNoAlias)
return AliasAnalysis::getModRefInfo(CS1, CS2);
if (!mayAliasInScopes(
CS1.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
CS2.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
- return NoModRef;
+ return MRI_NoModRef;
if (!mayAliasInScopes(
CS2.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
CS1.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
- return NoModRef;
+ return MRI_NoModRef;
return AliasAnalysis::getModRefInfo(CS1, CS2);
}
const MemoryLocation &LocB) override;
bool pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) override;
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
- ModRefBehavior getModRefBehavior(const Function *F) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override;
+ FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
+ FunctionModRefBehavior getModRefBehavior(const Function *F) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override;
};
} // End of anonymous namespace
return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
}
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
TypeBasedAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
if (!EnableTBAA)
return AliasAnalysis::getModRefBehavior(CS);
- ModRefBehavior Min = UnknownModRefBehavior;
+ FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
// If this is an "immutable" type, we can assume the call doesn't write
// to memory.
if (const MDNode *M = CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa))
if ((!isStructPathTBAA(M) && TBAANode(M).TypeIsImmutable()) ||
(isStructPathTBAA(M) && TBAAStructTagNode(M).TypeIsImmutable()))
- Min = OnlyReadsMemory;
+ Min = FMRB_OnlyReadsMemory;
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
+ return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
}
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
TypeBasedAliasAnalysis::getModRefBehavior(const Function *F) {
// Functions don't have metadata. Just chain to the next implementation.
return AliasAnalysis::getModRefBehavior(F);
}
-AliasAnalysis::ModRefResult
-TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) {
+ModRefInfo TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
if (!EnableTBAA)
return AliasAnalysis::getModRefInfo(CS, Loc);
if (const MDNode *M =
CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa))
if (!Aliases(L, M))
- return NoModRef;
+ return MRI_NoModRef;
return AliasAnalysis::getModRefInfo(CS, Loc);
}
-AliasAnalysis::ModRefResult
-TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) {
+ModRefInfo TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
if (!EnableTBAA)
return AliasAnalysis::getModRefInfo(CS1, CS2);
if (const MDNode *M2 =
CS2.getInstruction()->getMetadata(LLVMContext::MD_tbaa))
if (!Aliases(M1, M2))
- return NoModRef;
+ return MRI_NoModRef;
return AliasAnalysis::getModRefInfo(CS1, CS2);
}
BasicBlock *BB = Load->getParent();
MemoryLocation Loc = MemoryLocation::get(Load);
- if (AA.canInstructionRangeModRef(BB->front(), *Load, Loc,
- AliasAnalysis::Mod))
+ if (AA.canInstructionRangeModRef(BB->front(), *Load, Loc, MRI_Mod))
return false; // Pointer is invalidated!
// Now check every path from the entry block to the load for transparency.
// memory and give up.
return false;
- AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(F);
- if (MRB == AliasAnalysis::DoesNotAccessMemory)
+ FunctionModRefBehavior MRB = AA->getModRefBehavior(F);
+ if (MRB == FMRB_DoesNotAccessMemory)
// Already perfect!
continue;
// Ignore calls to functions in the same SCC.
if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction()))
continue;
- AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(CS);
+ FunctionModRefBehavior MRB = AA->getModRefBehavior(CS);
// If the call doesn't access arbitrary memory, we may be able to
// figure out something.
if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {
MemoryLocation Loc(Arg, MemoryLocation::UnknownSize, AAInfo);
if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) {
- if (MRB & AliasAnalysis::Mod)
+ if (MRB & MRI_Mod)
// Writes non-local memory. Give up.
return false;
- if (MRB & AliasAnalysis::Ref)
+ if (MRB & MRI_Ref)
// Ok, it reads non-local memory.
ReadsMemory = true;
}
continue;
}
// The call could access any memory. If that includes writes, give up.
- if (MRB & AliasAnalysis::Mod)
+ if (MRB & MRI_Mod)
return false;
// If it reads, note it.
- if (MRB & AliasAnalysis::Ref)
+ if (MRB & MRI_Ref)
ReadsMemory = true;
continue;
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
};
static IntrinsicKind getIntrinsicKind(Intrinsic::ID iid) {
- const int DoesNotAccessMemory = IK_DoesNotAccessMemory;
- const int OnlyReadsArgumentPointees = IK_OnlyReadsMemory;
- const int OnlyReadsMemory = IK_OnlyReadsMemory;
- const int OnlyAccessesArgumentPointees = IK_WritesMemory;
- const int UnknownModRefBehavior = IK_WritesMemory;
+ const int FMRB_DoesNotAccessMemory = IK_DoesNotAccessMemory;
+ const int FMRB_OnlyReadsArgumentPointees = IK_OnlyReadsMemory;
+ const int FMRB_OnlyReadsMemory = IK_OnlyReadsMemory;
+ const int FMRB_OnlyAccessesArgumentPointees = IK_WritesMemory;
+ const int FMRB_UnknownModRefBehavior = IK_WritesMemory;
#define GET_INTRINSIC_MODREF_BEHAVIOR
-#define ModRefBehavior IntrinsicKind
+#define FunctionModRefBehavior IntrinsicKind
#include "llvm/IR/Intrinsics.gen"
-#undef ModRefBehavior
+#undef FunctionModRefBehavior
#undef GET_INTRINSIC_MODREF_BEHAVIOR
}
assert(CS && "Only calls can alter reference counts!");
// See if AliasAnalysis can help us with the call.
- AliasAnalysis::ModRefBehavior MRB = PA.getAA()->getModRefBehavior(CS);
+ FunctionModRefBehavior MRB = PA.getAA()->getModRefBehavior(CS);
if (AliasAnalysis::onlyReadsMemory(MRB))
return false;
if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {
return false;
}
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
// We have nothing to do. Just chain to the next AliasAnalysis.
return AliasAnalysis::getModRefBehavior(CS);
}
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
if (!EnableARCOpts)
return AliasAnalysis::getModRefBehavior(F);
switch (GetFunctionClass(F)) {
case ARCInstKind::NoopCast:
- return DoesNotAccessMemory;
+ return FMRB_DoesNotAccessMemory;
default:
break;
}
return AliasAnalysis::getModRefBehavior(F);
}
-AliasAnalysis::ModRefResult
-ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) {
+ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
if (!EnableARCOpts)
return AliasAnalysis::getModRefInfo(CS, Loc);
// These functions don't access any memory visible to the compiler.
// Note that this doesn't include objc_retainBlock, because it updates
// pointers when it copies block data.
- return NoModRef;
+ return MRI_NoModRef;
default:
break;
}
return AliasAnalysis::getModRefInfo(CS, Loc);
}
-AliasAnalysis::ModRefResult
-ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) {
+ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
// TODO: Theoretically we could check for dependencies between objc_* calls
- // and OnlyAccessesArgumentPointees calls or other well-behaved calls.
+ // and FMRB_OnlyAccessesArgumentPointees calls or other well-behaved calls.
return AliasAnalysis::getModRefInfo(CS1, CS2);
}
const MemoryLocation &LocB) override;
bool pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) override;
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
- ModRefBehavior getModRefBehavior(const Function *F) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override;
+ FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
+ FunctionModRefBehavior getModRefBehavior(const Function *F) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
+ ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override;
};
} // namespace objcarc
// Ok, now we know we have not seen a store yet. See if Inst can write to
// our load location, if it can not, just ignore the instruction.
- if (!(AA->getModRefInfo(Inst, Loc) & AliasAnalysis::Mod))
+ if (!(AA->getModRefInfo(Inst, Loc) & MRI_Mod))
continue;
Store = dyn_cast<StoreInst>(Inst);
if (DepWrite == &BB.front()) break;
// Can't look past this instruction if it might read 'Loc'.
- if (AA->getModRefInfo(DepWrite, Loc) & AliasAnalysis::Ref)
+ if (AA->getModRefInfo(DepWrite, Loc) & MRI_Ref)
break;
InstDep = MD->getPointerDependencyFrom(Loc, false, DepWrite, &BB);
// the call is live.
DeadStackObjects.remove_if([&](Value *I) {
// See if the call site touches the value.
- AliasAnalysis::ModRefResult A = AA->getModRefInfo(
+ ModRefInfo A = AA->getModRefInfo(
CS, I, getPointerSize(I, DL, AA->getTargetLibraryInfo()));
- return A == AliasAnalysis::ModRef || A == AliasAnalysis::Ref;
+ return A == MRI_ModRef || A == MRI_Ref;
});
// If all of the allocas were clobbered by the call then we're not going
return false;
// Handle simple cases by querying alias analysis.
- AliasAnalysis::ModRefBehavior Behavior = AA->getModRefBehavior(CI);
- if (Behavior == AliasAnalysis::DoesNotAccessMemory)
+ FunctionModRefBehavior Behavior = AA->getModRefBehavior(CI);
+ if (Behavior == FMRB_DoesNotAccessMemory)
return true;
if (AliasAnalysis::onlyReadsMemory(Behavior)) {
// If this call only reads from memory and there are no writes to memory
/// mayLoopAccessLocation - Return true if the specified loop might access the
/// specified pointer location, which is a loop-strided access. The 'Access'
/// argument specifies what the verboten forms of access are (read or write).
-static bool mayLoopAccessLocation(Value *Ptr,AliasAnalysis::ModRefResult Access,
- Loop *L, const SCEV *BECount,
- unsigned StoreSize, AliasAnalysis &AA,
+static bool mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
+ const SCEV *BECount, unsigned StoreSize,
+ AliasAnalysis &AA,
Instruction *IgnoredStore) {
// Get the location that may be stored across the loop. Since the access is
// strided positively through memory, we say that the modified location starts
Expander.expandCodeFor(Ev->getStart(), DestInt8PtrTy,
Preheader->getTerminator());
- if (mayLoopAccessLocation(BasePtr, AliasAnalysis::ModRef,
- CurLoop, BECount,
- StoreSize, getAnalysis<AliasAnalysis>(), TheStore)) {
+ if (mayLoopAccessLocation(BasePtr, MRI_ModRef, CurLoop, BECount, StoreSize,
+ getAnalysis<AliasAnalysis>(), TheStore)) {
Expander.clear();
// If we generated new code for the base pointer, clean up.
RecursivelyDeleteTriviallyDeadInstructions(BasePtr, TLI);
Builder.getInt8PtrTy(SI->getPointerAddressSpace()),
Preheader->getTerminator());
- if (mayLoopAccessLocation(StoreBasePtr, AliasAnalysis::ModRef,
- CurLoop, BECount, StoreSize,
- getAnalysis<AliasAnalysis>(), SI)) {
+ if (mayLoopAccessLocation(StoreBasePtr, MRI_ModRef, CurLoop, BECount,
+ StoreSize, getAnalysis<AliasAnalysis>(), SI)) {
Expander.clear();
// If we generated new code for the base pointer, clean up.
RecursivelyDeleteTriviallyDeadInstructions(StoreBasePtr, TLI);
Builder.getInt8PtrTy(LI->getPointerAddressSpace()),
Preheader->getTerminator());
- if (mayLoopAccessLocation(LoadBasePtr, AliasAnalysis::Mod, CurLoop, BECount,
- StoreSize, getAnalysis<AliasAnalysis>(), SI)) {
+ if (mayLoopAccessLocation(LoadBasePtr, MRI_Mod, CurLoop, BECount, StoreSize,
+ getAnalysis<AliasAnalysis>(), SI)) {
Expander.clear();
// If we generated new code for the base pointer, clean up.
RecursivelyDeleteTriviallyDeadInstructions(LoadBasePtr, TLI);
MemoryLocation StoreLoc = MemoryLocation::get(SI);
for (BasicBlock::iterator I = --BasicBlock::iterator(SI),
E = C; I != E; --I) {
- if (AA.getModRefInfo(&*I, StoreLoc) != AliasAnalysis::NoModRef) {
+ if (AA.getModRefInfo(&*I, StoreLoc) != MRI_NoModRef) {
C = nullptr;
break;
}
// the use analysis, we also need to know that it does not sneakily
// access dest. We rely on AA to figure this out for us.
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
- AliasAnalysis::ModRefResult MR = AA.getModRefInfo(C, cpyDest, srcSize);
+ ModRefInfo MR = AA.getModRefInfo(C, cpyDest, srcSize);
// If necessary, perform additional analysis.
- if (MR != AliasAnalysis::NoModRef)
+ if (MR != MRI_NoModRef)
MR = AA.callCapturesBefore(C, cpyDest, srcSize, &DT);
- if (MR != AliasAnalysis::NoModRef)
+ if (MR != MRI_NoModRef)
return false;
// All the checks have passed, so do the transformation.
const Instruction& End,
LoadInst* LI) {
MemoryLocation Loc = MemoryLocation::get(LI);
- return AA->canInstructionRangeModRef(Start, End, Loc, AliasAnalysis::Mod);
+ return AA->canInstructionRangeModRef(Start, End, Loc, MRI_Mod);
}
///
bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction &Start,
const Instruction &End,
MemoryLocation Loc) {
- return AA->canInstructionRangeModRef(Start, End, Loc, AliasAnalysis::ModRef);
+ return AA->canInstructionRangeModRef(Start, End, Loc, MRI_ModRef);
}
///
if (LoadInst *L = dyn_cast<LoadInst>(Inst)) {
MemoryLocation Loc = MemoryLocation::get(L);
for (Instruction *S : Stores)
- if (AA->getModRefInfo(S, Loc) & AliasAnalysis::Mod)
+ if (AA->getModRefInfo(S, Loc) & MRI_Mod)
return false;
}
IsFuncCall = true;
if (AA) {
- AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(ICS);
- if (MRB == AliasAnalysis::OnlyAccessesArgumentPointees ||
- MRB == AliasAnalysis::OnlyReadsArgumentPointees)
+ FunctionModRefBehavior MRB = AA->getModRefBehavior(ICS);
+ if (MRB == FMRB_OnlyAccessesArgumentPointees ||
+ MRB == FMRB_OnlyReadsArgumentPointees)
IsArgMemOnlyCall = true;
}
// This is going to check that calling getModRefInfo without a location, and
// with a default location, first, doesn't crash, and second, gives the right
// answer.
- void CheckModRef(Instruction *I, AliasAnalysis::ModRefResult Result) {
+ void CheckModRef(Instruction *I, ModRefInfo Result) {
static char ID;
class CheckModRefTestPass : public FunctionPass {
public:
- CheckModRefTestPass(Instruction *I, AliasAnalysis::ModRefResult Result)
+ CheckModRefTestPass(Instruction *I, ModRefInfo Result)
: FunctionPass(ID), ExpectResult(Result), I(I) {}
static int initialize() {
PassInfo *PI = new PassInfo("CheckModRef testing pass", "", &ID,
EXPECT_EQ(AA.getModRefInfo(I), ExpectResult);
return false;
}
- AliasAnalysis::ModRefResult ExpectResult;
+ ModRefInfo ExpectResult;
Instruction *I;
};
static int initialize = CheckModRefTestPass::initialize();
ReturnInst::Create(C, nullptr, BB);
// Check basic results
- CheckModRef(Store1, AliasAnalysis::ModRefResult::Mod);
- CheckModRef(Load1, AliasAnalysis::ModRefResult::Ref);
- CheckModRef(Add1, AliasAnalysis::ModRefResult::NoModRef);
- CheckModRef(VAArg1, AliasAnalysis::ModRefResult::ModRef);
- CheckModRef(CmpXChg1, AliasAnalysis::ModRefResult::ModRef);
- CheckModRef(AtomicRMW, AliasAnalysis::ModRefResult::ModRef);
+ CheckModRef(Store1, MRI_Mod);
+ CheckModRef(Load1, MRI_Ref);
+ CheckModRef(Add1, MRI_NoModRef);
+ CheckModRef(VAArg1, MRI_ModRef);
+ CheckModRef(CmpXChg1, MRI_ModRef);
+ CheckModRef(AtomicRMW, MRI_ModRef);
}
} // end anonymous namspace
<< "\"Unknown intrinsic.\");\n\n";
OS << "static const uint8_t IntrinsicModRefBehavior[] = {\n"
- << " /* invalid */ UnknownModRefBehavior,\n";
+ << " /* invalid */ FMRB_UnknownModRefBehavior,\n";
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
OS << " /* " << TargetPrefix << Ints[i].EnumName << " */ ";
switch (Ints[i].ModRef) {
case CodeGenIntrinsic::NoMem:
- OS << "DoesNotAccessMemory,\n";
+ OS << "FMRB_DoesNotAccessMemory,\n";
break;
case CodeGenIntrinsic::ReadArgMem:
- OS << "OnlyReadsArgumentPointees,\n";
+ OS << "FMRB_OnlyReadsArgumentPointees,\n";
break;
case CodeGenIntrinsic::ReadMem:
- OS << "OnlyReadsMemory,\n";
+ OS << "FMRB_OnlyReadsMemory,\n";
break;
case CodeGenIntrinsic::ReadWriteArgMem:
- OS << "OnlyAccessesArgumentPointees,\n";
+ OS << "FMRB_OnlyAccessesArgumentPointees,\n";
break;
case CodeGenIntrinsic::ReadWriteMem:
- OS << "UnknownModRefBehavior,\n";
+ OS << "FMRB_UnknownModRefBehavior,\n";
break;
}
}
OS << "};\n\n"
- << "return static_cast<ModRefBehavior>(IntrinsicModRefBehavior[iid]);\n"
+ << "return "
+ "static_cast<FunctionModRefBehavior>(IntrinsicModRefBehavior[iid]);\n"
<< "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
}