[PM/AA] Extract the ModRef enums from the AliasAnalysis class in

preparation for de-coupling the AA implementations.

In order to do this, they had to become fake-scoped using the
traditional LLVM pattern of a leading initialism. These can't be actual
scoped enumerations because they're bitfields and thus inherently we use
them as integers.

I've also renamed the behavior enums that are specific to reasoning
about the mod/ref behavior of functions when called. This makes it more
clear that they have a very narrow domain of applicability.

I think there is a significantly cleaner API for all of this, but
I don't want to try to do really substantive changes for now, I just
want to refactor the things away from analysis groups so I'm preserving
the exact original design and just cleaning up the names, style, and
lifting out of the class.

Differential Revision: http://reviews.llvm.org/D10564

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242963 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2015-07-22 23:15:57 +00:00
parent 90b20e96a1
commit 52ab0bc417
32 changed files with 542 additions and 529 deletions

View File

@ -84,6 +84,77 @@ enum AliasResult {
MustAlias, 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 { class AliasAnalysis {
protected: protected:
const DataLayout *DL; const DataLayout *DL;
@ -185,71 +256,19 @@ public:
/// Simple mod/ref information... /// 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 /// 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 /// 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 /// that these bits do not necessarily account for the overall behavior of
/// the function, but rather only provide additional per-argument /// the function, but rather only provide additional per-argument
/// information. /// 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. /// 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. /// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known. /// 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 /// doesNotAccessMemory - If the specified call is known to never read or
/// write memory, return true. If the call only reads from known-constant /// write memory, return true. If the call only reads from known-constant
@ -263,14 +282,14 @@ public:
/// This property corresponds to the GCC 'const' attribute. /// This property corresponds to the GCC 'const' attribute.
/// ///
bool doesNotAccessMemory(ImmutableCallSite CS) { bool doesNotAccessMemory(ImmutableCallSite CS) {
return getModRefBehavior(CS) == DoesNotAccessMemory; return getModRefBehavior(CS) == FMRB_DoesNotAccessMemory;
} }
/// doesNotAccessMemory - If the specified function is known to never read or /// doesNotAccessMemory - If the specified function is known to never read or
/// write memory, return true. For use when the call site is not known. /// write memory, return true. For use when the call site is not known.
/// ///
bool doesNotAccessMemory(const Function *F) { 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 - If the specified call is known to only read from
@ -297,39 +316,39 @@ public:
/// onlyReadsMemory - Return true if functions with the specified behavior are /// onlyReadsMemory - Return true if functions with the specified behavior are
/// known to only read from non-volatile memory (or not access memory at all). /// known to only read from non-volatile memory (or not access memory at all).
/// ///
static bool onlyReadsMemory(ModRefBehavior MRB) { static bool onlyReadsMemory(FunctionModRefBehavior MRB) {
return !(MRB & Mod); return !(MRB & MRI_Mod);
} }
/// onlyAccessesArgPointees - Return true if functions with the specified /// onlyAccessesArgPointees - Return true if functions with the specified
/// behavior are known to read and write at most from objects pointed to by /// behavior are known to read and write at most from objects pointed to by
/// their pointer-typed arguments (with arbitrary offsets). /// their pointer-typed arguments (with arbitrary offsets).
/// ///
static bool onlyAccessesArgPointees(ModRefBehavior MRB) { static bool onlyAccessesArgPointees(FunctionModRefBehavior MRB) {
return !(MRB & Anywhere & ~ArgumentPointees); return !(MRB & FMRL_Anywhere & ~FMRL_ArgumentPointees);
} }
/// doesAccessArgPointees - Return true if functions with the specified /// doesAccessArgPointees - Return true if functions with the specified
/// behavior are known to potentially read or write from objects pointed /// behavior are known to potentially read or write from objects pointed
/// to be their pointer-typed arguments (with arbitrary offsets). /// to be their pointer-typed arguments (with arbitrary offsets).
/// ///
static bool doesAccessArgPointees(ModRefBehavior MRB) { static bool doesAccessArgPointees(FunctionModRefBehavior MRB) {
return (MRB & ModRef) && (MRB & ArgumentPointees); return (MRB & MRI_ModRef) && (MRB & FMRL_ArgumentPointees);
} }
/// getModRefInfo - Return information about whether or not an /// getModRefInfo - Return information about whether or not an
/// instruction may read or write memory (without regard to a /// instruction may read or write memory (without regard to a
/// specific location) /// specific location)
ModRefResult getModRefInfo(const Instruction *I) { ModRefInfo getModRefInfo(const Instruction *I) {
if (auto CS = ImmutableCallSite(I)) { if (auto CS = ImmutableCallSite(I)) {
auto MRB = getModRefBehavior(CS); auto MRB = getModRefBehavior(CS);
if (MRB & ModRef) if (MRB & MRI_ModRef)
return ModRef; return MRI_ModRef;
else if (MRB & Ref) else if (MRB & MRI_Ref)
return Ref; return MRI_Ref;
else if (MRB & Mod) else if (MRB & MRI_Mod)
return Mod; return MRI_Mod;
return NoModRef; return MRI_NoModRef;
} }
return getModRefInfo(I, MemoryLocation()); return getModRefInfo(I, MemoryLocation());
@ -338,7 +357,7 @@ public:
/// getModRefInfo - Return information about whether or not an instruction may /// getModRefInfo - Return information about whether or not an instruction may
/// read or write the specified memory location. An instruction /// read or write the specified memory location. An instruction
/// that doesn't read or write memory may be trivially LICM'd for example. /// 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()) { switch (I->getOpcode()) {
case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc); case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc);
case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc); case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc);
@ -350,132 +369,130 @@ public:
return getModRefInfo((const AtomicRMWInst*)I, Loc); return getModRefInfo((const AtomicRMWInst*)I, Loc);
case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc); case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc);
case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc); case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
default: return NoModRef; default:
return MRI_NoModRef;
} }
} }
/// getModRefInfo - A convenience wrapper. /// getModRefInfo - A convenience wrapper.
ModRefResult getModRefInfo(const Instruction *I, ModRefInfo getModRefInfo(const Instruction *I, const Value *P,
const Value *P, uint64_t Size) { uint64_t Size) {
return getModRefInfo(I, MemoryLocation(P, Size)); return getModRefInfo(I, MemoryLocation(P, Size));
} }
/// getModRefInfo (for call sites) - Return information about whether /// getModRefInfo (for call sites) - Return information about whether
/// a particular call site modifies or reads the specified memory location. /// a particular call site modifies or reads the specified memory location.
virtual ModRefResult getModRefInfo(ImmutableCallSite CS, virtual ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc); const MemoryLocation &Loc);
/// getModRefInfo (for call sites) - A convenience wrapper. /// getModRefInfo (for call sites) - A convenience wrapper.
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS, const Value *P,
const Value *P, uint64_t Size) { uint64_t Size) {
return getModRefInfo(CS, MemoryLocation(P, Size)); return getModRefInfo(CS, MemoryLocation(P, Size));
} }
/// getModRefInfo (for calls) - Return information about whether /// getModRefInfo (for calls) - Return information about whether
/// a particular call modifies or reads the specified memory location. /// 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); return getModRefInfo(ImmutableCallSite(C), Loc);
} }
/// getModRefInfo (for calls) - A convenience wrapper. /// 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)); return getModRefInfo(C, MemoryLocation(P, Size));
} }
/// getModRefInfo (for invokes) - Return information about whether /// getModRefInfo (for invokes) - Return information about whether
/// a particular invoke modifies or reads the specified memory location. /// 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); return getModRefInfo(ImmutableCallSite(I), Loc);
} }
/// getModRefInfo (for invokes) - A convenience wrapper. /// getModRefInfo (for invokes) - A convenience wrapper.
ModRefResult getModRefInfo(const InvokeInst *I, ModRefInfo getModRefInfo(const InvokeInst *I, const Value *P, uint64_t Size) {
const Value *P, uint64_t Size) {
return getModRefInfo(I, MemoryLocation(P, Size)); return getModRefInfo(I, MemoryLocation(P, Size));
} }
/// getModRefInfo (for loads) - Return information about whether /// getModRefInfo (for loads) - Return information about whether
/// a particular load modifies or reads the specified memory location. /// 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. /// 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)); return getModRefInfo(L, MemoryLocation(P, Size));
} }
/// getModRefInfo (for stores) - Return information about whether /// getModRefInfo (for stores) - Return information about whether
/// a particular store modifies or reads the specified memory location. /// 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. /// 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)); return getModRefInfo(S, MemoryLocation(P, Size));
} }
/// getModRefInfo (for fences) - Return information about whether /// getModRefInfo (for fences) - Return information about whether
/// a particular store modifies or reads the specified memory location. /// 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 // Conservatively correct. (We could possibly be a bit smarter if
// Loc is a alloca that doesn't escape.) // Loc is a alloca that doesn't escape.)
return ModRef; return MRI_ModRef;
} }
/// getModRefInfo (for fences) - A convenience wrapper. /// 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)); return getModRefInfo(S, MemoryLocation(P, Size));
} }
/// getModRefInfo (for cmpxchges) - Return information about whether /// getModRefInfo (for cmpxchges) - Return information about whether
/// a particular cmpxchg modifies or reads the specified memory location. /// a particular cmpxchg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX,
const MemoryLocation &Loc); const MemoryLocation &Loc);
/// getModRefInfo (for cmpxchges) - A convenience wrapper. /// getModRefInfo (for cmpxchges) - A convenience wrapper.
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX, const Value *P,
const Value *P, unsigned Size) { unsigned Size) {
return getModRefInfo(CX, MemoryLocation(P, Size)); return getModRefInfo(CX, MemoryLocation(P, Size));
} }
/// getModRefInfo (for atomicrmws) - Return information about whether /// getModRefInfo (for atomicrmws) - Return information about whether
/// a particular atomicrmw modifies or reads the specified memory location. /// a particular atomicrmw modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc);
const MemoryLocation &Loc);
/// getModRefInfo (for atomicrmws) - A convenience wrapper. /// getModRefInfo (for atomicrmws) - A convenience wrapper.
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const Value *P,
const Value *P, unsigned Size) { unsigned Size) {
return getModRefInfo(RMW, MemoryLocation(P, Size)); return getModRefInfo(RMW, MemoryLocation(P, Size));
} }
/// getModRefInfo (for va_args) - Return information about whether /// getModRefInfo (for va_args) - Return information about whether
/// a particular va_arg modifies or reads the specified memory location. /// 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. /// 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)); return getModRefInfo(I, MemoryLocation(P, Size));
} }
/// getModRefInfo - Return information about whether a call and an instruction /// getModRefInfo - Return information about whether a call and an instruction
/// may refer to the same memory locations. /// may refer to the same memory locations.
ModRefResult getModRefInfo(Instruction *I, ModRefInfo getModRefInfo(Instruction *I, ImmutableCallSite Call);
ImmutableCallSite Call);
/// getModRefInfo - Return information about whether two call sites may refer /// getModRefInfo - Return information about whether two call sites may refer
/// to the same set of memory locations. See /// to the same set of memory locations. See
/// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo /// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
/// for details. /// for details.
virtual ModRefResult getModRefInfo(ImmutableCallSite CS1, virtual ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2); ImmutableCallSite CS2);
/// callCapturesBefore - Return information about whether a particular call /// callCapturesBefore - Return information about whether a particular call
/// site modifies or reads the specified memory location. /// site modifies or reads the specified memory location.
ModRefResult callCapturesBefore(const Instruction *I, ModRefInfo callCapturesBefore(const Instruction *I,
const MemoryLocation &MemLoc, const MemoryLocation &MemLoc,
DominatorTree *DT); DominatorTree *DT);
/// callCapturesBefore - A convenience wrapper. /// callCapturesBefore - A convenience wrapper.
ModRefResult callCapturesBefore(const Instruction *I, const Value *P, ModRefInfo callCapturesBefore(const Instruction *I, const Value *P,
uint64_t Size, DominatorTree *DT) { uint64_t Size, DominatorTree *DT) {
return callCapturesBefore(I, MemoryLocation(P, Size), DT); return callCapturesBefore(I, MemoryLocation(P, Size), DT);
} }
@ -499,12 +516,12 @@ public:
/// I1 and I2 must be in the same basic block. /// I1 and I2 must be in the same basic block.
bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2, bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2,
const MemoryLocation &Loc, const MemoryLocation &Loc,
const ModRefResult Mode); const ModRefInfo Mode);
/// canInstructionRangeModRef - A convenience wrapper. /// canInstructionRangeModRef - A convenience wrapper.
bool canInstructionRangeModRef(const Instruction &I1, bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2,
const Instruction &I2, const Value *Ptr, const Value *Ptr, uint64_t Size,
uint64_t Size, const ModRefResult Mode) { const ModRefInfo Mode) {
return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode); return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode);
} }
}; };

