43#define DEBUG_TYPE "bpf-mi-simplify-patchable"
58 std::set<MachineInstr *> SkipInsts;
63 bool isLoadInst(
unsigned Opcode);
70 bool doSrcRegProp,
bool IsAma);
94 LLVM_DEBUG(
dbgs() <<
"*** BPF simplify patchable insts pass ***\n\n");
97static bool isST(
unsigned Opcode) {
98 return Opcode == BPF::STB_imm || Opcode == BPF::STH_imm ||
99 Opcode == BPF::STW_imm || Opcode == BPF::STD_imm;
102static bool isSTX32(
unsigned Opcode) {
103 return Opcode == BPF::STB32 || Opcode == BPF::STH32 || Opcode == BPF::STW32;
106static bool isSTX64(
unsigned Opcode) {
107 return Opcode == BPF::STB || Opcode == BPF::STH || Opcode == BPF::STW ||
111static bool isLDX32(
unsigned Opcode) {
112 return Opcode == BPF::LDB32 || Opcode == BPF::LDH32 || Opcode == BPF::LDW32;
115static bool isLDX64(
unsigned Opcode) {
116 return Opcode == BPF::LDB || Opcode == BPF::LDH || Opcode == BPF::LDW ||
120static bool isLDSX(
unsigned Opcode) {
121 return Opcode == BPF::LDBSX || Opcode == BPF::LDHSX || Opcode == BPF::LDWSX;
124bool BPFMISimplifyPatchable::isLoadInst(
unsigned Opcode) {
125 return isLDX32(Opcode) || isLDX64(Opcode) || isLDSX(Opcode);
140 if (!
MRI->getUniqueVRegDef(MO.getReg()))
146 if (isLDX64(Opcode) || isLDSX(Opcode))
147 COREOp = BPF::CORE_LD64;
148 else if (isLDX32(Opcode))
149 COREOp = BPF::CORE_LD32;
150 else if (isSTX64(Opcode) || isSTX32(Opcode) || isST(Opcode))
151 COREOp = BPF::CORE_ST;
163 if (isSTX64(Opcode) || isSTX32(Opcode)) {
193 if (
MRI->getRegClass(DstReg) == &BPF::GPR32RegClass) {
201 auto Begin =
MRI->use_begin(DstReg),
End =
MRI->use_end();
203 for (
auto I = Begin;
I !=
End;
I = NextI) {
204 NextI = std::next(
I);
205 if (!
MRI->getUniqueVRegDef(
I->getReg()))
208 unsigned Opcode =
I->getParent()->getOpcode();
209 if (Opcode == BPF::SUBREG_TO_REG) {
210 Register TmpReg =
I->getParent()->getOperand(0).getReg();
211 processDstReg(
MRI, TmpReg, DstReg, GVal,
false, IsAma);
217 .
addReg(SrcReg, 0, BPF::sub_32);
222 processDstReg(
MRI, DstReg, SrcReg, GVal,
true, IsAma);
227 bool doSrcRegProp,
bool IsAma) {
228 auto Begin =
MRI->use_begin(DstReg),
End =
MRI->use_end();
230 for (
auto I = Begin;
I !=
End;
I = NextI) {
231 NextI = std::next(
I);
260 if (IsAma &&
MRI->getUniqueVRegDef(
I->getReg()))
261 processInst(
MRI,
I->getParent(), &*
I, GVal);
289 if (isLoadInst(Opcode)) {
290 SkipInsts.insert(Inst);
294 if (Opcode == BPF::ADD_rr)
295 checkADDrr(
MRI, RelocOp, GVal);
296 else if (Opcode == BPF::SLL_rr)
297 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SLL_ri);
298 else if (Opcode == BPF::SRA_rr)
299 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRA_ri);
300 else if (Opcode == BPF::SRL_rr)
301 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRL_ri);
305bool BPFMISimplifyPatchable::removeLD() {
308 bool Changed =
false;
318 if (!isLoadInst(
MI.getOpcode()))
321 if (SkipInsts.find(&
MI) != SkipInsts.end())
324 if (!
MI.getOperand(0).isReg() || !
MI.getOperand(1).isReg())
327 if (!
MI.getOperand(2).isImm() ||
MI.getOperand(2).getImm())
337 if (DefInst->
getOpcode() != BPF::LD_imm64)
345 auto *GVar = dyn_cast<GlobalVariable>(GVal);
356 processCandidate(
MRI,
MBB,
MI, SrcReg, DstReg, GVal, IsAma);
369 "BPF PreEmit SimplifyPatchable",
false,
false)
371char BPFMISimplifyPatchable::
ID = 0;
373 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.
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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.
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,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
void initializeBPFMISimplifyPatchablePass(PassRegistry &)
FunctionPass * createBPFMISimplifyPatchablePass()
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.