From b128e057c191a441e3778ffc872ffca943b2e5b1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 1 Aug 2022 08:16:54 +0200 Subject: [PATCH] [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 --- llvm/include/llvm/Analysis/AliasAnalysis.h | 19 +++++++++---- llvm/lib/Analysis/AliasAnalysis.cpp | 33 ++++++++++------------ llvm/lib/Analysis/AliasSetTracker.cpp | 4 +-- llvm/lib/Analysis/BasicAliasAnalysis.cpp | 8 +++--- llvm/lib/Analysis/GlobalsModRef.cpp | 8 +++--- .../Target/Hexagon/HexagonLoopIdiomRecognition.cpp | 3 +- llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 3 +- 7 files changed, 40 insertions(+), 38 deletions(-) diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h index 438702f..65d7d5b 100644 --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -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(MRI) & static_cast(ModRefInfo::Ref); } +[[deprecated("Use operator | instead")]] LLVM_NODISCARD inline ModRefInfo setMod(const ModRefInfo MRI) { - return ModRefInfo(static_cast(MRI) | static_cast(ModRefInfo::Mod)); + return MRI | ModRefInfo::Mod; } +[[deprecated("Use operator | instead")]] LLVM_NODISCARD inline ModRefInfo setRef(const ModRefInfo MRI) { - return ModRefInfo(static_cast(MRI) | static_cast(ModRefInfo::Ref)); + return MRI | ModRefInfo::Ref; } +[[deprecated("Use operator & instead")]] LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) { - return ModRefInfo(static_cast(MRI) & static_cast(ModRefInfo::Ref)); + return MRI & ModRefInfo::Ref; } +[[deprecated("Use operator & instead")]] LLVM_NODISCARD inline ModRefInfo clearRef(const ModRefInfo MRI) { - return ModRefInfo(static_cast(MRI) & static_cast(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(MRI1) | static_cast(MRI2)); + return MRI1 | MRI2; } +[[deprecated("Use operator & instead")]] LLVM_NODISCARD inline ModRefInfo intersectModRef(const ModRefInfo MRI1, const ModRefInfo MRI2) { - return ModRefInfo(static_cast(MRI1) & static_cast(MRI2)); + return MRI1 & MRI2; } /// The locations at which a function might access memory. diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp index 0d8da68..637c260 100644 --- a/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/llvm/lib/Analysis/AliasAnalysis.cpp @@ -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; } diff --git a/llvm/lib/Analysis/AliasSetTracker.cpp b/llvm/lib/Analysis/AliasSetTracker.cpp index bb25244..b0f9061 100644 --- a/llvm/lib/Analysis/AliasSetTracker.cpp +++ b/llvm/lib/Analysis/AliasSetTracker.cpp @@ -459,7 +459,7 @@ void AliasSetTracker::add(Instruction *I) { using namespace PatternMatch; if (Call->use_empty() && match(Call, m_Intrinsic())) - 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)); } diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index b534164..96a80fb 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -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; } diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp index 99769c1..f87f198 100644 --- a/llvm/lib/Analysis/GlobalsModRef.cpp +++ b/llvm/lib/Analysis/GlobalsModRef.cpp @@ -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; } diff --git a/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp b/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp index 2d49fa3..97a4524 100644 --- a/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp +++ b/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp @@ -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; diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index 3ed022f..f176220 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -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; } -- 2.7.4