View File

@ -38,11 +38,11 @@ namespace llvm {
} }
~LibCallAliasAnalysis() override; ~LibCallAliasAnalysis() override;
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) override; const MemoryLocation &Loc) override;
ModRefResult getModRefInfo(ImmutableCallSite CS1, ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) override { ImmutableCallSite CS2) override {
// TODO: Could compare two direct calls against each other if we cared to. // TODO: Could compare two direct calls against each other if we cared to.
return AliasAnalysis::getModRefInfo(CS1, CS2); return AliasAnalysis::getModRefInfo(CS1, CS2);
} }
@ -62,9 +62,9 @@ namespace llvm {
} }
private: private:
ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, ModRefInfo AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
ImmutableCallSite CS, ImmutableCallSite CS,
const MemoryLocation &Loc); const MemoryLocation &Loc);
}; };
} // End of llvm namespace } // End of llvm namespace

View File

@ -71,15 +71,15 @@ class InvokeInst;
/// any specific context knowledge. For example, if the function is known /// 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, /// to be readonly, this would be set to 'ref'. If known to be readnone,
/// this is set to NoModRef. /// this is set to NoModRef.
AliasAnalysis::ModRefResult UniversalBehavior; ModRefInfo UniversalBehavior;
/// LocationMRInfo - This pair captures info about whether a specific /// LocationMRInfo - This pair captures info about whether a specific
/// location is modified or referenced by a libcall. /// location is modified or referenced by a libcall.
struct LocationMRInfo { struct LocationMRInfo {
/// LocationID - ID # of the accessed location or ~0U for array end. /// LocationID - ID # of the accessed location or ~0U for array end.
unsigned LocationID; unsigned LocationID;
/// MRInfo - Mod/Ref info for this location. /// MRInfo - Mod/Ref info for this location.
AliasAnalysis::ModRefResult MRInfo; ModRefInfo MRInfo;
}; };
/// DetailsType - Indicate the sense of the LocationDetails array. This /// DetailsType - Indicate the sense of the LocationDetails array. This

View File

