blob: 19c52d013749ec826176833be178710d42f84f6f [file] [log] [blame]
Eugene Zelenko900b6332017-08-29 22:32:07 +00001//===- ImplicitNullChecks.cpp - Fold null checks into memory accesses -----===//
Sanjoy Das69fad072015-06-15 18:44:27 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass turns explicit null checks of the form
11//
12// test %r10, %r10
13// je throw_npe
14// movl (%r10), %esi
15// ...
16//
17// to
18//
19// faulting_load_op("movl (%r10), %esi", throw_npe)
20// ...
21//
22// With the help of a runtime that understands the .fault_maps section,
23// faulting_load_op branches to throw_npe if executing movl (%r10), %esi incurs
24// a page fault.
Serguei Katkov51c220c2017-04-12 04:41:35 +000025// Store and LoadStore are also supported.
Sanjoy Das69fad072015-06-15 18:44:27 +000026//
27//===----------------------------------------------------------------------===//
28
Eugene Zelenko900b6332017-08-29 22:32:07 +000029#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/None.h"
31#include "llvm/ADT/Optional.h"
32#include "llvm/ADT/STLExtras.h"
Sanjoy Das69fad072015-06-15 18:44:27 +000033#include "llvm/ADT/SmallVector.h"
Sanjoy Das8ee6a302015-07-06 23:32:10 +000034#include "llvm/ADT/Statistic.h"
Sanjoy Dase57bf682016-06-22 22:16:51 +000035#include "llvm/Analysis/AliasAnalysis.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000036#include "llvm/Analysis/MemoryLocation.h"
Sanjoy Das2f63cbc2017-02-07 19:19:49 +000037#include "llvm/CodeGen/FaultMaps.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000038#include "llvm/CodeGen/MachineBasicBlock.h"
Sanjoy Das69fad072015-06-15 18:44:27 +000039#include "llvm/CodeGen/MachineFunction.h"
Sanjoy Das69fad072015-06-15 18:44:27 +000040#include "llvm/CodeGen/MachineFunctionPass.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000041#include "llvm/CodeGen/MachineInstr.h"
Sanjoy Das69fad072015-06-15 18:44:27 +000042#include "llvm/CodeGen/MachineInstrBuilder.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000043#include "llvm/CodeGen/MachineMemOperand.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000044#include "llvm/CodeGen/MachineOperand.h"
45#include "llvm/CodeGen/MachineRegisterInfo.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000046#include "llvm/CodeGen/PseudoSourceValue.h"
Sanjoy Das69fad072015-06-15 18:44:27 +000047#include "llvm/IR/BasicBlock.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000048#include "llvm/IR/DebugLoc.h"
Chen Li00038782015-08-04 04:41:34 +000049#include "llvm/IR/LLVMContext.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000050#include "llvm/MC/MCInstrDesc.h"
51#include "llvm/MC/MCRegisterInfo.h"
52#include "llvm/Pass.h"
Sanjoy Das69fad072015-06-15 18:44:27 +000053#include "llvm/Support/CommandLine.h"
Sanjoy Das69fad072015-06-15 18:44:27 +000054#include "llvm/Target/TargetInstrInfo.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000055#include "llvm/Target/TargetOpcodes.h"
56#include "llvm/Target/TargetRegisterInfo.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000057#include "llvm/Target/TargetSubtargetInfo.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000058#include <cassert>
59#include <cstdint>
60#include <iterator>
Sanjoy Das69fad072015-06-15 18:44:27 +000061
62using namespace llvm;
63
Chad Rosierc27a18f2016-03-09 16:00:35 +000064static cl::opt<int> PageSize("imp-null-check-page-size",
65 cl::desc("The page size of the target in bytes"),
66 cl::init(4096));
Sanjoy Das69fad072015-06-15 18:44:27 +000067
Sanjoy Das9a129802016-12-23 00:41:21 +000068static 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::init(8));
73
Sanjoy Das8ee6a302015-07-06 23:32:10 +000074#define DEBUG_TYPE "implicit-null-checks"
75
76STATISTIC(NumImplicitNullChecks,
77 "Number of explicit null checks made implicit");
78
Sanjoy Das69fad072015-06-15 18:44:27 +000079namespace {
80
81class ImplicitNullChecks : public MachineFunctionPass {
Sanjoy Das9a129802016-12-23 00:41:21 +000082 /// Return true if \c computeDependence can process \p MI.
83 static bool canHandle(const MachineInstr *MI);
84
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);
89
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
93 /// depednency.
94 struct DependenceResult {
95 /// Can we actually re-order \p MI with \p Insts (see \c
96 /// computeDependence).
97 bool CanReorder;
98
99 /// If non-None, then an instruction in \p Insts that also must be
100 /// hoisted.
101 Optional<ArrayRef<MachineInstr *>::iterator> PotentialDependence;
102
103 /*implicit*/ DependenceResult(
104 bool CanReorder,
105 Optional<ArrayRef<MachineInstr *>::iterator> PotentialDependence)
106 : CanReorder(CanReorder), PotentialDependence(PotentialDependence) {
107 assert((!PotentialDependence || CanReorder) &&
108 "!CanReorder && PotentialDependence.hasValue() not allowed!");
109 }
110 };
111
112 /// Compute a result for the following question: can \p MI be
113 /// re-ordered from after \p Insts to before it.
114 ///
115 /// \c canHandle should return true for all instructions in \p
116 /// Insts.
117 DependenceResult computeDependence(const MachineInstr *MI,
118 ArrayRef<MachineInstr *> Insts);
119
Sanjoy Das69fad072015-06-15 18:44:27 +0000120 /// Represents one null check that can be made implicit.
Sanjoy Dase173b9a2016-06-21 02:10:18 +0000121 class NullCheck {
Sanjoy Das69fad072015-06-15 18:44:27 +0000122 // The memory operation the null check can be folded into.
123 MachineInstr *MemOperation;
124
125 // The instruction actually doing the null check (Ptr != 0).
126 MachineInstr *CheckOperation;
127
128 // The block the check resides in.
129 MachineBasicBlock *CheckBlock;
130
Eric Christopher572e03a2015-06-19 01:53:21 +0000131 // The block branched to if the pointer is non-null.
Sanjoy Das69fad072015-06-15 18:44:27 +0000132 MachineBasicBlock *NotNullSucc;
133
Eric Christopher572e03a2015-06-19 01:53:21 +0000134 // The block branched to if the pointer is null.
Sanjoy Das69fad072015-06-15 18:44:27 +0000135 MachineBasicBlock *NullSucc;
136
Sanjoy Dase57bf682016-06-22 22:16:51 +0000137 // If this is non-null, then MemOperation has a dependency on on this
138 // instruction; and it needs to be hoisted to execute before MemOperation.
139 MachineInstr *OnlyDependency;
140
Sanjoy Dase173b9a2016-06-21 02:10:18 +0000141 public:
Sanjoy Das69fad072015-06-15 18:44:27 +0000142 explicit NullCheck(MachineInstr *memOperation, MachineInstr *checkOperation,
143 MachineBasicBlock *checkBlock,
144 MachineBasicBlock *notNullSucc,
Sanjoy Dase57bf682016-06-22 22:16:51 +0000145 MachineBasicBlock *nullSucc,
146 MachineInstr *onlyDependency)
Sanjoy Das69fad072015-06-15 18:44:27 +0000147 : MemOperation(memOperation), CheckOperation(checkOperation),
Sanjoy Dase57bf682016-06-22 22:16:51 +0000148 CheckBlock(checkBlock), NotNullSucc(notNullSucc), NullSucc(nullSucc),
149 OnlyDependency(onlyDependency) {}
Sanjoy Dase173b9a2016-06-21 02:10:18 +0000150
151 MachineInstr *getMemOperation() const { return MemOperation; }
152
153 MachineInstr *getCheckOperation() const { return CheckOperation; }
154
155 MachineBasicBlock *getCheckBlock() const { return CheckBlock; }
156
157 MachineBasicBlock *getNotNullSucc() const { return NotNullSucc; }
158
159 MachineBasicBlock *getNullSucc() const { return NullSucc; }
Sanjoy Dase57bf682016-06-22 22:16:51 +0000160
161 MachineInstr *getOnlyDependency() const { return OnlyDependency; }
Sanjoy Das69fad072015-06-15 18:44:27 +0000162 };
163
164 const TargetInstrInfo *TII = nullptr;
165 const TargetRegisterInfo *TRI = nullptr;
Sanjoy Dase57bf682016-06-22 22:16:51 +0000166 AliasAnalysis *AA = nullptr;
Sanjoy Daseef785c2017-02-28 07:04:49 +0000167 MachineFrameInfo *MFI = nullptr;
Sanjoy Das69fad072015-06-15 18:44:27 +0000168
169 bool analyzeBlockForNullChecks(MachineBasicBlock &MBB,
170 SmallVectorImpl<NullCheck> &NullCheckList);
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000171 MachineInstr *insertFaultingInstr(MachineInstr *MI, MachineBasicBlock *MBB,
172 MachineBasicBlock *HandlerMBB);
Sanjoy Das69fad072015-06-15 18:44:27 +0000173 void rewriteNullChecks(ArrayRef<NullCheck> NullCheckList);
174
Sanjoy Daseef785c2017-02-28 07:04:49 +0000175 enum AliasResult {
176 AR_NoAlias,
177 AR_MayAlias,
178 AR_WillAliasEverything
179 };
Eugene Zelenko900b6332017-08-29 22:32:07 +0000180
Sanjoy Daseef785c2017-02-28 07:04:49 +0000181 /// 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(MachineInstr &MI, MachineInstr *PrevMI);
Sanjoy Das15e50b52017-02-01 02:49:25 +0000185
Sanjoy Daseef785c2017-02-28 07:04:49 +0000186 enum SuitabilityResult {
187 SR_Suitable,
188 SR_Unsuitable,
189 SR_Impossible
190 };
Eugene Zelenko900b6332017-08-29 22:32:07 +0000191
Sanjoy Das15e50b52017-02-01 02:49:25 +0000192 /// Return SR_Suitable if \p MI a memory operation that can be used to
193 /// implicitly null check the value in \p PointerReg, SR_Unsuitable if
194 /// \p MI cannot be used to null check and SR_Impossible if there is
195 /// no sense to continue lookup due to any other instruction will not be able
196 /// to be used. \p PrevInsts is the set of instruction seen since
Sanjoy Daseef785c2017-02-28 07:04:49 +0000197 /// the explicit null check on \p PointerReg.
Sanjoy Das15e50b52017-02-01 02:49:25 +0000198 SuitabilityResult isSuitableMemoryOp(MachineInstr &MI, unsigned PointerReg,
Sanjoy Daseef785c2017-02-28 07:04:49 +0000199 ArrayRef<MachineInstr *> PrevInsts);
Sanjoy Das50fef432016-12-23 00:41:24 +0000200
201 /// Return true if \p FaultingMI can be hoisted from after the the
202 /// instructions in \p InstsSeenSoFar to before them. Set \p Dependence to a
203 /// non-null value if we also need to (and legally can) hoist a depedency.
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000204 bool canHoistInst(MachineInstr *FaultingMI, unsigned PointerReg,
205 ArrayRef<MachineInstr *> InstsSeenSoFar,
206 MachineBasicBlock *NullSucc, MachineInstr *&Dependence);
Sanjoy Das50fef432016-12-23 00:41:24 +0000207
Sanjoy Das69fad072015-06-15 18:44:27 +0000208public:
209 static char ID;
210
211 ImplicitNullChecks() : MachineFunctionPass(ID) {
212 initializeImplicitNullChecksPass(*PassRegistry::getPassRegistry());
213 }
214
215 bool runOnMachineFunction(MachineFunction &MF) override;
Eugene Zelenko900b6332017-08-29 22:32:07 +0000216
Sanjoy Dase57bf682016-06-22 22:16:51 +0000217 void getAnalysisUsage(AnalysisUsage &AU) const override {
218 AU.addRequired<AAResultsWrapperPass>();
219 MachineFunctionPass::getAnalysisUsage(AU);
220 }
Derek Schuffad154c82016-03-28 17:05:30 +0000221
222 MachineFunctionProperties getRequiredProperties() const override {
223 return MachineFunctionProperties().set(
Matthias Braun1eb47362016-08-25 01:27:13 +0000224 MachineFunctionProperties::Property::NoVRegs);
Derek Schuffad154c82016-03-28 17:05:30 +0000225 }
Sanjoy Das69fad072015-06-15 18:44:27 +0000226};
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000227
Eugene Zelenko900b6332017-08-29 22:32:07 +0000228} // end anonymous namespace
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000229
Sanjoy Das9a129802016-12-23 00:41:21 +0000230bool ImplicitNullChecks::canHandle(const MachineInstr *MI) {
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000231 if (MI->isCall() || MI->hasUnmodeledSideEffects())
Sanjoy Das9a129802016-12-23 00:41:21 +0000232 return false;
233 auto IsRegMask = [](const MachineOperand &MO) { return MO.isRegMask(); };
234 (void)IsRegMask;
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000235
Sanjoy Das9a129802016-12-23 00:41:21 +0000236 assert(!llvm::any_of(MI->operands(), IsRegMask) &&
237 "Calls were filtered out above!");
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000238
Sanjoy Das9a129802016-12-23 00:41:21 +0000239 auto IsUnordered = [](MachineMemOperand *MMO) { return MMO->isUnordered(); };
240 return llvm::all_of(MI->memoperands(), IsUnordered);
241}
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000242
Sanjoy Das9a129802016-12-23 00:41:21 +0000243ImplicitNullChecks::DependenceResult
244ImplicitNullChecks::computeDependence(const MachineInstr *MI,
245 ArrayRef<MachineInstr *> Block) {
246 assert(llvm::all_of(Block, canHandle) && "Check this first!");
Eugene Zelenko900b6332017-08-29 22:32:07 +0000247 assert(!is_contained(Block, MI) && "Block must be exclusive of MI!");
Sanjoy Das9a129802016-12-23 00:41:21 +0000248
249 Optional<ArrayRef<MachineInstr *>::iterator> Dep;
250
251 for (auto I = Block.begin(), E = Block.end(); I != E; ++I) {
252 if (canReorder(*I, MI))
253 continue;
254
255 if (Dep == None) {
256 // Found one possible dependency, keep track of it.
257 Dep = I;
258 } else {
259 // We found two dependencies, so bail out.
260 return {false, None};
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000261 }
262 }
263
Sanjoy Das9a129802016-12-23 00:41:21 +0000264 return {true, Dep};
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000265}
266
Sanjoy Das9a129802016-12-23 00:41:21 +0000267bool ImplicitNullChecks::canReorder(const MachineInstr *A,
268 const MachineInstr *B) {
269 assert(canHandle(A) && canHandle(B) && "Precondition!");
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000270
Sanjoy Das9a129802016-12-23 00:41:21 +0000271 // canHandle makes sure that we _can_ correctly analyze the dependencies
272 // between A and B here -- for instance, we should not be dealing with heap
273 // load-store dependencies here.
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000274
Sanjoy Das9a129802016-12-23 00:41:21 +0000275 for (auto MOA : A->operands()) {
276 if (!(MOA.isReg() && MOA.getReg()))
277 continue;
Sanjoy Dase57bf682016-06-22 22:16:51 +0000278
Sanjoy Das9a129802016-12-23 00:41:21 +0000279 unsigned RegA = MOA.getReg();
280 for (auto MOB : B->operands()) {
281 if (!(MOB.isReg() && MOB.getReg()))
282 continue;
Sanjoy Dase57bf682016-06-22 22:16:51 +0000283
Sanjoy Das9a129802016-12-23 00:41:21 +0000284 unsigned RegB = MOB.getReg();
Sanjoy Dase57bf682016-06-22 22:16:51 +0000285
Sanjoy Das08da2e22017-02-01 16:04:21 +0000286 if (TRI->regsOverlap(RegA, RegB) && (MOA.isDef() || MOB.isDef()))
Sanjoy Das9a129802016-12-23 00:41:21 +0000287 return false;
Sanjoy Dasedc394f2015-11-12 20:51:44 +0000288 }
289 }
290
291 return true;
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000292}
Sanjoy Das69fad072015-06-15 18:44:27 +0000293
294bool ImplicitNullChecks::runOnMachineFunction(MachineFunction &MF) {
295 TII = MF.getSubtarget().getInstrInfo();
296 TRI = MF.getRegInfo().getTargetRegisterInfo();
Sanjoy Daseef785c2017-02-28 07:04:49 +0000297 MFI = &MF.getFrameInfo();
Sanjoy Dase57bf682016-06-22 22:16:51 +0000298 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
Sanjoy Das69fad072015-06-15 18:44:27 +0000299
300 SmallVector<NullCheck, 16> NullCheckList;
301
302 for (auto &MBB : MF)
303 analyzeBlockForNullChecks(MBB, NullCheckList);
304
305 if (!NullCheckList.empty())
306 rewriteNullChecks(NullCheckList);
307
308 return !NullCheckList.empty();
309}
310
Sanjoy Dase57bf682016-06-22 22:16:51 +0000311// Return true if any register aliasing \p Reg is live-in into \p MBB.
312static bool AnyAliasLiveIn(const TargetRegisterInfo *TRI,
313 MachineBasicBlock *MBB, unsigned Reg) {
314 for (MCRegAliasIterator AR(Reg, TRI, /*IncludeSelf*/ true); AR.isValid();
315 ++AR)
316 if (MBB->isLiveIn(*AR))
317 return true;
318 return false;
319}
320
Sanjoy Daseef785c2017-02-28 07:04:49 +0000321ImplicitNullChecks::AliasResult
322ImplicitNullChecks::areMemoryOpsAliased(MachineInstr &MI,
323 MachineInstr *PrevMI) {
324 // If it is not memory access, skip the check.
325 if (!(PrevMI->mayStore() || PrevMI->mayLoad()))
326 return AR_NoAlias;
327 // Load-Load may alias
328 if (!(MI.mayStore() || PrevMI->mayStore()))
329 return AR_NoAlias;
330 // We lost info, conservatively alias. If it was store then no sense to
331 // continue because we won't be able to check against it further.
332 if (MI.memoperands_empty())
333 return MI.mayStore() ? AR_WillAliasEverything : AR_MayAlias;
334 if (PrevMI->memoperands_empty())
335 return PrevMI->mayStore() ? AR_WillAliasEverything : AR_MayAlias;
336
337 for (MachineMemOperand *MMO1 : MI.memoperands()) {
338 // MMO1 should have a value due it comes from operation we'd like to use
339 // as implicit null check.
340 assert(MMO1->getValue() && "MMO1 should have a Value!");
341 for (MachineMemOperand *MMO2 : PrevMI->memoperands()) {
342 if (const PseudoSourceValue *PSV = MMO2->getPseudoValue()) {
343 if (PSV->mayAlias(MFI))
344 return AR_MayAlias;
345 continue;
346 }
347 llvm::AliasResult AAResult = AA->alias(
348 MemoryLocation(MMO1->getValue(), MemoryLocation::UnknownSize,
349 MMO1->getAAInfo()),
350 MemoryLocation(MMO2->getValue(), MemoryLocation::UnknownSize,
351 MMO2->getAAInfo()));
352 if (AAResult != NoAlias)
353 return AR_MayAlias;
354 }
355 }
356 return AR_NoAlias;
357}
358
Sanjoy Das15e50b52017-02-01 02:49:25 +0000359ImplicitNullChecks::SuitabilityResult
360ImplicitNullChecks::isSuitableMemoryOp(MachineInstr &MI, unsigned PointerReg,
Sanjoy Daseef785c2017-02-28 07:04:49 +0000361 ArrayRef<MachineInstr *> PrevInsts) {
Sanjoy Das50fef432016-12-23 00:41:24 +0000362 int64_t Offset;
363 unsigned BaseReg;
364
365 if (!TII->getMemOpBaseRegImmOfs(MI, BaseReg, Offset, TRI) ||
366 BaseReg != PointerReg)
Sanjoy Daseef785c2017-02-28 07:04:49 +0000367 return SR_Unsuitable;
Sanjoy Das50fef432016-12-23 00:41:24 +0000368
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000369 // We want the mem access to be issued at a sane offset from PointerReg,
370 // so that if PointerReg is null then the access reliably page faults.
371 if (!((MI.mayLoad() || MI.mayStore()) && !MI.isPredicable() &&
372 Offset < PageSize))
Sanjoy Daseef785c2017-02-28 07:04:49 +0000373 return SR_Unsuitable;
Sanjoy Das50fef432016-12-23 00:41:24 +0000374
Serguei Katkov0b0dc572017-06-21 06:38:23 +0000375 // Finally, check whether the current memory access aliases with previous one.
376 for (auto *PrevMI : PrevInsts) {
377 AliasResult AR = areMemoryOpsAliased(MI, PrevMI);
378 if (AR == AR_WillAliasEverything)
379 return SR_Impossible;
380 if (AR == AR_MayAlias)
381 return SR_Unsuitable;
382 }
383 return SR_Suitable;
Sanjoy Das50fef432016-12-23 00:41:24 +0000384}
385
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000386bool ImplicitNullChecks::canHoistInst(MachineInstr *FaultingMI,
387 unsigned PointerReg,
388 ArrayRef<MachineInstr *> InstsSeenSoFar,
389 MachineBasicBlock *NullSucc,
390 MachineInstr *&Dependence) {
Sanjoy Das50fef432016-12-23 00:41:24 +0000391 auto DepResult = computeDependence(FaultingMI, InstsSeenSoFar);
392 if (!DepResult.CanReorder)
393 return false;
394
395 if (!DepResult.PotentialDependence) {
396 Dependence = nullptr;
397 return true;
398 }
399
400 auto DependenceItr = *DepResult.PotentialDependence;
401 auto *DependenceMI = *DependenceItr;
402
403 // We don't want to reason about speculating loads. Note -- at this point
404 // we should have already filtered out all of the other non-speculatable
405 // things, like calls and stores.
Serguei Katkov6ea2e812017-08-09 05:17:02 +0000406 // We also do not want to hoist stores because it might change the memory
407 // while the FaultingMI may result in faulting.
Sanjoy Das50fef432016-12-23 00:41:24 +0000408 assert(canHandle(DependenceMI) && "Should never have reached here!");
Serguei Katkov6ea2e812017-08-09 05:17:02 +0000409 if (DependenceMI->mayLoadOrStore())
Sanjoy Das50fef432016-12-23 00:41:24 +0000410 return false;
411
412 for (auto &DependenceMO : DependenceMI->operands()) {
413 if (!(DependenceMO.isReg() && DependenceMO.getReg()))
414 continue;
415
416 // Make sure that we won't clobber any live ins to the sibling block by
417 // hoisting Dependency. For instance, we can't hoist INST to before the
418 // null check (even if it safe, and does not violate any dependencies in
419 // the non_null_block) if %rdx is live in to _null_block.
420 //
421 // test %rcx, %rcx
422 // je _null_block
423 // _non_null_block:
424 // %rdx<def> = INST
425 // ...
426 //
427 // This restriction does not apply to the faulting load inst because in
428 // case the pointer loaded from is in the null page, the load will not
429 // semantically execute, and affect machine state. That is, if the load
430 // was loading into %rax and it faults, the value of %rax should stay the
431 // same as it would have been had the load not have executed and we'd have
432 // branched to NullSucc directly.
433 if (AnyAliasLiveIn(TRI, NullSucc, DependenceMO.getReg()))
434 return false;
435
436 // The Dependency can't be re-defining the base register -- then we won't
437 // get the memory operation on the address we want. This is already
438 // checked in \c IsSuitableMemoryOp.
Sanjoy Das08da2e22017-02-01 16:04:21 +0000439 assert(!(DependenceMO.isDef() &&
440 TRI->regsOverlap(DependenceMO.getReg(), PointerReg)) &&
Sanjoy Das50fef432016-12-23 00:41:24 +0000441 "Should have been checked before!");
442 }
443
444 auto DepDepResult =
445 computeDependence(DependenceMI, {InstsSeenSoFar.begin(), DependenceItr});
446
447 if (!DepDepResult.CanReorder || DepDepResult.PotentialDependence)
448 return false;
449
450 Dependence = DependenceMI;
451 return true;
452}
453
Sanjoy Das69fad072015-06-15 18:44:27 +0000454/// Analyze MBB to check if its terminating branch can be turned into an
455/// implicit null check. If yes, append a description of the said null check to
456/// NullCheckList and return true, else return false.
457bool ImplicitNullChecks::analyzeBlockForNullChecks(
458 MachineBasicBlock &MBB, SmallVectorImpl<NullCheck> &NullCheckList) {
Eugene Zelenko900b6332017-08-29 22:32:07 +0000459 using MachineBranchPredicate = TargetInstrInfo::MachineBranchPredicate;
Sanjoy Das69fad072015-06-15 18:44:27 +0000460
Sanjoy Dase8b81642015-11-12 20:51:49 +0000461 MDNode *BranchMD = nullptr;
462 if (auto *BB = MBB.getBasicBlock())
463 BranchMD = BB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit);
464
Sanjoy Das9c41a932015-06-30 21:22:32 +0000465 if (!BranchMD)
466 return false;
467
Sanjoy Das69fad072015-06-15 18:44:27 +0000468 MachineBranchPredicate MBP;
469
Jacques Pienaar71c30a12016-07-15 14:41:04 +0000470 if (TII->analyzeBranchPredicate(MBB, MBP, true))
Sanjoy Das69fad072015-06-15 18:44:27 +0000471 return false;
472
473 // Is the predicate comparing an integer to zero?
474 if (!(MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
475 (MBP.Predicate == MachineBranchPredicate::PRED_NE ||
476 MBP.Predicate == MachineBranchPredicate::PRED_EQ)))
477 return false;
478
479 // If we cannot erase the test instruction itself, then making the null check
480 // implicit does not buy us much.
481 if (!MBP.SingleUseCondition)
482 return false;
483
484 MachineBasicBlock *NotNullSucc, *NullSucc;
485
486 if (MBP.Predicate == MachineBranchPredicate::PRED_NE) {
487 NotNullSucc = MBP.TrueDest;
488 NullSucc = MBP.FalseDest;
489 } else {
490 NotNullSucc = MBP.FalseDest;
491 NullSucc = MBP.TrueDest;
492 }
493
494 // We handle the simplest case for now. We can potentially do better by using
495 // the machine dominator tree.
496 if (NotNullSucc->pred_size() != 1)
497 return false;
498
499 // Starting with a code fragment like:
500 //
501 // test %RAX, %RAX
502 // jne LblNotNull
503 //
504 // LblNull:
505 // callq throw_NullPointerException
506 //
507 // LblNotNull:
Sanjoy Dasb7718452015-07-09 20:13:25 +0000508 // Inst0
509 // Inst1
510 // ...
Sanjoy Das69fad072015-06-15 18:44:27 +0000511 // Def = Load (%RAX + <offset>)
512 // ...
513 //
514 //
515 // we want to end up with
516 //
Sanjoy Dasac9c5b12015-11-13 08:14:00 +0000517 // Def = FaultingLoad (%RAX + <offset>), LblNull
Sanjoy Das69fad072015-06-15 18:44:27 +0000518 // jmp LblNotNull ;; explicit or fallthrough
519 //
520 // LblNotNull:
Sanjoy Dasb7718452015-07-09 20:13:25 +0000521 // Inst0
522 // Inst1
Sanjoy Das69fad072015-06-15 18:44:27 +0000523 // ...
524 //
525 // LblNull:
526 // callq throw_NullPointerException
527 //
Sanjoy Dasac9c5b12015-11-13 08:14:00 +0000528 //
529 // To see why this is legal, consider the two possibilities:
530 //
531 // 1. %RAX is null: since we constrain <offset> to be less than PageSize, the
532 // load instruction dereferences the null page, causing a segmentation
533 // fault.
534 //
535 // 2. %RAX is not null: in this case we know that the load cannot fault, as
536 // otherwise the load would've faulted in the original program too and the
537 // original program would've been undefined.
538 //
539 // This reasoning cannot be extended to justify hoisting through arbitrary
540 // control flow. For instance, in the example below (in pseudo-C)
541 //
542 // if (ptr == null) { throw_npe(); unreachable; }
543 // if (some_cond) { return 42; }
544 // v = ptr->field; // LD
545 // ...
546 //
547 // we cannot (without code duplication) use the load marked "LD" to null check
548 // ptr -- clause (2) above does not apply in this case. In the above program
549 // the safety of ptr->field can be dependent on some_cond; and, for instance,
550 // ptr could be some non-null invalid reference that never gets loaded from
551 // because some_cond is always true.
Sanjoy Das69fad072015-06-15 18:44:27 +0000552
Sanjoy Das9a129802016-12-23 00:41:21 +0000553 const unsigned PointerReg = MBP.LHS.getReg();
Sanjoy Dasb7718452015-07-09 20:13:25 +0000554
Sanjoy Das9a129802016-12-23 00:41:21 +0000555 SmallVector<MachineInstr *, 8> InstsSeenSoFar;
Sanjoy Dasb7718452015-07-09 20:13:25 +0000556
Sanjoy Das9a129802016-12-23 00:41:21 +0000557 for (auto &MI : *NotNullSucc) {
558 if (!canHandle(&MI) || InstsSeenSoFar.size() >= MaxInstsToConsider)
559 return false;
560
561 MachineInstr *Dependence;
Sanjoy Daseef785c2017-02-28 07:04:49 +0000562 SuitabilityResult SR = isSuitableMemoryOp(MI, PointerReg, InstsSeenSoFar);
Sanjoy Das15e50b52017-02-01 02:49:25 +0000563 if (SR == SR_Impossible)
564 return false;
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000565 if (SR == SR_Suitable &&
566 canHoistInst(&MI, PointerReg, InstsSeenSoFar, NullSucc, Dependence)) {
Sanjoy Das9a129802016-12-23 00:41:21 +0000567 NullCheckList.emplace_back(&MI, MBP.ConditionDef, &MBB, NotNullSucc,
568 NullSucc, Dependence);
569 return true;
570 }
571
Serguei Katkov0b0dc572017-06-21 06:38:23 +0000572 // If MI re-defines the PointerReg then we cannot move further.
Eugene Zelenko900b6332017-08-29 22:32:07 +0000573 if (llvm::any_of(MI.operands(), [&](MachineOperand &MO) {
Serguei Katkov0b0dc572017-06-21 06:38:23 +0000574 return MO.isReg() && MO.getReg() && MO.isDef() &&
575 TRI->regsOverlap(MO.getReg(), PointerReg);
576 }))
577 return false;
Sanjoy Das9a129802016-12-23 00:41:21 +0000578 InstsSeenSoFar.push_back(&MI);
Sanjoy Dasb7718452015-07-09 20:13:25 +0000579 }
580
Sanjoy Das69fad072015-06-15 18:44:27 +0000581 return false;
582}
583
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000584/// Wrap a machine instruction, MI, into a FAULTING machine instruction.
585/// The FAULTING instruction does the same load/store as MI
586/// (defining the same register), and branches to HandlerMBB if the mem access
587/// faults. The FAULTING instruction is inserted at the end of MBB.
588MachineInstr *ImplicitNullChecks::insertFaultingInstr(
589 MachineInstr *MI, MachineBasicBlock *MBB, MachineBasicBlock *HandlerMBB) {
Sanjoy Das93d608c2015-07-20 20:31:39 +0000590 const unsigned NoRegister = 0; // Guaranteed to be the NoRegister value for
591 // all targets.
592
Sanjoy Das69fad072015-06-15 18:44:27 +0000593 DebugLoc DL;
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000594 unsigned NumDefs = MI->getDesc().getNumDefs();
Sanjoy Das93d608c2015-07-20 20:31:39 +0000595 assert(NumDefs <= 1 && "other cases unhandled!");
Sanjoy Das69fad072015-06-15 18:44:27 +0000596
Sanjoy Das93d608c2015-07-20 20:31:39 +0000597 unsigned DefReg = NoRegister;
598 if (NumDefs != 0) {
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000599 DefReg = MI->defs().begin()->getReg();
600 assert(std::distance(MI->defs().begin(), MI->defs().end()) == 1 &&
Sanjoy Das93d608c2015-07-20 20:31:39 +0000601 "expected exactly one def!");
602 }
Sanjoy Das69fad072015-06-15 18:44:27 +0000603
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000604 FaultMaps::FaultKind FK;
605 if (MI->mayLoad())
606 FK =
607 MI->mayStore() ? FaultMaps::FaultingLoadStore : FaultMaps::FaultingLoad;
608 else
609 FK = FaultMaps::FaultingStore;
Sanjoy Das69fad072015-06-15 18:44:27 +0000610
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000611 auto MIB = BuildMI(MBB, DL, TII->get(TargetOpcode::FAULTING_OP), DefReg)
612 .addImm(FK)
613 .addMBB(HandlerMBB)
614 .addImm(MI->getOpcode());
615
Matthias Braun605f77952017-05-31 22:23:08 +0000616 for (auto &MO : MI->uses()) {
617 if (MO.isReg()) {
618 MachineOperand NewMO = MO;
619 if (MO.isUse()) {
620 NewMO.setIsKill(false);
621 } else {
622 assert(MO.isDef() && "Expected def or use");
623 NewMO.setIsDead(false);
624 }
625 MIB.add(NewMO);
626 } else {
627 MIB.add(MO);
628 }
629 }
Sanjoy Das69fad072015-06-15 18:44:27 +0000630
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000631 MIB.setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
Sanjoy Das69fad072015-06-15 18:44:27 +0000632
633 return MIB;
634}
635
636/// Rewrite the null checks in NullCheckList into implicit null checks.
637void ImplicitNullChecks::rewriteNullChecks(
638 ArrayRef<ImplicitNullChecks::NullCheck> NullCheckList) {
639 DebugLoc DL;
640
641 for (auto &NC : NullCheckList) {
Sanjoy Das69fad072015-06-15 18:44:27 +0000642 // Remove the conditional branch dependent on the null check.
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +0000643 unsigned BranchesRemoved = TII->removeBranch(*NC.getCheckBlock());
Sanjoy Das69fad072015-06-15 18:44:27 +0000644 (void)BranchesRemoved;
645 assert(BranchesRemoved > 0 && "expected at least one branch!");
646
Sanjoy Dase57bf682016-06-22 22:16:51 +0000647 if (auto *DepMI = NC.getOnlyDependency()) {
648 DepMI->removeFromParent();
649 NC.getCheckBlock()->insert(NC.getCheckBlock()->end(), DepMI);
650 }
651
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000652 // Insert a faulting instruction where the conditional branch was
653 // originally. We check earlier ensures that this bit of code motion
654 // is legal. We do not touch the successors list for any basic block
655 // since we haven't changed control flow, we've just made it implicit.
656 MachineInstr *FaultingInstr = insertFaultingInstr(
Sanjoy Dase173b9a2016-06-21 02:10:18 +0000657 NC.getMemOperation(), NC.getCheckBlock(), NC.getNullSucc());
Quentin Colombet26dab3a2016-05-03 18:09:06 +0000658 // Now the values defined by MemOperation, if any, are live-in of
659 // the block of MemOperation.
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000660 // The original operation may define implicit-defs alongside
661 // the value.
Sanjoy Dase173b9a2016-06-21 02:10:18 +0000662 MachineBasicBlock *MBB = NC.getMemOperation()->getParent();
Sanjoy Das2f63cbc2017-02-07 19:19:49 +0000663 for (const MachineOperand &MO : FaultingInstr->operands()) {
Quentin Colombet26dab3a2016-05-03 18:09:06 +0000664 if (!MO.isReg() || !MO.isDef())
665 continue;
666 unsigned Reg = MO.getReg();
667 if (!Reg || MBB->isLiveIn(Reg))
668 continue;
669 MBB->addLiveIn(Reg);
Quentin Colombet12b69912016-04-27 23:26:40 +0000670 }
Sanjoy Dase57bf682016-06-22 22:16:51 +0000671
672 if (auto *DepMI = NC.getOnlyDependency()) {
673 for (auto &MO : DepMI->operands()) {
674 if (!MO.isReg() || !MO.getReg() || !MO.isDef())
675 continue;
676 if (!NC.getNotNullSucc()->isLiveIn(MO.getReg()))
677 NC.getNotNullSucc()->addLiveIn(MO.getReg());
678 }
679 }
680
Sanjoy Dase173b9a2016-06-21 02:10:18 +0000681 NC.getMemOperation()->eraseFromParent();
682 NC.getCheckOperation()->eraseFromParent();
Sanjoy Das69fad072015-06-15 18:44:27 +0000683
684 // Insert an *unconditional* branch to not-null successor.
Matt Arsenaulte8e0f5c2016-09-14 17:24:15 +0000685 TII->insertBranch(*NC.getCheckBlock(), NC.getNotNullSucc(), nullptr,
Sanjoy Dase173b9a2016-06-21 02:10:18 +0000686 /*Cond=*/None, DL);
Sanjoy Das69fad072015-06-15 18:44:27 +0000687
Sanjoy Das8ee6a302015-07-06 23:32:10 +0000688 NumImplicitNullChecks++;
Sanjoy Das69fad072015-06-15 18:44:27 +0000689 }
690}
691
692char ImplicitNullChecks::ID = 0;
Eugene Zelenko900b6332017-08-29 22:32:07 +0000693
Sanjoy Das69fad072015-06-15 18:44:27 +0000694char &llvm::ImplicitNullChecksID = ImplicitNullChecks::ID;
Eugene Zelenko900b6332017-08-29 22:32:07 +0000695
Matthias Braun1527baa2017-05-25 21:26:32 +0000696INITIALIZE_PASS_BEGIN(ImplicitNullChecks, DEBUG_TYPE,
Sanjoy Das69fad072015-06-15 18:44:27 +0000697 "Implicit null checks", false, false)
Sanjoy Dase57bf682016-06-22 22:16:51 +0000698INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
Matthias Braun1527baa2017-05-25 21:26:32 +0000699INITIALIZE_PASS_END(ImplicitNullChecks, DEBUG_TYPE,
Sanjoy Das69fad072015-06-15 18:44:27 +0000700 "Implicit null checks", false, false)