@@ -158,11 +158,16 @@ class ImplicitNullChecks : public MachineFunctionPass {
158
158
MachineBasicBlock *HandlerMBB);
159
159
void rewriteNullChecks (ArrayRef<NullCheck> NullCheckList);
160
160
161
- // / Is \p MI a memory operation that can be used to implicitly null check the
162
- // / value in \p PointerReg? \p PrevInsts is the set of instruction seen since
161
+ enum SuitabilityResult { SR_Suitable, SR_Unsuitable, SR_Impossible };
162
+
163
+ // / Return SR_Suitable if \p MI a memory operation that can be used to
164
+ // / implicitly null check the value in \p PointerReg, SR_Unsuitable if
165
+ // / \p MI cannot be used to null check and SR_Impossible if there is
166
+ // / no sense to continue lookup due to any other instruction will not be able
167
+ // / to be used. \p PrevInsts is the set of instruction seen since
163
168
// / the explicit null check on \p PointerReg.
164
- bool isSuitableMemoryOp (MachineInstr &MI, unsigned PointerReg,
165
- ArrayRef<MachineInstr *> PrevInsts);
169
+ SuitabilityResult isSuitableMemoryOp (MachineInstr &MI, unsigned PointerReg,
170
+ ArrayRef<MachineInstr *> PrevInsts);
166
171
167
172
// / Return true if \p FaultingMI can be hoisted from after the the
168
173
// / instructions in \p InstsSeenSoFar to before them. Set \p Dependence to a
@@ -283,30 +288,33 @@ static bool AnyAliasLiveIn(const TargetRegisterInfo *TRI,
283
288
return false ;
284
289
}
285
290
286
- bool ImplicitNullChecks::isSuitableMemoryOp (
287
- MachineInstr &MI, unsigned PointerReg, ArrayRef<MachineInstr *> PrevInsts) {
291
+ ImplicitNullChecks::SuitabilityResult
292
+ ImplicitNullChecks::isSuitableMemoryOp (MachineInstr &MI, unsigned PointerReg,
293
+ ArrayRef<MachineInstr *> PrevInsts) {
288
294
int64_t Offset;
289
295
unsigned BaseReg;
290
296
291
297
if (!TII->getMemOpBaseRegImmOfs (MI, BaseReg, Offset, TRI) ||
292
298
BaseReg != PointerReg)
293
- return false ;
299
+ return SR_Unsuitable ;
294
300
295
301
// We want the load to be issued at a sane offset from PointerReg, so that
296
302
// if PointerReg is null then the load reliably page faults.
297
303
if (!(MI.mayLoad () && !MI.isPredicable () && Offset < PageSize))
298
- return false ;
304
+ return SR_Unsuitable ;
299
305
300
306
// Finally, we need to make sure that the load instruction actually is
301
307
// loading from PointerReg, and there isn't some re-definition of PointerReg
302
308
// between the compare and the load.
309
+ // If PointerReg has been redefined before then there is no sense to continue
310
+ // lookup due to this condition will fail for any further instruction.
303
311
for (auto *PrevMI : PrevInsts)
304
312
for (auto &PrevMO : PrevMI->operands ())
305
313
if (PrevMO.isReg () && PrevMO.getReg () &&
306
314
TRI->regsOverlap (PrevMO.getReg (), PointerReg))
307
- return false ;
315
+ return SR_Impossible ;
308
316
309
- return true ;
317
+ return SR_Suitable ;
310
318
}
311
319
312
320
bool ImplicitNullChecks::canHoistLoadInst (
@@ -481,9 +489,11 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks(
481
489
return false ;
482
490
483
491
MachineInstr *Dependence;
484
- if (isSuitableMemoryOp (MI, PointerReg, InstsSeenSoFar) &&
485
- canHoistLoadInst (&MI, PointerReg, InstsSeenSoFar, NullSucc,
486
- Dependence)) {
492
+ SuitabilityResult SR = isSuitableMemoryOp (MI, PointerReg, InstsSeenSoFar);
493
+ if (SR == SR_Impossible)
494
+ return false ;
495
+ if (SR == SR_Suitable && canHoistLoadInst (&MI, PointerReg, InstsSeenSoFar,
496
+ NullSucc, Dependence)) {
487
497
NullCheckList.emplace_back (&MI, MBP.ConditionDef , &MBB, NotNullSucc,
488
498
NullSucc, Dependence);
489
499
return true ;
0 commit comments