@ -60,14 +60,14 @@ bool AliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc,
return AA->pointsToConstantMemory(Loc, OrLocal); return AA->pointsToConstantMemory(Loc, OrLocal);
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getArgModRefInfo(ImmutableCallSite CS,
AliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { unsigned ArgIdx) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
return AA->getArgModRefInfo(CS, ArgIdx); return AA->getArgModRefInfo(CS, ArgIdx);
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getModRefInfo(Instruction *I,
AliasAnalysis::getModRefInfo(Instruction *I, ImmutableCallSite Call) { ImmutableCallSite Call) {
// We may have two calls // We may have two calls
if (auto CS = ImmutableCallSite(I)) { if (auto CS = ImmutableCallSite(I)) {
// Check if the two calls modify the same memory // Check if the two calls modify the same memory
@ -78,27 +78,27 @@ AliasAnalysis::getModRefInfo(Instruction *I, ImmutableCallSite Call) {
// is that if the call references what this instruction // is that if the call references what this instruction
// defines, it must be clobbered by this location. // defines, it must be clobbered by this location.
const MemoryLocation DefLoc = MemoryLocation::get(I); const MemoryLocation DefLoc = MemoryLocation::get(I);
if (getModRefInfo(Call, DefLoc) != AliasAnalysis::NoModRef) if (getModRefInfo(Call, DefLoc) != MRI_NoModRef)
return AliasAnalysis::ModRef; return MRI_ModRef;
} }
return AliasAnalysis::NoModRef; return MRI_NoModRef;
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getModRefInfo(ImmutableCallSite CS,
AliasAnalysis::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) { const MemoryLocation &Loc) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
ModRefBehavior MRB = getModRefBehavior(CS); auto MRB = getModRefBehavior(CS);
if (MRB == DoesNotAccessMemory) if (MRB == FMRB_DoesNotAccessMemory)
return NoModRef; return MRI_NoModRef;
ModRefResult Mask = ModRef; ModRefInfo Mask = MRI_ModRef;
if (onlyReadsMemory(MRB)) if (onlyReadsMemory(MRB))
Mask = Ref; Mask = MRI_Ref;
if (onlyAccessesArgPointees(MRB)) { if (onlyAccessesArgPointees(MRB)) {
bool doesAlias = false; bool doesAlias = false;
ModRefResult AllArgsMask = NoModRef; ModRefInfo AllArgsMask = MRI_NoModRef;
if (doesAccessArgPointees(MRB)) { if (doesAccessArgPointees(MRB)) {
for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
AI != AE; ++AI) { AI != AE; ++AI) {
@ -109,57 +109,59 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
MemoryLocation ArgLoc = MemoryLocation ArgLoc =
MemoryLocation::getForArgument(CS, ArgIdx, *TLI); MemoryLocation::getForArgument(CS, ArgIdx, *TLI);
if (!isNoAlias(ArgLoc, Loc)) { if (!isNoAlias(ArgLoc, Loc)) {
ModRefResult ArgMask = getArgModRefInfo(CS, ArgIdx); ModRefInfo ArgMask = getArgModRefInfo(CS, ArgIdx);
doesAlias = true; doesAlias = true;
AllArgsMask = ModRefResult(AllArgsMask | ArgMask); AllArgsMask = ModRefInfo(AllArgsMask | ArgMask);
} }
} }
} }
if (!doesAlias) if (!doesAlias)
return NoModRef; return MRI_NoModRef;
Mask = ModRefResult(Mask & AllArgsMask); Mask = ModRefInfo(Mask & AllArgsMask);
} }
// If Loc is a constant memory location, the call definitely could not // If Loc is a constant memory location, the call definitely could not
// modify the memory location. // modify the memory location.
if ((Mask & Mod) && pointsToConstantMemory(Loc)) if ((Mask & MRI_Mod) && pointsToConstantMemory(Loc))
Mask = ModRefResult(Mask & ~Mod); Mask = ModRefInfo(Mask & ~MRI_Mod);
// If this is the end of the chain, don't forward. // If this is the end of the chain, don't forward.
if (!AA) return Mask; if (!AA) return Mask;
// Otherwise, fall back to the next AA in the chain. But we can merge // Otherwise, fall back to the next AA in the chain. But we can merge
// in any mask we've managed to compute. // in any mask we've managed to compute.
return ModRefResult(AA->getModRefInfo(CS, Loc) & Mask); return ModRefInfo(AA->getModRefInfo(CS, Loc) & Mask);
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { ImmutableCallSite CS2) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
// If CS1 or CS2 are readnone, they don't interact. // If CS1 or CS2 are readnone, they don't interact.
ModRefBehavior CS1B = getModRefBehavior(CS1); auto CS1B = getModRefBehavior(CS1);
if (CS1B == DoesNotAccessMemory) return NoModRef; if (CS1B == FMRB_DoesNotAccessMemory)
return MRI_NoModRef;
ModRefBehavior CS2B = getModRefBehavior(CS2); auto CS2B = getModRefBehavior(CS2);
if (CS2B == DoesNotAccessMemory) return NoModRef; if (CS2B == FMRB_DoesNotAccessMemory)
return MRI_NoModRef;
// If they both only read from memory, there is no dependence. // If they both only read from memory, there is no dependence.
if (onlyReadsMemory(CS1B) && onlyReadsMemory(CS2B)) 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 // If CS1 only reads memory, the only dependence on CS2 can be
// from CS1 reading memory written by CS2. // from CS1 reading memory written by CS2.
if (onlyReadsMemory(CS1B)) if (onlyReadsMemory(CS1B))
Mask = ModRefResult(Mask & Ref); Mask = ModRefInfo(Mask & MRI_Ref);
// If CS2 only access memory through arguments, accumulate the mod/ref // If CS2 only access memory through arguments, accumulate the mod/ref
// information from CS1's references to the memory referenced by // information from CS1's references to the memory referenced by
// CS2's arguments. // CS2's arguments.
if (onlyAccessesArgPointees(CS2B)) { if (onlyAccessesArgPointees(CS2B)) {
AliasAnalysis::ModRefResult R = NoModRef; ModRefInfo R = MRI_NoModRef;
if (doesAccessArgPointees(CS2B)) { if (doesAccessArgPointees(CS2B)) {
for (ImmutableCallSite::arg_iterator for (ImmutableCallSite::arg_iterator
I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) { I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
@ -171,13 +173,13 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
// ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence of // ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence of
// CS1 on that location is the inverse. // CS1 on that location is the inverse.
ModRefResult ArgMask = getArgModRefInfo(CS2, CS2ArgIdx); ModRefInfo ArgMask = getArgModRefInfo(CS2, CS2ArgIdx);
if (ArgMask == Mod) if (ArgMask == MRI_Mod)
ArgMask = ModRef; ArgMask = MRI_ModRef;
else if (ArgMask == Ref) else if (ArgMask == MRI_Ref)
ArgMask = Mod; ArgMask = MRI_Mod;
R = ModRefResult((R | (getModRefInfo(CS1, CS2ArgLoc) & ArgMask)) & Mask); R = ModRefInfo((R | (getModRefInfo(CS1, CS2ArgLoc) & ArgMask)) & Mask);
if (R == Mask) if (R == Mask)
break; break;
} }
@ -188,7 +190,7 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
// If CS1 only accesses memory through arguments, check if CS2 references // If CS1 only accesses memory through arguments, check if CS2 references
// any of the memory referenced by CS1's arguments. If not, return NoModRef. // any of the memory referenced by CS1's arguments. If not, return NoModRef.
if (onlyAccessesArgPointees(CS1B)) { if (onlyAccessesArgPointees(CS1B)) {
AliasAnalysis::ModRefResult R = NoModRef; ModRefInfo R = MRI_NoModRef;
if (doesAccessArgPointees(CS1B)) { if (doesAccessArgPointees(CS1B)) {
for (ImmutableCallSite::arg_iterator for (ImmutableCallSite::arg_iterator
I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) { I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) {
@ -201,11 +203,13 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
// ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod // 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 // 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. // might Ref, then we care only about a Mod by CS2.
ModRefResult ArgMask = getArgModRefInfo(CS1, CS1ArgIdx); ModRefInfo ArgMask = getArgModRefInfo(CS1, CS1ArgIdx);
ModRefResult ArgR = getModRefInfo(CS2, CS1ArgLoc); ModRefInfo ArgR = getModRefInfo(CS2, CS1ArgLoc);
if (((ArgMask & Mod) != NoModRef && (ArgR & ModRef) != NoModRef) || if (((ArgMask & MRI_Mod) != MRI_NoModRef &&
((ArgMask & Ref) != NoModRef && (ArgR & Mod) != NoModRef)) (ArgR & MRI_ModRef) != MRI_NoModRef) ||
R = ModRefResult((R | ArgMask) & Mask); ((ArgMask & MRI_Ref) != MRI_NoModRef &&
(ArgR & MRI_Mod) != MRI_NoModRef))
R = ModRefInfo((R | ArgMask) & Mask);
if (R == Mask) if (R == Mask)
break; break;
@ -219,14 +223,13 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
// Otherwise, fall back to the next AA in the chain. But we can merge // Otherwise, fall back to the next AA in the chain. But we can merge
// in any mask we've managed to compute. // in any mask we've managed to compute.
return ModRefResult(AA->getModRefInfo(CS1, CS2) & Mask); return ModRefInfo(AA->getModRefInfo(CS1, CS2) & Mask);
} }
AliasAnalysis::ModRefBehavior FunctionModRefBehavior AliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
AliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); 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 // Call back into the alias analysis with the other form of getModRefBehavior
// to see if it can give a better response. // to see if it can give a better response.
@ -238,11 +241,10 @@ AliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
// Otherwise, fall back to the next AA in the chain. But we can merge // Otherwise, fall back to the next AA in the chain. But we can merge
// in any result we've managed to compute. // in any result we've managed to compute.
return ModRefBehavior(AA->getModRefBehavior(CS) & Min); return FunctionModRefBehavior(AA->getModRefBehavior(CS) & Min);
} }
AliasAnalysis::ModRefBehavior FunctionModRefBehavior AliasAnalysis::getModRefBehavior(const Function *F) {
AliasAnalysis::getModRefBehavior(const Function *F) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
return AA->getModRefBehavior(F); return AA->getModRefBehavior(F);
} }
@ -251,116 +253,114 @@ AliasAnalysis::getModRefBehavior(const Function *F) {
// AliasAnalysis non-virtual helper method implementation // AliasAnalysis non-virtual helper method implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getModRefInfo(const LoadInst *L,
AliasAnalysis::getModRefInfo(const LoadInst *L, const MemoryLocation &Loc) { const MemoryLocation &Loc) {
// Be conservative in the face of volatile/atomic. // Be conservative in the face of volatile/atomic.
if (!L->isUnordered()) if (!L->isUnordered())
return ModRef; return MRI_ModRef;
// If the load address doesn't alias the given address, it doesn't read // If the load address doesn't alias the given address, it doesn't read
// or write the specified memory. // or write the specified memory.
if (Loc.Ptr && !alias(MemoryLocation::get(L), Loc)) if (Loc.Ptr && !alias(MemoryLocation::get(L), Loc))
return NoModRef; return MRI_NoModRef;
// Otherwise, a load just reads. // Otherwise, a load just reads.
return Ref; return MRI_Ref;
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getModRefInfo(const StoreInst *S,
AliasAnalysis::getModRefInfo(const StoreInst *S, const MemoryLocation &Loc) { const MemoryLocation &Loc) {
// Be conservative in the face of volatile/atomic. // Be conservative in the face of volatile/atomic.
if (!S->isUnordered()) if (!S->isUnordered())
return ModRef; return MRI_ModRef;
if (Loc.Ptr) { if (Loc.Ptr) {
// If the store address cannot alias the pointer in question, then the // If the store address cannot alias the pointer in question, then the
// specified memory cannot be modified by the store. // specified memory cannot be modified by the store.
if (!alias(MemoryLocation::get(S), Loc)) 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 // If the pointer is a pointer to constant memory, then it could not have
// been modified by this store. // been modified by this store.
if (pointsToConstantMemory(Loc)) if (pointsToConstantMemory(Loc))
return NoModRef; return MRI_NoModRef;
} }
// Otherwise, a store just writes. // Otherwise, a store just writes.
return Mod; return MRI_Mod;
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getModRefInfo(const VAArgInst *V,
AliasAnalysis::getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc) { const MemoryLocation &Loc) {
if (Loc.Ptr) { if (Loc.Ptr) {
// If the va_arg address cannot alias the pointer in question, then the // If the va_arg address cannot alias the pointer in question, then the
// specified memory cannot be accessed by the va_arg. // specified memory cannot be accessed by the va_arg.
if (!alias(MemoryLocation::get(V), Loc)) 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 // If the pointer is a pointer to constant memory, then it could not have
// been modified by this va_arg. // been modified by this va_arg.
if (pointsToConstantMemory(Loc)) if (pointsToConstantMemory(Loc))
return NoModRef; return MRI_NoModRef;
} }
// Otherwise, a va_arg reads and writes. // Otherwise, a va_arg reads and writes.
return ModRef; return MRI_ModRef;
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX,
AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX, const MemoryLocation &Loc) {
const MemoryLocation &Loc) {
// Acquire/Release cmpxchg has properties that matter for arbitrary addresses. // Acquire/Release cmpxchg has properties that matter for arbitrary addresses.
if (CX->getSuccessOrdering() > Monotonic) if (CX->getSuccessOrdering() > Monotonic)
return ModRef; return MRI_ModRef;
// If the cmpxchg address does not alias the location, it does not access it. // If the cmpxchg address does not alias the location, it does not access it.
if (Loc.Ptr && !alias(MemoryLocation::get(CX), Loc)) if (Loc.Ptr && !alias(MemoryLocation::get(CX), Loc))
return NoModRef; return MRI_NoModRef;
return ModRef; return MRI_ModRef;
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW,
AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc) {
const MemoryLocation &Loc) {
// Acquire/Release atomicrmw has properties that matter for arbitrary addresses. // Acquire/Release atomicrmw has properties that matter for arbitrary addresses.
if (RMW->getOrdering() > Monotonic) if (RMW->getOrdering() > Monotonic)
return ModRef; return MRI_ModRef;
// If the atomicrmw address does not alias the location, it does not access it. // If the atomicrmw address does not alias the location, it does not access it.
if (Loc.Ptr && !alias(MemoryLocation::get(RMW), Loc)) 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. // FIXME: this is really just shoring-up a deficiency in alias analysis.
// BasicAA isn't willing to spend linear time determining whether an alloca // BasicAA isn't willing to spend linear time determining whether an alloca
// was captured before or after this particular call, while we are. However, // 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. // with a smarter AA in place, this test is just wasting compile time.
AliasAnalysis::ModRefResult AliasAnalysis::callCapturesBefore( ModRefInfo AliasAnalysis::callCapturesBefore(const Instruction *I,
const Instruction *I, const MemoryLocation &MemLoc, DominatorTree *DT) { const MemoryLocation &MemLoc,
DominatorTree *DT) {
if (!DT) if (!DT)
return AliasAnalysis::ModRef; return MRI_ModRef;
const Value *Object = GetUnderlyingObject(MemLoc.Ptr, *DL); const Value *Object = GetUnderlyingObject(MemLoc.Ptr, *DL);
if (!isIdentifiedObject(Object) || isa<GlobalValue>(Object) || if (!isIdentifiedObject(Object) || isa<GlobalValue>(Object) ||
isa<Constant>(Object)) isa<Constant>(Object))
return AliasAnalysis::ModRef; return MRI_ModRef;
ImmutableCallSite CS(I); ImmutableCallSite CS(I);
if (!CS.getInstruction() || CS.getInstruction() == Object) if (!CS.getInstruction() || CS.getInstruction() == Object)
return AliasAnalysis::ModRef; return MRI_ModRef;
if (llvm::PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true, if (llvm::PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true,
/* StoreCaptures */ true, I, DT, /* StoreCaptures */ true, I, DT,
/* include Object */ true)) /* include Object */ true))
return AliasAnalysis::ModRef; return MRI_ModRef;
unsigned ArgNo = 0; unsigned ArgNo = 0;
AliasAnalysis::ModRefResult R = AliasAnalysis::NoModRef; ModRefInfo R = MRI_NoModRef;
for (ImmutableCallSite::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) { CI != CE; ++CI, ++ArgNo) {
// Only look at the no-capture or byval pointer arguments. If this // Only look at the no-capture or byval pointer arguments. If this
@ -379,10 +379,10 @@ AliasAnalysis::ModRefResult AliasAnalysis::callCapturesBefore(
if (CS.doesNotAccessMemory(ArgNo)) if (CS.doesNotAccessMemory(ArgNo))
continue; continue;
if (CS.onlyReadsMemory(ArgNo)) { if (CS.onlyReadsMemory(ArgNo)) {
R = AliasAnalysis::Ref; R = MRI_Ref;
continue; continue;
} }
return AliasAnalysis::ModRef; return MRI_ModRef;
} }
return R; return R;
} }
@ -422,7 +422,7 @@ uint64_t AliasAnalysis::getTypeStoreSize(Type *Ty) {
/// ///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB, bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
const MemoryLocation &Loc) { 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 /// canInstructionRangeModRef - Return true if it is possible for the
@ -433,7 +433,7 @@ bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
bool AliasAnalysis::canInstructionRangeModRef(const Instruction &I1, bool AliasAnalysis::canInstructionRangeModRef(const Instruction &I1,
const Instruction &I2, const Instruction &I2,
const MemoryLocation &Loc, const MemoryLocation &Loc,
const ModRefResult Mode) { const ModRefInfo Mode) {
assert(I1.getParent() == I2.getParent() && assert(I1.getParent() == I2.getParent() &&
"Instructions not in same basic block!"); "Instructions not in same basic block!");
BasicBlock::const_iterator I = &I1; BasicBlock::const_iterator I = &I1;

View File

@ -62,15 +62,16 @@ namespace {
<< Must*100/AASum<<"%\n\n"; << 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) { if (MRSum) {
printLine("no mod/ref", NoMR, MRSum); printLine("no mod/ref", NoMR, MRSum);
printLine("ref", JustRef, MRSum); printLine("ref", JustRef, MRSum);
printLine("mod", JustMod, MRSum); printLine("mod", JustMod, MRSum);
printLine("mod/ref", MR, MRSum); printLine("mod/ref", MR, MRSum);
errs() << " Mod/Ref Analysis Counter Summary: " <<NoMR*100/MRSum errs() << " MRI_Mod/MRI_Ref Analysis Counter Summary: "
<< "%/" << JustRef*100/MRSum << "%/" << JustMod*100/MRSum << NoMR * 100 / MRSum << "%/" << JustRef * 100 / MRSum << "%/"
<< "%/" << MR*100/MRSum <<"%\n\n"; << JustMod * 100 / MRSum << "%/" << MR * 100 / MRSum
<< "%\n\n";
} }
} }
} }
@ -108,10 +109,10 @@ namespace {
AliasResult alias(const MemoryLocation &LocA, AliasResult alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) override; const MemoryLocation &LocB) override;
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) override; const MemoryLocation &Loc) override;
ModRefResult getModRefInfo(ImmutableCallSite CS1, ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) override { ImmutableCallSite CS2) override {
return AliasAnalysis::getModRefInfo(CS1,CS2); return AliasAnalysis::getModRefInfo(CS1,CS2);
} }
}; };
@ -150,20 +151,31 @@ AliasResult AliasAnalysisCounter::alias(const MemoryLocation &LocA,
return R; return R;
} }
AliasAnalysis::ModRefResult ModRefInfo AliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS,
AliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
const MemoryLocation &Loc) { ModRefInfo R = getAnalysis<AliasAnalysis>().getModRefInfo(CS, Loc);
ModRefResult R = getAnalysis<AliasAnalysis>().getModRefInfo(CS, Loc);
const char *MRString = nullptr; const char *MRString = nullptr;
switch (R) { switch (R) {
case NoModRef: NoMR++; MRString = "NoModRef"; break; case MRI_NoModRef:
case Ref: JustRef++; MRString = "JustRef"; break; NoMR++;
case Mod: JustMod++; MRString = "JustMod"; break; MRString = "MRI_NoModRef";
case ModRef: MR++; MRString = "ModRef"; break; 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() << MRString << ": Ptr: ";
errs() << "[" << Loc.Size << "B] "; errs() << "[" << Loc.Size << "B] ";
Loc.Ptr->printAsOperand(errs(), true, M); Loc.Ptr->printAsOperand(errs(), true, M);

View File

@ -292,19 +292,19 @@ bool AAEval::runOnFunction(Function &F) {
if (ElTy->isSized()) Size = AA.getTypeStoreSize(ElTy); if (ElTy->isSized()) Size = AA.getTypeStoreSize(ElTy);
switch (AA.getModRefInfo(*C, *V, Size)) { switch (AA.getModRefInfo(*C, *V, Size)) {
case AliasAnalysis::NoModRef: case MRI_NoModRef:
PrintModRefResults("NoModRef", PrintNoModRef, I, *V, F.getParent()); PrintModRefResults("NoModRef", PrintNoModRef, I, *V, F.getParent());
++NoModRefCount; ++NoModRefCount;
break; break;
case AliasAnalysis::Mod: case MRI_Mod:
PrintModRefResults("Just Mod", PrintMod, I, *V, F.getParent()); PrintModRefResults("Just Mod", PrintMod, I, *V, F.getParent());
++ModCount; ++ModCount;
break; break;
case AliasAnalysis::Ref: case MRI_Ref:
PrintModRefResults("Just Ref", PrintRef, I, *V, F.getParent()); PrintModRefResults("Just Ref", PrintRef, I, *V, F.getParent());
++RefCount; ++RefCount;
break; break;
case AliasAnalysis::ModRef: case MRI_ModRef:
PrintModRefResults("Both ModRef", PrintModRef, I, *V, F.getParent()); PrintModRefResults("Both ModRef", PrintModRef, I, *V, F.getParent());
++ModRefCount; ++ModRefCount;
break; break;
@ -319,19 +319,19 @@ bool AAEval::runOnFunction(Function &F) {
if (D == C) if (D == C)
continue; continue;
switch (AA.getModRefInfo(*C, *D)) { switch (AA.getModRefInfo(*C, *D)) {
case AliasAnalysis::NoModRef: case MRI_NoModRef:
PrintModRefResults("NoModRef", PrintNoModRef, *C, *D, F.getParent()); PrintModRefResults("NoModRef", PrintNoModRef, *C, *D, F.getParent());
++NoModRefCount; ++NoModRefCount;
break; break;
case AliasAnalysis::Mod: case MRI_Mod:
PrintModRefResults("Just Mod", PrintMod, *C, *D, F.getParent()); PrintModRefResults("Just Mod", PrintMod, *C, *D, F.getParent());
++ModCount; ++ModCount;
break; break;
case AliasAnalysis::Ref: case MRI_Ref:
PrintModRefResults("Just Ref", PrintRef, *C, *D, F.getParent()); PrintModRefResults("Just Ref", PrintRef, *C, *D, F.getParent());
++RefCount; ++RefCount;
break; break;
case AliasAnalysis::ModRef: case MRI_ModRef:
PrintModRefResults("Both ModRef", PrintModRef, *C, *D, F.getParent()); PrintModRefResults("Both ModRef", PrintModRef, *C, *D, F.getParent());
++ModRefCount; ++ModRefCount;
break; break;

View File

@ -103,14 +103,14 @@ namespace {
return AliasAnalysis::alias(LocA, LocB); return AliasAnalysis::alias(LocA, LocB);
} }
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) override { const MemoryLocation &Loc) override {
assert(Vals.find(Loc.Ptr) != Vals.end() && "Never seen value in AA before"); assert(Vals.find(Loc.Ptr) != Vals.end() && "Never seen value in AA before");
return AliasAnalysis::getModRefInfo(CS, Loc); return AliasAnalysis::getModRefInfo(CS, Loc);
} }
ModRefResult getModRefInfo(ImmutableCallSite CS1, ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) override { ImmutableCallSite CS2) override {
return AliasAnalysis::getModRefInfo(CS1,CS2); return AliasAnalysis::getModRefInfo(CS1,CS2);
} }

View File

@ -167,8 +167,7 @@ bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
if (!UnknownInsts.empty()) { if (!UnknownInsts.empty()) {
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
if (AA.getModRefInfo(UnknownInsts[i], if (AA.getModRefInfo(UnknownInsts[i],
MemoryLocation(Ptr, Size, AAInfo)) != MemoryLocation(Ptr, Size, AAInfo)) != MRI_NoModRef)
AliasAnalysis::NoModRef)
return true; return true;
} }
@ -182,16 +181,14 @@ bool AliasSet::aliasesUnknownInst(const Instruction *Inst,
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
ImmutableCallSite C1(getUnknownInst(i)), C2(Inst); ImmutableCallSite C1(getUnknownInst(i)), C2(Inst);
if (!C1 || !C2 || if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef ||
AA.getModRefInfo(C1, C2) != AliasAnalysis::NoModRef || AA.getModRefInfo(C2, C1) != MRI_NoModRef)
AA.getModRefInfo(C2, C1) != AliasAnalysis::NoModRef)
return true; return true;
} }
for (iterator I = begin(), E = end(); I != E; ++I) for (iterator I = begin(), E = end(); I != E; ++I)
if (AA.getModRefInfo( if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(),
Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())) != I.getAAInfo())) != MRI_NoModRef)
AliasAnalysis::NoModRef)
return true; return true;
return false; return false;

