1 //===- ImplicitNullChecks.cpp - Fold null checks into memory accesses -----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This pass turns explicit null checks of the form
18 // faulting_load_op("movl (%r10), %esi", throw_npe)
21 // With the help of a runtime that understands the .fault_maps section,
22 // faulting_load_op branches to throw_npe if executing movl (%r10), %esi incurs
24 // Store and LoadStore are also supported.
26 //===----------------------------------------------------------------------===//
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/None.h"
30 #include "llvm/ADT/Optional.h"
31 #include "llvm/ADT/STLExtras.h"
32 #include "llvm/ADT/SmallVector.h"
33 #include "llvm/ADT/Statistic.h"
34 #include "llvm/Analysis/AliasAnalysis.h"
35 #include "llvm/Analysis/MemoryLocation.h"
36 #include "llvm/CodeGen/FaultMaps.h"
37 #include "llvm/CodeGen/MachineBasicBlock.h"
38 #include "llvm/CodeGen/MachineFunction.h"
39 #include "llvm/CodeGen/MachineFunctionPass.h"
40 #include "llvm/CodeGen/MachineInstr.h"
41 #include "llvm/CodeGen/MachineInstrBuilder.h"
42 #include "llvm/CodeGen/MachineMemOperand.h"
43 #include "llvm/CodeGen/MachineOperand.h"
44 #include "llvm/CodeGen/MachineRegisterInfo.h"
45 #include "llvm/CodeGen/PseudoSourceValue.h"
46 #include "llvm/CodeGen/TargetInstrInfo.h"
47 #include "llvm/CodeGen/TargetOpcodes.h"
48 #include "llvm/CodeGen/TargetRegisterInfo.h"
49 #include "llvm/CodeGen/TargetSubtargetInfo.h"
50 #include "llvm/IR/BasicBlock.h"
51 #include "llvm/IR/DebugLoc.h"
52 #include "llvm/IR/LLVMContext.h"
53 #include "llvm/InitializePasses.h"
54 #include "llvm/MC/MCInstrDesc.h"
55 #include "llvm/MC/MCRegisterInfo.h"
56 #include "llvm/Pass.h"
57 #include "llvm/Support/CommandLine.h"
64 static cl::opt
<int> PageSize("imp-null-check-page-size",
65 cl::desc("The page size of the target in bytes"),
66 cl::init(4096), cl::Hidden
);
68 static cl::opt
<unsigned> MaxInstsToConsider(
69 "imp-null-max-insts-to-consider",
70 cl::desc("The max number of instructions to consider hoisting loads over "
71 "(the algorithm is quadratic over this number)"),
72 cl::Hidden
, cl::init(8));
74 #define DEBUG_TYPE "implicit-null-checks"
76 STATISTIC(NumImplicitNullChecks
,
77 "Number of explicit null checks made implicit");
81 class ImplicitNullChecks
: public MachineFunctionPass
{
82 /// Return true if \c computeDependence can process \p MI.
83 static bool canHandle(const MachineInstr
*MI
);
85 /// Helper function for \c computeDependence. Return true if \p A
86 /// and \p B do not have any dependences between them, and can be
87 /// re-ordered without changing program semantics.
88 bool canReorder(const MachineInstr
*A
, const MachineInstr
*B
);
90 /// A data type for representing the result computed by \c
91 /// computeDependence. States whether it is okay to reorder the
92 /// instruction passed to \c computeDependence with at most one
94 struct DependenceResult
{
95 /// Can we actually re-order \p MI with \p Insts (see \c
96 /// computeDependence).
99 /// If non-None, then an instruction in \p Insts that also must be
101 Optional
<ArrayRef
<MachineInstr
*>::iterator
> PotentialDependence
;
103 /*implicit*/ DependenceResult(
105 Optional
<ArrayRef
<MachineInstr
*>::iterator
> PotentialDependence
)
106 : CanReorder(CanReorder
), PotentialDependence(PotentialDependence
) {
107 assert((!PotentialDependence
|| CanReorder
) &&
108 "!CanReorder && PotentialDependence.hasValue() not allowed!");
112 /// Compute a result for the following question: can \p MI be
113 /// re-ordered from after \p Insts to before it.
115 /// \c canHandle should return true for all instructions in \p
117 DependenceResult
computeDependence(const MachineInstr
*MI
,
118 ArrayRef
<MachineInstr
*> Block
);
120 /// Represents one null check that can be made implicit.
122 // The memory operation the null check can be folded into.
123 MachineInstr
*MemOperation
;
125 // The instruction actually doing the null check (Ptr != 0).
126 MachineInstr
*CheckOperation
;
128 // The block the check resides in.
129 MachineBasicBlock
*CheckBlock
;
131 // The block branched to if the pointer is non-null.
132 MachineBasicBlock
*NotNullSucc
;
134 // The block branched to if the pointer is null.
135 MachineBasicBlock
*NullSucc
;
137 // If this is non-null, then MemOperation has a dependency on this
138 // instruction; and it needs to be hoisted to execute before MemOperation.
139 MachineInstr
*OnlyDependency
;
142 explicit NullCheck(MachineInstr
*memOperation
, MachineInstr
*checkOperation
,
143 MachineBasicBlock
*checkBlock
,
144 MachineBasicBlock
*notNullSucc
,
145 MachineBasicBlock
*nullSucc
,
146 MachineInstr
*onlyDependency
)
147 : MemOperation(memOperation
), CheckOperation(checkOperation
),
148 CheckBlock(checkBlock
), NotNullSucc(notNullSucc
), NullSucc(nullSucc
),
149 OnlyDependency(onlyDependency
) {}
151 MachineInstr
*getMemOperation() const { return MemOperation
; }
153 MachineInstr
*getCheckOperation() const { return CheckOperation
; }
155 MachineBasicBlock
*getCheckBlock() const { return CheckBlock
; }
157 MachineBasicBlock
*getNotNullSucc() const { return NotNullSucc
; }
159 MachineBasicBlock
*getNullSucc() const { return NullSucc
; }
161 MachineInstr
*getOnlyDependency() const { return OnlyDependency
; }
164 const TargetInstrInfo
*TII
= nullptr;
165 const TargetRegisterInfo
*TRI
= nullptr;
166 AliasAnalysis
*AA
= nullptr;
167 MachineFrameInfo
*MFI
= nullptr;
169 bool analyzeBlockForNullChecks(MachineBasicBlock
&MBB
,
170 SmallVectorImpl
<NullCheck
> &NullCheckList
);
171 MachineInstr
*insertFaultingInstr(MachineInstr
*MI
, MachineBasicBlock
*MBB
,
172 MachineBasicBlock
*HandlerMBB
);
173 void rewriteNullChecks(ArrayRef
<NullCheck
> NullCheckList
);
178 AR_WillAliasEverything
181 /// Returns AR_NoAlias if \p MI memory operation does not alias with
182 /// \p PrevMI, AR_MayAlias if they may alias and AR_WillAliasEverything if
183 /// they may alias and any further memory operation may alias with \p PrevMI.
184 AliasResult
areMemoryOpsAliased(const MachineInstr
&MI
,
185 const MachineInstr
*PrevMI
) const;
187 enum SuitabilityResult
{
193 /// Return SR_Suitable if \p MI a memory operation that can be used to
194 /// implicitly null check the value in \p PointerReg, SR_Unsuitable if
195 /// \p MI cannot be used to null check and SR_Impossible if there is
196 /// no sense to continue lookup due to any other instruction will not be able
197 /// to be used. \p PrevInsts is the set of instruction seen since
198 /// the explicit null check on \p PointerReg.
199 SuitabilityResult
isSuitableMemoryOp(const MachineInstr
&MI
,
201 ArrayRef
<MachineInstr
*> PrevInsts
);
203 /// Returns true if \p DependenceMI can clobber the liveIns in NullSucc block
204 /// if it was hoisted to the NullCheck block. This is used by caller
205 /// canHoistInst to decide if DependenceMI can be hoisted safely.
206 bool canDependenceHoistingClobberLiveIns(MachineInstr
*DependenceMI
,
207 MachineBasicBlock
*NullSucc
);
209 /// Return true if \p FaultingMI can be hoisted from after the
210 /// instructions in \p InstsSeenSoFar to before them. Set \p Dependence to a
211 /// non-null value if we also need to (and legally can) hoist a dependency.
212 bool canHoistInst(MachineInstr
*FaultingMI
,
213 ArrayRef
<MachineInstr
*> InstsSeenSoFar
,
214 MachineBasicBlock
*NullSucc
, MachineInstr
*&Dependence
);
219 ImplicitNullChecks() : MachineFunctionPass(ID
) {
220 initializeImplicitNullChecksPass(*PassRegistry::getPassRegistry());
223 bool runOnMachineFunction(MachineFunction
&MF
) override
;
225 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
226 AU
.addRequired
<AAResultsWrapperPass
>();
227 MachineFunctionPass::getAnalysisUsage(AU
);
230 MachineFunctionProperties
getRequiredProperties() const override
{
231 return MachineFunctionProperties().set(
232 MachineFunctionProperties::Property::NoVRegs
);
236 } // end anonymous namespace
238 bool ImplicitNullChecks::canHandle(const MachineInstr
*MI
) {
239 if (MI
->isCall() || MI
->mayRaiseFPException() ||
240 MI
->hasUnmodeledSideEffects())
242 auto IsRegMask
= [](const MachineOperand
&MO
) { return MO
.isRegMask(); };
245 assert(llvm::none_of(MI
->operands(), IsRegMask
) &&
246 "Calls were filtered out above!");
248 auto IsUnordered
= [](MachineMemOperand
*MMO
) { return MMO
->isUnordered(); };
249 return llvm::all_of(MI
->memoperands(), IsUnordered
);
252 ImplicitNullChecks::DependenceResult
253 ImplicitNullChecks::computeDependence(const MachineInstr
*MI
,
254 ArrayRef
<MachineInstr
*> Block
) {
255 assert(llvm::all_of(Block
, canHandle
) && "Check this first!");
256 assert(!is_contained(Block
, MI
) && "Block must be exclusive of MI!");
258 Optional
<ArrayRef
<MachineInstr
*>::iterator
> Dep
;
260 for (auto I
= Block
.begin(), E
= Block
.end(); I
!= E
; ++I
) {
261 if (canReorder(*I
, MI
))
265 // Found one possible dependency, keep track of it.
268 // We found two dependencies, so bail out.
269 return {false, None
};
276 bool ImplicitNullChecks::canReorder(const MachineInstr
*A
,
277 const MachineInstr
*B
) {
278 assert(canHandle(A
) && canHandle(B
) && "Precondition!");
280 // canHandle makes sure that we _can_ correctly analyze the dependencies
281 // between A and B here -- for instance, we should not be dealing with heap
282 // load-store dependencies here.
284 for (const auto &MOA
: A
->operands()) {
285 if (!(MOA
.isReg() && MOA
.getReg()))
288 Register RegA
= MOA
.getReg();
289 for (const auto &MOB
: B
->operands()) {
290 if (!(MOB
.isReg() && MOB
.getReg()))
293 Register RegB
= MOB
.getReg();
295 if (TRI
->regsOverlap(RegA
, RegB
) && (MOA
.isDef() || MOB
.isDef()))
303 bool ImplicitNullChecks::runOnMachineFunction(MachineFunction
&MF
) {
304 TII
= MF
.getSubtarget().getInstrInfo();
305 TRI
= MF
.getRegInfo().getTargetRegisterInfo();
306 MFI
= &MF
.getFrameInfo();
307 AA
= &getAnalysis
<AAResultsWrapperPass
>().getAAResults();
309 SmallVector
<NullCheck
, 16> NullCheckList
;
312 analyzeBlockForNullChecks(MBB
, NullCheckList
);
314 if (!NullCheckList
.empty())
315 rewriteNullChecks(NullCheckList
);
317 return !NullCheckList
.empty();
320 // Return true if any register aliasing \p Reg is live-in into \p MBB.
321 static bool AnyAliasLiveIn(const TargetRegisterInfo
*TRI
,
322 MachineBasicBlock
*MBB
, unsigned Reg
) {
323 for (MCRegAliasIterator
AR(Reg
, TRI
, /*IncludeSelf*/ true); AR
.isValid();
325 if (MBB
->isLiveIn(*AR
))
330 ImplicitNullChecks::AliasResult
331 ImplicitNullChecks::areMemoryOpsAliased(const MachineInstr
&MI
,
332 const MachineInstr
*PrevMI
) const {
333 // If it is not memory access, skip the check.
334 if (!(PrevMI
->mayStore() || PrevMI
->mayLoad()))
336 // Load-Load may alias
337 if (!(MI
.mayStore() || PrevMI
->mayStore()))
339 // We lost info, conservatively alias. If it was store then no sense to
340 // continue because we won't be able to check against it further.
341 if (MI
.memoperands_empty())
342 return MI
.mayStore() ? AR_WillAliasEverything
: AR_MayAlias
;
343 if (PrevMI
->memoperands_empty())
344 return PrevMI
->mayStore() ? AR_WillAliasEverything
: AR_MayAlias
;
346 for (MachineMemOperand
*MMO1
: MI
.memoperands()) {
347 // MMO1 should have a value due it comes from operation we'd like to use
348 // as implicit null check.
349 assert(MMO1
->getValue() && "MMO1 should have a Value!");
350 for (MachineMemOperand
*MMO2
: PrevMI
->memoperands()) {
351 if (const PseudoSourceValue
*PSV
= MMO2
->getPseudoValue()) {
352 if (PSV
->mayAlias(MFI
))
357 MemoryLocation::getAfter(MMO1
->getValue(), MMO1
->getAAInfo()),
358 MemoryLocation::getAfter(MMO2
->getValue(), MMO2
->getAAInfo())))
365 ImplicitNullChecks::SuitabilityResult
366 ImplicitNullChecks::isSuitableMemoryOp(const MachineInstr
&MI
,
368 ArrayRef
<MachineInstr
*> PrevInsts
) {
369 // Implementation restriction for faulting_op insertion
370 // TODO: This could be relaxed if we find a test case which warrants it.
371 if (MI
.getDesc().getNumDefs() > 1)
372 return SR_Unsuitable
;
374 if (!MI
.mayLoadOrStore() || MI
.isPredicable())
375 return SR_Unsuitable
;
376 auto AM
= TII
->getAddrModeFromMemoryOp(MI
, TRI
);
378 return SR_Unsuitable
;
380 const Register BaseReg
= AddrMode
.BaseReg
, ScaledReg
= AddrMode
.ScaledReg
;
381 int64_t Displacement
= AddrMode
.Displacement
;
383 // We need the base of the memory instruction to be same as the register
384 // where the null check is performed (i.e. PointerReg).
385 if (BaseReg
!= PointerReg
&& ScaledReg
!= PointerReg
)
386 return SR_Unsuitable
;
387 const MachineRegisterInfo
&MRI
= MI
.getMF()->getRegInfo();
388 unsigned PointerRegSizeInBits
= TRI
->getRegSizeInBits(PointerReg
, MRI
);
389 // Bail out of the sizes of BaseReg, ScaledReg and PointerReg are not the
392 TRI
->getRegSizeInBits(BaseReg
, MRI
) != PointerRegSizeInBits
) ||
394 TRI
->getRegSizeInBits(ScaledReg
, MRI
) != PointerRegSizeInBits
))
395 return SR_Unsuitable
;
397 // Returns true if RegUsedInAddr is used for calculating the displacement
398 // depending on addressing mode. Also calculates the Displacement.
399 auto CalculateDisplacementFromAddrMode
= [&](Register RegUsedInAddr
,
400 int64_t Multiplier
) {
401 // The register can be NoRegister, which is defined as zero for all targets.
402 // Consider instruction of interest as `movq 8(,%rdi,8), %rax`. Here the
403 // ScaledReg is %rdi, while there is no BaseReg.
406 assert(Multiplier
&& "expected to be non-zero!");
407 MachineInstr
*ModifyingMI
= nullptr;
408 for (auto It
= std::next(MachineBasicBlock::const_reverse_iterator(&MI
));
409 It
!= MI
.getParent()->rend(); It
++) {
410 const MachineInstr
*CurrMI
= &*It
;
411 if (CurrMI
->modifiesRegister(RegUsedInAddr
, TRI
)) {
412 ModifyingMI
= const_cast<MachineInstr
*>(CurrMI
);
418 // Check for the const value defined in register by ModifyingMI. This means
419 // all other previous values for that register has been invalidated.
421 if (!TII
->getConstValDefinedInReg(*ModifyingMI
, RegUsedInAddr
, ImmVal
))
423 // Calculate the reg size in bits, since this is needed for bailing out in
425 int32_t RegSizeInBits
= TRI
->getRegSizeInBits(RegUsedInAddr
, MRI
);
426 APInt
ImmValC(RegSizeInBits
, ImmVal
, true /*IsSigned*/);
427 APInt
MultiplierC(RegSizeInBits
, Multiplier
);
428 assert(MultiplierC
.isStrictlyPositive() &&
429 "expected to be a positive value!");
431 // Sign of the product depends on the sign of the ImmVal, since Multiplier
432 // is always positive.
433 APInt Product
= ImmValC
.smul_ov(MultiplierC
, IsOverflow
);
436 APInt
DisplacementC(64, Displacement
, true /*isSigned*/);
437 DisplacementC
= Product
.sadd_ov(DisplacementC
, IsOverflow
);
441 // We only handle diplacements upto 64 bits wide.
442 if (DisplacementC
.getActiveBits() > 64)
444 Displacement
= DisplacementC
.getSExtValue();
448 // If a register used in the address is constant, fold it's effect into the
449 // displacement for ease of analysis.
450 bool BaseRegIsConstVal
= false, ScaledRegIsConstVal
= false;
451 if (CalculateDisplacementFromAddrMode(BaseReg
, 1))
452 BaseRegIsConstVal
= true;
453 if (CalculateDisplacementFromAddrMode(ScaledReg
, AddrMode
.Scale
))
454 ScaledRegIsConstVal
= true;
456 // The register which is not null checked should be part of the Displacement
457 // calculation, otherwise we do not know whether the Displacement is made up
458 // by some symbolic values.
459 // This matters because we do not want to incorrectly assume that load from
460 // falls in the zeroth faulting page in the "sane offset check" below.
461 if ((BaseReg
&& BaseReg
!= PointerReg
&& !BaseRegIsConstVal
) ||
462 (ScaledReg
&& ScaledReg
!= PointerReg
&& !ScaledRegIsConstVal
))
463 return SR_Unsuitable
;
465 // We want the mem access to be issued at a sane offset from PointerReg,
466 // so that if PointerReg is null then the access reliably page faults.
467 if (!(-PageSize
< Displacement
&& Displacement
< PageSize
))
468 return SR_Unsuitable
;
470 // Finally, check whether the current memory access aliases with previous one.
471 for (auto *PrevMI
: PrevInsts
) {
472 AliasResult AR
= areMemoryOpsAliased(MI
, PrevMI
);
473 if (AR
== AR_WillAliasEverything
)
474 return SR_Impossible
;
475 if (AR
== AR_MayAlias
)
476 return SR_Unsuitable
;
481 bool ImplicitNullChecks::canDependenceHoistingClobberLiveIns(
482 MachineInstr
*DependenceMI
, MachineBasicBlock
*NullSucc
) {
483 for (const auto &DependenceMO
: DependenceMI
->operands()) {
484 if (!(DependenceMO
.isReg() && DependenceMO
.getReg()))
487 // Make sure that we won't clobber any live ins to the sibling block by
488 // hoisting Dependency. For instance, we can't hoist INST to before the
489 // null check (even if it safe, and does not violate any dependencies in
490 // the non_null_block) if %rdx is live in to _null_block.
498 // This restriction does not apply to the faulting load inst because in
499 // case the pointer loaded from is in the null page, the load will not
500 // semantically execute, and affect machine state. That is, if the load
501 // was loading into %rax and it faults, the value of %rax should stay the
502 // same as it would have been had the load not have executed and we'd have
503 // branched to NullSucc directly.
504 if (AnyAliasLiveIn(TRI
, NullSucc
, DependenceMO
.getReg()))
509 // The dependence does not clobber live-ins in NullSucc block.
513 bool ImplicitNullChecks::canHoistInst(MachineInstr
*FaultingMI
,
514 ArrayRef
<MachineInstr
*> InstsSeenSoFar
,
515 MachineBasicBlock
*NullSucc
,
516 MachineInstr
*&Dependence
) {
517 auto DepResult
= computeDependence(FaultingMI
, InstsSeenSoFar
);
518 if (!DepResult
.CanReorder
)
521 if (!DepResult
.PotentialDependence
) {
522 Dependence
= nullptr;
526 auto DependenceItr
= *DepResult
.PotentialDependence
;
527 auto *DependenceMI
= *DependenceItr
;
529 // We don't want to reason about speculating loads. Note -- at this point
530 // we should have already filtered out all of the other non-speculatable
531 // things, like calls and stores.
532 // We also do not want to hoist stores because it might change the memory
533 // while the FaultingMI may result in faulting.
534 assert(canHandle(DependenceMI
) && "Should never have reached here!");
535 if (DependenceMI
->mayLoadOrStore())
538 if (canDependenceHoistingClobberLiveIns(DependenceMI
, NullSucc
))
542 computeDependence(DependenceMI
, {InstsSeenSoFar
.begin(), DependenceItr
});
544 if (!DepDepResult
.CanReorder
|| DepDepResult
.PotentialDependence
)
547 Dependence
= DependenceMI
;
551 /// Analyze MBB to check if its terminating branch can be turned into an
552 /// implicit null check. If yes, append a description of the said null check to
553 /// NullCheckList and return true, else return false.
554 bool ImplicitNullChecks::analyzeBlockForNullChecks(
555 MachineBasicBlock
&MBB
, SmallVectorImpl
<NullCheck
> &NullCheckList
) {
556 using MachineBranchPredicate
= TargetInstrInfo::MachineBranchPredicate
;
558 MDNode
*BranchMD
= nullptr;
559 if (auto *BB
= MBB
.getBasicBlock())
560 BranchMD
= BB
->getTerminator()->getMetadata(LLVMContext::MD_make_implicit
);
565 MachineBranchPredicate MBP
;
567 if (TII
->analyzeBranchPredicate(MBB
, MBP
, true))
570 // Is the predicate comparing an integer to zero?
571 if (!(MBP
.LHS
.isReg() && MBP
.RHS
.isImm() && MBP
.RHS
.getImm() == 0 &&
572 (MBP
.Predicate
== MachineBranchPredicate::PRED_NE
||
573 MBP
.Predicate
== MachineBranchPredicate::PRED_EQ
)))
576 // If there is a separate condition generation instruction, we chose not to
577 // transform unless we can remove both condition and consuming branch.
578 if (MBP
.ConditionDef
&& !MBP
.SingleUseCondition
)
581 MachineBasicBlock
*NotNullSucc
, *NullSucc
;
583 if (MBP
.Predicate
== MachineBranchPredicate::PRED_NE
) {
584 NotNullSucc
= MBP
.TrueDest
;
585 NullSucc
= MBP
.FalseDest
;
587 NotNullSucc
= MBP
.FalseDest
;
588 NullSucc
= MBP
.TrueDest
;
591 // We handle the simplest case for now. We can potentially do better by using
592 // the machine dominator tree.
593 if (NotNullSucc
->pred_size() != 1)
596 const Register PointerReg
= MBP
.LHS
.getReg();
598 if (MBP
.ConditionDef
) {
599 // To prevent the invalid transformation of the following code:
612 // faulting_load_op("movl (%rax), %r10", throw_npe)
615 // we must ensure that there are no instructions between the 'test' and
616 // conditional jump that modify %rax.
617 assert(MBP
.ConditionDef
->getParent() == &MBB
&&
618 "Should be in basic block");
620 for (auto I
= MBB
.rbegin(); MBP
.ConditionDef
!= &*I
; ++I
)
621 if (I
->modifiesRegister(PointerReg
, TRI
))
624 // Starting with a code fragment like:
630 // callq throw_NullPointerException
636 // Def = Load (%rax + <offset>)
640 // we want to end up with
642 // Def = FaultingLoad (%rax + <offset>), LblNull
643 // jmp LblNotNull ;; explicit or fallthrough
651 // callq throw_NullPointerException
654 // To see why this is legal, consider the two possibilities:
656 // 1. %rax is null: since we constrain <offset> to be less than PageSize, the
657 // load instruction dereferences the null page, causing a segmentation
660 // 2. %rax is not null: in this case we know that the load cannot fault, as
661 // otherwise the load would've faulted in the original program too and the
662 // original program would've been undefined.
664 // This reasoning cannot be extended to justify hoisting through arbitrary
665 // control flow. For instance, in the example below (in pseudo-C)
667 // if (ptr == null) { throw_npe(); unreachable; }
668 // if (some_cond) { return 42; }
669 // v = ptr->field; // LD
672 // we cannot (without code duplication) use the load marked "LD" to null check
673 // ptr -- clause (2) above does not apply in this case. In the above program
674 // the safety of ptr->field can be dependent on some_cond; and, for instance,
675 // ptr could be some non-null invalid reference that never gets loaded from
676 // because some_cond is always true.
678 SmallVector
<MachineInstr
*, 8> InstsSeenSoFar
;
680 for (auto &MI
: *NotNullSucc
) {
681 if (!canHandle(&MI
) || InstsSeenSoFar
.size() >= MaxInstsToConsider
)
684 MachineInstr
*Dependence
;
685 SuitabilityResult SR
= isSuitableMemoryOp(MI
, PointerReg
, InstsSeenSoFar
);
686 if (SR
== SR_Impossible
)
688 if (SR
== SR_Suitable
&&
689 canHoistInst(&MI
, InstsSeenSoFar
, NullSucc
, Dependence
)) {
690 NullCheckList
.emplace_back(&MI
, MBP
.ConditionDef
, &MBB
, NotNullSucc
,
691 NullSucc
, Dependence
);
695 // If MI re-defines the PointerReg in a way that changes the value of
696 // PointerReg if it was null, then we cannot move further.
697 if (!TII
->preservesZeroValueInReg(&MI
, PointerReg
, TRI
))
699 InstsSeenSoFar
.push_back(&MI
);
705 /// Wrap a machine instruction, MI, into a FAULTING machine instruction.
706 /// The FAULTING instruction does the same load/store as MI
707 /// (defining the same register), and branches to HandlerMBB if the mem access
708 /// faults. The FAULTING instruction is inserted at the end of MBB.
709 MachineInstr
*ImplicitNullChecks::insertFaultingInstr(
710 MachineInstr
*MI
, MachineBasicBlock
*MBB
, MachineBasicBlock
*HandlerMBB
) {
711 const unsigned NoRegister
= 0; // Guaranteed to be the NoRegister value for
715 unsigned NumDefs
= MI
->getDesc().getNumDefs();
716 assert(NumDefs
<= 1 && "other cases unhandled!");
718 unsigned DefReg
= NoRegister
;
720 DefReg
= MI
->getOperand(0).getReg();
721 assert(NumDefs
== 1 && "expected exactly one def!");
724 FaultMaps::FaultKind FK
;
727 MI
->mayStore() ? FaultMaps::FaultingLoadStore
: FaultMaps::FaultingLoad
;
729 FK
= FaultMaps::FaultingStore
;
731 auto MIB
= BuildMI(MBB
, DL
, TII
->get(TargetOpcode::FAULTING_OP
), DefReg
)
734 .addImm(MI
->getOpcode());
736 for (auto &MO
: MI
->uses()) {
738 MachineOperand NewMO
= MO
;
740 NewMO
.setIsKill(false);
742 assert(MO
.isDef() && "Expected def or use");
743 NewMO
.setIsDead(false);
751 MIB
.setMemRefs(MI
->memoperands());
756 /// Rewrite the null checks in NullCheckList into implicit null checks.
757 void ImplicitNullChecks::rewriteNullChecks(
758 ArrayRef
<ImplicitNullChecks::NullCheck
> NullCheckList
) {
761 for (auto &NC
: NullCheckList
) {
762 // Remove the conditional branch dependent on the null check.
763 unsigned BranchesRemoved
= TII
->removeBranch(*NC
.getCheckBlock());
764 (void)BranchesRemoved
;
765 assert(BranchesRemoved
> 0 && "expected at least one branch!");
767 if (auto *DepMI
= NC
.getOnlyDependency()) {
768 DepMI
->removeFromParent();
769 NC
.getCheckBlock()->insert(NC
.getCheckBlock()->end(), DepMI
);
772 // Insert a faulting instruction where the conditional branch was
773 // originally. We check earlier ensures that this bit of code motion
774 // is legal. We do not touch the successors list for any basic block
775 // since we haven't changed control flow, we've just made it implicit.
776 MachineInstr
*FaultingInstr
= insertFaultingInstr(
777 NC
.getMemOperation(), NC
.getCheckBlock(), NC
.getNullSucc());
778 // Now the values defined by MemOperation, if any, are live-in of
779 // the block of MemOperation.
780 // The original operation may define implicit-defs alongside
782 MachineBasicBlock
*MBB
= NC
.getMemOperation()->getParent();
783 for (const MachineOperand
&MO
: FaultingInstr
->operands()) {
784 if (!MO
.isReg() || !MO
.isDef())
786 Register Reg
= MO
.getReg();
787 if (!Reg
|| MBB
->isLiveIn(Reg
))
792 if (auto *DepMI
= NC
.getOnlyDependency()) {
793 for (auto &MO
: DepMI
->operands()) {
794 if (!MO
.isReg() || !MO
.getReg() || !MO
.isDef() || MO
.isDead())
796 if (!NC
.getNotNullSucc()->isLiveIn(MO
.getReg()))
797 NC
.getNotNullSucc()->addLiveIn(MO
.getReg());
801 NC
.getMemOperation()->eraseFromParent();
802 if (auto *CheckOp
= NC
.getCheckOperation())
803 CheckOp
->eraseFromParent();
805 // Insert an *unconditional* branch to not-null successor - we expect
806 // block placement to remove fallthroughs later.
807 TII
->insertBranch(*NC
.getCheckBlock(), NC
.getNotNullSucc(), nullptr,
810 NumImplicitNullChecks
++;
814 char ImplicitNullChecks::ID
= 0;
816 char &llvm::ImplicitNullChecksID
= ImplicitNullChecks::ID
;
818 INITIALIZE_PASS_BEGIN(ImplicitNullChecks
, DEBUG_TYPE
,
819 "Implicit null checks", false, false)
820 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass
)
821 INITIALIZE_PASS_END(ImplicitNullChecks
, DEBUG_TYPE
,
822 "Implicit null checks", false, false)