43#define DEBUG_TYPE "bpf-mi-simplify-patchable"
56 std::set<MachineInstr *> SkipInsts;
61 bool isLoadInst(
unsigned Opcode);
68 bool doSrcRegProp,
bool IsAma);
92 LLVM_DEBUG(
dbgs() <<
"*** BPF simplify patchable insts pass ***\n\n");
95static bool isStoreImm(
unsigned Opcode) {
96 return Opcode == BPF::STB_imm || Opcode == BPF::STH_imm ||
97 Opcode == BPF::STW_imm || Opcode == BPF::STD_imm;
100static bool isStore32(
unsigned Opcode) {
101 return Opcode == BPF::STB32 || Opcode == BPF::STH32 || Opcode == BPF::STW32 ||
102 Opcode == BPF::STBREL32 || Opcode == BPF::STHREL32 ||
103 Opcode == BPF::STWREL32;
106static bool isStore64(
unsigned Opcode) {
107 return Opcode == BPF::STB || Opcode == BPF::STH || Opcode == BPF::STW ||
108 Opcode == BPF::STD || Opcode == BPF::STDREL;
111static bool isLoad32(
unsigned Opcode) {
112 return Opcode == BPF::LDB32 || Opcode == BPF::LDH32 || Opcode == BPF::LDW32 ||
113 Opcode == BPF::LDBACQ32 || Opcode == BPF::LDHACQ32 ||
114 Opcode == BPF::LDWACQ32;
117static bool isLoad64(
unsigned Opcode) {
118 return Opcode == BPF::LDB || Opcode == BPF::LDH || Opcode == BPF::LDW ||
119 Opcode == BPF::LDD || Opcode == BPF::LDDACQ;
122static bool isLoadSext(
unsigned Opcode) {
123 return Opcode == BPF::LDBSX || Opcode == BPF::LDHSX || Opcode == BPF::LDWSX;
126bool BPFMISimplifyPatchable::isLoadInst(
unsigned Opcode) {
127 return isLoad32(Opcode) || isLoad64(Opcode) || isLoadSext(Opcode);
142 if (!
MRI->getUniqueVRegDef(MO.getReg()))
148 if (isLoad64(Opcode) || isLoadSext(Opcode))
149 COREOp = BPF::CORE_LD64;
150 else if (isLoad32(Opcode))
151 COREOp = BPF::CORE_LD32;
152 else if (isStore64(Opcode) || isStore32(Opcode) || isStoreImm(Opcode))
153 COREOp = BPF::CORE_ST;
165 if (isStore64(Opcode) || isStore32(Opcode)) {
195 if (
MRI->getRegClass(DstReg) == &BPF::GPR32RegClass) {
203 auto Begin =
MRI->use_begin(DstReg), End =
MRI->use_end();
205 for (
auto I = Begin;
I != End;
I = NextI) {
206 NextI = std::next(
I);
207 if (!
MRI->getUniqueVRegDef(
I->getReg()))
210 unsigned Opcode =
I->getParent()->getOpcode();
211 if (Opcode == BPF::SUBREG_TO_REG) {
212 Register TmpReg =
I->getParent()->getOperand(0).getReg();
213 processDstReg(
MRI, TmpReg, DstReg, GVal,
false, IsAma);
219 .
addReg(SrcReg, 0, BPF::sub_32);
224 processDstReg(
MRI, DstReg, SrcReg, GVal,
true, IsAma);
229 bool doSrcRegProp,
bool IsAma) {
230 auto Begin =
MRI->use_begin(DstReg), End =
MRI->use_end();
232 for (
auto I = Begin;
I != End;
I = NextI) {
233 NextI = std::next(
I);
262 if (IsAma &&
MRI->getUniqueVRegDef(
I->getReg()))
263 processInst(
MRI,
I->getParent(), &*
I, GVal);
291 if (isLoadInst(Opcode)) {
292 SkipInsts.insert(Inst);
296 if (Opcode == BPF::ADD_rr)
297 checkADDrr(
MRI, RelocOp, GVal);
298 else if (Opcode == BPF::SLL_rr)
299 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SLL_ri);
300 else if (Opcode == BPF::SRA_rr)
301 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRA_ri);
302 else if (Opcode == BPF::SRL_rr)
303 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRL_ri);
307bool BPFMISimplifyPatchable::removeLD() {
320 if (!isLoadInst(
MI.getOpcode()))
323 if (SkipInsts.find(&
MI) != SkipInsts.end())
326 if (!
MI.getOperand(0).isReg() || !
MI.getOperand(1).isReg())
329 if (!
MI.getOperand(2).isImm() ||
MI.getOperand(2).getImm())
339 if (DefInst->
getOpcode() != BPF::LD_imm64)
358 processCandidate(
MRI,
MBB,
MI, SrcReg, DstReg, GVal, IsAma);
371 "BPF PreEmit SimplifyPatchable",
false,
false)
373char BPFMISimplifyPatchable::
ID = 0;
375 return new BPFMISimplifyPatchable();
unsigned const MachineRegisterInfo * MRI
const HexagonInstrInfo * TII
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
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.
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 & 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
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
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,...
Wrapper class representing virtual and physical registers.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
FunctionPass * createBPFMISimplifyPatchablePass()
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...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.