View File

@ -479,11 +479,11 @@ namespace {
return Alias; return Alias;
} }
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) override; const MemoryLocation &Loc) override;
ModRefResult getModRefInfo(ImmutableCallSite CS1, ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) override; ImmutableCallSite CS2) override;
/// pointsToConstantMemory - Chase pointers until we find a (constant /// pointsToConstantMemory - Chase pointers until we find a (constant
/// global) or not. /// global) or not.
@ -491,16 +491,15 @@ namespace {
bool OrLocal) override; bool OrLocal) override;
/// Get the location associated with a pointer argument of a callsite. /// Get the location associated with a pointer argument of a callsite.
ModRefResult getArgModRefInfo(ImmutableCallSite CS, ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override;
unsigned ArgIdx) override;
/// getModRefBehavior - Return the behavior when calling the given /// getModRefBehavior - Return the behavior when calling the given
/// call site. /// call site.
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
/// getModRefBehavior - Return the behavior when calling the given function. /// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known. /// 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 /// getAdjustedAnalysisPointer - This method is used when a pass implements
/// an analysis interface through multiple inheritance. If needed, it /// an analysis interface through multiple inheritance. If needed, it
@ -676,33 +675,33 @@ static bool isMemsetPattern16(const Function *MS,
} }
/// getModRefBehavior - Return the behavior when calling the given call site. /// getModRefBehavior - Return the behavior when calling the given call site.
AliasAnalysis::ModRefBehavior FunctionModRefBehavior
BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
if (CS.doesNotAccessMemory()) if (CS.doesNotAccessMemory())
// Can't do better than this. // 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 // If the callsite knows it only reads memory, don't return worse
// than that. // than that.
if (CS.onlyReadsMemory()) if (CS.onlyReadsMemory())
Min = OnlyReadsMemory; Min = FMRB_OnlyReadsMemory;
if (CS.onlyAccessesArgMemory()) if (CS.onlyAccessesArgMemory())
Min = ModRefBehavior(Min & OnlyAccessesArgumentPointees); Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
// The AliasAnalysis base class has some smarts, lets use them. // 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. /// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known. /// For use when the call site is not known.
AliasAnalysis::ModRefBehavior FunctionModRefBehavior
BasicAliasAnalysis::getModRefBehavior(const Function *F) { BasicAliasAnalysis::getModRefBehavior(const Function *F) {
// If the function declares it doesn't access memory, we can't do better. // If the function declares it doesn't access memory, we can't do better.
if (F->doesNotAccessMemory()) if (F->doesNotAccessMemory())
return DoesNotAccessMemory; return FMRB_DoesNotAccessMemory;
// For intrinsics, we can check the table. // For intrinsics, we can check the table.
if (Intrinsic::ID iid = F->getIntrinsicID()) { if (Intrinsic::ID iid = F->getIntrinsicID()) {
@ -711,26 +710,26 @@ BasicAliasAnalysis::getModRefBehavior(const Function *F) {
#undef GET_INTRINSIC_MODREF_BEHAVIOR #undef GET_INTRINSIC_MODREF_BEHAVIOR
} }
ModRefBehavior Min = UnknownModRefBehavior; FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
// If the function declares it only reads memory, go with that. // If the function declares it only reads memory, go with that.
if (F->onlyReadsMemory()) if (F->onlyReadsMemory())
Min = OnlyReadsMemory; Min = FMRB_OnlyReadsMemory;
if (F->onlyAccessesArgMemory()) if (F->onlyAccessesArgMemory())
Min = ModRefBehavior(Min & OnlyAccessesArgumentPointees); Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
const TargetLibraryInfo &TLI = const TargetLibraryInfo &TLI =
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
if (isMemsetPattern16(F, TLI)) if (isMemsetPattern16(F, TLI))
Min = OnlyAccessesArgumentPointees; Min = FMRB_OnlyAccessesArgumentPointees;
// Otherwise be conservative. // Otherwise be conservative.
return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min); return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
} }
AliasAnalysis::ModRefResult ModRefInfo BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS,
BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { unsigned ArgIdx) {
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction()))
switch (II->getIntrinsicID()) { switch (II->getIntrinsicID()) {
default: default:
@ -740,7 +739,7 @@ BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
case Intrinsic::memmove: case Intrinsic::memmove:
assert((ArgIdx == 0 || ArgIdx == 1) && assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memory intrinsic"); "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 // We can bound the aliasing properties of memset_pattern16 just as we can
@ -751,7 +750,7 @@ BasicAliasAnalysis::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
isMemsetPattern16(CS.getCalledFunction(), *TLI)) { isMemsetPattern16(CS.getCalledFunction(), *TLI)) {
assert((ArgIdx == 0 || ArgIdx == 1) && assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memset_pattern16"); "Invalid argument index for memset_pattern16");
return ArgIdx ? Ref : Mod; return ArgIdx ? MRI_Ref : MRI_Mod;
} }
// FIXME: Handle memset_pattern4 and memset_pattern8 also. // FIXME: Handle memset_pattern4 and memset_pattern8 also.
@ -775,9 +774,8 @@ bool BasicAliasAnalysis::doInitialization(Module &M) {
/// specified memory object. Since we only look at local properties of this /// 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 /// function, we really can't say much about this query. We do, however, use
/// simple "address taken" analysis on local objects. /// simple "address taken" analysis on local objects.
AliasAnalysis::ModRefResult ModRefInfo BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
const MemoryLocation &Loc) {
assert(notDifferentParent(CS.getInstruction(), Loc.Ptr) && assert(notDifferentParent(CS.getInstruction(), Loc.Ptr) &&
"AliasAnalysis query involving multiple functions!"); "AliasAnalysis query involving multiple functions!");
@ -791,7 +789,7 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
if (isa<AllocaInst>(Object)) if (isa<AllocaInst>(Object))
if (const CallInst *CI = dyn_cast<CallInst>(CS.getInstruction())) if (const CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
if (CI->isTailCall()) if (CI->isTailCall())
return NoModRef; return MRI_NoModRef;
// If the pointer is to a locally allocated object that does not escape, // 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 // then the call can not mod/ref the pointer unless the call takes the pointer
@ -820,27 +818,26 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
} }
if (!PassedAsArg) if (!PassedAsArg)
return NoModRef; return MRI_NoModRef;
} }
// While the assume intrinsic is marked as arbitrarily writing so that // While the assume intrinsic is marked as arbitrarily writing so that
// proper control dependencies will be maintained, it never aliases any // proper control dependencies will be maintained, it never aliases any
// particular memory location. // particular memory location.
if (isAssumeIntrinsic(CS)) if (isAssumeIntrinsic(CS))
return NoModRef; return MRI_NoModRef;
// The AliasAnalysis base class has some smarts, lets use them. // The AliasAnalysis base class has some smarts, lets use them.
return AliasAnalysis::getModRefInfo(CS, Loc); return AliasAnalysis::getModRefInfo(CS, Loc);
} }
AliasAnalysis::ModRefResult ModRefInfo BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
ImmutableCallSite CS2) {
// While the assume intrinsic is marked as arbitrarily writing so that // While the assume intrinsic is marked as arbitrarily writing so that
// proper control dependencies will be maintained, it never aliases any // proper control dependencies will be maintained, it never aliases any
// particular memory location. // particular memory location.
if (isAssumeIntrinsic(CS1) || isAssumeIntrinsic(CS2)) if (isAssumeIntrinsic(CS1) || isAssumeIntrinsic(CS2))
return NoModRef; return MRI_NoModRef;
// The AliasAnalysis base class has some smarts, lets use them. // The AliasAnalysis base class has some smarts, lets use them.
return AliasAnalysis::getModRefInfo(CS1, CS2); return AliasAnalysis::getModRefInfo(CS1, CS2);

View File

@ -71,7 +71,7 @@ struct FunctionRecord {
bool MayReadAnyGlobal; bool MayReadAnyGlobal;
unsigned getInfoForGlobal(const GlobalValue *GV) const { 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 = std::map<const GlobalValue *, unsigned>::const_iterator I =
GlobalInfo.find(GV); GlobalInfo.find(GV);
if (I != GlobalInfo.end()) if (I != GlobalInfo.end())
@ -168,51 +168,6 @@ public:
AU.setPreservesAll(); // Does not transform code AU.setPreservesAll(); // Does not transform code
} }
//------------------------------------------------
// 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 {
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;
if (FunctionRecord *FR = getFunctionInfo(F)) {
if (FR->FunctionEffect == 0)
Min = DoesNotAccessMemory;
else if ((FR->FunctionEffect & Mod) == 0)
Min = OnlyReadsMemory;
}
return ModRefBehavior(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;
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;
}
return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
}
/// getAdjustedAnalysisPointer - This method is used when a pass implements /// getAdjustedAnalysisPointer - This method is used when a pass implements
/// an analysis interface through multiple inheritance. If needed, it /// an analysis interface through multiple inheritance. If needed, it
/// should override this to adjust the this pointer as needed for the /// should override this to adjust the this pointer as needed for the
@ -223,6 +178,51 @@ public:
return this; return this;
} }
//------------------------------------------------
// Implement the AliasAnalysis API
//
AliasResult alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) 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.
FunctionModRefBehavior getModRefBehavior(const Function *F) override {
FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
if (FunctionRecord *FR = getFunctionInfo(F)) {
if (FR->FunctionEffect == 0)
Min = FMRB_DoesNotAccessMemory;
else if ((FR->FunctionEffect & MRI_Mod) == 0)
Min = FMRB_OnlyReadsMemory;
}
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.
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 = FMRB_DoesNotAccessMemory;
else if ((FR->FunctionEffect & MRI_Mod) == 0)
Min = FMRB_OnlyReadsMemory;
}
return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
}
private: private:
/// getFunctionInfo - Return the function info for the function, or null if /// getFunctionInfo - Return the function info for the function, or null if
/// we don't have anything useful to say about it. /// we don't have anything useful to say about it.
@ -280,11 +280,11 @@ void GlobalsModRef::AnalyzeGlobals(Module &M) {
Handles.front().I = Handles.begin(); Handles.front().I = Handles.begin();
for (Function *Reader : Readers) 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 if (!GV.isConstant()) // No need to keep track of writers to constants
for (Function *Writer : Writers) for (Function *Writer : Writers)
FunctionInfo[Writer].GlobalInfo[&GV] |= Mod; FunctionInfo[Writer].GlobalInfo[&GV] |= MRI_Mod;
++NumNonAddrTakenGlobalVars; ++NumNonAddrTakenGlobalVars;
// If this global holds a pointer type, see if it is an indirect global. // If this global holds a pointer type, see if it is an indirect global.
@ -455,13 +455,13 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
if (F->doesNotAccessMemory()) { if (F->doesNotAccessMemory()) {
// Can't do better than that! // Can't do better than that!
} else if (F->onlyReadsMemory()) { } else if (F->onlyReadsMemory()) {
FunctionEffect |= Ref; FunctionEffect |= MRI_Ref;
if (!F->isIntrinsic()) if (!F->isIntrinsic())
// This function might call back into the module and read a global - // This function might call back into the module and read a global -
// consider every global as possibly being read by this function. // consider every global as possibly being read by this function.
FR.MayReadAnyGlobal = true; FR.MayReadAnyGlobal = true;
} else { } else {
FunctionEffect |= ModRef; FunctionEffect |= MRI_ModRef;
// Can't say anything useful unless it's an intrinsic - they don't // Can't say anything useful unless it's an intrinsic - they don't
// read or write global variables of the kind considered here. // read or write global variables of the kind considered here.
KnowNothing = !F->isIntrinsic(); KnowNothing = !F->isIntrinsic();
@ -502,10 +502,10 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
// Scan the function bodies for explicit loads or stores. // Scan the function bodies for explicit loads or stores.
for (auto *Node : SCC) { for (auto *Node : SCC) {
if (FunctionEffect == ModRef) if (FunctionEffect == MRI_ModRef)
break; // The mod/ref lattice saturates here. break; // The mod/ref lattice saturates here.
for (Instruction &I : inst_range(Node->getFunction())) { for (Instruction &I : inst_range(Node->getFunction())) {
if (FunctionEffect == ModRef) if (FunctionEffect == MRI_ModRef)
break; // The mod/ref lattice saturates here. break; // The mod/ref lattice saturates here.
// We handle calls specially because the graph-relevant aspects are // We handle calls specially because the graph-relevant aspects are
@ -514,13 +514,13 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
if (isAllocationFn(&I, TLI) || isFreeCall(&I, TLI)) { if (isAllocationFn(&I, TLI) || isFreeCall(&I, TLI)) {
// FIXME: It is completely unclear why this is necessary and not // FIXME: It is completely unclear why this is necessary and not
// handled by the above graph code. // handled by the above graph code.
FunctionEffect |= ModRef; FunctionEffect |= MRI_ModRef;
} else if (Function *Callee = CS.getCalledFunction()) { } else if (Function *Callee = CS.getCalledFunction()) {
// The callgraph doesn't include intrinsic calls. // The callgraph doesn't include intrinsic calls.
if (Callee->isIntrinsic()) { if (Callee->isIntrinsic()) {
ModRefBehavior Behaviour = FunctionModRefBehavior Behaviour =
AliasAnalysis::getModRefBehavior(Callee); AliasAnalysis::getModRefBehavior(Callee);
FunctionEffect |= (Behaviour & ModRef); FunctionEffect |= (Behaviour & MRI_ModRef);
} }
} }
continue; continue;
@ -529,13 +529,13 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
// All non-call instructions we use the primary predicates for whether // All non-call instructions we use the primary predicates for whether
// thay read or write memory. // thay read or write memory.
if (I.mayReadFromMemory()) if (I.mayReadFromMemory())
FunctionEffect |= Ref; FunctionEffect |= MRI_Ref;
if (I.mayWriteToMemory()) if (I.mayWriteToMemory())
FunctionEffect |= Mod; FunctionEffect |= MRI_Mod;
} }
} }
if ((FunctionEffect & Mod) == 0) if ((FunctionEffect & MRI_Mod) == 0)
++NumReadMemFunctions; ++NumReadMemFunctions;
if (FunctionEffect == 0) if (FunctionEffect == 0)
++NumNoMemFunctions; ++NumNoMemFunctions;
@ -621,9 +621,9 @@ AliasResult GlobalsModRef::alias(const MemoryLocation &LocA,
return AliasAnalysis::alias(LocA, LocB); return AliasAnalysis::alias(LocA, LocB);
} }
AliasAnalysis::ModRefResult ModRefInfo GlobalsModRef::getModRefInfo(ImmutableCallSite CS,
GlobalsModRef::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) { const MemoryLocation &Loc) {
unsigned Known = ModRef; unsigned Known = MRI_ModRef;
// If we are asking for mod/ref info of a direct call with a pointer to a // 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. // global we are tracking, return information if we have it.
@ -636,7 +636,7 @@ GlobalsModRef::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
if (const FunctionRecord *FR = getFunctionInfo(F)) if (const FunctionRecord *FR = getFunctionInfo(F))
Known = FR->getInfoForGlobal(GV); Known = FR->getInfoForGlobal(GV);
if (Known == NoModRef) if (Known == MRI_NoModRef)
return NoModRef; // No need to query other mod/ref analyses return MRI_NoModRef; // No need to query other mod/ref analyses
return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, Loc)); return ModRefInfo(Known & AliasAnalysis::getModRefInfo(CS, Loc));
} }

