Skip to content

Commit b128e05

Browse files
committed
[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
1 parent 34ae308 commit b128e05

File tree

7 files changed

+40
-38
lines changed

7 files changed

+40
-38
lines changed

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ enum class ModRefInfo : uint8_t {
152152
Mod = 2,
153153
/// The access may reference and may modify the value stored in memory.
154154
ModRef = Ref | Mod,
155+
LLVM_MARK_AS_BITMASK_ENUM(ModRef),
155156
};
156157

157158
LLVM_NODISCARD inline bool isNoModRef(const ModRefInfo MRI) {
@@ -170,25 +171,31 @@ LLVM_NODISCARD inline bool isRefSet(const ModRefInfo MRI) {
170171
return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref);
171172
}
172173

174+
[[deprecated("Use operator | instead")]]
173175
LLVM_NODISCARD inline ModRefInfo setMod(const ModRefInfo MRI) {
174-
return ModRefInfo(static_cast<int>(MRI) | static_cast<int>(ModRefInfo::Mod));
176+
return MRI | ModRefInfo::Mod;
175177
}
178+
[[deprecated("Use operator | instead")]]
176179
LLVM_NODISCARD inline ModRefInfo setRef(const ModRefInfo MRI) {
177-
return ModRefInfo(static_cast<int>(MRI) | static_cast<int>(ModRefInfo::Ref));
180+
return MRI | ModRefInfo::Ref;
178181
}
182+
[[deprecated("Use operator & instead")]]
179183
LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) {
180-
return ModRefInfo(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref));
184+
return MRI & ModRefInfo::Ref;
181185
}
186+
[[deprecated("Use operator & instead")]]
182187
LLVM_NODISCARD inline ModRefInfo clearRef(const ModRefInfo MRI) {
183-
return ModRefInfo(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod));
188+
return MRI & ModRefInfo::Mod;
184189
}
190+
[[deprecated("Use operator | instead")]]
185191
LLVM_NODISCARD inline ModRefInfo unionModRef(const ModRefInfo MRI1,
186192
const ModRefInfo MRI2) {
187-
return ModRefInfo(static_cast<int>(MRI1) | static_cast<int>(MRI2));
193+
return MRI1 | MRI2;
188194
}
195+
[[deprecated("Use operator & instead")]]
189196
LLVM_NODISCARD inline ModRefInfo intersectModRef(const ModRefInfo MRI1,
190197
const ModRefInfo MRI2) {
191-
return ModRefInfo(static_cast<int>(MRI1) & static_cast<int>(MRI2));
198+
return MRI1 & MRI2;
192199
}
193200

194201
/// The locations at which a function might access memory.

llvm/lib/Analysis/AliasAnalysis.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ ModRefInfo AAResults::getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
178178
ModRefInfo Result = ModRefInfo::ModRef;
179179

180180
for (const auto &AA : AAs) {
181-
Result = intersectModRef(Result, AA->getArgModRefInfo(Call, ArgIdx));
181+
Result &= AA->getArgModRefInfo(Call, ArgIdx);
182182

183183
// Early-exit the moment we reach the bottom of the lattice.
184184
if (isNoModRef(Result))
@@ -226,7 +226,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
226226
ModRefInfo Result = ModRefInfo::ModRef;
227227

228228
for (const auto &AA : AAs) {
229-
Result = intersectModRef(Result, AA->getModRefInfo(Call, Loc, AAQI));
229+
Result &= AA->getModRefInfo(Call, Loc, AAQI);
230230

231231
// Early-exit the moment we reach the bottom of the lattice.
232232
if (isNoModRef(Result))
@@ -240,9 +240,9 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
240240
return ModRefInfo::NoModRef;
241241

242242
if (onlyReadsMemory(MRB))
243-
Result = clearMod(Result);
243+
Result &= ModRefInfo::Ref;
244244
else if (onlyWritesMemory(MRB))
245-
Result = clearRef(Result);
245+
Result &= ModRefInfo::Mod;
246246

247247
if (onlyAccessesArgPointees(MRB) || onlyAccessesInaccessibleOrArgMem(MRB)) {
248248
ModRefInfo AllArgsMask = ModRefInfo::NoModRef;
@@ -255,23 +255,21 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
255255
MemoryLocation ArgLoc =
256256
MemoryLocation::getForArgument(Call, ArgIdx, TLI);
257257
AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI);
258-
if (ArgAlias != AliasResult::NoAlias) {
259-
ModRefInfo ArgMask = getArgModRefInfo(Call, ArgIdx);
260-
AllArgsMask = unionModRef(AllArgsMask, ArgMask);
261-
}
258+
if (ArgAlias != AliasResult::NoAlias)
259+
AllArgsMask |= getArgModRefInfo(Call, ArgIdx);
262260
}
263261
}
264262
// Return NoModRef if no alias found with any argument.
265263
if (isNoModRef(AllArgsMask))
266264
return ModRefInfo::NoModRef;
267265
// Logical & between other AA analyses and argument analysis.
268-
Result = intersectModRef(Result, AllArgsMask);
266+
Result &= AllArgsMask;
269267
}
270268

