42#define DEBUG_TYPE "bpf-mi-simplify-patchable"
57 std::set<MachineInstr *> SkipInsts;
62 bool isLoadInst(
unsigned Opcode);
69 bool doSrcRegProp,
bool IsAma);
93 LLVM_DEBUG(
dbgs() <<
"*** BPF simplify patchable insts pass ***\n\n");
96static bool isST(
unsigned Opcode) {
97 return Opcode == BPF::STB_imm || Opcode == BPF::STH_imm ||
98 Opcode == BPF::STW_imm || Opcode == BPF::STD_imm;
101static bool isSTX32(
unsigned Opcode) {
102 return Opcode == BPF::STB32 || Opcode == BPF::STH32 || Opcode == BPF::STW32;
105static bool isSTX64(
unsigned Opcode) {
106 return Opcode == BPF::STB || Opcode == BPF::STH || Opcode == BPF::STW ||
110static bool isLDX32(
unsigned Opcode) {
111 return Opcode == BPF::LDB32 || Opcode == BPF::LDH32 || Opcode == BPF::LDW32;
114static bool isLDX64(
unsigned Opcode) {
115 return Opcode == BPF::LDB || Opcode == BPF::LDH || Opcode == BPF::LDW ||
119static bool isLDSX(
unsigned Opcode) {
120 return Opcode == BPF::LDBSX || Opcode == BPF::LDHSX || Opcode == BPF::LDWSX;
123bool BPFMISimplifyPatchable::isLoadInst(
unsigned Opcode) {
124 return isLDX32(Opcode) || isLDX64(Opcode) || isLDSX(Opcode);
139 if (!
MRI->getUniqueVRegDef(MO.getReg()))
145 if (isLDX64(Opcode) || isLDSX(Opcode))
146 COREOp = BPF::CORE_LD64;
147 else if (isLDX32(Opcode))
148 COREOp = BPF::CORE_LD32;
149 else if (isSTX64(Opcode) || isSTX32(Opcode) || isST(Opcode))
150 COREOp = BPF::CORE_ST;
162 if (isSTX64(Opcode) || isSTX32(Opcode)) {
192 if (
MRI->getRegClass(DstReg) == &BPF::GPR32RegClass) {
200 auto Begin =
MRI->use_begin(DstReg),
End =
MRI->use_end();
202 for (
auto I = Begin;
I !=
End;
I = NextI) {
203 NextI = std::next(
I);
204 if (!
MRI->getUniqueVRegDef(
I->getReg()))
207 unsigned Opcode =
I->getParent()->getOpcode();
208 if (Opcode == BPF::SUBREG_TO_REG) {
209 Register TmpReg =
I->getParent()->getOperand(0).getReg();
210 processDstReg(
MRI, TmpReg, DstReg, GVal,
false, IsAma);
216 .
addReg(SrcReg, 0, BPF::sub_32);
221 processDstReg(
MRI, DstReg, SrcReg, GVal,
true, IsAma);
226 bool doSrcRegProp,
bool IsAma) {
227 auto Begin =
MRI->use_begin(DstReg),
End =
MRI->use_end();
229 for (
auto I = Begin;
I !=
End;
I = NextI) {
230 NextI = std::next(
I);
259 if (IsAma &&
MRI->getUniqueVRegDef(
I->getReg()))
260 processInst(
MRI,
I->getParent(), &*
I, GVal);
288 if (isLoadInst(Opcode)) {
289 SkipInsts.insert(Inst);
293 if (Opcode == BPF::ADD_rr)
294 checkADDrr(
MRI, RelocOp, GVal);
295 else if (Opcode == BPF::SLL_rr)
296 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SLL_ri);
297 else if (Opcode == BPF::SRA_rr)
298 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRA_ri);
299 else if (Opcode == BPF::SRL_rr)
300 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRL_ri);
304bool BPFMISimplifyPatchable::removeLD() {
307 bool Changed =
false;
317 if (!isLoadInst(
MI.getOpcode()))
320 if (SkipInsts.find(&
MI) != SkipInsts.end())
323 if (!
MI.getOperand(0).isReg() || !
MI.getOperand(1).isReg())
326 if (!
MI.getOperand(2).isImm() ||
MI.getOperand(2).getImm())
336 if (DefInst->
getOpcode() != BPF::LD_imm64)
344 auto *GVar = dyn_cast<GlobalVariable>(GVal);
355 processCandidate(
MRI,
MBB,
MI, SrcReg, DstReg, GVal, IsAma);
368 "BPF PreEmit SimplifyPatchable",
false,
false)
370char BPFMISimplifyPatchable::
ID = 0;
372 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.