View File

@ -45,15 +45,16 @@ bool LibCallAliasAnalysis::runOnFunction(Function &F) {
/// AnalyzeLibCallDetails - Given a call to a function with the specified /// AnalyzeLibCallDetails - Given a call to a function with the specified
/// LibCallFunctionInfo, see if we can improve the mod/ref footprint of the call /// LibCallFunctionInfo, see if we can improve the mod/ref footprint of the call
/// vs the specified pointer/size. /// vs the specified pointer/size.
AliasAnalysis::ModRefResult ModRefInfo
LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
ImmutableCallSite CS, ImmutableCallSite CS,
const MemoryLocation &Loc) { const MemoryLocation &Loc) {
// If we have a function, check to see what kind of mod/ref effects it // 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. // has. Start by including any info globally known about the function.
AliasAnalysis::ModRefResult MRInfo = FI->UniversalBehavior; ModRefInfo MRInfo = FI->UniversalBehavior;
if (MRInfo == NoModRef) return MRInfo; if (MRInfo == MRI_NoModRef)
return MRInfo;
// If that didn't tell us that the function is 'readnone', check to see // 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 // if we have detailed info and if 'P' is any of the locations we know
// about. // about.
@ -75,7 +76,7 @@ LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
// If we find a match against a location that we 'do not' interact with, // If we find a match against a location that we 'do not' interact with,
// learn this info into MRInfo. // learn this info into MRInfo.
return ModRefResult(MRInfo & ~Details[i].MRInfo); return ModRefInfo(MRInfo & ~Details[i].MRInfo);
} }
return MRInfo; return MRInfo;
} }
@ -83,7 +84,7 @@ LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
// If the details are of the 'DoesOnly' sort, we know something if the pointer // 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 // 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 // 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); assert(FI->DetailsType == LibCallFunctionInfo::DoesOnly);
// Find out if the pointer refers to a known location. // Find out if the pointer refers to a known location.
@ -103,16 +104,16 @@ LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
// If we know that this pointer definitely is pointing into the location, // If we know that this pointer definitely is pointing into the location,
// merge in this information. // 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 // 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 // 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 // to some other location. Since the libcall doesn't mod/ref any other
// locations, return NoModRef. // locations, return MRI_NoModRef.
if (NoneMatch) if (NoneMatch)
return NoModRef; return MRI_NoModRef;
// Otherwise, return any other info gained so far. // Otherwise, return any other info gained so far.
return MRInfo; return MRInfo;
} }
@ -120,22 +121,22 @@ LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
// getModRefInfo - Check to see if the specified callsite can clobber the // getModRefInfo - Check to see if the specified callsite can clobber the
// specified memory object. // specified memory object.
// //
AliasAnalysis::ModRefResult ModRefInfo LibCallAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
LibCallAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
const MemoryLocation &Loc) { ModRefInfo MRInfo = MRI_ModRef;
ModRefResult MRInfo = ModRef;
// If this is a direct call to a function that LCI knows about, get the // If this is a direct call to a function that LCI knows about, get the
// information about the runtime function. // information about the runtime function.
if (LCI) { if (LCI) {
if (const Function *F = CS.getCalledFunction()) { if (const Function *F = CS.getCalledFunction()) {
if (const LibCallFunctionInfo *FI = LCI->getFunctionInfo(F)) { if (const LibCallFunctionInfo *FI = LCI->getFunctionInfo(F)) {
MRInfo = ModRefResult(MRInfo & AnalyzeLibCallDetails(FI, CS, Loc)); MRInfo = ModRefInfo(MRInfo & AnalyzeLibCallDetails(FI, CS, Loc));
if (MRInfo == NoModRef) return NoModRef; if (MRInfo == MRI_NoModRef)
return MRI_NoModRef;
} }
} }
} }
// The AliasAnalysis base class has some smarts, lets use them. // The AliasAnalysis base class has some smarts, lets use them.
return (ModRefResult)(MRInfo | AliasAnalysis::getModRefInfo(CS, Loc)); return (ModRefInfo)(MRInfo | AliasAnalysis::getModRefInfo(CS, Loc));
} }

View File

@ -246,9 +246,7 @@ Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
// If we have alias analysis and it says the store won't modify the loaded // If we have alias analysis and it says the store won't modify the loaded
// value, ignore the store. // value, ignore the store.
if (AA && if (AA && (AA->getModRefInfo(SI, StrippedPtr, AccessSize) & MRI_Mod) == 0)
(AA->getModRefInfo(SI, StrippedPtr, AccessSize) &
AliasAnalysis::Mod) == 0)
continue; continue;
// Otherwise the store that may or may not alias the pointer, bail out. // Otherwise the store that may or may not alias the pointer, bail out.
@ -261,8 +259,7 @@ Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
// If alias analysis claims that it really won't modify the load, // If alias analysis claims that it really won't modify the load,
// ignore it. // ignore it.
if (AA && if (AA &&
(AA->getModRefInfo(Inst, StrippedPtr, AccessSize) & (AA->getModRefInfo(Inst, StrippedPtr, AccessSize) & MRI_Mod) == 0)
AliasAnalysis::Mod) == 0)
continue; continue;
// May modify the pointer, bail out. // May modify the pointer, bail out.

View File

