Skip to content

Commit 63d2250

Browse files
committedDec 5, 2017
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
1 parent f6ae323 commit 63d2250

16 files changed

+171
-125
lines changed
 

‎llvm/include/llvm/Analysis/AliasAnalysis.h

+58-15
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,60 @@ enum AliasResult {
9595
///
9696
/// This is no access at all, a modification, a reference, or both
9797
/// a modification and a reference. These are specifically structured such that
98-
/// they form a two bit matrix and bit-tests for 'mod' or 'ref' work with any
99-
/// of the possible values.
98+
/// they form a two bit matrix and bit-tests for 'mod' or 'ref'
99+
/// work with any of the possible values.
100+
100101
enum ModRefInfo {
101102
/// The access neither references nor modifies the value stored in memory.
102103
MRI_NoModRef = 0,
103-
/// The access references the value stored in memory.
104+
/// The access may reference the value stored in memory.
104105
MRI_Ref = 1,
105-
/// The access modifies the value stored in memory.
106+
/// The access may modify the value stored in memory.
106107
MRI_Mod = 2,
107-
/// The access both references and modifies the value stored in memory.
108-
MRI_ModRef = MRI_Ref | MRI_Mod
108+
/// The access may reference and may modify the value stored in memory.
109+
MRI_ModRef = MRI_Ref | MRI_Mod,
109110
};
110111

112+
LLVM_NODISCARD inline bool isNoModRef(const ModRefInfo MRI) {
113+
return MRI == MRI_NoModRef;
114+
}
115+
LLVM_NODISCARD inline bool isModOrRefSet(const ModRefInfo MRI) {
116+
return MRI & MRI_ModRef;
117+
}
118+
LLVM_NODISCARD inline bool isModAndRefSet(const ModRefInfo MRI) {
119+
return (MRI & MRI_ModRef) == MRI_ModRef;
120+
}
121+
LLVM_NODISCARD inline bool isModSet(const ModRefInfo MRI) {
122+
return MRI & MRI_Mod;
123+
}
124+
LLVM_NODISCARD inline bool isRefSet(const ModRefInfo MRI) {
125+
return MRI & MRI_Ref;
126+
}
127+
128+
LLVM_NODISCARD inline ModRefInfo setRef(const ModRefInfo MRI) {
129+
return ModRefInfo(MRI | MRI_Ref);
130+
}
131+
LLVM_NODISCARD inline ModRefInfo setMod(const ModRefInfo MRI) {
132+
return ModRefInfo(MRI | MRI_Mod);
133+
}
134+
LLVM_NODISCARD inline ModRefInfo setModAndRef(const ModRefInfo MRI) {
135+
return ModRefInfo(MRI | MRI_ModRef);
136+
}
137+
LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) {
138+
return ModRefInfo(MRI & MRI_Ref);
139+
}
140+
LLVM_NODISCARD inline ModRefInfo clearRef(const ModRefInfo MRI) {
141+
return ModRefInfo(MRI & MRI_Mod);
142+
}
143+
LLVM_NODISCARD inline ModRefInfo unionModRef(const ModRefInfo MRI1,
144+
const ModRefInfo MRI2) {
145+
return ModRefInfo(MRI1 | MRI2);
146+
}
147+
LLVM_NODISCARD inline ModRefInfo intersectModRef(const ModRefInfo MRI1,
148+
const ModRefInfo MRI2) {
149+
return ModRefInfo(MRI1 & MRI2);
150+
}
151+
111152
/// The locations at which a function might access memory.
112153
///
113154
/// These are primarily used in conjunction with the \c AccessKind bits to
@@ -187,6 +228,15 @@ enum FunctionModRefBehavior {
187228
FMRB_UnknownModRefBehavior = FMRL_Anywhere | MRI_ModRef
188229
};
189230

