49 cl::desc(
"The page size of the target in "
53 #define DEBUG_TYPE "implicit-null-checks"
56 "Number of explicit null checks made implicit");
79 : MemOperation(), CheckOperation(), CheckBlock(), NotNullSucc(),
86 : MemOperation(memOperation), CheckOperation(checkOperation),
87 CheckBlock(checkBlock), NotNullSucc(notNullSucc), NullSucc(nullSucc) {
120 analyzeBlockForNullChecks(MBB, NullCheckList);
122 if (!NullCheckList.
empty())
123 rewriteNullChecks(NullCheckList);
125 return !NullCheckList.
empty();
131 bool ImplicitNullChecks::analyzeBlockForNullChecks(
142 MachineBranchPredicate MBP;
144 if (
TII->AnalyzeBranchPredicate(MBB, MBP,
true))
148 if (!(MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
155 if (!MBP.SingleUseCondition)
161 NotNullSucc = MBP.TrueDest;
162 NullSucc = MBP.FalseDest;
164 NotNullSucc = MBP.FalseDest;
165 NullSucc = MBP.TrueDest;
203 unsigned PointerReg = MBP.LHS.getReg();
215 for (
auto *MMO :
MI->memoperands())
216 if (!MMO->isUnordered())
219 for (
auto &MO :
MI->operands()) {
220 if (MO.isReg() && MO.getReg()) {
221 for (
unsigned Reg : RegDefs)
222 if (TRI->regsOverlap(
Reg, MO.getReg()))
226 for (
unsigned Reg : RegUses)
227 if (TRI->regsOverlap(
Reg, MO.getReg()))
235 for (
auto MII = NotNullSucc->
begin(), MIE = NotNullSucc->
end(); MII != MIE;
238 unsigned BaseReg, Offset;
239 if (
TII->getMemOpBaseRegImmOfs(MI, BaseReg, Offset, TRI))
243 NullCheckList.
emplace_back(MI, MBP.ConditionDef, &MBB, NotNullSucc,
256 if (!MMO->isUnordered())
264 if (!MO.isReg() || !MO.getReg())
268 RegDefs.insert(MO.getReg());
270 RegUses.
insert(MO.getReg());
286 assert(NumDefs == 1 &&
"other cases unhandled!");
289 unsigned DefReg = LoadMI->
defs().begin()->getReg();
290 assert(std::distance(LoadMI->
defs().begin(), LoadMI->
defs().end()) == 1 &&
291 "expected exactly one def!");
294 .addSym(HandlerLabel)
297 for (
auto &MO : LoadMI->
uses())
306 void ImplicitNullChecks::rewriteNullChecks(
310 for (
auto &
NC : NullCheckList) {
311 MCSymbol *HandlerLabel = MMI->getContext().createTempSymbol();
315 (void)BranchesRemoved;
316 assert(BranchesRemoved > 0 &&
"expected at least one branch!");
322 insertFaultingLoad(
NC.MemOperation,
NC.CheckBlock, HandlerLabel);
323 NC.MemOperation->eraseFromParent();
324 NC.CheckOperation->eraseFromParent();
334 NumImplicitNullChecks++;
341 "Implicit null checks",
false,
false)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
iterator_range< mop_iterator > uses()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
DenseSet - This implements a dense probed hash-table based set.
INITIALIZE_PASS_BEGIN(ImplicitNullChecks,"implicit-null-checks","Implicit null checks", false, false) INITIALIZE_PASS_END(ImplicitNullChecks
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
bool isPredicable(QueryType Type=AllInBundle) const
Return true if this instruction has a predicate operand that controls execution.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
iterator_range< mmo_iterator > memoperands()
iterator_range< mop_iterator > operands()
Represents a predicate at the MachineFunction level.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
const TargetRegisterInfo * getTargetRegisterInfo() const
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
implicit null Implicit null false
Reg
All possible values of the reg field in the ModR/M byte.
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
const BasicBlock * getBasicBlock() const
getBasicBlock - Return the LLVM basic block that this instance corresponded to originally.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
TargetInstrInfo - Interface to description of machine instruction set.
mmo_iterator memoperands_end() const
Loading instruction that may page fault, bundled with associated information on how to handle such a ...
initializer< Ty > init(const Ty &Val)
const MachineInstrBuilder & setMemRefs(MachineInstr::mmo_iterator b, MachineInstr::mmo_iterator e) const
unsigned RemoveBranch(MachineBasicBlock &MBB) const override
iterator_range< mop_iterator > defs()
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
void initializeImplicitNullChecksPass(PassRegistry &)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
char & ImplicitNullChecksID
ImplicitNullChecks - This pass folds null pointer checks into nearby memory operations.
std::pair< iterator, bool > insert(const ValueT &V)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
MDNode * getMetadata(unsigned KindID) const
getMetadata - Get the metadata of given kind attached to this Instruction.
Representation of each machine instruction.
void emplace_back(ArgTypes &&...Args)
static cl::opt< unsigned > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in ""bytes"), cl::init(4096))
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, DebugLoc DL) const override
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
MachineModuleInfo & getMMI() const
unsigned pred_size() const
MachineModuleInfo - This class contains meta information specific to a module.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.