@ -122,43 +122,43 @@ static void RemoveFromReverseMap(DenseMap<Instruction*,
/// location, fill in Loc with the details, otherwise set Loc.Ptr to null. /// location, fill in Loc with the details, otherwise set Loc.Ptr to null.
/// Return a ModRefInfo value describing the general behavior of the /// Return a ModRefInfo value describing the general behavior of the
/// instruction. /// instruction.
static AliasAnalysis::ModRefResult static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,
GetLocation(const Instruction *Inst, MemoryLocation &Loc, AliasAnalysis *AA) { AliasAnalysis *AA) {
if (const LoadInst *LI = dyn_cast<LoadInst>(Inst)) { if (const LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
if (LI->isUnordered()) { if (LI->isUnordered()) {
Loc = MemoryLocation::get(LI); Loc = MemoryLocation::get(LI);
return AliasAnalysis::Ref; return MRI_Ref;
} }
if (LI->getOrdering() == Monotonic) { if (LI->getOrdering() == Monotonic) {
Loc = MemoryLocation::get(LI); Loc = MemoryLocation::get(LI);
return AliasAnalysis::ModRef; return MRI_ModRef;
} }
Loc = MemoryLocation(); Loc = MemoryLocation();
return AliasAnalysis::ModRef; return MRI_ModRef;
} }
if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) { if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
if (SI->isUnordered()) { if (SI->isUnordered()) {
Loc = MemoryLocation::get(SI); Loc = MemoryLocation::get(SI);
return AliasAnalysis::Mod; return MRI_Mod;
} }
if (SI->getOrdering() == Monotonic) { if (SI->getOrdering() == Monotonic) {
Loc = MemoryLocation::get(SI); Loc = MemoryLocation::get(SI);
return AliasAnalysis::ModRef; return MRI_ModRef;
} }
Loc = MemoryLocation(); Loc = MemoryLocation();
return AliasAnalysis::ModRef; return MRI_ModRef;
} }
if (const VAArgInst *V = dyn_cast<VAArgInst>(Inst)) { if (const VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
Loc = MemoryLocation::get(V); Loc = MemoryLocation::get(V);
return AliasAnalysis::ModRef; return MRI_ModRef;
} }
if (const CallInst *CI = isFreeCall(Inst, AA->getTargetLibraryInfo())) { if (const CallInst *CI = isFreeCall(Inst, AA->getTargetLibraryInfo())) {
// calls to free() deallocate the entire structure // calls to free() deallocate the entire structure
Loc = MemoryLocation(CI->getArgOperand(0)); Loc = MemoryLocation(CI->getArgOperand(0));
return AliasAnalysis::Mod; return MRI_Mod;
} }
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) { if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
@ -174,7 +174,7 @@ GetLocation(const Instruction *Inst, MemoryLocation &Loc, AliasAnalysis *AA) {
cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AAInfo); cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AAInfo);
// These intrinsics don't really modify the memory, but returning Mod // These intrinsics don't really modify the memory, but returning Mod
// will allow them to be handled conservatively. // will allow them to be handled conservatively.
return AliasAnalysis::Mod; return MRI_Mod;
case Intrinsic::invariant_end: case Intrinsic::invariant_end:
II->getAAMetadata(AAInfo); II->getAAMetadata(AAInfo);
Loc = MemoryLocation( Loc = MemoryLocation(
@ -182,7 +182,7 @@ GetLocation(const Instruction *Inst, MemoryLocation &Loc, AliasAnalysis *AA) {
cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AAInfo); cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AAInfo);
// These intrinsics don't really modify the memory, but returning Mod // These intrinsics don't really modify the memory, but returning Mod
// will allow them to be handled conservatively. // will allow them to be handled conservatively.
return AliasAnalysis::Mod; return MRI_Mod;
default: default:
break; break;
} }
@ -190,10 +190,10 @@ GetLocation(const Instruction *Inst, MemoryLocation &Loc, AliasAnalysis *AA) {
// Otherwise, just do the coarse-grained thing that always works. // Otherwise, just do the coarse-grained thing that always works.
if (Inst->mayWriteToMemory()) if (Inst->mayWriteToMemory())
return AliasAnalysis::ModRef; return MRI_ModRef;
if (Inst->mayReadFromMemory()) if (Inst->mayReadFromMemory())
return AliasAnalysis::Ref; return MRI_Ref;
return AliasAnalysis::NoModRef; return MRI_NoModRef;
} }
/// getCallSiteDependencyFrom - Private helper for finding the local /// getCallSiteDependencyFrom - Private helper for finding the local
@ -215,10 +215,10 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall,
// If this inst is a memory op, get the pointer it accessed // If this inst is a memory op, get the pointer it accessed
MemoryLocation Loc; MemoryLocation Loc;
AliasAnalysis::ModRefResult MR = GetLocation(Inst, Loc, AA); ModRefInfo MR = GetLocation(Inst, Loc, AA);
if (Loc.Ptr) { if (Loc.Ptr) {
// A simple instruction. // A simple instruction.
if (AA->getModRefInfo(CS, Loc) != AliasAnalysis::NoModRef) if (AA->getModRefInfo(CS, Loc) != MRI_NoModRef)
return MemDepResult::getClobber(Inst); return MemDepResult::getClobber(Inst);
continue; continue;
} }
@ -228,10 +228,10 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall,
if (isa<DbgInfoIntrinsic>(Inst)) continue; if (isa<DbgInfoIntrinsic>(Inst)) continue;
// If these two calls do not interfere, look past it. // If these two calls do not interfere, look past it.
switch (AA->getModRefInfo(CS, InstCS)) { 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 // If the two calls are the same, return InstCS as a Def, so that
// CS can be found redundant and eliminated. // CS can be found redundant and eliminated.
if (isReadOnlyCall && !(MR & AliasAnalysis::Mod) && if (isReadOnlyCall && !(MR & MRI_Mod) &&
CS.getInstruction()->isIdenticalToWhenDefined(Inst)) CS.getInstruction()->isIdenticalToWhenDefined(Inst))
return MemDepResult::getDef(Inst); return MemDepResult::getDef(Inst);
@ -245,7 +245,7 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall,
// If we could not obtain a pointer for the instruction and the instruction // If we could not obtain a pointer for the instruction and the instruction
// touches memory then assume that this is a dependency. // touches memory then assume that this is a dependency.
if (MR != AliasAnalysis::NoModRef) if (MR != MRI_NoModRef)
return MemDepResult::getClobber(Inst); return MemDepResult::getClobber(Inst);
} }
@ -571,7 +571,7 @@ MemDepResult MemoryDependenceAnalysis::getPointerDependencyFrom(
// If alias analysis can tell that this store is guaranteed to not modify // 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, ignore it. Use getModRefInfo to handle cases where
// the query pointer points to constant memory etc. // the query pointer points to constant memory etc.
if (AA->getModRefInfo(SI, MemLoc) == AliasAnalysis::NoModRef) if (AA->getModRefInfo(SI, MemLoc) == MRI_NoModRef)
continue; continue;
// Ok, this store might clobber the query pointer. Check to see if it is // Ok, this store might clobber the query pointer. Check to see if it is
@ -620,17 +620,17 @@ MemDepResult MemoryDependenceAnalysis::getPointerDependencyFrom(
continue; continue;
// See if this instruction (e.g. a call or vaarg) mod/ref's the pointer. // 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 necessary, perform additional analysis.
if (MR == AliasAnalysis::ModRef) if (MR == MRI_ModRef)
MR = AA->callCapturesBefore(Inst, MemLoc, DT); MR = AA->callCapturesBefore(Inst, MemLoc, DT);
switch (MR) { switch (MR) {
case AliasAnalysis::NoModRef: case MRI_NoModRef:
// If the call has no effect on the queried pointer, just ignore it. // If the call has no effect on the queried pointer, just ignore it.
continue; continue;
case AliasAnalysis::Mod: case MRI_Mod:
return MemDepResult::getClobber(Inst); 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 // 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). // load query, we can safely ignore it (scan past it).
if (isLoad) if (isLoad)
@ -681,10 +681,10 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) {
LocalCache = MemDepResult::getNonFuncLocal(); LocalCache = MemDepResult::getNonFuncLocal();
} else { } else {
MemoryLocation MemLoc; MemoryLocation MemLoc;
AliasAnalysis::ModRefResult MR = GetLocation(QueryInst, MemLoc, AA); ModRefInfo MR = GetLocation(QueryInst, MemLoc, AA);
if (MemLoc.Ptr) { if (MemLoc.Ptr) {
// If we can do a pointer scan, make it happen. // 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)) if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(QueryInst))
isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_start; isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_start;

View File

@ -46,29 +46,29 @@ namespace {
return MayAlias; return MayAlias;
} }
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override { FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override {
return UnknownModRefBehavior; return FMRB_UnknownModRefBehavior;
} }
ModRefBehavior getModRefBehavior(const Function *F) override { FunctionModRefBehavior getModRefBehavior(const Function *F) override {
return UnknownModRefBehavior; return FMRB_UnknownModRefBehavior;
} }
bool pointsToConstantMemory(const MemoryLocation &Loc, bool pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) override { bool OrLocal) override {
return false; return false;
} }
ModRefResult getArgModRefInfo(ImmutableCallSite CS, ModRefInfo getArgModRefInfo(ImmutableCallSite CS,
unsigned ArgIdx) override { unsigned ArgIdx) override {
return ModRef; return MRI_ModRef;
} }
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) override { const MemoryLocation &Loc) override {
return ModRef; return MRI_ModRef;
} }
ModRefResult getModRefInfo(ImmutableCallSite CS1, ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) override { ImmutableCallSite CS2) override {
return ModRef; return MRI_ModRef;
} }
/// getAdjustedAnalysisPointer - This method is used when a pass implements /// getAdjustedAnalysisPointer - This method is used when a pass implements

View File

@ -102,12 +102,12 @@ private:
AliasResult alias(const MemoryLocation &LocA, AliasResult alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) override; const MemoryLocation &LocB) override;
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override; bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override;
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
ModRefBehavior getModRefBehavior(const Function *F) override; FunctionModRefBehavior getModRefBehavior(const Function *F) override;
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) override; const MemoryLocation &Loc) override;
ModRefResult getModRefInfo(ImmutableCallSite CS1, ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) override; ImmutableCallSite CS2) override;
}; };
} // End of anonymous namespace } // End of anonymous namespace
@ -204,48 +204,46 @@ bool ScopedNoAliasAA::pointsToConstantMemory(const MemoryLocation &Loc,
return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
} }
AliasAnalysis::ModRefBehavior FunctionModRefBehavior
ScopedNoAliasAA::getModRefBehavior(ImmutableCallSite CS) { ScopedNoAliasAA::getModRefBehavior(ImmutableCallSite CS) {
return AliasAnalysis::getModRefBehavior(CS); return AliasAnalysis::getModRefBehavior(CS);
} }
AliasAnalysis::ModRefBehavior FunctionModRefBehavior ScopedNoAliasAA::getModRefBehavior(const Function *F) {
ScopedNoAliasAA::getModRefBehavior(const Function *F) {
return AliasAnalysis::getModRefBehavior(F); return AliasAnalysis::getModRefBehavior(F);
} }
AliasAnalysis::ModRefResult ModRefInfo ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS,
ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
const MemoryLocation &Loc) {
if (!EnableScopedNoAlias) if (!EnableScopedNoAlias)
return AliasAnalysis::getModRefInfo(CS, Loc); return AliasAnalysis::getModRefInfo(CS, Loc);
if (!mayAliasInScopes(Loc.AATags.Scope, CS.getInstruction()->getMetadata( if (!mayAliasInScopes(Loc.AATags.Scope, CS.getInstruction()->getMetadata(
LLVMContext::MD_noalias))) LLVMContext::MD_noalias)))
return NoModRef; return MRI_NoModRef;
if (!mayAliasInScopes( if (!mayAliasInScopes(
CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
Loc.AATags.NoAlias)) Loc.AATags.NoAlias))
return NoModRef; return MRI_NoModRef;
return AliasAnalysis::getModRefInfo(CS, Loc); return AliasAnalysis::getModRefInfo(CS, Loc);
} }
AliasAnalysis::ModRefResult ModRefInfo ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS1,
ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { ImmutableCallSite CS2) {
if (!EnableScopedNoAlias) if (!EnableScopedNoAlias)
return AliasAnalysis::getModRefInfo(CS1, CS2); return AliasAnalysis::getModRefInfo(CS1, CS2);
if (!mayAliasInScopes( if (!mayAliasInScopes(
CS1.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), CS1.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
CS2.getInstruction()->getMetadata(LLVMContext::MD_noalias))) CS2.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
return NoModRef; return MRI_NoModRef;
if (!mayAliasInScopes( if (!mayAliasInScopes(
CS2.getInstruction()->getMetadata(LLVMContext::MD_alias_scope), CS2.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
CS1.getInstruction()->getMetadata(LLVMContext::MD_noalias))) CS1.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
return NoModRef; return MRI_NoModRef;
return AliasAnalysis::getModRefInfo(CS1, CS2); return AliasAnalysis::getModRefInfo(CS1, CS2);
} }

View File

@ -304,12 +304,12 @@ namespace {
const MemoryLocation &LocB) override; const MemoryLocation &LocB) override;
bool pointsToConstantMemory(const MemoryLocation &Loc, bool pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) override; bool OrLocal) override;
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
ModRefBehavior getModRefBehavior(const Function *F) override; FunctionModRefBehavior getModRefBehavior(const Function *F) override;
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) override; const MemoryLocation &Loc) override;
ModRefResult getModRefInfo(ImmutableCallSite CS1, ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) override; ImmutableCallSite CS2) override;
}; };
} // End of anonymous namespace } // End of anonymous namespace
@ -491,32 +491,31 @@ bool TypeBasedAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc,
return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
} }
AliasAnalysis::ModRefBehavior FunctionModRefBehavior
TypeBasedAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { TypeBasedAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
if (!EnableTBAA) if (!EnableTBAA)
return AliasAnalysis::getModRefBehavior(CS); 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 // If this is an "immutable" type, we can assume the call doesn't write
// to memory. // to memory.
if (const MDNode *M = CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa)) if (const MDNode *M = CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa))
if ((!isStructPathTBAA(M) && TBAANode(M).TypeIsImmutable()) || if ((!isStructPathTBAA(M) && TBAANode(M).TypeIsImmutable()) ||
(isStructPathTBAA(M) && TBAAStructTagNode(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) { TypeBasedAliasAnalysis::getModRefBehavior(const Function *F) {
// Functions don't have metadata. Just chain to the next implementation. // Functions don't have metadata. Just chain to the next implementation.
return AliasAnalysis::getModRefBehavior(F); return AliasAnalysis::getModRefBehavior(F);
} }
AliasAnalysis::ModRefResult ModRefInfo TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
const MemoryLocation &Loc) {
if (!EnableTBAA) if (!EnableTBAA)
return AliasAnalysis::getModRefInfo(CS, Loc); return AliasAnalysis::getModRefInfo(CS, Loc);
@ -524,14 +523,13 @@ TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
if (const MDNode *M = if (const MDNode *M =
CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa)) CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa))
if (!Aliases(L, M)) if (!Aliases(L, M))
return NoModRef; return MRI_NoModRef;
return AliasAnalysis::getModRefInfo(CS, Loc); return AliasAnalysis::getModRefInfo(CS, Loc);
} }
AliasAnalysis::ModRefResult ModRefInfo TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
ImmutableCallSite CS2) {
if (!EnableTBAA) if (!EnableTBAA)
return AliasAnalysis::getModRefInfo(CS1, CS2); return AliasAnalysis::getModRefInfo(CS1, CS2);
@ -540,7 +538,7 @@ TypeBasedAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
if (const MDNode *M2 = if (const MDNode *M2 =
CS2.getInstruction()->getMetadata(LLVMContext::MD_tbaa)) CS2.getInstruction()->getMetadata(LLVMContext::MD_tbaa))
if (!Aliases(M1, M2)) if (!Aliases(M1, M2))
return NoModRef; return MRI_NoModRef;
return AliasAnalysis::getModRefInfo(CS1, CS2); return AliasAnalysis::getModRefInfo(CS1, CS2);
} }