231+
// Wrapper method strips bits significant only in FunctionModRefBehavior,
232+
// to obtain a valid ModRefInfo. The benefit of using the wrapper is that if
233+
// ModRefInfo enum changes, the wrapper can be updated to & with the new enum
234+
// entry with all bits set to 1.
235+
LLVM_NODISCARD inline ModRefInfo
236+
createModRefInfo(const FunctionModRefBehavior FMRB) {
237+
return ModRefInfo(FMRB & MRI_ModRef);
238+
}
239+
190240
class AAResults {
191241
public:
192242
// Make these results default constructable and movable. We have to spell
@@ -520,14 +570,7 @@ class AAResults {
520570
const Optional<MemoryLocation> &OptLoc) {
521571
if (OptLoc == None) {
522572
if (auto CS = ImmutableCallSite(I)) {
523-
auto MRB = getModRefBehavior(CS);
524-
if ((MRB & MRI_ModRef) == MRI_ModRef)
525-
return MRI_ModRef;
526-
if (MRB & MRI_Ref)
527-
return MRI_Ref;
528-
if (MRB & MRI_Mod)
529-
return MRI_Mod;
530-
return MRI_NoModRef;
573+
return createModRefInfo(getModRefBehavior(CS));
531574
}
532575
}
533576

@@ -570,7 +613,7 @@ class AAResults {
570613

571614
/// \brief Return information about whether a particular call site modifies
572615
/// or reads the specified memory location \p MemLoc before instruction \p I
573-
/// in a BasicBlock. A ordered basic block \p OBB can be used to speed up
616+
/// in a BasicBlock. An ordered basic block \p OBB can be used to speed up
574617
/// instruction ordering queries inside the BasicBlock containing \p I.
575618
ModRefInfo callCapturesBefore(const Instruction *I,
576619
const MemoryLocation &MemLoc, DominatorTree *DT,

‎llvm/lib/Analysis/AliasAnalysis.cpp

+42-36
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,10 @@ ModRefInfo AAResults::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
122122
ModRefInfo Result = MRI_ModRef;
123123

124124
for (const auto &AA : AAs) {
125-
Result = ModRefInfo(Result & AA->getArgModRefInfo(CS, ArgIdx));
125+
Result = intersectModRef(Result, AA->getArgModRefInfo(CS, ArgIdx));
126126

127127
// Early-exit the moment we reach the bottom of the lattice.
128-
if (Result == MRI_NoModRef)
128+
if (isNoModRef(Result))
129129
return Result;
130130
}
131131

@@ -146,8 +146,9 @@ ModRefInfo AAResults::getModRefInfo(Instruction *I, ImmutableCallSite Call) {
146146
// is that if the call references what this instruction
147147
// defines, it must be clobbered by this location.
148148
const MemoryLocation DefLoc = MemoryLocation::get(I);
149-
if (getModRefInfo(Call, DefLoc) != MRI_NoModRef)
150-
return MRI_ModRef;
149+
ModRefInfo MR = getModRefInfo(Call, DefLoc);
150+
if (isModOrRefSet(MR))
151+
return setModAndRef(MR);
151152
}
152153
return MRI_NoModRef;
153154
}
@@ -157,10 +158,10 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
157158
ModRefInfo Result = MRI_ModRef;
158159

159160
for (const auto &AA : AAs) {
160-
Result = ModRefInfo(Result & AA->getModRefInfo(CS, Loc));
161+
Result = intersectModRef(Result, AA->getModRefInfo(CS, Loc));
161162

162163
// Early-exit the moment we reach the bottom of the lattice.
163-
if (Result == MRI_NoModRef)
164+
if (isNoModRef(Result))
164165
return Result;
165166
}
166167

@@ -172,9 +173,9 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
172173
return MRI_NoModRef;
173174

174175
if (onlyReadsMemory(MRB))
175-
Result = ModRefInfo(Result & MRI_Ref);
176+
Result = clearMod(Result);
176177
else if (doesNotReadMemory(MRB))
177-
Result = ModRefInfo(Result & MRI_Mod);
178+
Result = clearRef(Result);
178179

179180
if (onlyAccessesArgPointees(MRB) || onlyAccessesInaccessibleOrArgMem(MRB)) {
180181
bool DoesAlias = false;
@@ -190,20 +191,21 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
190191
if (ArgAlias != NoAlias) {
191192
ModRefInfo ArgMask = getArgModRefInfo(CS, ArgIdx);
192193
DoesAlias = true;
193-
AllArgsMask = ModRefInfo(AllArgsMask | ArgMask);
194+
AllArgsMask = unionModRef(AllArgsMask, ArgMask);
194195
}
195196
}
196197
}
198+
// Return MRI_NoModRef if no alias found with any argument.
197199
if (!DoesAlias)
198200
return MRI_NoModRef;
199-
Result = ModRefInfo(Result & AllArgsMask);
201+
// Logical & between other AA analyses and argument analysis.
202+
Result = intersectModRef(Result, AllArgsMask);
200203
}
201204

202205
// If Loc is a constant memory location, the call definitely could not
203206
// modify the memory location.
204-
if ((Result & MRI_Mod) &&
205-
pointsToConstantMemory(Loc, /*OrLocal*/ false))
206-
Result = ModRefInfo(Result & ~MRI_Mod);
207+
if (isModSet(Result) && pointsToConstantMemory(Loc, /*OrLocal*/ false))
208+
Result = clearMod(Result);
207209

208210
return Result;
209211
}
@@ -213,10 +215,10 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
213215
ModRefInfo Result = MRI_ModRef;
214216

215217
for (const auto &AA : AAs) {
216-
Result = ModRefInfo(Result & AA->getModRefInfo(CS1, CS2));
218+
Result = intersectModRef(Result, AA->getModRefInfo(CS1, CS2));
217219

218220
// Early-exit the moment we reach the bottom of the lattice.
219-
if (Result == MRI_NoModRef)
221+
if (isNoModRef(Result))
220222
return Result;
221223
}
222224

