#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/CodeGen/FaultMaps.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include <cassert>
#include <cstdint>
#include <iterator>
usingnamespacellvm;
static cl::opt<int> PageSize("imp-null-check-page-size",
cl::desc("The page size of the target in bytes"),
cl::init(4096), cl::Hidden);
static cl::opt<unsigned> MaxInstsToConsider(
"imp-null-max-insts-to-consider",
cl::desc("The max number of instructions to consider hoisting loads over "
"(the algorithm is quadratic over this number)"),
cl::Hidden, cl::init(8));
#define DEBUG_TYPE …
STATISTIC(NumImplicitNullChecks,
"Number of explicit null checks made implicit");
namespace {
class ImplicitNullChecks : public MachineFunctionPass { … };
}
bool ImplicitNullChecks::canHandle(const MachineInstr *MI) { … }
ImplicitNullChecks::DependenceResult
ImplicitNullChecks::computeDependence(const MachineInstr *MI,
ArrayRef<MachineInstr *> Block) { … }
bool ImplicitNullChecks::canReorder(const MachineInstr *A,
const MachineInstr *B) { … }
bool ImplicitNullChecks::runOnMachineFunction(MachineFunction &MF) { … }
static bool AnyAliasLiveIn(const TargetRegisterInfo *TRI,
MachineBasicBlock *MBB, unsigned Reg) { … }
ImplicitNullChecks::AliasResult
ImplicitNullChecks::areMemoryOpsAliased(const MachineInstr &MI,
const MachineInstr *PrevMI) const { … }
ImplicitNullChecks::SuitabilityResult
ImplicitNullChecks::isSuitableMemoryOp(const MachineInstr &MI,
unsigned PointerReg,
ArrayRef<MachineInstr *> PrevInsts) { … }
bool ImplicitNullChecks::canDependenceHoistingClobberLiveIns(
MachineInstr *DependenceMI, MachineBasicBlock *NullSucc) { … }
bool ImplicitNullChecks::canHoistInst(MachineInstr *FaultingMI,
ArrayRef<MachineInstr *> InstsSeenSoFar,
MachineBasicBlock *NullSucc,
MachineInstr *&Dependence) { … }
bool ImplicitNullChecks::analyzeBlockForNullChecks(
MachineBasicBlock &MBB, SmallVectorImpl<NullCheck> &NullCheckList) { … }
MachineInstr *ImplicitNullChecks::insertFaultingInstr(
MachineInstr *MI, MachineBasicBlock *MBB, MachineBasicBlock *HandlerMBB) { … }
void ImplicitNullChecks::rewriteNullChecks(
ArrayRef<ImplicitNullChecks::NullCheck> NullCheckList) { … }
char ImplicitNullChecks::ID = …;
char &llvm::ImplicitNullChecksID = …;
INITIALIZE_PASS_BEGIN(ImplicitNullChecks, DEBUG_TYPE,
"Implicit null checks", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(ImplicitNullChecks, DEBUG_TYPE,
"Implicit null checks", false, false)