View File

@ -571,8 +571,7 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg,
BasicBlock *BB = Load->getParent(); BasicBlock *BB = Load->getParent();
MemoryLocation Loc = MemoryLocation::get(Load); MemoryLocation Loc = MemoryLocation::get(Load);
if (AA.canInstructionRangeModRef(BB->front(), *Load, Loc, if (AA.canInstructionRangeModRef(BB->front(), *Load, Loc, MRI_Mod))
AliasAnalysis::Mod))
return false; // Pointer is invalidated! return false; // Pointer is invalidated!
// Now check every path from the entry block to the load for transparency. // Now check every path from the entry block to the load for transparency.

View File

@ -166,8 +166,8 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
// memory and give up. // memory and give up.
return false; return false;
AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(F); FunctionModRefBehavior MRB = AA->getModRefBehavior(F);
if (MRB == AliasAnalysis::DoesNotAccessMemory) if (MRB == FMRB_DoesNotAccessMemory)
// Already perfect! // Already perfect!
continue; continue;
@ -193,7 +193,7 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
// Ignore calls to functions in the same SCC. // Ignore calls to functions in the same SCC.
if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction())) if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction()))
continue; 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 // If the call doesn't access arbitrary memory, we may be able to
// figure out something. // figure out something.
if (AliasAnalysis::onlyAccessesArgPointees(MRB)) { if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {
@ -210,10 +210,10 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
MemoryLocation Loc(Arg, MemoryLocation::UnknownSize, AAInfo); MemoryLocation Loc(Arg, MemoryLocation::UnknownSize, AAInfo);
if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) { if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) {
if (MRB & AliasAnalysis::Mod) if (MRB & MRI_Mod)
// Writes non-local memory. Give up. // Writes non-local memory. Give up.
return false; return false;
if (MRB & AliasAnalysis::Ref) if (MRB & MRI_Ref)
// Ok, it reads non-local memory. // Ok, it reads non-local memory.
ReadsMemory = true; ReadsMemory = true;
} }
@ -222,10 +222,10 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
continue; continue;
} }
// The call could access any memory. If that includes writes, give up. // The call could access any memory. If that includes writes, give up.
if (MRB & AliasAnalysis::Mod) if (MRB & MRI_Mod)
return false; return false;
// If it reads, note it. // If it reads, note it.
if (MRB & AliasAnalysis::Ref) if (MRB & MRI_Ref)
ReadsMemory = true; ReadsMemory = true;
continue; continue;
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) { } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {

View File

@ -1867,15 +1867,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
}; };
static IntrinsicKind getIntrinsicKind(Intrinsic::ID iid) { static IntrinsicKind getIntrinsicKind(Intrinsic::ID iid) {
const int DoesNotAccessMemory = IK_DoesNotAccessMemory; const int FMRB_DoesNotAccessMemory = IK_DoesNotAccessMemory;
const int OnlyReadsArgumentPointees = IK_OnlyReadsMemory; const int FMRB_OnlyReadsArgumentPointees = IK_OnlyReadsMemory;
const int OnlyReadsMemory = IK_OnlyReadsMemory; const int FMRB_OnlyReadsMemory = IK_OnlyReadsMemory;
const int OnlyAccessesArgumentPointees = IK_WritesMemory; const int FMRB_OnlyAccessesArgumentPointees = IK_WritesMemory;
const int UnknownModRefBehavior = IK_WritesMemory; const int FMRB_UnknownModRefBehavior = IK_WritesMemory;
#define GET_INTRINSIC_MODREF_BEHAVIOR #define GET_INTRINSIC_MODREF_BEHAVIOR
#define ModRefBehavior IntrinsicKind #define FunctionModRefBehavior IntrinsicKind
#include "llvm/IR/Intrinsics.gen" #include "llvm/IR/Intrinsics.gen"
#undef ModRefBehavior #undef FunctionModRefBehavior
#undef GET_INTRINSIC_MODREF_BEHAVIOR #undef GET_INTRINSIC_MODREF_BEHAVIOR
} }

View File

@ -49,7 +49,7 @@ bool llvm::objcarc::CanAlterRefCount(const Instruction *Inst, const Value *Ptr,
assert(CS && "Only calls can alter reference counts!"); assert(CS && "Only calls can alter reference counts!");
// See if AliasAnalysis can help us with the call. // 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)) if (AliasAnalysis::onlyReadsMemory(MRB))
return false; return false;
if (AliasAnalysis::onlyAccessesArgPointees(MRB)) { if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {

View File

@ -112,20 +112,20 @@ bool ObjCARCAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc,
return false; return false;
} }
AliasAnalysis::ModRefBehavior FunctionModRefBehavior
ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
// We have nothing to do. Just chain to the next AliasAnalysis. // We have nothing to do. Just chain to the next AliasAnalysis.
return AliasAnalysis::getModRefBehavior(CS); return AliasAnalysis::getModRefBehavior(CS);
} }
AliasAnalysis::ModRefBehavior FunctionModRefBehavior
ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) { ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
if (!EnableARCOpts) if (!EnableARCOpts)
return AliasAnalysis::getModRefBehavior(F); return AliasAnalysis::getModRefBehavior(F);
switch (GetFunctionClass(F)) { switch (GetFunctionClass(F)) {
case ARCInstKind::NoopCast: case ARCInstKind::NoopCast:
return DoesNotAccessMemory; return FMRB_DoesNotAccessMemory;
default: default:
break; break;
} }
@ -133,9 +133,8 @@ ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
return AliasAnalysis::getModRefBehavior(F); return AliasAnalysis::getModRefBehavior(F);
} }
AliasAnalysis::ModRefResult ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
const MemoryLocation &Loc) {
if (!EnableARCOpts) if (!EnableARCOpts)
return AliasAnalysis::getModRefInfo(CS, Loc); return AliasAnalysis::getModRefInfo(CS, Loc);
@ -151,7 +150,7 @@ ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
// These functions don't access any memory visible to the compiler. // These functions don't access any memory visible to the compiler.
// Note that this doesn't include objc_retainBlock, because it updates // Note that this doesn't include objc_retainBlock, because it updates
// pointers when it copies block data. // pointers when it copies block data.
return NoModRef; return MRI_NoModRef;
default: default:
break; break;
} }
@ -159,10 +158,9 @@ ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
return AliasAnalysis::getModRefInfo(CS, Loc); return AliasAnalysis::getModRefInfo(CS, Loc);
} }
AliasAnalysis::ModRefResult ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
ImmutableCallSite CS2) {
// TODO: Theoretically we could check for dependencies between objc_* calls // 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); return AliasAnalysis::getModRefInfo(CS1, CS2);
} }

View File

@ -60,12 +60,12 @@ namespace objcarc {
const MemoryLocation &LocB) override; const MemoryLocation &LocB) override;
bool pointsToConstantMemory(const MemoryLocation &Loc, bool pointsToConstantMemory(const MemoryLocation &Loc,
bool OrLocal) override; bool OrLocal) override;
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
ModRefBehavior getModRefBehavior(const Function *F) override; FunctionModRefBehavior getModRefBehavior(const Function *F) override;
ModRefResult getModRefInfo(ImmutableCallSite CS, ModRefInfo getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) override; const MemoryLocation &Loc) override;
ModRefResult getModRefInfo(ImmutableCallSite CS1, ModRefInfo getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) override; ImmutableCallSite CS2) override;
}; };
} // namespace objcarc } // namespace objcarc

View File

@ -247,7 +247,7 @@ static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
// Ok, now we know we have not seen a store yet. See if Inst can write to // 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. // 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; continue;
Store = dyn_cast<StoreInst>(Inst); Store = dyn_cast<StoreInst>(Inst);

View File