@@ -239,9 +241,9 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
239241
// If CS1 only reads memory, the only dependence on CS2 can be
240242
// from CS1 reading memory written by CS2.
241243
if (onlyReadsMemory(CS1B))
242-
Result = ModRefInfo(Result & MRI_Ref);
244+
Result = clearMod(Result);
243245
else if (doesNotReadMemory(CS1B))
244-
Result = ModRefInfo(Result & MRI_Mod);
246+
Result = clearRef(Result);
245247

246248
// If CS2 only access memory through arguments, accumulate the mod/ref
247249
// information from CS1's references to the memory referenced by
@@ -256,17 +258,23 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
256258
unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I);
257259
auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI);
258260

259-
// ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence
260-
// of CS1 on that location is the inverse.
261-
ModRefInfo ArgMask = getArgModRefInfo(CS2, CS2ArgIdx);
262-
if (ArgMask == MRI_Mod)
261+
// ArgModRefCS2 indicates what CS2 might do to CS2ArgLoc, and the
262+
// dependence of CS1 on that location is the inverse:
263+
// - If CS2 modifies location, dependence exists if CS1 reads or writes.
264+
// - If CS2 only reads location, dependence exists if CS1 writes.
265+
ModRefInfo ArgModRefCS2 = getArgModRefInfo(CS2, CS2ArgIdx);
266+
ModRefInfo ArgMask;
267+
if (isModSet(ArgModRefCS2))
263268
ArgMask = MRI_ModRef;
264-
else if (ArgMask == MRI_Ref)
269+
else if (isRefSet(ArgModRefCS2))
265270
ArgMask = MRI_Mod;
266271

267-
ArgMask = ModRefInfo(ArgMask & getModRefInfo(CS1, CS2ArgLoc));
272+
// ModRefCS1 indicates what CS1 might do to CS2ArgLoc, and we use
273+
// above ArgMask to update dependence info.
274+
ModRefInfo ModRefCS1 = getModRefInfo(CS1, CS2ArgLoc);
275+
ArgMask = intersectModRef(ArgMask, ModRefCS1);
268276

269-
R = ModRefInfo((R | ArgMask) & Result);
277+
R = intersectModRef(unionModRef(R, ArgMask), Result);
270278
if (R == Result)
271279
break;
272280
}
@@ -286,16 +294,14 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
286294
unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I);
287295
auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI);
288296

289-
// ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod
290-
// CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If CS1
291-
// might Ref, then we care only about a Mod by CS2.
292-
ModRefInfo ArgMask = getArgModRefInfo(CS1, CS1ArgIdx);
293-
ModRefInfo ArgR = getModRefInfo(CS2, CS1ArgLoc);
294-
if (((ArgMask & MRI_Mod) != MRI_NoModRef &&
295-
(ArgR & MRI_ModRef) != MRI_NoModRef) ||
296-
((ArgMask & MRI_Ref) != MRI_NoModRef &&
297-
(ArgR & MRI_Mod) != MRI_NoModRef))
298-
R = ModRefInfo((R | ArgMask) & Result);
297+
// ArgModRefCS1 indicates what CS1 might do to CS1ArgLoc; if CS1 might
298+
// Mod CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If
299+
// CS1 might Ref, then we care only about a Mod by CS2.
300+
ModRefInfo ArgModRefCS1 = getArgModRefInfo(CS1, CS1ArgIdx);
301+
ModRefInfo ModRefCS2 = getModRefInfo(CS2, CS1ArgLoc);
302+
if ((isModSet(ArgModRefCS1) && isModOrRefSet(ModRefCS2)) ||
303+
(isRefSet(ArgModRefCS1) && isModSet(ModRefCS2)))
304+
R = intersectModRef(unionModRef(R, ArgModRefCS1), Result);
299305

300306
if (R == Result)
301307
break;
@@ -456,7 +462,7 @@ ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW,
456462

457463
/// \brief Return information about whether a particular call site modifies
458464
/// or reads the specified memory location \p MemLoc before instruction \p I
459-
/// in a BasicBlock. A ordered basic block \p OBB can be used to speed up
465+
/// in a BasicBlock. An ordered basic block \p OBB can be used to speed up
460466
/// instruction-ordering queries inside the BasicBlock containing \p I.
461467
/// FIXME: this is really just shoring-up a deficiency in alias analysis.
462468
/// BasicAA isn't willing to spend linear time determining whether an alloca
@@ -538,7 +544,7 @@ bool AAResults::canInstructionRangeModRef(const Instruction &I1,
538544
++E; // Convert from inclusive to exclusive range.
539545

540546
for (; I != E; ++I) // Check every instruction in range
541-
if (getModRefInfo(&*I, Loc) & Mode)
547+
if (intersectModRef(getModRefInfo(&*I, Loc), Mode))
542548
return true;
543549
return false;
544550
}