271269
// If Loc is a constant memory location, the call definitely could not
272270
// modify the memory location.
273271
if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false))
274-
Result = clearMod(Result);
272+
Result &= ModRefInfo::Ref;
275273

276274
return Result;
277275
}
@@ -287,7 +285,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
287285
ModRefInfo Result = ModRefInfo::ModRef;
288286

289287
for (const auto &AA : AAs) {
290-
Result = intersectModRef(Result, AA->getModRefInfo(Call1, Call2, AAQI));
288+
Result &= AA->getModRefInfo(Call1, Call2, AAQI);
291289

292290
// Early-exit the moment we reach the bottom of the lattice.
293291
if (isNoModRef(Result))
@@ -313,9 +311,9 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
313311
// If Call1 only reads memory, the only dependence on Call2 can be
314312
// from Call1 reading memory written by Call2.
315313
if (onlyReadsMemory(Call1B))
316-
Result = clearMod(Result);
314+
Result &= ModRefInfo::Ref;
317315
else if (onlyWritesMemory(Call1B))
318-
Result = clearRef(Result);
316+
Result &= ModRefInfo::Mod;
319317

320318
// If Call2 only access memory through arguments, accumulate the mod/ref
321319
// information from Call1's references to the memory referenced by
@@ -346,10 +344,9 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
346344

347345
// ModRefC1 indicates what Call1 might do to Call2ArgLoc, and we use
348346
// above ArgMask to update dependence info.
349-
ModRefInfo ModRefC1 = getModRefInfo(Call1, Call2ArgLoc, AAQI);
350-
ArgMask = intersectModRef(ArgMask, ModRefC1);
347+
ArgMask &= getModRefInfo(Call1, Call2ArgLoc, AAQI);
351348

352-
R = intersectModRef(unionModRef(R, ArgMask), Result);
349+
R = (R | ArgMask) & Result;
353350
if (R == Result)
354351
break;
355352
}
@@ -378,7 +375,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
378375
ModRefInfo ModRefC2 = getModRefInfo(Call2, Call1ArgLoc, AAQI);
379376
if ((isModSet(ArgModRefC1) && isModOrRefSet(ModRefC2)) ||
380377
(isRefSet(ArgModRefC1) && isModSet(ModRefC2)))
381-
R = intersectModRef(unionModRef(R, ArgModRefC1), Result);
378+
R = (R | ArgModRefC1) & Result;
382379

383380
if (R == Result)
384381
break;
@@ -746,7 +743,7 @@ bool AAResults::canInstructionRangeModRef(const Instruction &I1,
746743
++E; // Convert from inclusive to exclusive range.
747744

748745
for (; I != E; ++I) // Check every instruction in range
749-
if (isModOrRefSet(intersectModRef(getModRefInfo(&*I, Loc), Mode)))
746+
if (isModOrRefSet(getModRefInfo(&*I, Loc) & Mode))
750747
return true;
751748
return false;
752749
}

