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");
96bool BPFMISimplifyPatchable::isLoadInst(
unsigned Opcode) {
97 return Opcode == BPF::LDD || Opcode == BPF::LDW || Opcode == BPF::LDH ||
98 Opcode == BPF::LDB || Opcode == BPF::LDW32 || Opcode == BPF::LDH32 ||
114 if (!
MRI->getUniqueVRegDef(MO.getReg()))
120 if (Opcode == BPF::LDB || Opcode == BPF::LDH || Opcode == BPF::LDW ||
121 Opcode == BPF::LDD || Opcode == BPF::STB || Opcode == BPF::STH ||
122 Opcode == BPF::STW || Opcode == BPF::STD)
123 COREOp = BPF::CORE_MEM;
124 else if (Opcode == BPF::LDB32 || Opcode == BPF::LDH32 ||
125 Opcode == BPF::LDW32 || Opcode == BPF::STB32 ||
126 Opcode == BPF::STH32 || Opcode == BPF::STW32)
127 COREOp = BPF::CORE_ALU32_MEM;
139 if (Opcode == BPF::STB || Opcode == BPF::STH || Opcode == BPF::STW ||
140 Opcode == BPF::STD || Opcode == BPF::STB32 || Opcode == BPF::STH32 ||
141 Opcode == BPF::STW32) {
171 if (
MRI->getRegClass(DstReg) == &BPF::GPR32RegClass) {
179 auto Begin =
MRI->use_begin(DstReg),
End =
MRI->use_end();
181 for (
auto I = Begin;
I !=
End;
I = NextI) {
182 NextI = std::next(
I);
183 if (!
MRI->getUniqueVRegDef(
I->getReg()))
186 unsigned Opcode =
I->getParent()->getOpcode();
187 if (Opcode == BPF::SUBREG_TO_REG) {
188 Register TmpReg =
I->getParent()->getOperand(0).getReg();
189 processDstReg(
MRI, TmpReg, DstReg, GVal,
false, IsAma);
195 .
addReg(SrcReg, 0, BPF::sub_32);
200 processDstReg(
MRI, DstReg, SrcReg, GVal,
true, IsAma);
205 bool doSrcRegProp,
bool IsAma) {
206 auto Begin =
MRI->use_begin(DstReg),
End =
MRI->use_end();
208 for (
auto I = Begin;
I !=
End;
I = NextI) {
209 NextI = std::next(
I);
214 if (IsAma &&
MRI->getUniqueVRegDef(
I->getReg()))
215 processInst(
MRI,
I->getParent(), &*
I, GVal);
243 if (isLoadInst(Opcode)) {
244 SkipInsts.insert(Inst);
248 if (Opcode == BPF::ADD_rr)
249 checkADDrr(
MRI, RelocOp, GVal);
250 else if (Opcode == BPF::SLL_rr)
251 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SLL_ri);
252 else if (Opcode == BPF::SRA_rr)
253 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRA_ri);
254 else if (Opcode == BPF::SRL_rr)
255 checkShift(
MRI, *Inst->
getParent(), RelocOp, GVal, BPF::SRL_ri);
259bool BPFMISimplifyPatchable::removeLD() {
262 bool Changed =
false;
272 if (!isLoadInst(
MI.getOpcode()))
275 if (SkipInsts.find(&
MI) != SkipInsts.end())
278 if (!
MI.getOperand(0).isReg() || !
MI.getOperand(1).isReg())
281 if (!
MI.getOperand(2).isImm() ||
MI.getOperand(2).getImm())
291 if (DefInst->
getOpcode() != BPF::LD_imm64)
299 auto *GVar = dyn_cast<GlobalVariable>(GVal);
310 processCandidate(
MRI,
MBB,
MI, SrcReg, DstReg, GVal, IsAma);
323 "BPF PreEmit SimplifyPatchable",
false,
false)
325char BPFMISimplifyPatchable::
ID = 0;
327 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.