‎llvm/lib/Analysis/AliasSetTracker.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
211211
if (!UnknownInsts.empty()) {
212212
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
213213
if (auto *Inst = getUnknownInst(i))
214-
if (AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo)) !=
215-
MRI_NoModRef)
214+
if (isModOrRefSet(
215+
AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo))))
216216
return true;
217217
}
218218

@@ -231,15 +231,15 @@ bool AliasSet::aliasesUnknownInst(const Instruction *Inst,
231231
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
232232
if (auto *UnknownInst = getUnknownInst(i)) {
233233
ImmutableCallSite C1(UnknownInst), C2(Inst);
234-
if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef ||
235-
AA.getModRefInfo(C2, C1) != MRI_NoModRef)
234+
if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) ||
235+
isModOrRefSet(AA.getModRefInfo(C2, C1)))
236236
return true;
237237
}
238238
}
239239

240240
for (iterator I = begin(), E = end(); I != E; ++I)
241-
if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(),
242-
I.getAAInfo())) != MRI_NoModRef)
241+
if (isModOrRefSet(AA.getModRefInfo(
242+
Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))))
243243
return true;
244244

245245
return false;
@@ -572,12 +572,11 @@ AliasSet &AliasSetTracker::mergeAllAliasSets() {
572572
AliasAnyAS->AliasAny = true;
573573

574574
for (auto Cur : ASVector) {
575-
576575
// If Cur was already forwarding, just forward to the new AS instead.
577576
AliasSet *FwdTo = Cur->Forward;
578577
if (FwdTo) {
579578
Cur->Forward = AliasAnyAS;
580-
AliasAnyAS->addRef();
579+
AliasAnyAS->addRef();
581580
FwdTo->dropRef(*this);
582581
continue;
583582
}

‎llvm/lib/Analysis/BasicAliasAnalysis.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -809,12 +809,12 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS,
809809
// Operand aliases 'Object', but call doesn't modify it. Strengthen
810810
// initial assumption and keep looking in case if there are more aliases.
811811
if (CS.onlyReadsMemory(OperandNo)) {
812-
Result = static_cast<ModRefInfo>(Result | MRI_Ref);
812+
Result = setRef(Result);
813813
continue;
814814
}
815815
// Operand aliases 'Object' but call only writes into it.
816816
if (CS.doesNotReadMemory(OperandNo)) {
817-
Result = static_cast<ModRefInfo>(Result | MRI_Mod);
817+
Result = setMod(Result);
818818
continue;
819819
}
820820
// This operand aliases 'Object' and call reads and writes into it.
@@ -832,7 +832,7 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS,
832832
// routines do not read values visible in the IR. TODO: Consider special
833833
// casing realloc and strdup routines which access only their arguments as
834834
// well. Or alternatively, replace all of this with inaccessiblememonly once
835-
// that's implemented fully.
835+
// that's implemented fully.
836836
auto *Inst = CS.getInstruction();
837837
if (isMallocOrCallocLikeFn(Inst, &TLI)) {
838838
// Be conservative if the accessed pointer may alias the allocation -
@@ -860,9 +860,9 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS,
860860
// It's also possible for Loc to alias both src and dest, or neither.
861861
ModRefInfo rv = MRI_NoModRef;
862862
if (SrcAA != NoAlias)
863-
rv = static_cast<ModRefInfo>(rv | MRI_Ref);
863+
rv = setRef(rv);
864864
if (DestAA != NoAlias)
865-
rv = static_cast<ModRefInfo>(rv | MRI_Mod);
865+
rv = setMod(rv);
866866
return rv;
867867
}
868868

@@ -933,10 +933,12 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS1,
933933
// possibilities for guard intrinsics.
934934

935935
if (isIntrinsicCall(CS1, Intrinsic::experimental_guard))
936-
return getModRefBehavior(CS2) & MRI_Mod ? MRI_Ref : MRI_NoModRef;
936+
return isModSet(ModRefInfo(getModRefBehavior(CS2))) ? MRI_Ref
937+
: MRI_NoModRef;
937938

938939
if (isIntrinsicCall(CS2, Intrinsic::experimental_guard))
939-
return getModRefBehavior(CS1) & MRI_Mod ? MRI_Mod : MRI_NoModRef;
940+
return isModSet(ModRefInfo(getModRefBehavior(CS1))) ? MRI_Mod
941+
: MRI_NoModRef;
940942

941943
// The AAResultBase base class has some smarts, lets use them.
942944
return AAResultBase::getModRefInfo(CS1, CS2);

0 commit comments

Comments
 (0)
Please sign in to comment.