Modify ModRefInfo values using static inline method abstractions [NFC].
Summary:
The aim is to make ModRefInfo checks and changes more intuitive
and less error prone using inline methods that abstract the bit operations.
Ideally ModRefInfo would become an enum class, but that change will require
a wider set of changes into FunctionModRefBehavior.
Reviewers: sanjoy, george.burgess.iv, dberlin, hfinkel
Subscribers: nlopes, llvm-commits
Differential Revision: https://reviews.llvm.org/D40749
llvm-svn: 319821
diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h
index 41bb03c..f7a2a6b 100644
--- a/llvm/include/llvm/Analysis/AliasAnalysis.h
+++ b/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -95,19 +95,60 @@
///
/// 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.
+/// 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.
+ /// The access may reference the value stored in memory.
MRI_Ref = 1,
- /// The access modifies the value stored in memory.
+ /// The access may modify 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 access may reference and may modify the value stored in memory.
+ MRI_ModRef = MRI_Ref | MRI_Mod,
};
+LLVM_NODISCARD inline bool isNoModRef(const ModRefInfo MRI) {
+ return MRI == MRI_NoModRef;
+}
+LLVM_NODISCARD inline bool isModOrRefSet(const ModRefInfo MRI) {
+ return MRI & MRI_ModRef;
+}
+LLVM_NODISCARD inline bool isModAndRefSet(const ModRefInfo MRI) {
+ return (MRI & MRI_ModRef) == MRI_ModRef;
+}
+LLVM_NODISCARD inline bool isModSet(const ModRefInfo MRI) {
+ return MRI & MRI_Mod;
+}
+LLVM_NODISCARD inline bool isRefSet(const ModRefInfo MRI) {
+ return MRI & MRI_Ref;
+}
+
+LLVM_NODISCARD inline ModRefInfo setRef(const ModRefInfo MRI) {
+ return ModRefInfo(MRI | MRI_Ref);
+}
+LLVM_NODISCARD inline ModRefInfo setMod(const ModRefInfo MRI) {
+ return ModRefInfo(MRI | MRI_Mod);
+}
+LLVM_NODISCARD inline ModRefInfo setModAndRef(const ModRefInfo MRI) {
+ return ModRefInfo(MRI | MRI_ModRef);
+}
+LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) {
+ return ModRefInfo(MRI & MRI_Ref);
+}
+LLVM_NODISCARD inline ModRefInfo clearRef(const ModRefInfo MRI) {
+ return ModRefInfo(MRI & MRI_Mod);
+}
+LLVM_NODISCARD inline ModRefInfo unionModRef(const ModRefInfo MRI1,
+ const ModRefInfo MRI2) {
+ return ModRefInfo(MRI1 | MRI2);
+}
+LLVM_NODISCARD inline ModRefInfo intersectModRef(const ModRefInfo MRI1,
+ const ModRefInfo MRI2) {
+ return ModRefInfo(MRI1 & MRI2);
+}
+
/// The locations at which a function might access memory.
///
/// These are primarily used in conjunction with the \c AccessKind bits to
@@ -187,6 +228,15 @@
FMRB_UnknownModRefBehavior = FMRL_Anywhere | MRI_ModRef
};
+// Wrapper method strips bits significant only in FunctionModRefBehavior,
+// to obtain a valid ModRefInfo. The benefit of using the wrapper is that if
+// ModRefInfo enum changes, the wrapper can be updated to & with the new enum
+// entry with all bits set to 1.
+LLVM_NODISCARD inline ModRefInfo
+createModRefInfo(const FunctionModRefBehavior FMRB) {
+ return ModRefInfo(FMRB & MRI_ModRef);
+}
+
class AAResults {
public:
// Make these results default constructable and movable. We have to spell
@@ -520,14 +570,7 @@
const Optional<MemoryLocation> &OptLoc) {
if (OptLoc == None) {
if (auto CS = ImmutableCallSite(I)) {
- auto MRB = getModRefBehavior(CS);
- if ((MRB & MRI_ModRef) == MRI_ModRef)
- return MRI_ModRef;
- if (MRB & MRI_Ref)
- return MRI_Ref;
- if (MRB & MRI_Mod)
- return MRI_Mod;
- return MRI_NoModRef;
+ return createModRefInfo(getModRefBehavior(CS));
}
}
@@ -570,7 +613,7 @@
/// \brief Return information about whether a particular call site modifies
/// or reads the specified memory location \p MemLoc before instruction \p I
- /// in a BasicBlock. A ordered basic block \p OBB can be used to speed up
+ /// in a BasicBlock. An ordered basic block \p OBB can be used to speed up
/// instruction ordering queries inside the BasicBlock containing \p I.
ModRefInfo callCapturesBefore(const Instruction *I,
const MemoryLocation &MemLoc, DominatorTree *DT,
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
index 897f89d..449d90f 100644
--- a/llvm/lib/Analysis/AliasAnalysis.cpp
+++ b/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -122,10 +122,10 @@
ModRefInfo Result = MRI_ModRef;
for (const auto &AA : AAs) {
- Result = ModRefInfo(Result & AA->getArgModRefInfo(CS, ArgIdx));
+ Result = intersectModRef(Result, AA->getArgModRefInfo(CS, ArgIdx));
// Early-exit the moment we reach the bottom of the lattice.
- if (Result == MRI_NoModRef)
+ if (isNoModRef(Result))
return Result;
}
@@ -146,8 +146,9 @@
// is that if the call references what this instruction
// defines, it must be clobbered by this location.
const MemoryLocation DefLoc = MemoryLocation::get(I);
- if (getModRefInfo(Call, DefLoc) != MRI_NoModRef)
- return MRI_ModRef;
+ ModRefInfo MR = getModRefInfo(Call, DefLoc);
+ if (isModOrRefSet(MR))
+ return setModAndRef(MR);
}
return MRI_NoModRef;
}
@@ -157,10 +158,10 @@
ModRefInfo Result = MRI_ModRef;
for (const auto &AA : AAs) {
- Result = ModRefInfo(Result & AA->getModRefInfo(CS, Loc));
+ Result = intersectModRef(Result, AA->getModRefInfo(CS, Loc));
// Early-exit the moment we reach the bottom of the lattice.
- if (Result == MRI_NoModRef)
+ if (isNoModRef(Result))
return Result;
}
@@ -172,9 +173,9 @@
return MRI_NoModRef;
if (onlyReadsMemory(MRB))
- Result = ModRefInfo(Result & MRI_Ref);
+ Result = clearMod(Result);
else if (doesNotReadMemory(MRB))
- Result = ModRefInfo(Result & MRI_Mod);
+ Result = clearRef(Result);
if (onlyAccessesArgPointees(MRB) || onlyAccessesInaccessibleOrArgMem(MRB)) {
bool DoesAlias = false;
@@ -190,20 +191,21 @@
if (ArgAlias != NoAlias) {
ModRefInfo ArgMask = getArgModRefInfo(CS, ArgIdx);
DoesAlias = true;
- AllArgsMask = ModRefInfo(AllArgsMask | ArgMask);
+ AllArgsMask = unionModRef(AllArgsMask, ArgMask);
}
}
}
+ // Return MRI_NoModRef if no alias found with any argument.
if (!DoesAlias)
return MRI_NoModRef;
- Result = ModRefInfo(Result & AllArgsMask);
+ // Logical & between other AA analyses and argument analysis.
+ Result = intersectModRef(Result, AllArgsMask);
}
// If Loc is a constant memory location, the call definitely could not
// modify the memory location.
- if ((Result & MRI_Mod) &&
- pointsToConstantMemory(Loc, /*OrLocal*/ false))
- Result = ModRefInfo(Result & ~MRI_Mod);
+ if (isModSet(Result) && pointsToConstantMemory(Loc, /*OrLocal*/ false))
+ Result = clearMod(Result);
return Result;
}
@@ -213,10 +215,10 @@
ModRefInfo Result = MRI_ModRef;
for (const auto &AA : AAs) {
- Result = ModRefInfo(Result & AA->getModRefInfo(CS1, CS2));
+ Result = intersectModRef(Result, AA->getModRefInfo(CS1, CS2));
// Early-exit the moment we reach the bottom of the lattice.
- if (Result == MRI_NoModRef)
+ if (isNoModRef(Result))
return Result;
}
@@ -239,9 +241,9 @@
// If CS1 only reads memory, the only dependence on CS2 can be
// from CS1 reading memory written by CS2.
if (onlyReadsMemory(CS1B))
- Result = ModRefInfo(Result & MRI_Ref);
+ Result = clearMod(Result);
else if (doesNotReadMemory(CS1B))
- Result = ModRefInfo(Result & MRI_Mod);
+ Result = clearRef(Result);
// If CS2 only access memory through arguments, accumulate the mod/ref
// information from CS1's references to the memory referenced by
@@ -256,17 +258,23 @@
unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I);
auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI);
- // ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence
- // of CS1 on that location is the inverse.
- ModRefInfo ArgMask = getArgModRefInfo(CS2, CS2ArgIdx);
- if (ArgMask == MRI_Mod)
+ // ArgModRefCS2 indicates what CS2 might do to CS2ArgLoc, and the
+ // dependence of CS1 on that location is the inverse:
+ // - If CS2 modifies location, dependence exists if CS1 reads or writes.
+ // - If CS2 only reads location, dependence exists if CS1 writes.
+ ModRefInfo ArgModRefCS2 = getArgModRefInfo(CS2, CS2ArgIdx);
+ ModRefInfo ArgMask;
+ if (isModSet(ArgModRefCS2))
ArgMask = MRI_ModRef;
- else if (ArgMask == MRI_Ref)
+ else if (isRefSet(ArgModRefCS2))
ArgMask = MRI_Mod;
- ArgMask = ModRefInfo(ArgMask & getModRefInfo(CS1, CS2ArgLoc));
+ // ModRefCS1 indicates what CS1 might do to CS2ArgLoc, and we use
+ // above ArgMask to update dependence info.
+ ModRefInfo ModRefCS1 = getModRefInfo(CS1, CS2ArgLoc);
+ ArgMask = intersectModRef(ArgMask, ModRefCS1);
- R = ModRefInfo((R | ArgMask) & Result);
+ R = intersectModRef(unionModRef(R, ArgMask), Result);
if (R == Result)
break;
}
@@ -286,16 +294,14 @@
unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I);
auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI);
- // ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod
- // CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If CS1
- // might Ref, then we care only about a Mod by CS2.
- ModRefInfo ArgMask = getArgModRefInfo(CS1, CS1ArgIdx);
- ModRefInfo ArgR = getModRefInfo(CS2, CS1ArgLoc);
- if (((ArgMask & MRI_Mod) != MRI_NoModRef &&
- (ArgR & MRI_ModRef) != MRI_NoModRef) ||
- ((ArgMask & MRI_Ref) != MRI_NoModRef &&
- (ArgR & MRI_Mod) != MRI_NoModRef))
- R = ModRefInfo((R | ArgMask) & Result);
+ // ArgModRefCS1 indicates what CS1 might do to CS1ArgLoc; if CS1 might
+ // Mod CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If
+ // CS1 might Ref, then we care only about a Mod by CS2.
+ ModRefInfo ArgModRefCS1 = getArgModRefInfo(CS1, CS1ArgIdx);
+ ModRefInfo ModRefCS2 = getModRefInfo(CS2, CS1ArgLoc);
+ if ((isModSet(ArgModRefCS1) && isModOrRefSet(ModRefCS2)) ||
+ (isRefSet(ArgModRefCS1) && isModSet(ModRefCS2)))
+ R = intersectModRef(unionModRef(R, ArgModRefCS1), Result);
if (R == Result)
break;
@@ -456,7 +462,7 @@
/// \brief Return information about whether a particular call site modifies
/// or reads the specified memory location \p MemLoc before instruction \p I
-/// in a BasicBlock. A ordered basic block \p OBB can be used to speed up
+/// in a BasicBlock. An ordered basic block \p OBB can be used to speed up
/// instruction-ordering queries inside the BasicBlock containing \p I.
/// FIXME: this is really just shoring-up a deficiency in alias analysis.
/// BasicAA isn't willing to spend linear time determining whether an alloca
@@ -538,7 +544,7 @@
++E; // Convert from inclusive to exclusive range.
for (; I != E; ++I) // Check every instruction in range
- if (getModRefInfo(&*I, Loc) & Mode)
+ if (intersectModRef(getModRefInfo(&*I, Loc), Mode))
return true;
return false;
}
diff --git a/llvm/lib/Analysis/AliasSetTracker.cpp b/llvm/lib/Analysis/AliasSetTracker.cpp
index b575944..c88e0dd 100644
--- a/llvm/lib/Analysis/AliasSetTracker.cpp
+++ b/llvm/lib/Analysis/AliasSetTracker.cpp
@@ -211,8 +211,8 @@
if (!UnknownInsts.empty()) {
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
if (auto *Inst = getUnknownInst(i))
- if (AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo)) !=
- MRI_NoModRef)
+ if (isModOrRefSet(
+ AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo))))
return true;
}
@@ -231,15 +231,15 @@
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
if (auto *UnknownInst = getUnknownInst(i)) {
ImmutableCallSite C1(UnknownInst), C2(Inst);
- if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef ||
- AA.getModRefInfo(C2, C1) != MRI_NoModRef)
+ if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) ||
+ isModOrRefSet(AA.getModRefInfo(C2, C1)))
return true;
}
}
for (iterator I = begin(), E = end(); I != E; ++I)
- if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(),
- I.getAAInfo())) != MRI_NoModRef)
+ if (isModOrRefSet(AA.getModRefInfo(
+ Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))))
return true;
return false;
@@ -572,12 +572,11 @@
AliasAnyAS->AliasAny = true;
for (auto Cur : ASVector) {
-
// If Cur was already forwarding, just forward to the new AS instead.
AliasSet *FwdTo = Cur->Forward;
if (FwdTo) {
Cur->Forward = AliasAnyAS;
- AliasAnyAS->addRef();
+ AliasAnyAS->addRef();
FwdTo->dropRef(*this);
continue;
}
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index fb9ece2..de0b023 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -809,12 +809,12 @@
// Operand aliases 'Object', but call doesn't modify it. Strengthen
// initial assumption and keep looking in case if there are more aliases.
if (CS.onlyReadsMemory(OperandNo)) {
- Result = static_cast<ModRefInfo>(Result | MRI_Ref);
+ Result = setRef(Result);
continue;
}
// Operand aliases 'Object' but call only writes into it.
if (CS.doesNotReadMemory(OperandNo)) {
- Result = static_cast<ModRefInfo>(Result | MRI_Mod);
+ Result = setMod(Result);
continue;
}
// This operand aliases 'Object' and call reads and writes into it.
@@ -832,7 +832,7 @@
// routines do not read values visible in the IR. TODO: Consider special
// casing realloc and strdup routines which access only their arguments as
// well. Or alternatively, replace all of this with inaccessiblememonly once
- // that's implemented fully.
+ // that's implemented fully.
auto *Inst = CS.getInstruction();
if (isMallocOrCallocLikeFn(Inst, &TLI)) {
// Be conservative if the accessed pointer may alias the allocation -
@@ -860,9 +860,9 @@
// It's also possible for Loc to alias both src and dest, or neither.
ModRefInfo rv = MRI_NoModRef;
if (SrcAA != NoAlias)
- rv = static_cast<ModRefInfo>(rv | MRI_Ref);
+ rv = setRef(rv);
if (DestAA != NoAlias)
- rv = static_cast<ModRefInfo>(rv | MRI_Mod);
+ rv = setMod(rv);
return rv;
}
@@ -933,10 +933,12 @@
// possibilities for guard intrinsics.
if (isIntrinsicCall(CS1, Intrinsic::experimental_guard))
- return getModRefBehavior(CS2) & MRI_Mod ? MRI_Ref : MRI_NoModRef;
+ return isModSet(ModRefInfo(getModRefBehavior(CS2))) ? MRI_Ref
+ : MRI_NoModRef;
if (isIntrinsicCall(CS2, Intrinsic::experimental_guard))
- return getModRefBehavior(CS1) & MRI_Mod ? MRI_Mod : MRI_NoModRef;
+ return isModSet(ModRefInfo(getModRefBehavior(CS1))) ? MRI_Mod
+ : MRI_NoModRef;
// The AAResultBase base class has some smarts, lets use them.
return AAResultBase::getModRefInfo(CS1, CS2);
diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp
index 4ef0233..732be0d 100644
--- a/llvm/lib/Analysis/GlobalsModRef.cpp
+++ b/llvm/lib/Analysis/GlobalsModRef.cpp
@@ -84,6 +84,7 @@
/// The bit that flags that this function may read any global. This is
/// chosen to mix together with ModRefInfo bits.
+ /// FIXME: This assumes ModRefInfo lattice will remain 4 bits!
enum { MayReadAnyGlobal = 4 };
/// Checks to document the invariants of the bit packing here.
@@ -230,9 +231,9 @@
FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
if (FunctionInfo *FI = getFunctionInfo(F)) {
- if (FI->getModRefInfo() == MRI_NoModRef)
+ if (!isModOrRefSet(FI->getModRefInfo()))
Min = FMRB_DoesNotAccessMemory;
- else if ((FI->getModRefInfo() & MRI_Mod) == 0)
+ else if (!isModSet(FI->getModRefInfo()))
Min = FMRB_OnlyReadsMemory;
}
@@ -246,9 +247,9 @@
if (!CS.hasOperandBundles())
if (const Function *F = CS.getCalledFunction())
if (FunctionInfo *FI = getFunctionInfo(F)) {
- if (FI->getModRefInfo() == MRI_NoModRef)
+ if (!isModOrRefSet(FI->getModRefInfo()))
Min = FMRB_DoesNotAccessMemory;
- else if ((FI->getModRefInfo() & MRI_Mod) == 0)
+ else if (!isModSet(FI->getModRefInfo()))
Min = FMRB_OnlyReadsMemory;
}
@@ -544,7 +545,7 @@
// Scan the function bodies for explicit loads or stores.
for (auto *Node : SCC) {
- if (FI.getModRefInfo() == MRI_ModRef)
+ if (isModAndRefSet(FI.getModRefInfo()))
break; // The mod/ref lattice saturates here.
// Don't prove any properties based on the implementation of an optnone
@@ -554,7 +555,7 @@
continue;
for (Instruction &I : instructions(Node->getFunction())) {
- if (FI.getModRefInfo() == MRI_ModRef)
+ if (isModAndRefSet(FI.getModRefInfo()))
break; // The mod/ref lattice saturates here.
// We handle calls specially because the graph-relevant aspects are
@@ -584,9 +585,9 @@
}
}
- if ((FI.getModRefInfo() & MRI_Mod) == 0)
+ if (!isModSet(FI.getModRefInfo()))
++NumReadMemFunctions;
- if (FI.getModRefInfo() == MRI_NoModRef)
+ if (!isModOrRefSet(FI.getModRefInfo()))
++NumNoMemFunctions;
// Finally, now that we know the full effect on this SCC, clone the
@@ -894,7 +895,7 @@
ModRefInfo GlobalsAAResult::getModRefInfo(ImmutableCallSite CS,
const MemoryLocation &Loc) {
- unsigned Known = MRI_ModRef;
+ ModRefInfo Known = MRI_ModRef;
// If we are asking for mod/ref info of a direct call with a pointer to a
// global we are tracking, return information if we have it.
@@ -904,12 +905,12 @@
if (const Function *F = CS.getCalledFunction())
if (NonAddressTakenGlobals.count(GV))
if (const FunctionInfo *FI = getFunctionInfo(F))
- Known = FI->getModRefInfoForGlobal(*GV) |
- getModRefInfoForArgument(CS, GV);
+ Known = unionModRef(FI->getModRefInfoForGlobal(*GV),
+ getModRefInfoForArgument(CS, GV));
- if (Known == MRI_NoModRef)
+ if (!isModOrRefSet(Known))
return MRI_NoModRef; // No need to query other mod/ref analyses
- return ModRefInfo(Known & AAResultBase::getModRefInfo(CS, Loc));
+ return intersectModRef(Known, AAResultBase::getModRefInfo(CS, Loc));
}
GlobalsAAResult::GlobalsAAResult(const DataLayout &DL,
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 78b673b..834727c 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -414,7 +414,7 @@
// If we have alias analysis and it says the store won't modify the loaded
// value, ignore the store.
- if (AA && (AA->getModRefInfo(SI, StrippedPtr, AccessSize) & MRI_Mod) == 0)
+ if (AA && !isModSet(AA->getModRefInfo(SI, StrippedPtr, AccessSize)))
continue;
// Otherwise the store that may or may not alias the pointer, bail out.
@@ -426,8 +426,7 @@
if (Inst->mayWriteToMemory()) {
// If alias analysis claims that it really won't modify the load,
// ignore it.
- if (AA &&
- (AA->getModRefInfo(Inst, StrippedPtr, AccessSize) & MRI_Mod) == 0)
+ if (AA && !isModSet(AA->getModRefInfo(Inst, StrippedPtr, AccessSize)))
continue;
// May modify the pointer, bail out.
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
index d41b6be..c54f676 100644
--- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -212,32 +212,30 @@
ModRefInfo MR = GetLocation(Inst, Loc, TLI);
if (Loc.Ptr) {
// A simple instruction.
- if (AA.getModRefInfo(CS, Loc) != MRI_NoModRef)
+ if (isModOrRefSet(AA.getModRefInfo(CS, Loc)))
return MemDepResult::getClobber(Inst);
continue;
}
if (auto InstCS = CallSite(Inst)) {
// If these two calls do not interfere, look past it.
- switch (AA.getModRefInfo(CS, InstCS)) {
- case MRI_NoModRef:
+ if (isNoModRef(AA.getModRefInfo(CS, InstCS))) {
// If the two calls are the same, return InstCS as a Def, so that
// CS can be found redundant and eliminated.
- if (isReadOnlyCall && !(MR & MRI_Mod) &&
+ if (isReadOnlyCall && !isModSet(MR) &&
CS.getInstruction()->isIdenticalToWhenDefined(Inst))
return MemDepResult::getDef(Inst);
// Otherwise if the two calls don't interact (e.g. InstCS is readnone)
// keep scanning.
continue;
- default:
+ } else
return MemDepResult::getClobber(Inst);
- }
}
// If we could not obtain a pointer for the instruction and the instruction
// touches memory then assume that this is a dependency.
- if (MR != MRI_NoModRef)
+ if (isModOrRefSet(MR))
return MemDepResult::getClobber(Inst);
}
@@ -642,7 +640,7 @@
// If alias analysis can tell that this store is guaranteed to not modify
// the query pointer, ignore it. Use getModRefInfo to handle cases where
// the query pointer points to constant memory etc.
- if (AA.getModRefInfo(SI, MemLoc) == MRI_NoModRef)
+ if (!isModOrRefSet(AA.getModRefInfo(SI, MemLoc)))
continue;
// Ok, this store might clobber the query pointer. Check to see if it is
@@ -688,7 +686,7 @@
// See if this instruction (e.g. a call or vaarg) mod/ref's the pointer.
ModRefInfo MR = AA.getModRefInfo(Inst, MemLoc);
// If necessary, perform additional analysis.
- if (MR == MRI_ModRef)
+ if (isModAndRefSet(MR))
MR = AA.callCapturesBefore(Inst, MemLoc, &DT, &OBB);
switch (MR) {
case MRI_NoModRef:
diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp
index 4af18cc..8fe190e 100644
--- a/llvm/lib/Analysis/MemorySSA.cpp
+++ b/llvm/lib/Analysis/MemorySSA.cpp
@@ -262,7 +262,7 @@
if (UseCS) {
ModRefInfo I = AA.getModRefInfo(DefInst, UseCS);
- return I != MRI_NoModRef;
+ return isModOrRefSet(I);
}
if (auto *DefLoad = dyn_cast<LoadInst>(DefInst)) {
@@ -278,7 +278,7 @@
}
}
- return AA.getModRefInfo(DefInst, UseLoc) & MRI_Mod;
+ return isModSet(AA.getModRefInfo(DefInst, UseLoc));
}
static bool instructionClobbersQuery(MemoryDef *MD, const MemoryUseOrDef *MU,
@@ -1526,8 +1526,8 @@
// Separate memory aliasing and ordering into two different chains so that we
// can precisely represent both "what memory will this read/write/is clobbered
// by" and "what instructions can I move this past".
- bool Def = bool(ModRef & MRI_Mod) || isOrdered(I);
- bool Use = bool(ModRef & MRI_Ref);
+ bool Def = isModSet(ModRef) || isOrdered(I);
+ bool Use = isRefSet(ModRef);
// It's possible for an instruction to not modify memory at all. During
// construction, we ignore them.
diff --git a/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp b/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
index 25f101b..0931eb8 100644
--- a/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
@@ -1928,7 +1928,8 @@
for (auto *B : L->blocks())
for (auto &I : *B)
- if (Ignored.count(&I) == 0 && (AA.getModRefInfo(&I, StoreLoc) & Access))
+ if (Ignored.count(&I) == 0 &&
+ intersectModRef(AA.getModRefInfo(&I, StoreLoc), Access))
return true;
return false;
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index f985061..5352e32 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -130,17 +130,18 @@
SCCNodes.count(CS.getCalledFunction()))
continue;
FunctionModRefBehavior MRB = AAR.getModRefBehavior(CS);
+ ModRefInfo MRI = createModRefInfo(MRB);
// If the call doesn't access memory, we're done.
- if (!(MRB & MRI_ModRef))
+ if (isNoModRef(MRI))
continue;
if (!AliasAnalysis::onlyAccessesArgPointees(MRB)) {
// The call could access any memory. If that includes writes, give up.
- if (MRB & MRI_Mod)
+ if (isModSet(MRI))
return MAK_MayWrite;
// If it reads, note it.
- if (MRB & MRI_Ref)
+ if (isRefSet(MRI))
ReadsMemory = true;
continue;
}
@@ -162,10 +163,10 @@
if (AAR.pointsToConstantMemory(Loc, /*OrLocal=*/true))
continue;
- if (MRB & MRI_Mod)
+ if (isModSet(MRI))
// Writes non-local memory. Give up.
return MAK_MayWrite;
- if (MRB & MRI_Ref)
+ if (isRefSet(MRI))
// Ok, it reads non-local memory.
ReadsMemory = true;
}
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index e70e759..c4e6121 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -248,7 +248,7 @@
// Ok, now we know we have not seen a store yet. See if Inst can write to
// our load location, if it can not, just ignore the instruction.
- if (!(AA->getModRefInfo(Inst, Loc) & MRI_Mod))
+ if (!isModSet(AA->getModRefInfo(Inst, Loc)))
continue;
Store = dyn_cast<StoreInst>(Inst);
diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 877050e..e703014 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -594,11 +594,9 @@
}
for (; BI != EI; ++BI) {
Instruction *I = &*BI;
- if (I->mayWriteToMemory() && I != SecondI) {
- auto Res = AA->getModRefInfo(I, MemLoc);
- if (Res & MRI_Mod)
+ if (I->mayWriteToMemory() && I != SecondI)
+ if (isModSet(AA->getModRefInfo(I, MemLoc)))
return false;
- }
}
if (B != FirstBB) {
assert(B != &FirstBB->getParent()->getEntryBlock() &&
@@ -822,9 +820,7 @@
// the call is live.
DeadStackObjects.remove_if([&](Value *I) {
// See if the call site touches the value.
- ModRefInfo A = AA->getModRefInfo(CS, I, getPointerSize(I, DL, *TLI));
-
- return A == MRI_ModRef || A == MRI_Ref;
+ return isRefSet(AA->getModRefInfo(CS, I, getPointerSize(I, DL, *TLI)));
});
// If all of the allocas were clobbered by the call then we're not going
@@ -1255,7 +1251,7 @@
if (DepWrite == &BB.front()) break;
// Can't look past this instruction if it might read 'Loc'.
- if (AA->getModRefInfo(DepWrite, Loc) & MRI_Ref)
+ if (isRefSet(AA->getModRefInfo(DepWrite, Loc)))
break;
InstDep = MD->getPointerDependencyFrom(Loc, /*isLoad=*/ false,
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 3e331cd..052ead8 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -788,7 +788,7 @@
++BI)
for (Instruction &I : **BI)
if (IgnoredStores.count(&I) == 0 &&
- (AA.getModRefInfo(&I, StoreLoc) & Access))
+ intersectModRef(AA.getModRefInfo(&I, StoreLoc), Access))
return true;
return false;
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 86d7b5e..cd3e4ba 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -518,7 +518,7 @@
const LoadInst *LI) {
// If the store alias this position, early bail out.
MemoryLocation StoreLoc = MemoryLocation::get(SI);
- if (AA.getModRefInfo(P, StoreLoc) != MRI_NoModRef)
+ if (isModOrRefSet(AA.getModRefInfo(P, StoreLoc)))
return false;
// Keep track of the arguments of all instruction we plan to lift
@@ -542,20 +542,20 @@
for (auto I = --SI->getIterator(), E = P->getIterator(); I != E; --I) {
auto *C = &*I;
- bool MayAlias = AA.getModRefInfo(C, None) != MRI_NoModRef;
+ bool MayAlias = isModOrRefSet(AA.getModRefInfo(C, None));
bool NeedLift = false;
if (Args.erase(C))
NeedLift = true;
else if (MayAlias) {
NeedLift = llvm::any_of(MemLocs, [C, &AA](const MemoryLocation &ML) {
- return AA.getModRefInfo(C, ML);
+ return isModOrRefSet(AA.getModRefInfo(C, ML));
});
if (!NeedLift)
NeedLift =
llvm::any_of(CallSites, [C, &AA](const ImmutableCallSite &CS) {
- return AA.getModRefInfo(C, CS);
+ return isModOrRefSet(AA.getModRefInfo(C, CS));
});
}
@@ -565,18 +565,18 @@
if (MayAlias) {
// Since LI is implicitly moved downwards past the lifted instructions,
// none of them may modify its source.
- if (AA.getModRefInfo(C, LoadLoc) & MRI_Mod)
+ if (isModSet(AA.getModRefInfo(C, LoadLoc)))
return false;
else if (auto CS = ImmutableCallSite(C)) {
// If we can't lift this before P, it's game over.
- if (AA.getModRefInfo(P, CS) != MRI_NoModRef)
+ if (isModOrRefSet(AA.getModRefInfo(P, CS)))
return false;
CallSites.push_back(CS);
} else if (isa<LoadInst>(C) || isa<StoreInst>(C) || isa<VAArgInst>(C)) {
// If we can't lift this before P, it's game over.
auto ML = MemoryLocation::get(C);
- if (AA.getModRefInfo(P, ML) != MRI_NoModRef)
+ if (isModOrRefSet(AA.getModRefInfo(P, ML)))
return false;
MemLocs.push_back(ML);
@@ -631,7 +631,7 @@
// of at the store position.
Instruction *P = SI;
for (auto &I : make_range(++LI->getIterator(), SI->getIterator())) {
- if (AA.getModRefInfo(&I, LoadLoc) & MRI_Mod) {
+ if (isModSet(AA.getModRefInfo(&I, LoadLoc))) {
P = &I;
break;
}
@@ -702,7 +702,7 @@
MemoryLocation StoreLoc = MemoryLocation::get(SI);
for (BasicBlock::iterator I = --SI->getIterator(), E = C->getIterator();
I != E; --I) {
- if (AA.getModRefInfo(&*I, StoreLoc) != MRI_NoModRef) {
+ if (isModOrRefSet(AA.getModRefInfo(&*I, StoreLoc))) {
C = nullptr;
break;
}
@@ -934,9 +934,9 @@
AliasAnalysis &AA = LookupAliasAnalysis();
ModRefInfo MR = AA.getModRefInfo(C, cpyDest, srcSize);
// If necessary, perform additional analysis.
- if (MR != MRI_NoModRef)
+ if (isModOrRefSet(MR))
MR = AA.callCapturesBefore(C, cpyDest, srcSize, &DT);
- if (MR != MRI_NoModRef)
+ if (isModOrRefSet(MR))
return false;
// We can't create address space casts here because we don't know if they're
diff --git a/llvm/lib/Transforms/Scalar/Sink.cpp b/llvm/lib/Transforms/Scalar/Sink.cpp
index 5210f16..cfb8a06 100644
--- a/llvm/lib/Transforms/Scalar/Sink.cpp
+++ b/llvm/lib/Transforms/Scalar/Sink.cpp
@@ -68,7 +68,7 @@
if (LoadInst *L = dyn_cast<LoadInst>(Inst)) {
MemoryLocation Loc = MemoryLocation::get(L);
for (Instruction *S : Stores)
- if (AA.getModRefInfo(S, Loc) & MRI_Mod)
+ if (isModSet(AA.getModRefInfo(S, Loc)))
return false;
}
@@ -83,7 +83,7 @@
return false;
for (Instruction *S : Stores)
- if (AA.getModRefInfo(S, CS) & MRI_Mod)
+ if (isModSet(AA.getModRefInfo(S, CS)))
return false;
}
diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
index f5aa47f..a8782e0 100644
--- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -332,7 +332,7 @@
// Writes to memory only matter if they may alias the pointer
// being loaded from.
const DataLayout &DL = L->getModule()->getDataLayout();
- if ((AA->getModRefInfo(CI, MemoryLocation::get(L)) & MRI_Mod) ||
+ if (isModSet(AA->getModRefInfo(CI, MemoryLocation::get(L))) ||
!isSafeToLoadUnconditionally(L->getPointerOperand(),
L->getAlignment(), DL, L))
return false;