diff options
Diffstat (limited to 'include/llvm/Analysis/AliasAnalysis.h')
-rw-r--r-- | include/llvm/Analysis/AliasAnalysis.h | 77 |
1 files changed, 59 insertions, 18 deletions
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 9de075dfd681a..362096b08e134 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -95,46 +95,81 @@ enum AliasResult { /// /// 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' +/// they form a three bit matrix and bit-tests for 'mod' or 'ref' or 'must' /// work with any of the possible values. - enum class ModRefInfo { + /// Must is provided for completeness, but no routines will return only + /// Must today. See definition of Must below. + Must = 0, + /// The access may reference the value stored in memory, + /// a mustAlias relation was found, and no mayAlias or partialAlias found. + MustRef = 1, + /// The access may modify the value stored in memory, + /// a mustAlias relation was found, and no mayAlias or partialAlias found. + MustMod = 2, + /// The access may reference, modify or both the value stored in memory, + /// a mustAlias relation was found, and no mayAlias or partialAlias found. + MustModRef = MustRef | MustMod, /// The access neither references nor modifies the value stored in memory. - NoModRef = 0, + NoModRef = 4, /// The access may reference the value stored in memory. - Ref = 1, + Ref = NoModRef | MustRef, /// The access may modify the value stored in memory. - Mod = 2, + Mod = NoModRef | MustMod, /// The access may reference and may modify the value stored in memory. ModRef = Ref | Mod, + + /// About Must: + /// Must is set in a best effort manner. + /// We usually do not try our best to infer Must, instead it is merely + /// another piece of "free" information that is presented when available. + /// Must set means there was certainly a MustAlias found. For calls, + /// where multiple arguments are checked (argmemonly), this translates to + /// only MustAlias or NoAlias was found. + /// Must is not set for RAR accesses, even if the two locations must + /// alias. The reason is that two read accesses translate to an early return + /// of NoModRef. An additional alias check to set Must may be + /// expensive. Other cases may also not set Must(e.g. callCapturesBefore). + /// We refer to Must being *set* when the most significant bit is *cleared*. + /// Conversely we *clear* Must information by *setting* the Must bit to 1. }; LLVM_NODISCARD inline bool isNoModRef(const ModRefInfo MRI) { - return MRI == ModRefInfo::NoModRef; + return (static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustModRef)) == + static_cast<int>(ModRefInfo::Must); } LLVM_NODISCARD inline bool isModOrRefSet(const ModRefInfo MRI) { - return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::ModRef); + return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustModRef); } LLVM_NODISCARD inline bool isModAndRefSet(const ModRefInfo MRI) { - return (static_cast<int>(MRI) & static_cast<int>(ModRefInfo::ModRef)) == - static_cast<int>(ModRefInfo::ModRef); + return (static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustModRef)) == + static_cast<int>(ModRefInfo::MustModRef); } LLVM_NODISCARD inline bool isModSet(const ModRefInfo MRI) { - return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod); + return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustMod); } LLVM_NODISCARD inline bool isRefSet(const ModRefInfo MRI) { - return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref); + return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustRef); +} +LLVM_NODISCARD inline bool isMustSet(const ModRefInfo MRI) { + return !(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::NoModRef)); } LLVM_NODISCARD inline ModRefInfo setMod(const ModRefInfo MRI) { - return ModRefInfo(static_cast<int>(MRI) | static_cast<int>(ModRefInfo::Mod)); + return ModRefInfo(static_cast<int>(MRI) | + static_cast<int>(ModRefInfo::MustMod)); } LLVM_NODISCARD inline ModRefInfo setRef(const ModRefInfo MRI) { - return ModRefInfo(static_cast<int>(MRI) | static_cast<int>(ModRefInfo::Ref)); + return ModRefInfo(static_cast<int>(MRI) | + static_cast<int>(ModRefInfo::MustRef)); +} +LLVM_NODISCARD inline ModRefInfo setMust(const ModRefInfo MRI) { + return ModRefInfo(static_cast<int>(MRI) & + static_cast<int>(ModRefInfo::MustModRef)); } LLVM_NODISCARD inline ModRefInfo setModAndRef(const ModRefInfo MRI) { return ModRefInfo(static_cast<int>(MRI) | - static_cast<int>(ModRefInfo::ModRef)); + static_cast<int>(ModRefInfo::MustModRef)); } LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) { return ModRefInfo(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref)); @@ -142,6 +177,10 @@ LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) { LLVM_NODISCARD inline ModRefInfo clearRef(const ModRefInfo MRI) { return ModRefInfo(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod)); } +LLVM_NODISCARD inline ModRefInfo clearMust(const ModRefInfo MRI) { + return ModRefInfo(static_cast<int>(MRI) | + static_cast<int>(ModRefInfo::NoModRef)); +} LLVM_NODISCARD inline ModRefInfo unionModRef(const ModRefInfo MRI1, const ModRefInfo MRI2) { return ModRefInfo(static_cast<int>(MRI1) | static_cast<int>(MRI2)); @@ -160,11 +199,11 @@ enum FunctionModRefLocation { /// Base case is no access to memory. FMRL_Nowhere = 0, /// Access to memory via argument pointers. - FMRL_ArgumentPointees = 4, + FMRL_ArgumentPointees = 8, /// Memory that is inaccessible via LLVM IR. - FMRL_InaccessibleMem = 8, + FMRL_InaccessibleMem = 16, /// Access to any memory. - FMRL_Anywhere = 16 | FMRL_InaccessibleMem | FMRL_ArgumentPointees + FMRL_Anywhere = 32 | FMRL_InaccessibleMem | FMRL_ArgumentPointees }; /// Summary of how a function affects memory in the program. @@ -344,7 +383,7 @@ public: /// result's bits are set to indicate the allowed aliasing ModRef kinds. Note /// that these bits do not necessarily account for the overall behavior of /// the function, but rather only provide additional per-argument - /// information. + /// information. This never sets ModRefInfo::Must. ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx); /// Return the behavior of the given call site. @@ -624,6 +663,8 @@ public: /// or reads the specified memory location \p MemLoc before instruction \p I /// in a BasicBlock. An ordered basic block \p OBB can be used to speed up /// instruction ordering queries inside the BasicBlock containing \p I. + /// Early exits in callCapturesBefore may lead to ModRefInfo::Must not being + /// set. ModRefInfo callCapturesBefore(const Instruction *I, const MemoryLocation &MemLoc, DominatorTree *DT, OrderedBasicBlock *OBB = nullptr); |