@ -609,7 +609,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
if (DepWrite == &BB.front()) break; if (DepWrite == &BB.front()) break;
// Can't look past this instruction if it might read 'Loc'. // 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; break;
InstDep = MD->getPointerDependencyFrom(Loc, false, DepWrite, &BB); InstDep = MD->getPointerDependencyFrom(Loc, false, DepWrite, &BB);
@ -795,10 +795,10 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
// the call is live. // the call is live.
DeadStackObjects.remove_if([&](Value *I) { DeadStackObjects.remove_if([&](Value *I) {
// See if the call site touches the value. // See if the call site touches the value.
AliasAnalysis::ModRefResult A = AA->getModRefInfo( ModRefInfo A = AA->getModRefInfo(
CS, I, getPointerSize(I, DL, AA->getTargetLibraryInfo())); 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 // If all of the allocas were clobbered by the call then we're not going

View File

@ -457,8 +457,8 @@ bool canSinkOrHoistInst(Instruction &I, AliasAnalysis *AA, DominatorTree *DT,
return false; return false;
// Handle simple cases by querying alias analysis. // Handle simple cases by querying alias analysis.
AliasAnalysis::ModRefBehavior Behavior = AA->getModRefBehavior(CI); FunctionModRefBehavior Behavior = AA->getModRefBehavior(CI);
if (Behavior == AliasAnalysis::DoesNotAccessMemory) if (Behavior == FMRB_DoesNotAccessMemory)
return true; return true;
if (AliasAnalysis::onlyReadsMemory(Behavior)) { if (AliasAnalysis::onlyReadsMemory(Behavior)) {
// If this call only reads from memory and there are no writes to memory // If this call only reads from memory and there are no writes to memory

View File

@ -826,9 +826,9 @@ processLoopMemSet(MemSetInst *MSI, const SCEV *BECount) {
/// mayLoopAccessLocation - Return true if the specified loop might access the /// mayLoopAccessLocation - Return true if the specified loop might access the
/// specified pointer location, which is a loop-strided access. The 'Access' /// specified pointer location, which is a loop-strided access. The 'Access'
/// argument specifies what the verboten forms of access are (read or write). /// argument specifies what the verboten forms of access are (read or write).
static bool mayLoopAccessLocation(Value *Ptr,AliasAnalysis::ModRefResult Access, static bool mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
Loop *L, const SCEV *BECount, const SCEV *BECount, unsigned StoreSize,
unsigned StoreSize, AliasAnalysis &AA, AliasAnalysis &AA,
Instruction *IgnoredStore) { Instruction *IgnoredStore) {
// Get the location that may be stored across the loop. Since the access is // 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 // strided positively through memory, we say that the modified location starts
@ -949,9 +949,8 @@ processLoopStridedStore(Value *DestPtr, unsigned StoreSize,
Expander.expandCodeFor(Ev->getStart(), DestInt8PtrTy, Expander.expandCodeFor(Ev->getStart(), DestInt8PtrTy,
Preheader->getTerminator()); Preheader->getTerminator());
if (mayLoopAccessLocation(BasePtr, AliasAnalysis::ModRef, if (mayLoopAccessLocation(BasePtr, MRI_ModRef, CurLoop, BECount, StoreSize,
CurLoop, BECount, getAnalysis<AliasAnalysis>(), TheStore)) {
StoreSize, getAnalysis<AliasAnalysis>(), TheStore)) {
Expander.clear(); Expander.clear();
// If we generated new code for the base pointer, clean up. // If we generated new code for the base pointer, clean up.
RecursivelyDeleteTriviallyDeadInstructions(BasePtr, TLI); RecursivelyDeleteTriviallyDeadInstructions(BasePtr, TLI);
@ -1047,9 +1046,8 @@ processLoopStoreOfLoopLoad(StoreInst *SI, unsigned StoreSize,
Builder.getInt8PtrTy(SI->getPointerAddressSpace()), Builder.getInt8PtrTy(SI->getPointerAddressSpace()),
Preheader->getTerminator()); Preheader->getTerminator());
if (mayLoopAccessLocation(StoreBasePtr, AliasAnalysis::ModRef, if (mayLoopAccessLocation(StoreBasePtr, MRI_ModRef, CurLoop, BECount,
CurLoop, BECount, StoreSize, StoreSize, getAnalysis<AliasAnalysis>(), SI)) {
getAnalysis<AliasAnalysis>(), SI)) {
Expander.clear(); Expander.clear();
// If we generated new code for the base pointer, clean up. // If we generated new code for the base pointer, clean up.
RecursivelyDeleteTriviallyDeadInstructions(StoreBasePtr, TLI); RecursivelyDeleteTriviallyDeadInstructions(StoreBasePtr, TLI);
@ -1063,8 +1061,8 @@ processLoopStoreOfLoopLoad(StoreInst *SI, unsigned StoreSize,
Builder.getInt8PtrTy(LI->getPointerAddressSpace()), Builder.getInt8PtrTy(LI->getPointerAddressSpace()),
Preheader->getTerminator()); Preheader->getTerminator());
if (mayLoopAccessLocation(LoadBasePtr, AliasAnalysis::Mod, CurLoop, BECount, if (mayLoopAccessLocation(LoadBasePtr, MRI_Mod, CurLoop, BECount, StoreSize,
StoreSize, getAnalysis<AliasAnalysis>(), SI)) { getAnalysis<AliasAnalysis>(), SI)) {
Expander.clear(); Expander.clear();
// If we generated new code for the base pointer, clean up. // If we generated new code for the base pointer, clean up.
RecursivelyDeleteTriviallyDeadInstructions(LoadBasePtr, TLI); RecursivelyDeleteTriviallyDeadInstructions(LoadBasePtr, TLI);

View File

@ -506,7 +506,7 @@ bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
MemoryLocation StoreLoc = MemoryLocation::get(SI); MemoryLocation StoreLoc = MemoryLocation::get(SI);
for (BasicBlock::iterator I = --BasicBlock::iterator(SI), for (BasicBlock::iterator I = --BasicBlock::iterator(SI),
E = C; I != E; --I) { E = C; I != E; --I) {
if (AA.getModRefInfo(&*I, StoreLoc) != AliasAnalysis::NoModRef) { if (AA.getModRefInfo(&*I, StoreLoc) != MRI_NoModRef) {
C = nullptr; C = nullptr;
break; break;
} }
@ -704,11 +704,11 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy,
// the use analysis, we also need to know that it does not sneakily // 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. // access dest. We rely on AA to figure this out for us.
AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); 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 necessary, perform additional analysis.
if (MR != AliasAnalysis::NoModRef) if (MR != MRI_NoModRef)
MR = AA.callCapturesBefore(C, cpyDest, srcSize, &DT); MR = AA.callCapturesBefore(C, cpyDest, srcSize, &DT);
if (MR != AliasAnalysis::NoModRef) if (MR != MRI_NoModRef)
return false; return false;
// All the checks have passed, so do the transformation. // All the checks have passed, so do the transformation.

View File

@ -241,7 +241,7 @@ bool MergedLoadStoreMotion::isLoadHoistBarrierInRange(const Instruction& Start,
const Instruction& End, const Instruction& End,
LoadInst* LI) { LoadInst* LI) {
MemoryLocation Loc = MemoryLocation::get(LI); MemoryLocation Loc = MemoryLocation::get(LI);
return AA->canInstructionRangeModRef(Start, End, Loc, AliasAnalysis::Mod); return AA->canInstructionRangeModRef(Start, End, Loc, MRI_Mod);
} }
/// ///
@ -398,7 +398,7 @@ bool MergedLoadStoreMotion::mergeLoads(BasicBlock *BB) {
bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction &Start, bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction &Start,
const Instruction &End, const Instruction &End,
MemoryLocation Loc) { MemoryLocation Loc) {
return AA->canInstructionRangeModRef(Start, End, Loc, AliasAnalysis::ModRef); return AA->canInstructionRangeModRef(Start, End, Loc, MRI_ModRef);
} }
/// ///

View File

@ -165,7 +165,7 @@ static bool isSafeToMove(Instruction *Inst, AliasAnalysis *AA,
if (LoadInst *L = dyn_cast<LoadInst>(Inst)) { if (LoadInst *L = dyn_cast<LoadInst>(Inst)) {
MemoryLocation Loc = MemoryLocation::get(L); MemoryLocation Loc = MemoryLocation::get(L);
for (Instruction *S : Stores) for (Instruction *S : Stores)
if (AA->getModRefInfo(S, Loc) & AliasAnalysis::Mod) if (AA->getModRefInfo(S, Loc) & MRI_Mod)
return false; return false;
} }

View File

@ -481,9 +481,9 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap,
IsFuncCall = true; IsFuncCall = true;
if (AA) { if (AA) {
AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(ICS); FunctionModRefBehavior MRB = AA->getModRefBehavior(ICS);
if (MRB == AliasAnalysis::OnlyAccessesArgumentPointees || if (MRB == FMRB_OnlyAccessesArgumentPointees ||
MRB == AliasAnalysis::OnlyReadsArgumentPointees) MRB == FMRB_OnlyReadsArgumentPointees)
IsArgMemOnlyCall = true; IsArgMemOnlyCall = true;
} }

View File

@ -27,11 +27,11 @@ protected:
// This is going to check that calling getModRefInfo without a location, and // 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 // with a default location, first, doesn't crash, and second, gives the right
// answer. // answer.
void CheckModRef(Instruction *I, AliasAnalysis::ModRefResult Result) { void CheckModRef(Instruction *I, ModRefInfo Result) {
static char ID; static char ID;
class CheckModRefTestPass : public FunctionPass { class CheckModRefTestPass : public FunctionPass {
public: public:
CheckModRefTestPass(Instruction *I, AliasAnalysis::ModRefResult Result) CheckModRefTestPass(Instruction *I, ModRefInfo Result)
: FunctionPass(ID), ExpectResult(Result), I(I) {} : FunctionPass(ID), ExpectResult(Result), I(I) {}
static int initialize() { static int initialize() {
PassInfo *PI = new PassInfo("CheckModRef testing pass", "", &ID, PassInfo *PI = new PassInfo("CheckModRef testing pass", "", &ID,
@ -51,7 +51,7 @@ protected:
EXPECT_EQ(AA.getModRefInfo(I), ExpectResult); EXPECT_EQ(AA.getModRefInfo(I), ExpectResult);
return false; return false;
} }
AliasAnalysis::ModRefResult ExpectResult; ModRefInfo ExpectResult;
Instruction *I; Instruction *I;
}; };
static int initialize = CheckModRefTestPass::initialize(); static int initialize = CheckModRefTestPass::initialize();
@ -92,12 +92,12 @@ TEST_F(AliasAnalysisTest, getModRefInfo) {
ReturnInst::Create(C, nullptr, BB); ReturnInst::Create(C, nullptr, BB);
// Check basic results // Check basic results
CheckModRef(Store1, AliasAnalysis::ModRefResult::Mod); CheckModRef(Store1, MRI_Mod);
CheckModRef(Load1, AliasAnalysis::ModRefResult::Ref); CheckModRef(Load1, MRI_Ref);
CheckModRef(Add1, AliasAnalysis::ModRefResult::NoModRef); CheckModRef(Add1, MRI_NoModRef);
CheckModRef(VAArg1, AliasAnalysis::ModRefResult::ModRef); CheckModRef(VAArg1, MRI_ModRef);
CheckModRef(CmpXChg1, AliasAnalysis::ModRefResult::ModRef); CheckModRef(CmpXChg1, MRI_ModRef);
CheckModRef(AtomicRMW, AliasAnalysis::ModRefResult::ModRef); CheckModRef(AtomicRMW, MRI_ModRef);
} }
} // end anonymous namspace } // end anonymous namspace

View File

@ -722,29 +722,30 @@ EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
<< "\"Unknown intrinsic.\");\n\n"; << "\"Unknown intrinsic.\");\n\n";
OS << "static const uint8_t IntrinsicModRefBehavior[] = {\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) { for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
OS << " /* " << TargetPrefix << Ints[i].EnumName << " */ "; OS << " /* " << TargetPrefix << Ints[i].EnumName << " */ ";
switch (Ints[i].ModRef) { switch (Ints[i].ModRef) {
case CodeGenIntrinsic::NoMem: case CodeGenIntrinsic::NoMem:
OS << "DoesNotAccessMemory,\n"; OS << "FMRB_DoesNotAccessMemory,\n";
break; break;
case CodeGenIntrinsic::ReadArgMem: case CodeGenIntrinsic::ReadArgMem:
OS << "OnlyReadsArgumentPointees,\n"; OS << "FMRB_OnlyReadsArgumentPointees,\n";
break; break;
case CodeGenIntrinsic::ReadMem: case CodeGenIntrinsic::ReadMem:
OS << "OnlyReadsMemory,\n"; OS << "FMRB_OnlyReadsMemory,\n";
break; break;
case CodeGenIntrinsic::ReadWriteArgMem: case CodeGenIntrinsic::ReadWriteArgMem:
OS << "OnlyAccessesArgumentPointees,\n"; OS << "FMRB_OnlyAccessesArgumentPointees,\n";
break; break;
case CodeGenIntrinsic::ReadWriteMem: case CodeGenIntrinsic::ReadWriteMem:
OS << "UnknownModRefBehavior,\n"; OS << "FMRB_UnknownModRefBehavior,\n";
break; break;
} }
} }
OS << "};\n\n" OS << "};\n\n"
<< "return static_cast<ModRefBehavior>(IntrinsicModRefBehavior[iid]);\n" << "return "
"static_cast<FunctionModRefBehavior>(IntrinsicModRefBehavior[iid]);\n"
<< "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
} }