46#define DEBUG_TYPE "bpf-mi-simplify-patchable"
50 cl::desc(
"Disable CORE relocation optimization"));
54struct BPFMISimplifyPatchableImpl {
59 std::set<MachineInstr *> SkipInsts;
64 bool isLoadInst(
unsigned Opcode);
71 bool doSrcRegProp,
bool IsAma);
92 BPFMISimplifyPatchableLegacy() : MachineFunctionPass(ID) {}
95 bool runOnMachineFunction(MachineFunction &MF)
override;
102 LLVM_DEBUG(
dbgs() <<
"*** BPF simplify patchable insts pass ***\n\n");
105static bool isStoreImm(
unsigned Opcode) {
106 return Opcode == BPF::STB_imm || Opcode == BPF::STH_imm ||
107 Opcode == BPF::STW_imm || Opcode == BPF::STD_imm;
110static bool isStore32(
unsigned Opcode) {
111 return Opcode == BPF::STB32 || Opcode == BPF::STH32 || Opcode == BPF::STW32 ||
112 Opcode == BPF::STBREL32 || Opcode == BPF::STHREL32 ||
113 Opcode == BPF::STWREL32;
116static bool isStore64(
unsigned Opcode) {
117 return Opcode == BPF::STB || Opcode == BPF::STH || Opcode == BPF::STW ||
118 Opcode == BPF::STD || Opcode == BPF::STDREL;
121static bool isLoad32(
unsigned Opcode) {
122 return Opcode == BPF::LDB32 || Opcode == BPF::LDH32 || Opcode == BPF::LDW32 ||
123 Opcode == BPF::LDBACQ32 || Opcode == BPF::LDHACQ32 ||
124 Opcode == BPF::LDWACQ32;
127static bool isLoad64(
unsigned Opcode) {
128 return Opcode == BPF::LDB || Opcode == BPF::LDH || Opcode == BPF::LDW ||
129 Opcode == BPF::LDD || Opcode == BPF::LDDACQ;
132static bool isLoadSext(
unsigned Opcode) {
133 return Opcode == BPF::LDBSX || Opcode == BPF::LDHSX || Opcode == BPF::LDWSX;
136bool BPFMISimplifyPatchableImpl::isLoadInst(
unsigned Opcode) {
137 return isLoad32(Opcode) || isLoad64(Opcode) || isLoadSext(Opcode);
140void BPFMISimplifyPatchableImpl::checkADDrr(MachineRegisterInfo *MRI,
141 MachineOperand *RelocOp,
142 const GlobalValue *GVal) {
143 const MachineInstr *Inst = RelocOp->
getParent();
144 const MachineOperand *Op1 = &Inst->
getOperand(1);
145 const MachineOperand *Op2 = &Inst->
getOperand(2);
146 const MachineOperand *BaseOp = (RelocOp == Op1) ? Op2 : Op1;
149 const MachineOperand Op0 = Inst->
getOperand(0);
150 for (MachineOperand &MO :
156 MachineInstr *DefInst = MO.getParent();
159 if (isLoad64(Opcode) || isLoadSext(Opcode))
160 COREOp = BPF::CORE_LD64;
161 else if (isLoad32(Opcode))
162 COREOp = BPF::CORE_LD32;
163 else if (isStore64(Opcode) || isStore32(Opcode) || isStoreImm(Opcode))
164 COREOp = BPF::CORE_ST;
169 const MachineOperand &ImmOp = DefInst->
getOperand(2);
176 if (isStore64(Opcode) || isStore32(Opcode)) {
177 const MachineOperand &Opnd = DefInst->
getOperand(0);
189void BPFMISimplifyPatchableImpl::checkShift(MachineRegisterInfo *MRI,
190 MachineBasicBlock &
MBB,
191 MachineOperand *RelocOp,
192 const GlobalValue *GVal,
195 MachineInstr *Inst = RelocOp->
getParent();
205void BPFMISimplifyPatchableImpl::processCandidate(
206 MachineRegisterInfo *MRI, MachineBasicBlock &
MBB, MachineInstr &
MI,
208 if (MRI->
getRegClass(DstReg) == &BPF::GPR32RegClass) {
218 for (
auto I = Begin;
I != End;
I = NextI) {
219 NextI = std::next(
I);
223 unsigned Opcode =
I->getParent()->getOpcode();
224 if (Opcode == BPF::SUBREG_TO_REG) {
225 Register TmpReg =
I->getParent()->getOperand(0).getReg();
226 processDstReg(MRI, TmpReg, DstReg, GVal,
false, IsAma);
232 .
addReg(SrcReg, {}, BPF::sub_32);
237 processDstReg(MRI, DstReg, SrcReg, GVal,
true, IsAma);
240void BPFMISimplifyPatchableImpl::processDstReg(MachineRegisterInfo *MRI,
243 const GlobalValue *GVal,
244 bool doSrcRegProp,
bool IsAma) {
247 for (
auto I = Begin;
I != End;
I = NextI) {
248 NextI = std::next(
I);
278 processInst(MRI,
I->getParent(), &*
I, GVal);
303void BPFMISimplifyPatchableImpl::processInst(MachineRegisterInfo *MRI,
305 MachineOperand *RelocOp,
306 const GlobalValue *GVal) {
308 if (isLoadInst(Opcode)) {
309 SkipInsts.insert(Inst);
316 if (Opcode == BPF::ADD_rr) {
318 StringRef AccessPattern = GVal->
getName();
321 size_t SecondColon = AccessPattern.
find_first_of(
':', FirstColon + 1);
322 StringRef PatchImmStr =
323 AccessPattern.
substr(SecondColon + 1, FirstDollar - SecondColon);
324 int PatchImm = std::stoll(std::string(PatchImmStr));
325 if (PatchImm <= INT16_MAX)
326 checkADDrr(MRI, RelocOp, GVal);
330 if (Opcode == BPF::SLL_rr)
331 checkShift(MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SLL_ri);
332 else if (Opcode == BPF::SRA_rr)
333 checkShift(MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRA_ri);
334 else if (Opcode == BPF::SRL_rr)
335 checkShift(MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRL_ri);
339bool BPFMISimplifyPatchableImpl::removeLD() {
341 MachineInstr *ToErase =
nullptr;
344 for (MachineBasicBlock &
MBB : *MF) {
345 for (MachineInstr &
MI :
MBB) {
352 if (!isLoadInst(
MI.getOpcode()))
355 if (SkipInsts.find(&
MI) != SkipInsts.end())
358 if (!
MI.getOperand(0).isReg() || !
MI.getOperand(1).isReg())
361 if (!
MI.getOperand(2).isImm() ||
MI.getOperand(2).getImm())
371 if (DefInst->
getOpcode() != BPF::LD_imm64)
374 const MachineOperand &MO = DefInst->
getOperand(1);
378 const GlobalValue *GVal = MO.
getGlobal();
390 processCandidate(MRI,
MBB,
MI, SrcReg, DstReg, GVal, IsAma);
403 "BPF PreEmit SimplifyPatchable",
false,
false)
405char BPFMISimplifyPatchableLegacy::ID = 0;
407 return new BPFMISimplifyPatchableLegacy();
410bool BPFMISimplifyPatchableLegacy::runOnMachineFunction(MachineFunction &MF) {
414 BPFMISimplifyPatchableImpl Impl;
415 return Impl.runOnMachineFunction(MF);
421 BPFMISimplifyPatchableImpl Impl;
422 return Impl.runOnMachineFunction(MF)
static cl::opt< bool > DisableCOREOptimization("disable-bpf-core-optimization", cl::Hidden, cl::desc("Disable CORE relocation optimization"))
const HexagonInstrInfo * TII
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static constexpr StringRef TypeIdAttr
The attribute attached to globals representing a type id.
static constexpr StringRef AmaAttr
The attribute attached to globals representing a field access.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Represents analyses that only rely on functions' control flow.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
use_iterator use_begin(Register RegNo) const
static use_iterator use_end()
iterator_range< use_iterator > use_operands(Register Reg) const
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Wrapper class representing virtual and physical registers.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Pass manager infrastructure for declaring and invalidating analyses.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createBPFMISimplifyPatchableLegacyPass()