llvm/lib/Analysis/AliasSetTracker.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ void AliasSetTracker::add(Instruction *I) {
459459
using namespace PatternMatch;
460460
if (Call->use_empty() &&
461461
match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
462-
CallMask = clearMod(CallMask);
462+
CallMask &= ModRefInfo::Ref;
463463

464464
for (auto IdxArgPair : enumerate(Call->args())) {
465465
int ArgIdx = IdxArgPair.index();
@@ -469,7 +469,7 @@ void AliasSetTracker::add(Instruction *I) {
469469
MemoryLocation ArgLoc =
470470
MemoryLocation::getForArgument(Call, ArgIdx, nullptr);
471471
ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
472-
ArgMask = intersectModRef(CallMask, ArgMask);
472+
ArgMask &= CallMask;
473473
if (!isNoModRef(ArgMask))
474474
addPointer(ArgLoc, getAccessFromModRef(ArgMask));
475475
}

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,12 +940,12 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
940940
// Operand aliases 'Object', but call doesn't modify it. Strengthen
941941
// initial assumption and keep looking in case if there are more aliases.
942942
if (Call->onlyReadsMemory(OperandNo)) {
943-
Result = setRef(Result);
943+
Result |= ModRefInfo::Ref;
944944
continue;
945945
}
946946
// Operand aliases 'Object' but call only writes into it.
947947
if (Call->onlyWritesMemory(OperandNo)) {
948-
Result = setMod(Result);
948+
Result |= ModRefInfo::Mod;
949949
continue;
950950
}
951951
// This operand aliases 'Object' and call reads and writes into it.
@@ -988,9 +988,9 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
988988
// It's also possible for Loc to alias both src and dest, or neither.
989989
ModRefInfo rv = ModRefInfo::NoModRef;
990990
if (SrcAA != AliasResult::NoAlias || Call->hasReadingOperandBundles())
991-
rv = setRef(rv);
991+
rv |= ModRefInfo::Ref;
992992
if (DestAA != AliasResult::NoAlias || Call->hasClobberingOperandBundles())
993-
rv = setMod(rv);
993+
rv |= ModRefInfo::Mod;
994994
return rv;
995995
}
996996

llvm/lib/Analysis/GlobalsModRef.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class GlobalsAAResult::FunctionInfo {
160160
if (AlignedMap *P = Info.getPointer()) {
161161
auto I = P->Map.find(&GV);
162162
if (I != P->Map.end())
163-
GlobalMRI = unionModRef(GlobalMRI, I->second);
163+
GlobalMRI |= I->second;
164164
}
165165
return GlobalMRI;
166166
}
@@ -185,7 +185,7 @@ class GlobalsAAResult::FunctionInfo {
185185
Info.setPointer(P);
186186
}
187187
auto &GlobalMRI = P->Map[&GV];
188-
GlobalMRI = unionModRef(GlobalMRI, NewMRI);
188+
GlobalMRI |= NewMRI;
189189
}
190190

191191
/// Clear a global's ModRef info. Should be used when a global is being
@@ -938,8 +938,8 @@ ModRefInfo GlobalsAAResult::getModRefInfo(const CallBase *Call,
938938
if (const Function *F = Call->getCalledFunction())
939939
if (NonAddressTakenGlobals.count(GV))
940940
if (const FunctionInfo *FI = getFunctionInfo(F))
941-
Known = unionModRef(FI->getModRefInfoForGlobal(*GV),
942-
getModRefInfoForArgument(Call, GV, AAQI));
941+
Known = FI->getModRefInfoForGlobal(*GV) |
942+
getModRefInfoForArgument(Call, GV, AAQI);
943943

944944
return Known;
945945
}

llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,8 +2003,7 @@ mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
20032003
for (auto *B : L->blocks())
20042004
for (auto &I : *B)
20052005
if (Ignored.count(&I) == 0 &&
2006-
isModOrRefSet(
2007-
intersectModRef(AA.getModRefInfo(&I, StoreLoc), Access)))
2006+
isModOrRefSet(AA.getModRefInfo(&I, StoreLoc) & Access))
20082007
return true;
20092008

20102009
return false;

llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,8 +1028,7 @@ mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
10281028
for (BasicBlock *B : L->blocks())
10291029
for (Instruction &I : *B)
10301030
if (!IgnoredInsts.contains(&I) &&
1031-
isModOrRefSet(
1032-
intersectModRef(AA.getModRefInfo(&I, StoreLoc), Access)))
1031+
isModOrRefSet(AA.getModRefInfo(&I, StoreLoc) & Access))
10331032
return true;
10341033
return false;
10351034
}

0 commit comments

Comments
 (0)