35#define DEBUG_TYPE "bpf-mi-zext-elim"
40STATISTIC(ZExtElemNum,
"Number of zero extension shifts eliminated");
63 bool eliminateZExtSeq();
66 std::set<MachineInstr *> PhiInsns;
79 bool ZExtSeqExist, ZExtExist;
80 ZExtSeqExist = eliminateZExtSeq();
81 ZExtExist = eliminateZExt();
82 return ZExtSeqExist || ZExtExist;
91 LLVM_DEBUG(
dbgs() <<
"*** BPF MachineSSA ZEXT Elim peephole pass ***\n\n");
105 if (!
Reg.isVirtual())
108 if (
MRI->getRegClass(Reg) == &BPF::GPRRegClass)
112 if (!isInsnFrom32Def(DefInsn))
120 for (
unsigned i = 1, e = PhiMI->
getNumOperands(); i < e; i += 2) {
129 if (PhiDef->
isPHI()) {
130 if (!PhiInsns.insert(PhiDef).second)
132 if (!isPhiFrom32Def(PhiDef))
135 if (PhiDef->
getOpcode() == BPF::COPY && !isCopyFrom32Def(PhiDef))
143bool BPFMIPeephole::isInsnFrom32Def(
MachineInstr *DefInsn)
148 if (DefInsn->
isPHI()) {
149 if (!PhiInsns.insert(DefInsn).second)
151 if (!isPhiFrom32Def(DefInsn))
153 }
else if (DefInsn->
getOpcode() == BPF::COPY) {
154 if (!isCopyFrom32Def(DefInsn))
169 if (!isInsnFrom32Def(DefInsn))
177bool BPFMIPeephole::eliminateZExtSeq() {
179 bool Eliminated =
false;
194 if (
MI.getOpcode() == BPF::SRL_ri &&
195 MI.getOperand(2).getImm() == 32) {
222 if (!isMovFrom32Def(MovMI)) {
224 <<
" One ZExt elim sequence failed qualifying elim.\n");
245bool BPFMIPeephole::eliminateZExt() {
247 bool Eliminated =
false;
257 if (
MI.getOpcode() != BPF::MOV_32_64)
270 if (!isMovFrom32Def(&
MI))
293 "BPF MachineSSA Peephole Optimization For ZEXT Eliminate",
296char BPFMIPeephole::
ID = 0;
299STATISTIC(RedundantMovElemNum,
"Number of redundant moves eliminated");
319 bool in16BitRange(
int Num);
320 bool eliminateRedundantMov();
333 Changed = eliminateRedundantMov();
335 Changed = adjustBranch() || Changed;
349bool BPFMIPreEmitPeephole::eliminateRedundantMov() {
351 bool Eliminated =
false;
372 unsigned Opcode =
MI.getOpcode();
373 if (Opcode == BPF::MOV_rr) {
381 RedundantMovElemNum++;
390bool BPFMIPreEmitPeephole::in16BitRange(
int Num) {
409bool BPFMIPreEmitPeephole::adjustBranch() {
410 bool Changed =
false;
411 int CurrNumInsns = 0;
414 std::vector<MachineBasicBlock *> MBBs;
423 CurrNumInsns += (int)
MBB.
size();
424 SoFarNumInsns[&
MBB] = CurrNumInsns;
425 if (PrevBB !=
nullptr)
426 FollowThroughBB[PrevBB] = &
MBB;
431 FollowThroughBB[PrevBB] =
nullptr;
433 for (
unsigned i = 0; i < MBBs.size(); i++) {
443 if (
Term.isConditionalBranch()) {
444 assert(CondJmp ==
nullptr);
446 }
else if (
Term.isUnconditionalBranch()) {
447 assert(UncondJmp ==
nullptr);
453 if (!CondJmp && !UncondJmp)
457 CurrNumInsns = SoFarNumInsns[
MBB];
460 if (!CondJmp && UncondJmp) {
461 JmpBB = UncondJmp->getOperand(0).getMBB();
462 if (in16BitRange(SoFarNumInsns[JmpBB] - JmpBB->
size() - CurrNumInsns))
479 Dist = SoFarNumInsns[CondTargetBB] - CondTargetBB->
size() - CurrNumInsns;
480 if (in16BitRange(Dist))
502 MF->insert(MBB_I, New_B0);
503 MF->insert(MBB_I, New_B1);
538 JmpBB = UncondJmp->getOperand(0).getMBB();
558 Dist = SoFarNumInsns[CondTargetBB] - CondTargetBB->
size() - CurrNumInsns;
559 if (!in16BitRange(Dist)) {
577 if (CondTargetBB != JmpBB)
589 if (!in16BitRange(SoFarNumInsns[JmpBB] - CurrNumInsns)) {
602 "BPF PreEmit Peephole Optimization",
false,
false)
604char BPFMIPreEmitPeephole::
ID = 0;
607 return new BPFMIPreEmitPeephole();
unsigned const MachineRegisterInfo * MRI
static cl::opt< int > GotolAbsLowBound("gotol-abs-low-bound", cl::Hidden, cl::init(INT16_MAX > > 1), cl::desc("Specify gotol lower bound"))
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
LLVM Basic Block Representation.
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.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
iterator_range< iterator > terminators()
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...
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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getNumOperands() const
Retuns the total number of operands.
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.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void initializeBPFMIPreEmitPeepholePass(PassRegistry &)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createBPFMIPreEmitPeepholePass()
void initializeBPFMIPeepholePass(PassRegistry &)
FunctionPass * createBPFMIPeepholePass()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.