[AA] Make ModRefInfo a bitmask enum (NFC)
Mark ModRefInfo as a bitmask enum, which allows using normal & and | operators on it. This supersedes various functions like unionModRef() and intersectModRef(). I think this makes the code cleaner than going through helper functions... Differential Revision: https://reviews.llvm.org/D130870
This commit is contained in:
parent
34ae308c73
commit
b128e057c1
|
@ -152,6 +152,7 @@ enum class ModRefInfo : uint8_t {
|
|||
Mod = 2,
|
||||
/// The access may reference and may modify the value stored in memory.
|
||||
ModRef = Ref | Mod,
|
||||
LLVM_MARK_AS_BITMASK_ENUM(ModRef),
|
||||
};
|
||||
|
||||
LLVM_NODISCARD inline bool isNoModRef(const ModRefInfo MRI) {
|
||||
|
@ -170,25 +171,31 @@ LLVM_NODISCARD inline bool isRefSet(const ModRefInfo MRI) {
|
|||
return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref);
|
||||
}
|
||||
|
||||
[[deprecated("Use operator | instead")]]
|
||||
LLVM_NODISCARD inline ModRefInfo setMod(const ModRefInfo MRI) {
|
||||
return ModRefInfo(static_cast<int>(MRI) | static_cast<int>(ModRefInfo::Mod));
|
||||
return MRI | ModRefInfo::Mod;
|
||||
}
|
||||
[[deprecated("Use operator | instead")]]
|
||||
LLVM_NODISCARD inline ModRefInfo setRef(const ModRefInfo MRI) {
|
||||
return ModRefInfo(static_cast<int>(MRI) | static_cast<int>(ModRefInfo::Ref));
|
||||
return MRI | ModRefInfo::Ref;
|
||||
}
|
||||
[[deprecated("Use operator & instead")]]
|
||||
LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) {
|
||||
return ModRefInfo(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref));
|
||||
return MRI & ModRefInfo::Ref;
|
||||
}
|
||||
[[deprecated("Use operator & instead")]]
|
||||
LLVM_NODISCARD inline ModRefInfo clearRef(const ModRefInfo MRI) {
|
||||
return ModRefInfo(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod));
|
||||
return MRI & ModRefInfo::Mod;
|
||||
}
|
||||
[[deprecated("Use operator | instead")]]
|
||||
LLVM_NODISCARD inline ModRefInfo unionModRef(const ModRefInfo MRI1,
|
||||
const ModRefInfo MRI2) {
|
||||
return ModRefInfo(static_cast<int>(MRI1) | static_cast<int>(MRI2));
|
||||
return MRI1 | MRI2;
|
||||
}
|
||||
[[deprecated("Use operator & instead")]]
|
||||
LLVM_NODISCARD inline ModRefInfo intersectModRef(const ModRefInfo MRI1,
|
||||
const ModRefInfo MRI2) {
|
||||
return ModRefInfo(static_cast<int>(MRI1) & static_cast<int>(MRI2));
|
||||
return MRI1 & MRI2;
|
||||
}
|
||||
|
||||
/// The locations at which a function might access memory.
|
||||
|
|
|
@ -178,7 +178,7 @@ ModRefInfo AAResults::getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
|
|||
ModRefInfo Result = ModRefInfo::ModRef;
|
||||
|
||||
for (const auto &AA : AAs) {
|
||||
Result = intersectModRef(Result, AA->getArgModRefInfo(Call, ArgIdx));
|
||||
Result &= AA->getArgModRefInfo(Call, ArgIdx);
|
||||
|
||||
// Early-exit the moment we reach the bottom of the lattice.
|
||||
if (isNoModRef(Result))
|
||||
|
@ -226,7 +226,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
|
|||
ModRefInfo Result = ModRefInfo::ModRef;
|
||||
|
||||
for (const auto &AA : AAs) {
|
||||
Result = intersectModRef(Result, AA->getModRefInfo(Call, Loc, AAQI));
|
||||
Result &= AA->getModRefInfo(Call, Loc, AAQI);
|
||||
|
||||
// Early-exit the moment we reach the bottom of the lattice.
|
||||
if (isNoModRef(Result))
|
||||
|
@ -240,9 +240,9 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
|
|||
return ModRefInfo::NoModRef;
|
||||
|
||||
if (onlyReadsMemory(MRB))
|
||||
Result = clearMod(Result);
|
||||
Result &= ModRefInfo::Ref;
|
||||
else if (onlyWritesMemory(MRB))
|
||||
Result = clearRef(Result);
|
||||
Result &= ModRefInfo::Mod;
|
||||
|
||||
if (onlyAccessesArgPointees(MRB) || onlyAccessesInaccessibleOrArgMem(MRB)) {
|
||||
ModRefInfo AllArgsMask = ModRefInfo::NoModRef;
|
||||
|
@ -255,23 +255,21 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
|
|||
MemoryLocation ArgLoc =
|
||||
MemoryLocation::getForArgument(Call, ArgIdx, TLI);
|
||||
AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI);
|
||||
if (ArgAlias != AliasResult::NoAlias) {
|
||||
ModRefInfo ArgMask = getArgModRefInfo(Call, ArgIdx);
|
||||
AllArgsMask = unionModRef(AllArgsMask, ArgMask);
|
||||
}
|
||||
if (ArgAlias != AliasResult::NoAlias)
|
||||
AllArgsMask |= getArgModRefInfo(Call, ArgIdx);
|
||||
}
|
||||
}
|
||||
// Return NoModRef if no alias found with any argument.
|
||||
if (isNoModRef(AllArgsMask))
|
||||
return ModRefInfo::NoModRef;
|
||||
// Logical & between other AA analyses and argument analysis.
|
||||
Result = intersectModRef(Result, AllArgsMask);
|
||||
Result &= AllArgsMask;
|
||||
}
|
||||
|
||||
// If Loc is a constant memory location, the call definitely could not
|
||||
// modify the memory location.
|
||||
if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false))
|
||||
Result = clearMod(Result);
|
||||
Result &= ModRefInfo::Ref;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
@ -287,7 +285,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
|
|||
ModRefInfo Result = ModRefInfo::ModRef;
|
||||
|
||||
for (const auto &AA : AAs) {
|
||||
Result = intersectModRef(Result, AA->getModRefInfo(Call1, Call2, AAQI));
|
||||
Result &= AA->getModRefInfo(Call1, Call2, AAQI);
|
||||
|
||||
// Early-exit the moment we reach the bottom of the lattice.
|
||||
if (isNoModRef(Result))
|
||||
|
@ -313,9 +311,9 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
|
|||
// If Call1 only reads memory, the only dependence on Call2 can be
|
||||
// from Call1 reading memory written by Call2.
|
||||
if (onlyReadsMemory(Call1B))
|
||||
Result = clearMod(Result);
|
||||
Result &= ModRefInfo::Ref;
|
||||
else if (onlyWritesMemory(Call1B))
|
||||
Result = clearRef(Result);
|
||||
Result &= ModRefInfo::Mod;
|
||||
|
||||
// If Call2 only access memory through arguments, accumulate the mod/ref
|
||||
// information from Call1's references to the memory referenced by
|
||||
|
@ -346,10 +344,9 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
|
|||
|
||||
// ModRefC1 indicates what Call1 might do to Call2ArgLoc, and we use
|
||||
// above ArgMask to update dependence info.
|
||||
ModRefInfo ModRefC1 = getModRefInfo(Call1, Call2ArgLoc, AAQI);
|
||||
ArgMask = intersectModRef(ArgMask, ModRefC1);
|
||||
ArgMask &= getModRefInfo(Call1, Call2ArgLoc, AAQI);
|
||||
|
||||
R = intersectModRef(unionModRef(R, ArgMask), Result);
|
||||
R = (R | ArgMask) & Result;
|
||||
if (R == Result)
|
||||
break;
|
||||
}
|
||||
|
@ -378,7 +375,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
|
|||
ModRefInfo ModRefC2 = getModRefInfo(Call2, Call1ArgLoc, AAQI);
|
||||
if ((isModSet(ArgModRefC1) && isModOrRefSet(ModRefC2)) ||
|
||||
(isRefSet(ArgModRefC1) && isModSet(ModRefC2)))
|
||||
R = intersectModRef(unionModRef(R, ArgModRefC1), Result);
|
||||
R = (R | ArgModRefC1) & Result;
|
||||
|
||||
if (R == Result)
|
||||
break;
|
||||
|
@ -746,7 +743,7 @@ bool AAResults::canInstructionRangeModRef(const Instruction &I1,
|
|||
++E; // Convert from inclusive to exclusive range.
|
||||
|
||||
for (; I != E; ++I) // Check every instruction in range
|
||||
if (isModOrRefSet(intersectModRef(getModRefInfo(&*I, Loc), Mode)))
|
||||
if (isModOrRefSet(getModRefInfo(&*I, Loc) & Mode))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -459,7 +459,7 @@ void AliasSetTracker::add(Instruction *I) {
|
|||
using namespace PatternMatch;
|
||||
if (Call->use_empty() &&
|
||||
match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
|
||||
CallMask = clearMod(CallMask);
|
||||
CallMask &= ModRefInfo::Ref;
|
||||
|
||||
for (auto IdxArgPair : enumerate(Call->args())) {
|
||||
int ArgIdx = IdxArgPair.index();
|
||||
|
@ -469,7 +469,7 @@ void AliasSetTracker::add(Instruction *I) {
|
|||
MemoryLocation ArgLoc =
|
||||
MemoryLocation::getForArgument(Call, ArgIdx, nullptr);
|
||||
ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
|
||||
ArgMask = intersectModRef(CallMask, ArgMask);
|
||||
ArgMask &= CallMask;
|
||||
if (!isNoModRef(ArgMask))
|
||||
addPointer(ArgLoc, getAccessFromModRef(ArgMask));
|
||||
}
|
||||
|
|
|
@ -940,12 +940,12 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
|
|||
// Operand aliases 'Object', but call doesn't modify it. Strengthen
|
||||
// initial assumption and keep looking in case if there are more aliases.
|
||||
if (Call->onlyReadsMemory(OperandNo)) {
|
||||
Result = setRef(Result);
|
||||
Result |= ModRefInfo::Ref;
|
||||
continue;
|
||||
}
|
||||
// Operand aliases 'Object' but call only writes into it.
|
||||
if (Call->onlyWritesMemory(OperandNo)) {
|
||||
Result = setMod(Result);
|
||||
Result |= ModRefInfo::Mod;
|
||||
continue;
|
||||
}
|
||||
// This operand aliases 'Object' and call reads and writes into it.
|
||||
|
@ -988,9 +988,9 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
|
|||
// It's also possible for Loc to alias both src and dest, or neither.
|
||||
ModRefInfo rv = ModRefInfo::NoModRef;
|
||||
if (SrcAA != AliasResult::NoAlias || Call->hasReadingOperandBundles())
|
||||
rv = setRef(rv);
|
||||
rv |= ModRefInfo::Ref;
|
||||
if (DestAA != AliasResult::NoAlias || Call->hasClobberingOperandBundles())
|
||||
rv = setMod(rv);
|
||||
rv |= ModRefInfo::Mod;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
if (AlignedMap *P = Info.getPointer()) {
|
||||
auto I = P->Map.find(&GV);
|
||||
if (I != P->Map.end())
|
||||
GlobalMRI = unionModRef(GlobalMRI, I->second);
|
||||
GlobalMRI |= I->second;
|
||||
}
|
||||
return GlobalMRI;
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ public:
|
|||
Info.setPointer(P);
|
||||
}
|
||||
auto &GlobalMRI = P->Map[&GV];
|
||||
GlobalMRI = unionModRef(GlobalMRI, NewMRI);
|
||||
GlobalMRI |= NewMRI;
|
||||
}
|
||||
|
||||
/// Clear a global's ModRef info. Should be used when a global is being
|
||||
|
@ -938,8 +938,8 @@ ModRefInfo GlobalsAAResult::getModRefInfo(const CallBase *Call,
|
|||
if (const Function *F = Call->getCalledFunction())
|
||||
if (NonAddressTakenGlobals.count(GV))
|
||||
if (const FunctionInfo *FI = getFunctionInfo(F))
|
||||
Known = unionModRef(FI->getModRefInfoForGlobal(*GV),
|
||||
getModRefInfoForArgument(Call, GV, AAQI));
|
||||
Known = FI->getModRefInfoForGlobal(*GV) |
|
||||
getModRefInfoForArgument(Call, GV, AAQI);
|
||||
|
||||
return Known;
|
||||
}
|
||||
|
|
|
@ -2003,8 +2003,7 @@ mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
|
|||
for (auto *B : L->blocks())
|
||||
for (auto &I : *B)
|
||||
if (Ignored.count(&I) == 0 &&
|
||||
isModOrRefSet(
|
||||
intersectModRef(AA.getModRefInfo(&I, StoreLoc), Access)))
|
||||
isModOrRefSet(AA.getModRefInfo(&I, StoreLoc) & Access))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -1028,8 +1028,7 @@ mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
|
|||
for (BasicBlock *B : L->blocks())
|
||||
for (Instruction &I : *B)
|
||||
if (!IgnoredInsts.contains(&I) &&
|
||||
isModOrRefSet(
|
||||
intersectModRef(AA.getModRefInfo(&I, StoreLoc), Access)))
|
||||
isModOrRefSet(AA.getModRefInfo(&I, StoreLoc) & Access))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue