@@ -122,10 +122,10 @@ ModRefInfo AAResults::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) {
122
122
ModRefInfo Result = MRI_ModRef;
123
123
124
124
for (const auto &AA : AAs) {
125
- Result = ModRefInfo (Result & AA->getArgModRefInfo (CS, ArgIdx));
125
+ Result = intersectModRef (Result, AA->getArgModRefInfo (CS, ArgIdx));
126
126
127
127
// Early-exit the moment we reach the bottom of the lattice.
128
- if (Result == MRI_NoModRef )
128
+ if (isNoModRef ( Result) )
129
129
return Result;
130
130
}
131
131
@@ -146,8 +146,9 @@ ModRefInfo AAResults::getModRefInfo(Instruction *I, ImmutableCallSite Call) {
146
146
// is that if the call references what this instruction
147
147
// defines, it must be clobbered by this location.
148
148
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);
151
152
}
152
153
return MRI_NoModRef;
153
154
}
@@ -157,10 +158,10 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
157
158
ModRefInfo Result = MRI_ModRef;
158
159
159
160
for (const auto &AA : AAs) {
160
- Result = ModRefInfo (Result & AA->getModRefInfo (CS, Loc));
161
+ Result = intersectModRef (Result, AA->getModRefInfo (CS, Loc));
161
162
162
163
// Early-exit the moment we reach the bottom of the lattice.
163
- if (Result == MRI_NoModRef )
164
+ if (isNoModRef ( Result) )
164
165
return Result;
165
166
}
166
167
@@ -172,9 +173,9 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
172
173
return MRI_NoModRef;
173
174
174
175
if (onlyReadsMemory (MRB))
175
- Result = ModRefInfo (Result & MRI_Ref );
176
+ Result = clearMod (Result);
176
177
else if (doesNotReadMemory (MRB))
177
- Result = ModRefInfo (Result & MRI_Mod );
178
+ Result = clearRef (Result);
178
179
179
180
if (onlyAccessesArgPointees (MRB) || onlyAccessesInaccessibleOrArgMem (MRB)) {
180
181
bool DoesAlias = false ;
@@ -190,20 +191,21 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS,
190
191
if (ArgAlias != NoAlias) {
191
192
ModRefInfo ArgMask = getArgModRefInfo (CS, ArgIdx);
192
193
DoesAlias = true ;
193
- AllArgsMask = ModRefInfo (AllArgsMask | ArgMask);
194
+ AllArgsMask = unionModRef (AllArgsMask, ArgMask);
194
195
}
195
196
}
196
197
}
198
+ // Return MRI_NoModRef if no alias found with any argument.
197
199
if (!DoesAlias)
198
200
return MRI_NoModRef;
199
- Result = ModRefInfo (Result & AllArgsMask);
201
+ // Logical & between other AA analyses and argument analysis.
202
+ Result = intersectModRef (Result, AllArgsMask);
200
203
}
201
204
202
205
// If Loc is a constant memory location, the call definitely could not
203
206
// 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);
207
209
208
210
return Result;
209
211
}
@@ -213,10 +215,10 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
213
215
ModRefInfo Result = MRI_ModRef;
214
216
215
217
for (const auto &AA : AAs) {
216
- Result = ModRefInfo (Result & AA->getModRefInfo (CS1, CS2));
218
+ Result = intersectModRef (Result, AA->getModRefInfo (CS1, CS2));
217
219
218
220
// Early-exit the moment we reach the bottom of the lattice.
219
- if (Result == MRI_NoModRef )
221
+ if (isNoModRef ( Result) )
220
222
return Result;
221
223
}
222
224
@@ -239,9 +241,9 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
239
241
// If CS1 only reads memory, the only dependence on CS2 can be
240
242
// from CS1 reading memory written by CS2.
241
243
if (onlyReadsMemory (CS1B))
242
- Result = ModRefInfo (Result & MRI_Ref );
244
+ Result = clearMod (Result);
243
245
else if (doesNotReadMemory (CS1B))
244
- Result = ModRefInfo (Result & MRI_Mod );
246
+ Result = clearRef (Result);
245
247
246
248
// If CS2 only access memory through arguments, accumulate the mod/ref
247
249
// information from CS1's references to the memory referenced by
@@ -256,17 +258,23 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
256
258
unsigned CS2ArgIdx = std::distance (CS2.arg_begin (), I);
257
259
auto CS2ArgLoc = MemoryLocation::getForArgument (CS2, CS2ArgIdx, TLI);
258
260
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))
263
268
ArgMask = MRI_ModRef;
264
- else if (ArgMask == MRI_Ref )
269
+ else if (isRefSet (ArgModRefCS2) )
265
270
ArgMask = MRI_Mod;
266
271
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);
268
276
269
- R = ModRefInfo ((R | ArgMask) & Result);
277
+ R = intersectModRef ( unionModRef (R, ArgMask), Result);
270
278
if (R == Result)
271
279
break ;
272
280
}
@@ -286,16 +294,14 @@ ModRefInfo AAResults::getModRefInfo(ImmutableCallSite CS1,
286
294
unsigned CS1ArgIdx = std::distance (CS1.arg_begin (), I);
287
295
auto CS1ArgLoc = MemoryLocation::getForArgument (CS1, CS1ArgIdx, TLI);
288
296
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);
299
305
300
306
if (R == Result)
301
307
break ;
@@ -456,7 +462,7 @@ ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW,
456
462
457
463
// / \brief Return information about whether a particular call site modifies
458
464
// / 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
460
466
// / instruction-ordering queries inside the BasicBlock containing \p I.
461
467
// / FIXME: this is really just shoring-up a deficiency in alias analysis.
462
468
// / BasicAA isn't willing to spend linear time determining whether an alloca
@@ -538,7 +544,7 @@ bool AAResults::canInstructionRangeModRef(const Instruction &I1,
538
544
++E; // Convert from inclusive to exclusive range.
539
545
540
546
for (; I != E; ++I) // Check every instruction in range
541
- if (getModRefInfo (&*I, Loc) & Mode)
547
+ if (intersectModRef ( getModRefInfo (&*I, Loc), Mode) )
542
548
return true ;
543
549
return false ;
544
550
}
0 commit comments