169fad079SSanjoy Das //===-- ImplicitNullChecks.cpp - Fold null checks into memory accesses ----===//
269fad079SSanjoy Das //
369fad079SSanjoy Das //                     The LLVM Compiler Infrastructure
469fad079SSanjoy Das //
569fad079SSanjoy Das // This file is distributed under the University of Illinois Open Source
669fad079SSanjoy Das // License. See LICENSE.TXT for details.
769fad079SSanjoy Das //
869fad079SSanjoy Das //===----------------------------------------------------------------------===//
969fad079SSanjoy Das //
1069fad079SSanjoy Das // This pass turns explicit null checks of the form
1169fad079SSanjoy Das //
1269fad079SSanjoy Das //   test %r10, %r10
1369fad079SSanjoy Das //   je throw_npe
1469fad079SSanjoy Das //   movl (%r10), %esi
1569fad079SSanjoy Das //   ...
1669fad079SSanjoy Das //
1769fad079SSanjoy Das // to
1869fad079SSanjoy Das //
1969fad079SSanjoy Das //   faulting_load_op("movl (%r10), %esi", throw_npe)
2069fad079SSanjoy Das //   ...
2169fad079SSanjoy Das //
2269fad079SSanjoy Das // With the help of a runtime that understands the .fault_maps section,
2369fad079SSanjoy Das // faulting_load_op branches to throw_npe if executing movl (%r10), %esi incurs
2469fad079SSanjoy Das // a page fault.
2569fad079SSanjoy Das //
2669fad079SSanjoy Das //===----------------------------------------------------------------------===//
2769fad079SSanjoy Das 
28b7718454SSanjoy Das #include "llvm/ADT/DenseSet.h"
2969fad079SSanjoy Das #include "llvm/ADT/SmallVector.h"
308ee6a30bSSanjoy Das #include "llvm/ADT/Statistic.h"
31*e57bf680SSanjoy Das #include "llvm/Analysis/AliasAnalysis.h"
3269fad079SSanjoy Das #include "llvm/CodeGen/Passes.h"
3369fad079SSanjoy Das #include "llvm/CodeGen/MachineFunction.h"
34b7718454SSanjoy Das #include "llvm/CodeGen/MachineMemOperand.h"
3569fad079SSanjoy Das #include "llvm/CodeGen/MachineOperand.h"
3669fad079SSanjoy Das #include "llvm/CodeGen/MachineFunctionPass.h"
3769fad079SSanjoy Das #include "llvm/CodeGen/MachineInstrBuilder.h"
3869fad079SSanjoy Das #include "llvm/CodeGen/MachineRegisterInfo.h"
3969fad079SSanjoy Das #include "llvm/CodeGen/MachineModuleInfo.h"
4069fad079SSanjoy Das #include "llvm/IR/BasicBlock.h"
4169fad079SSanjoy Das #include "llvm/IR/Instruction.h"
4200038784SChen Li #include "llvm/IR/LLVMContext.h"
4369fad079SSanjoy Das #include "llvm/Support/CommandLine.h"
4469fad079SSanjoy Das #include "llvm/Support/Debug.h"
4569fad079SSanjoy Das #include "llvm/Target/TargetSubtargetInfo.h"
4669fad079SSanjoy Das #include "llvm/Target/TargetInstrInfo.h"
4769fad079SSanjoy Das 
4869fad079SSanjoy Das using namespace llvm;
4969fad079SSanjoy Das 
50c27a18f3SChad Rosier static cl::opt<int> PageSize("imp-null-check-page-size",
51c27a18f3SChad Rosier                              cl::desc("The page size of the target in bytes"),
5269fad079SSanjoy Das                              cl::init(4096));
5369fad079SSanjoy Das 
548ee6a30bSSanjoy Das #define DEBUG_TYPE "implicit-null-checks"
558ee6a30bSSanjoy Das 
568ee6a30bSSanjoy Das STATISTIC(NumImplicitNullChecks,
578ee6a30bSSanjoy Das           "Number of explicit null checks made implicit");
588ee6a30bSSanjoy Das 
5969fad079SSanjoy Das namespace {
6069fad079SSanjoy Das 
6169fad079SSanjoy Das class ImplicitNullChecks : public MachineFunctionPass {
6269fad079SSanjoy Das   /// Represents one null check that can be made implicit.
63e173b9aeSSanjoy Das   class NullCheck {
6469fad079SSanjoy Das     // The memory operation the null check can be folded into.
6569fad079SSanjoy Das     MachineInstr *MemOperation;
6669fad079SSanjoy Das 
6769fad079SSanjoy Das     // The instruction actually doing the null check (Ptr != 0).
6869fad079SSanjoy Das     MachineInstr *CheckOperation;
6969fad079SSanjoy Das 
7069fad079SSanjoy Das     // The block the check resides in.
7169fad079SSanjoy Das     MachineBasicBlock *CheckBlock;
7269fad079SSanjoy Das 
73572e03a3SEric Christopher     // The block branched to if the pointer is non-null.
7469fad079SSanjoy Das     MachineBasicBlock *NotNullSucc;
7569fad079SSanjoy Das 
76572e03a3SEric Christopher     // The block branched to if the pointer is null.
7769fad079SSanjoy Das     MachineBasicBlock *NullSucc;
7869fad079SSanjoy Das 
79*e57bf680SSanjoy Das     // If this is non-null, then MemOperation has a dependency on on this
80*e57bf680SSanjoy Das     // instruction; and it needs to be hoisted to execute before MemOperation.
81*e57bf680SSanjoy Das     MachineInstr *OnlyDependency;
82*e57bf680SSanjoy Das 
83e173b9aeSSanjoy Das   public:
8469fad079SSanjoy Das     explicit NullCheck(MachineInstr *memOperation, MachineInstr *checkOperation,
8569fad079SSanjoy Das                        MachineBasicBlock *checkBlock,
8669fad079SSanjoy Das                        MachineBasicBlock *notNullSucc,
87*e57bf680SSanjoy Das                        MachineBasicBlock *nullSucc,
88*e57bf680SSanjoy Das                        MachineInstr *onlyDependency)
8969fad079SSanjoy Das         : MemOperation(memOperation), CheckOperation(checkOperation),
90*e57bf680SSanjoy Das           CheckBlock(checkBlock), NotNullSucc(notNullSucc), NullSucc(nullSucc),
91*e57bf680SSanjoy Das           OnlyDependency(onlyDependency) {}
92e173b9aeSSanjoy Das 
93e173b9aeSSanjoy Das     MachineInstr *getMemOperation() const { return MemOperation; }
94e173b9aeSSanjoy Das 
95e173b9aeSSanjoy Das     MachineInstr *getCheckOperation() const { return CheckOperation; }
96e173b9aeSSanjoy Das 
97e173b9aeSSanjoy Das     MachineBasicBlock *getCheckBlock() const { return CheckBlock; }
98e173b9aeSSanjoy Das 
99e173b9aeSSanjoy Das     MachineBasicBlock *getNotNullSucc() const { return NotNullSucc; }
100e173b9aeSSanjoy Das 
101e173b9aeSSanjoy Das     MachineBasicBlock *getNullSucc() const { return NullSucc; }
102*e57bf680SSanjoy Das 
103*e57bf680SSanjoy Das     MachineInstr *getOnlyDependency() const { return OnlyDependency; }
10469fad079SSanjoy Das   };
10569fad079SSanjoy Das 
10669fad079SSanjoy Das   const TargetInstrInfo *TII = nullptr;
10769fad079SSanjoy Das   const TargetRegisterInfo *TRI = nullptr;
108*e57bf680SSanjoy Das   AliasAnalysis *AA = nullptr;
10969fad079SSanjoy Das   MachineModuleInfo *MMI = nullptr;
11069fad079SSanjoy Das 
11169fad079SSanjoy Das   bool analyzeBlockForNullChecks(MachineBasicBlock &MBB,
11269fad079SSanjoy Das                                  SmallVectorImpl<NullCheck> &NullCheckList);
11369fad079SSanjoy Das   MachineInstr *insertFaultingLoad(MachineInstr *LoadMI, MachineBasicBlock *MBB,
1144e1d389aSQuentin Colombet                                    MachineBasicBlock *HandlerMBB);
11569fad079SSanjoy Das   void rewriteNullChecks(ArrayRef<NullCheck> NullCheckList);
11669fad079SSanjoy Das 
11769fad079SSanjoy Das public:
11869fad079SSanjoy Das   static char ID;
11969fad079SSanjoy Das 
12069fad079SSanjoy Das   ImplicitNullChecks() : MachineFunctionPass(ID) {
12169fad079SSanjoy Das     initializeImplicitNullChecksPass(*PassRegistry::getPassRegistry());
12269fad079SSanjoy Das   }
12369fad079SSanjoy Das 
12469fad079SSanjoy Das   bool runOnMachineFunction(MachineFunction &MF) override;
125*e57bf680SSanjoy Das   void getAnalysisUsage(AnalysisUsage &AU) const override {
126*e57bf680SSanjoy Das     AU.addRequired<AAResultsWrapperPass>();
127*e57bf680SSanjoy Das     MachineFunctionPass::getAnalysisUsage(AU);
128*e57bf680SSanjoy Das   }
129ad154c83SDerek Schuff 
130ad154c83SDerek Schuff   MachineFunctionProperties getRequiredProperties() const override {
131ad154c83SDerek Schuff     return MachineFunctionProperties().set(
132ad154c83SDerek Schuff         MachineFunctionProperties::Property::AllVRegsAllocated);
133ad154c83SDerek Schuff   }
13469fad079SSanjoy Das };
135edc394f1SSanjoy Das 
136edc394f1SSanjoy Das /// \brief Detect re-ordering hazards and dependencies.
137edc394f1SSanjoy Das ///
138edc394f1SSanjoy Das /// This class keeps track of defs and uses, and can be queried if a given
139edc394f1SSanjoy Das /// machine instruction can be re-ordered from after the machine instructions
140edc394f1SSanjoy Das /// seen so far to before them.
141edc394f1SSanjoy Das class HazardDetector {
142*e57bf680SSanjoy Das   static MachineInstr *getUnknownMI() {
143*e57bf680SSanjoy Das     return DenseMapInfo<MachineInstr *>::getTombstoneKey();
144*e57bf680SSanjoy Das   }
145*e57bf680SSanjoy Das 
146*e57bf680SSanjoy Das   // Maps physical registers to the instruction defining them.  If there has
147*e57bf680SSanjoy Das   // been more than one def of an specific register, that register is mapped to
148*e57bf680SSanjoy Das   // getUnknownMI().
149*e57bf680SSanjoy Das   DenseMap<unsigned, MachineInstr *> RegDefs;
150edc394f1SSanjoy Das   DenseSet<unsigned> RegUses;
151edc394f1SSanjoy Das   const TargetRegisterInfo &TRI;
152edc394f1SSanjoy Das   bool hasSeenClobber;
153*e57bf680SSanjoy Das   AliasAnalysis &AA;
154edc394f1SSanjoy Das 
155edc394f1SSanjoy Das public:
156*e57bf680SSanjoy Das   explicit HazardDetector(const TargetRegisterInfo &TRI, AliasAnalysis &AA)
157*e57bf680SSanjoy Das       : TRI(TRI), hasSeenClobber(false), AA(AA) {}
158edc394f1SSanjoy Das 
159edc394f1SSanjoy Das   /// \brief Make a note of \p MI for later queries to isSafeToHoist.
160edc394f1SSanjoy Das   ///
161edc394f1SSanjoy Das   /// May clobber this HazardDetector instance.  \see isClobbered.
162edc394f1SSanjoy Das   void rememberInstruction(MachineInstr *MI);
163edc394f1SSanjoy Das 
164edc394f1SSanjoy Das   /// \brief Return true if it is safe to hoist \p MI from after all the
165*e57bf680SSanjoy Das   /// instructions seen so far (via rememberInstruction) to before it.  If \p MI
166*e57bf680SSanjoy Das   /// has one and only one transitive dependency, set \p Dependency to that
167*e57bf680SSanjoy Das   /// instruction.  If there are more dependencies, return false.
168*e57bf680SSanjoy Das   bool isSafeToHoist(MachineInstr *MI, MachineInstr *&Dependency);
169edc394f1SSanjoy Das 
170edc394f1SSanjoy Das   /// \brief Return true if this instance of HazardDetector has been clobbered
171edc394f1SSanjoy Das   /// (i.e. has no more useful information).
172edc394f1SSanjoy Das   ///
173edc394f1SSanjoy Das   /// A HazardDetecter is clobbered when it sees a construct it cannot
174edc394f1SSanjoy Das   /// understand, and it would have to return a conservative answer for all
175edc394f1SSanjoy Das   /// future queries.  Having a separate clobbered state lets the client code
176edc394f1SSanjoy Das   /// bail early, without making queries about all of the future instructions
177edc394f1SSanjoy Das   /// (which would have returned the most conservative answer anyway).
178edc394f1SSanjoy Das   ///
179edc394f1SSanjoy Das   /// Calling rememberInstruction or isSafeToHoist on a clobbered HazardDetector
180edc394f1SSanjoy Das   /// is an error.
181edc394f1SSanjoy Das   bool isClobbered() { return hasSeenClobber; }
182edc394f1SSanjoy Das };
183edc394f1SSanjoy Das }
184edc394f1SSanjoy Das 
185edc394f1SSanjoy Das 
186edc394f1SSanjoy Das void HazardDetector::rememberInstruction(MachineInstr *MI) {
187edc394f1SSanjoy Das   assert(!isClobbered() &&
188edc394f1SSanjoy Das          "Don't add instructions to a clobbered hazard detector");
189edc394f1SSanjoy Das 
190edc394f1SSanjoy Das   if (MI->mayStore() || MI->hasUnmodeledSideEffects()) {
191edc394f1SSanjoy Das     hasSeenClobber = true;
192edc394f1SSanjoy Das     return;
193edc394f1SSanjoy Das   }
194edc394f1SSanjoy Das 
195edc394f1SSanjoy Das   for (auto *MMO : MI->memoperands()) {
196edc394f1SSanjoy Das     // Right now we don't want to worry about LLVM's memory model.
197edc394f1SSanjoy Das     if (!MMO->isUnordered()) {
198edc394f1SSanjoy Das       hasSeenClobber = true;
199edc394f1SSanjoy Das       return;
200edc394f1SSanjoy Das     }
201edc394f1SSanjoy Das   }
202edc394f1SSanjoy Das 
203edc394f1SSanjoy Das   for (auto &MO : MI->operands()) {
204edc394f1SSanjoy Das     if (!MO.isReg() || !MO.getReg())
205edc394f1SSanjoy Das       continue;
206edc394f1SSanjoy Das 
207*e57bf680SSanjoy Das     if (MO.isDef()) {
208*e57bf680SSanjoy Das       auto It = RegDefs.find(MO.getReg());
209*e57bf680SSanjoy Das       if (It == RegDefs.end())
210*e57bf680SSanjoy Das         RegDefs.insert({MO.getReg(), MI});
211*e57bf680SSanjoy Das       else {
212*e57bf680SSanjoy Das         assert(It->second && "Found null MI?");
213*e57bf680SSanjoy Das         It->second = getUnknownMI();
214*e57bf680SSanjoy Das       }
215*e57bf680SSanjoy Das     } else
216edc394f1SSanjoy Das       RegUses.insert(MO.getReg());
217edc394f1SSanjoy Das   }
218edc394f1SSanjoy Das }
219edc394f1SSanjoy Das 
220*e57bf680SSanjoy Das bool HazardDetector::isSafeToHoist(MachineInstr *MI,
221*e57bf680SSanjoy Das                                    MachineInstr *&Dependency) {
222edc394f1SSanjoy Das   assert(!isClobbered() && "isSafeToHoist cannot do anything useful!");
223*e57bf680SSanjoy Das   Dependency = nullptr;
224edc394f1SSanjoy Das 
225edc394f1SSanjoy Das   // Right now we don't want to worry about LLVM's memory model.  This can be
226edc394f1SSanjoy Das   // made more precise later.
227edc394f1SSanjoy Das   for (auto *MMO : MI->memoperands())
228edc394f1SSanjoy Das     if (!MMO->isUnordered())
229edc394f1SSanjoy Das       return false;
230edc394f1SSanjoy Das 
231edc394f1SSanjoy Das   for (auto &MO : MI->operands()) {
232edc394f1SSanjoy Das     if (MO.isReg() && MO.getReg()) {
233*e57bf680SSanjoy Das       for (auto &RegDef : RegDefs) {
234*e57bf680SSanjoy Das         unsigned Reg = RegDef.first;
235*e57bf680SSanjoy Das         MachineInstr *MI = RegDef.second;
236*e57bf680SSanjoy Das         if (!TRI.regsOverlap(Reg, MO.getReg()))
237*e57bf680SSanjoy Das           continue;
238*e57bf680SSanjoy Das 
239*e57bf680SSanjoy Das         // We found a write-after-write or read-after-write, see if the
240*e57bf680SSanjoy Das         // instruction causing this dependency can be hoisted too.
241*e57bf680SSanjoy Das 
242*e57bf680SSanjoy Das         if (MI == getUnknownMI())
243*e57bf680SSanjoy Das           // We don't have precise dependency information.
244*e57bf680SSanjoy Das           return false;
245*e57bf680SSanjoy Das 
246*e57bf680SSanjoy Das         if (Dependency) {
247*e57bf680SSanjoy Das           if (Dependency == MI)
248*e57bf680SSanjoy Das             continue;
249*e57bf680SSanjoy Das           // We already have one dependency, and we can track only one.
250*e57bf680SSanjoy Das           return false;
251*e57bf680SSanjoy Das         }
252*e57bf680SSanjoy Das 
253*e57bf680SSanjoy Das         // Now check if MI is actually a dependency that can be hoisted.
254*e57bf680SSanjoy Das 
255*e57bf680SSanjoy Das         // We don't want to track transitive dependencies.  We already know that
256*e57bf680SSanjoy Das         // MI is the only instruction that defines Reg, but we need to be sure
257*e57bf680SSanjoy Das         // that it does not use any registers that have been defined (trivially
258*e57bf680SSanjoy Das         // checked below by ensuring that there are no register uses), and that
259*e57bf680SSanjoy Das         // it is the only def for every register it defines (otherwise we could
260*e57bf680SSanjoy Das         // violate a write after write hazard).
261*e57bf680SSanjoy Das         auto IsMIOperandSafe = [&](MachineOperand &MO) {
262*e57bf680SSanjoy Das           if (!MO.isReg() || !MO.getReg())
263*e57bf680SSanjoy Das             return true;
264*e57bf680SSanjoy Das           if (MO.isUse())
265*e57bf680SSanjoy Das             return false;
266*e57bf680SSanjoy Das           assert((!MO.isDef() || RegDefs.count(MO.getReg())) &&
267*e57bf680SSanjoy Das                  "All defs must be tracked in RegDefs by now!");
268*e57bf680SSanjoy Das           return !MO.isDef() || RegDefs.find(MO.getReg())->second == MI;
269*e57bf680SSanjoy Das         };
270*e57bf680SSanjoy Das 
271*e57bf680SSanjoy Das         if (!all_of(MI->operands(), IsMIOperandSafe))
272*e57bf680SSanjoy Das           return false;
273*e57bf680SSanjoy Das 
274*e57bf680SSanjoy Das         // Now check for speculation safety:
275*e57bf680SSanjoy Das         bool SawStore = true;
276*e57bf680SSanjoy Das         if (!MI->isSafeToMove(&AA, SawStore) || MI->mayLoad())
277*e57bf680SSanjoy Das           return false;
278*e57bf680SSanjoy Das 
279*e57bf680SSanjoy Das         Dependency = MI;
280*e57bf680SSanjoy Das       }
281edc394f1SSanjoy Das 
282edc394f1SSanjoy Das       if (MO.isDef())
283edc394f1SSanjoy Das         for (unsigned Reg : RegUses)
284edc394f1SSanjoy Das           if (TRI.regsOverlap(Reg, MO.getReg()))
285edc394f1SSanjoy Das             return false;  // We found a write-after-read
286edc394f1SSanjoy Das     }
287edc394f1SSanjoy Das   }
288edc394f1SSanjoy Das 
289edc394f1SSanjoy Das   return true;
290f00654e3SAlexander Kornienko }
29169fad079SSanjoy Das 
29269fad079SSanjoy Das bool ImplicitNullChecks::runOnMachineFunction(MachineFunction &MF) {
29369fad079SSanjoy Das   TII = MF.getSubtarget().getInstrInfo();
29469fad079SSanjoy Das   TRI = MF.getRegInfo().getTargetRegisterInfo();
29569fad079SSanjoy Das   MMI = &MF.getMMI();
296*e57bf680SSanjoy Das   AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
29769fad079SSanjoy Das 
29869fad079SSanjoy Das   SmallVector<NullCheck, 16> NullCheckList;
29969fad079SSanjoy Das 
30069fad079SSanjoy Das   for (auto &MBB : MF)
30169fad079SSanjoy Das     analyzeBlockForNullChecks(MBB, NullCheckList);
30269fad079SSanjoy Das 
30369fad079SSanjoy Das   if (!NullCheckList.empty())
30469fad079SSanjoy Das     rewriteNullChecks(NullCheckList);
30569fad079SSanjoy Das 
30669fad079SSanjoy Das   return !NullCheckList.empty();
30769fad079SSanjoy Das }
30869fad079SSanjoy Das 
309*e57bf680SSanjoy Das // Return true if any register aliasing \p Reg is live-in into \p MBB.
310*e57bf680SSanjoy Das static bool AnyAliasLiveIn(const TargetRegisterInfo *TRI,
311*e57bf680SSanjoy Das                            MachineBasicBlock *MBB, unsigned Reg) {
312*e57bf680SSanjoy Das   for (MCRegAliasIterator AR(Reg, TRI, /*IncludeSelf*/ true); AR.isValid();
313*e57bf680SSanjoy Das        ++AR)
314*e57bf680SSanjoy Das     if (MBB->isLiveIn(*AR))
315*e57bf680SSanjoy Das       return true;
316*e57bf680SSanjoy Das   return false;
317*e57bf680SSanjoy Das }
318*e57bf680SSanjoy Das 
31969fad079SSanjoy Das /// Analyze MBB to check if its terminating branch can be turned into an
32069fad079SSanjoy Das /// implicit null check.  If yes, append a description of the said null check to
32169fad079SSanjoy Das /// NullCheckList and return true, else return false.
32269fad079SSanjoy Das bool ImplicitNullChecks::analyzeBlockForNullChecks(
32369fad079SSanjoy Das     MachineBasicBlock &MBB, SmallVectorImpl<NullCheck> &NullCheckList) {
32469fad079SSanjoy Das   typedef TargetInstrInfo::MachineBranchPredicate MachineBranchPredicate;
32569fad079SSanjoy Das 
326e8b81649SSanjoy Das   MDNode *BranchMD = nullptr;
327e8b81649SSanjoy Das   if (auto *BB = MBB.getBasicBlock())
328e8b81649SSanjoy Das     BranchMD = BB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit);
329e8b81649SSanjoy Das 
3309c41a93eSSanjoy Das   if (!BranchMD)
3319c41a93eSSanjoy Das     return false;
3329c41a93eSSanjoy Das 
33369fad079SSanjoy Das   MachineBranchPredicate MBP;
33469fad079SSanjoy Das 
33569fad079SSanjoy Das   if (TII->AnalyzeBranchPredicate(MBB, MBP, true))
33669fad079SSanjoy Das     return false;
33769fad079SSanjoy Das 
33869fad079SSanjoy Das   // Is the predicate comparing an integer to zero?
33969fad079SSanjoy Das   if (!(MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
34069fad079SSanjoy Das         (MBP.Predicate == MachineBranchPredicate::PRED_NE ||
34169fad079SSanjoy Das          MBP.Predicate == MachineBranchPredicate::PRED_EQ)))
34269fad079SSanjoy Das     return false;
34369fad079SSanjoy Das 
34469fad079SSanjoy Das   // If we cannot erase the test instruction itself, then making the null check
34569fad079SSanjoy Das   // implicit does not buy us much.
34669fad079SSanjoy Das   if (!MBP.SingleUseCondition)
34769fad079SSanjoy Das     return false;
34869fad079SSanjoy Das 
34969fad079SSanjoy Das   MachineBasicBlock *NotNullSucc, *NullSucc;
35069fad079SSanjoy Das 
35169fad079SSanjoy Das   if (MBP.Predicate == MachineBranchPredicate::PRED_NE) {
35269fad079SSanjoy Das     NotNullSucc = MBP.TrueDest;
35369fad079SSanjoy Das     NullSucc = MBP.FalseDest;
35469fad079SSanjoy Das   } else {
35569fad079SSanjoy Das     NotNullSucc = MBP.FalseDest;
35669fad079SSanjoy Das     NullSucc = MBP.TrueDest;
35769fad079SSanjoy Das   }
35869fad079SSanjoy Das 
35969fad079SSanjoy Das   // We handle the simplest case for now.  We can potentially do better by using
36069fad079SSanjoy Das   // the machine dominator tree.
36169fad079SSanjoy Das   if (NotNullSucc->pred_size() != 1)
36269fad079SSanjoy Das     return false;
36369fad079SSanjoy Das 
36469fad079SSanjoy Das   // Starting with a code fragment like:
36569fad079SSanjoy Das   //
36669fad079SSanjoy Das   //   test %RAX, %RAX
36769fad079SSanjoy Das   //   jne LblNotNull
36869fad079SSanjoy Das   //
36969fad079SSanjoy Das   //  LblNull:
37069fad079SSanjoy Das   //   callq throw_NullPointerException
37169fad079SSanjoy Das   //
37269fad079SSanjoy Das   //  LblNotNull:
373b7718454SSanjoy Das   //   Inst0
374b7718454SSanjoy Das   //   Inst1
375b7718454SSanjoy Das   //   ...
37669fad079SSanjoy Das   //   Def = Load (%RAX + <offset>)
37769fad079SSanjoy Das   //   ...
37869fad079SSanjoy Das   //
37969fad079SSanjoy Das   //
38069fad079SSanjoy Das   // we want to end up with
38169fad079SSanjoy Das   //
382ac9c5b19SSanjoy Das   //   Def = FaultingLoad (%RAX + <offset>), LblNull
38369fad079SSanjoy Das   //   jmp LblNotNull ;; explicit or fallthrough
38469fad079SSanjoy Das   //
38569fad079SSanjoy Das   //  LblNotNull:
386b7718454SSanjoy Das   //   Inst0
387b7718454SSanjoy Das   //   Inst1
38869fad079SSanjoy Das   //   ...
38969fad079SSanjoy Das   //
39069fad079SSanjoy Das   //  LblNull:
39169fad079SSanjoy Das   //   callq throw_NullPointerException
39269fad079SSanjoy Das   //
393ac9c5b19SSanjoy Das   //
394ac9c5b19SSanjoy Das   // To see why this is legal, consider the two possibilities:
395ac9c5b19SSanjoy Das   //
396ac9c5b19SSanjoy Das   //  1. %RAX is null: since we constrain <offset> to be less than PageSize, the
397ac9c5b19SSanjoy Das   //     load instruction dereferences the null page, causing a segmentation
398ac9c5b19SSanjoy Das   //     fault.
399ac9c5b19SSanjoy Das   //
400ac9c5b19SSanjoy Das   //  2. %RAX is not null: in this case we know that the load cannot fault, as
401ac9c5b19SSanjoy Das   //     otherwise the load would've faulted in the original program too and the
402ac9c5b19SSanjoy Das   //     original program would've been undefined.
403ac9c5b19SSanjoy Das   //
404ac9c5b19SSanjoy Das   // This reasoning cannot be extended to justify hoisting through arbitrary
405ac9c5b19SSanjoy Das   // control flow.  For instance, in the example below (in pseudo-C)
406ac9c5b19SSanjoy Das   //
407ac9c5b19SSanjoy Das   //    if (ptr == null) { throw_npe(); unreachable; }
408ac9c5b19SSanjoy Das   //    if (some_cond) { return 42; }
409ac9c5b19SSanjoy Das   //    v = ptr->field;  // LD
410ac9c5b19SSanjoy Das   //    ...
411ac9c5b19SSanjoy Das   //
412ac9c5b19SSanjoy Das   // we cannot (without code duplication) use the load marked "LD" to null check
413ac9c5b19SSanjoy Das   // ptr -- clause (2) above does not apply in this case.  In the above program
414ac9c5b19SSanjoy Das   // the safety of ptr->field can be dependent on some_cond; and, for instance,
415ac9c5b19SSanjoy Das   // ptr could be some non-null invalid reference that never gets loaded from
416ac9c5b19SSanjoy Das   // because some_cond is always true.
41769fad079SSanjoy Das 
41869fad079SSanjoy Das   unsigned PointerReg = MBP.LHS.getReg();
419b7718454SSanjoy Das 
420*e57bf680SSanjoy Das   HazardDetector HD(*TRI, *AA);
421b7718454SSanjoy Das 
422b7718454SSanjoy Das   for (auto MII = NotNullSucc->begin(), MIE = NotNullSucc->end(); MII != MIE;
423b7718454SSanjoy Das        ++MII) {
424b7718454SSanjoy Das     MachineInstr *MI = &*MII;
425c27a18f3SChad Rosier     unsigned BaseReg;
426c27a18f3SChad Rosier     int64_t Offset;
427*e57bf680SSanjoy Das     MachineInstr *Dependency = nullptr;
428b7718454SSanjoy Das     if (TII->getMemOpBaseRegImmOfs(MI, BaseReg, Offset, TRI))
429b7718454SSanjoy Das       if (MI->mayLoad() && !MI->isPredicable() && BaseReg == PointerReg &&
43093d608c3SSanjoy Das           Offset < PageSize && MI->getDesc().getNumDefs() <= 1 &&
431*e57bf680SSanjoy Das           HD.isSafeToHoist(MI, Dependency)) {
432*e57bf680SSanjoy Das 
433*e57bf680SSanjoy Das         auto DependencyOperandIsOk = [&](MachineOperand &MO) {
434*e57bf680SSanjoy Das           assert(!(MO.isReg() && MO.isUse()) &&
435*e57bf680SSanjoy Das                  "No transitive dependendencies please!");
436*e57bf680SSanjoy Das           if (!MO.isReg() || !MO.getReg() || !MO.isDef())
43769fad079SSanjoy Das             return true;
438*e57bf680SSanjoy Das 
439*e57bf680SSanjoy Das           // Make sure that we won't clobber any live ins to the sibling block
440*e57bf680SSanjoy Das           // by hoisting Dependency.  For instance, we can't hoist INST to
441*e57bf680SSanjoy Das           // before the null check (even if it safe, and does not violate any
442*e57bf680SSanjoy Das           // dependencies in the non_null_block) if %rdx is live in to
443*e57bf680SSanjoy Das           // _null_block.
444*e57bf680SSanjoy Das           //
445*e57bf680SSanjoy Das           //    test %rcx, %rcx
446*e57bf680SSanjoy Das           //    je _null_block
447*e57bf680SSanjoy Das           //  _non_null_block:
448*e57bf680SSanjoy Das           //    %rdx<def> = INST
449*e57bf680SSanjoy Das           //    ...
450*e57bf680SSanjoy Das           if (AnyAliasLiveIn(TRI, NullSucc, MO.getReg()))
451*e57bf680SSanjoy Das             return false;
452*e57bf680SSanjoy Das 
453*e57bf680SSanjoy Das           // Make sure Dependency isn't re-defining the base register.  Then we
454*e57bf680SSanjoy Das           // won't get the memory operation on the address we want.
455*e57bf680SSanjoy Das           if (TRI->regsOverlap(MO.getReg(), BaseReg))
456*e57bf680SSanjoy Das             return false;
457*e57bf680SSanjoy Das 
458*e57bf680SSanjoy Das           return true;
459*e57bf680SSanjoy Das         };
460*e57bf680SSanjoy Das 
461*e57bf680SSanjoy Das         bool DependencyOperandsAreOk =
462*e57bf680SSanjoy Das             !Dependency ||
463*e57bf680SSanjoy Das             all_of(Dependency->operands(), DependencyOperandIsOk);
464*e57bf680SSanjoy Das 
465*e57bf680SSanjoy Das         if (DependencyOperandsAreOk) {
466*e57bf680SSanjoy Das           NullCheckList.emplace_back(MI, MBP.ConditionDef, &MBB, NotNullSucc,
467*e57bf680SSanjoy Das                                      NullSucc, Dependency);
468*e57bf680SSanjoy Das           return true;
469*e57bf680SSanjoy Das         }
47069fad079SSanjoy Das       }
47169fad079SSanjoy Das 
472edc394f1SSanjoy Das     HD.rememberInstruction(MI);
473edc394f1SSanjoy Das     if (HD.isClobbered())
474b7718454SSanjoy Das       return false;
475b7718454SSanjoy Das   }
476b7718454SSanjoy Das 
47769fad079SSanjoy Das   return false;
47869fad079SSanjoy Das }
47969fad079SSanjoy Das 
48069fad079SSanjoy Das /// Wrap a machine load instruction, LoadMI, into a FAULTING_LOAD_OP machine
48169fad079SSanjoy Das /// instruction.  The FAULTING_LOAD_OP instruction does the same load as LoadMI
4824e1d389aSQuentin Colombet /// (defining the same register), and branches to HandlerMBB if the load
48369fad079SSanjoy Das /// faults.  The FAULTING_LOAD_OP instruction is inserted at the end of MBB.
4844e1d389aSQuentin Colombet MachineInstr *
4854e1d389aSQuentin Colombet ImplicitNullChecks::insertFaultingLoad(MachineInstr *LoadMI,
48669fad079SSanjoy Das                                        MachineBasicBlock *MBB,
4874e1d389aSQuentin Colombet                                        MachineBasicBlock *HandlerMBB) {
48893d608c3SSanjoy Das   const unsigned NoRegister = 0; // Guaranteed to be the NoRegister value for
48993d608c3SSanjoy Das                                  // all targets.
49093d608c3SSanjoy Das 
49169fad079SSanjoy Das   DebugLoc DL;
49269fad079SSanjoy Das   unsigned NumDefs = LoadMI->getDesc().getNumDefs();
49393d608c3SSanjoy Das   assert(NumDefs <= 1 && "other cases unhandled!");
49469fad079SSanjoy Das 
49593d608c3SSanjoy Das   unsigned DefReg = NoRegister;
49693d608c3SSanjoy Das   if (NumDefs != 0) {
49793d608c3SSanjoy Das     DefReg = LoadMI->defs().begin()->getReg();
49869fad079SSanjoy Das     assert(std::distance(LoadMI->defs().begin(), LoadMI->defs().end()) == 1 &&
49969fad079SSanjoy Das            "expected exactly one def!");
50093d608c3SSanjoy Das   }
50169fad079SSanjoy Das 
50269fad079SSanjoy Das   auto MIB = BuildMI(MBB, DL, TII->get(TargetOpcode::FAULTING_LOAD_OP), DefReg)
5034e1d389aSQuentin Colombet                  .addMBB(HandlerMBB)
50469fad079SSanjoy Das                  .addImm(LoadMI->getOpcode());
50569fad079SSanjoy Das 
50669fad079SSanjoy Das   for (auto &MO : LoadMI->uses())
50769fad079SSanjoy Das     MIB.addOperand(MO);
50869fad079SSanjoy Das 
50969fad079SSanjoy Das   MIB.setMemRefs(LoadMI->memoperands_begin(), LoadMI->memoperands_end());
51069fad079SSanjoy Das 
51169fad079SSanjoy Das   return MIB;
51269fad079SSanjoy Das }
51369fad079SSanjoy Das 
51469fad079SSanjoy Das /// Rewrite the null checks in NullCheckList into implicit null checks.
51569fad079SSanjoy Das void ImplicitNullChecks::rewriteNullChecks(
51669fad079SSanjoy Das     ArrayRef<ImplicitNullChecks::NullCheck> NullCheckList) {
51769fad079SSanjoy Das   DebugLoc DL;
51869fad079SSanjoy Das 
51969fad079SSanjoy Das   for (auto &NC : NullCheckList) {
52069fad079SSanjoy Das     // Remove the conditional branch dependent on the null check.
521e173b9aeSSanjoy Das     unsigned BranchesRemoved = TII->RemoveBranch(*NC.getCheckBlock());
52269fad079SSanjoy Das     (void)BranchesRemoved;
52369fad079SSanjoy Das     assert(BranchesRemoved > 0 && "expected at least one branch!");
52469fad079SSanjoy Das 
525*e57bf680SSanjoy Das     if (auto *DepMI = NC.getOnlyDependency()) {
526*e57bf680SSanjoy Das       DepMI->removeFromParent();
527*e57bf680SSanjoy Das       NC.getCheckBlock()->insert(NC.getCheckBlock()->end(), DepMI);
528*e57bf680SSanjoy Das     }
529*e57bf680SSanjoy Das 
53069fad079SSanjoy Das     // Insert a faulting load where the conditional branch was originally.  We
53169fad079SSanjoy Das     // check earlier ensures that this bit of code motion is legal.  We do not
53269fad079SSanjoy Das     // touch the successors list for any basic block since we haven't changed
53369fad079SSanjoy Das     // control flow, we've just made it implicit.
534e173b9aeSSanjoy Das     MachineInstr *FaultingLoad = insertFaultingLoad(
535e173b9aeSSanjoy Das         NC.getMemOperation(), NC.getCheckBlock(), NC.getNullSucc());
53626dab3a4SQuentin Colombet     // Now the values defined by MemOperation, if any, are live-in of
53726dab3a4SQuentin Colombet     // the block of MemOperation.
53826dab3a4SQuentin Colombet     // The original load operation may define implicit-defs alongside
53926dab3a4SQuentin Colombet     // the loaded value.
540e173b9aeSSanjoy Das     MachineBasicBlock *MBB = NC.getMemOperation()->getParent();
54126dab3a4SQuentin Colombet     for (const MachineOperand &MO : FaultingLoad->operands()) {
54226dab3a4SQuentin Colombet       if (!MO.isReg() || !MO.isDef())
54326dab3a4SQuentin Colombet         continue;
54426dab3a4SQuentin Colombet       unsigned Reg = MO.getReg();
54526dab3a4SQuentin Colombet       if (!Reg || MBB->isLiveIn(Reg))
54626dab3a4SQuentin Colombet         continue;
54712b69919SQuentin Colombet       MBB->addLiveIn(Reg);
54812b69919SQuentin Colombet     }
549*e57bf680SSanjoy Das 
550*e57bf680SSanjoy Das     if (auto *DepMI = NC.getOnlyDependency()) {
551*e57bf680SSanjoy Das       for (auto &MO : DepMI->operands()) {
552*e57bf680SSanjoy Das         if (!MO.isReg() || !MO.getReg() || !MO.isDef())
553*e57bf680SSanjoy Das           continue;
554*e57bf680SSanjoy Das         if (!NC.getNotNullSucc()->isLiveIn(MO.getReg()))
555*e57bf680SSanjoy Das           NC.getNotNullSucc()->addLiveIn(MO.getReg());
556*e57bf680SSanjoy Das       }
557*e57bf680SSanjoy Das     }
558*e57bf680SSanjoy Das 
559e173b9aeSSanjoy Das     NC.getMemOperation()->eraseFromParent();
560e173b9aeSSanjoy Das     NC.getCheckOperation()->eraseFromParent();
56169fad079SSanjoy Das 
56269fad079SSanjoy Das     // Insert an *unconditional* branch to not-null successor.
563e173b9aeSSanjoy Das     TII->InsertBranch(*NC.getCheckBlock(), NC.getNotNullSucc(), nullptr,
564e173b9aeSSanjoy Das                       /*Cond=*/None, DL);
56569fad079SSanjoy Das 
5668ee6a30bSSanjoy Das     NumImplicitNullChecks++;
56769fad079SSanjoy Das   }
56869fad079SSanjoy Das }
56969fad079SSanjoy Das 
57069fad079SSanjoy Das char ImplicitNullChecks::ID = 0;
57169fad079SSanjoy Das char &llvm::ImplicitNullChecksID = ImplicitNullChecks::ID;
57269fad079SSanjoy Das INITIALIZE_PASS_BEGIN(ImplicitNullChecks, "implicit-null-checks",
57369fad079SSanjoy Das                       "Implicit null checks", false, false)
574*e57bf680SSanjoy Das INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
57569fad079SSanjoy Das INITIALIZE_PASS_END(ImplicitNullChecks, "implicit-null-checks",
57669fad079SSanjoy Das                     "Implicit null checks", false, false)
577