43#define DEBUG_TYPE "bpf-mi-zext-elim"
48STATISTIC(ZExtElemNum,
"Number of zero extension shifts eliminated");
52struct BPFMIPeepholeImpl {
65 bool eliminateZExtSeq();
68 std::set<MachineInstr *> PhiInsns;
78 bool ZExtSeqExist, ZExtExist;
79 ZExtSeqExist = eliminateZExtSeq();
80 ZExtExist = eliminateZExt();
81 return ZExtSeqExist || ZExtExist;
88 BPFMIPeepholeLegacy() : MachineFunctionPass(ID) {}
97 LLVM_DEBUG(
dbgs() <<
"*** BPF MachineSSA ZEXT Elim peephole pass ***\n\n");
100bool BPFMIPeepholeImpl::isCopyFrom32Def(MachineInstr *CopyMI) {
114 if (!isInsnFrom32Def(DefInsn))
120bool BPFMIPeepholeImpl::isPhiFrom32Def(MachineInstr *PhiMI) {
121 for (
unsigned i = 1, e = PhiMI->
getNumOperands(); i < e; i += 2) {
127 if (PhiDef->
isPHI()) {
128 if (!PhiInsns.insert(PhiDef).second)
130 if (!isPhiFrom32Def(PhiDef))
133 if (PhiDef->
getOpcode() == BPF::COPY && !isCopyFrom32Def(PhiDef))
141bool BPFMIPeepholeImpl::isInsnFrom32Def(MachineInstr *DefInsn) {
145 if (DefInsn->
isPHI()) {
146 if (!PhiInsns.insert(DefInsn).second)
148 if (!isPhiFrom32Def(DefInsn))
150 }
else if (DefInsn->
getOpcode() == BPF::COPY) {
151 if (!isCopyFrom32Def(DefInsn))
158bool BPFMIPeepholeImpl::isMovFrom32Def(MachineInstr *MovMI)
160 const MachineOperand &Src = MovMI->
getOperand(1);
164 MachineInstr *DefInsn = MRI->
getVRegDef(Src.getReg());
170 if (!isInsnFrom32Def(DefInsn))
178bool BPFMIPeepholeImpl::eliminateZExtSeq() {
179 MachineInstr* ToErase =
nullptr;
180 bool Eliminated =
false;
182 for (MachineBasicBlock &
MBB : *MF) {
183 for (MachineInstr &
MI :
MBB) {
195 if (
MI.getOpcode() == BPF::SRL_ri &&
196 MI.getOperand(2).getImm() == 32) {
199 MachineInstr *SllMI = MRI->
getVRegDef(ShfReg);
223 if (!isMovFrom32Def(MovMI)) {
225 <<
" One ZExt elim sequence failed qualifying elim.\n");
247bool BPFMIPeepholeImpl::eliminateZExt() {
248 MachineInstr* ToErase =
nullptr;
249 bool Eliminated =
false;
251 for (MachineBasicBlock &
MBB : *MF) {
252 for (MachineInstr &
MI :
MBB) {
259 if (
MI.getOpcode() != BPF::MOV_32_64)
272 if (!isMovFrom32Def(&
MI))
296 "BPF MachineSSA Peephole Optimization For ZEXT Eliminate",
299char BPFMIPeepholeLegacy::ID = 0;
301 return new BPFMIPeepholeLegacy();
308 BPFMIPeepholeImpl Impl;
309 return Impl.runOnMachineFunction(MF);
314 BPFMIPeepholeImpl Impl;
315 return Impl.runOnMachineFunction(MF)
321STATISTIC(RedundantMovElemNum,
"Number of redundant moves eliminated");
325struct BPFMIPreEmitPeepholeImpl {
335 bool in16BitRange(
int Num);
336 bool eliminateRedundantMov();
338 bool insertMissingCallerSavedSpills();
339 bool removeMayGotoZero();
340 bool addExitAfterUnreachable();
347 bool Changed = eliminateRedundantMov();
350 Changed |= insertMissingCallerSavedSpills();
351 Changed |= removeMayGotoZero();
352 Changed |= addExitAfterUnreachable();
357class BPFMIPreEmitPeepholeLegacy :
public MachineFunctionPass {
360 BPFMIPreEmitPeepholeLegacy() : MachineFunctionPass(
ID) {}
369 SupportGotol = MF->
getSubtarget<BPFSubtarget>().hasGotol();
373bool BPFMIPreEmitPeepholeImpl::eliminateRedundantMov() {
374 MachineInstr* ToErase =
nullptr;
375 bool Eliminated =
false;
377 for (MachineBasicBlock &
MBB : *MF) {
378 for (MachineInstr &
MI :
MBB) {
396 unsigned Opcode =
MI.getOpcode();
397 if (Opcode == BPF::MOV_rr) {
405 RedundantMovElemNum++;
414bool BPFMIPreEmitPeepholeImpl::in16BitRange(
int Num) {
433bool BPFMIPreEmitPeepholeImpl::adjustBranch() {
435 int CurrNumInsns = 0;
436 DenseMap<MachineBasicBlock *, int> SoFarNumInsns;
437 DenseMap<MachineBasicBlock *, MachineBasicBlock *> FollowThroughBB;
438 std::vector<MachineBasicBlock *> MBBs;
440 MachineBasicBlock *PrevBB =
nullptr;
441 for (MachineBasicBlock &
MBB : *MF) {
447 CurrNumInsns += (int)
MBB.
size();
448 SoFarNumInsns[&
MBB] = CurrNumInsns;
449 if (PrevBB !=
nullptr)
450 FollowThroughBB[PrevBB] = &
MBB;
453 MBBs.push_back(&
MBB);
455 FollowThroughBB[PrevBB] =
nullptr;
457 for (
unsigned i = 0; i < MBBs.size(); i++) {
463 MachineInstr *CondJmp =
nullptr, *UncondJmp =
nullptr;
465 MachineBasicBlock *
MBB = MBBs[i];
467 if (
Term.isConditionalBranch()) {
468 assert(CondJmp ==
nullptr);
470 }
else if (
Term.isUnconditionalBranch()) {
471 assert(UncondJmp ==
nullptr);
477 if (!CondJmp && !UncondJmp)
480 MachineBasicBlock *CondTargetBB, *JmpBB;
481 CurrNumInsns = SoFarNumInsns[
MBB];
484 if (!CondJmp && UncondJmp) {
485 JmpBB = UncondJmp->getOperand(0).getMBB();
486 if (in16BitRange(SoFarNumInsns[JmpBB] - JmpBB->
size() - CurrNumInsns))
498 MachineOperand &CondTarget =
504 CondTargetBB = CondTarget.
getMBB();
505 MachineBasicBlock *FollowBB = FollowThroughBB[
MBB];
506 Dist = SoFarNumInsns[CondTargetBB] - CondTargetBB->
size() - CurrNumInsns;
507 if (in16BitRange(Dist))
524 MachineBasicBlock *New_B0 = MF->CreateMachineBasicBlock(TermBB);
525 MachineBasicBlock *New_B1 = MF->CreateMachineBasicBlock(TermBB);
529 MF->insert(MBB_I, New_B0);
530 MF->insert(MBB_I, New_B1);
533 CondTarget.
setMBB(New_B1);
554 CondTargetBB = CondTarget.
getMBB();
555 JmpBB = UncondJmp->getOperand(0).getMBB();
575 Dist = SoFarNumInsns[CondTargetBB] - CondTargetBB->
size() - CurrNumInsns;
576 if (!in16BitRange(Dist)) {
577 MachineBasicBlock *New_B = MF->CreateMachineBasicBlock(TermBB);
585 if (CondTargetBB != JmpBB)
596 if (!in16BitRange(SoFarNumInsns[JmpBB] - CurrNumInsns)) {
606static const unsigned CallerSavedRegs[] = {BPF::R0, BPF::R1, BPF::R2,
607 BPF::R3, BPF::R4, BPF::R5};
611 unsigned LiveCallerSavedRegs;
614static void collectBPFFastCalls(
const TargetRegisterInfo *
TRI,
615 LivePhysRegs &LiveRegs, MachineBasicBlock &BB,
616 SmallVectorImpl<BPFFastCall> &Calls) {
618 LiveRegs.addLiveOuts(BB);
622 unsigned LiveCallerSavedRegs = 0;
623 for (MCRegister R : CallerSavedRegs) {
624 bool DoSpillFill =
false;
626 DoSpillFill |= !
MI.definesRegister(SR,
TRI) && LiveRegs.contains(SR);
629 LiveCallerSavedRegs |= 1 <<
R;
631 if (LiveCallerSavedRegs)
634 LiveRegs.stepBackward(
MI);
638static int64_t computeMinFixedObjOffset(MachineFrameInfo &MFI,
640 int64_t MinFixedObjOffset = 0;
648 (SlotSize + MinFixedObjOffset % SlotSize) & (SlotSize - 1);
649 return MinFixedObjOffset;
652bool BPFMIPreEmitPeepholeImpl::insertMissingCallerSavedSpills() {
653 MachineFrameInfo &MFI = MF->getFrameInfo();
655 LivePhysRegs LiveRegs;
656 const unsigned SlotSize = 8;
657 int64_t MinFixedObjOffset = computeMinFixedObjOffset(MFI, SlotSize);
659 for (MachineBasicBlock &BB : *MF) {
660 collectBPFFastCalls(
TRI, LiveRegs, BB, Calls);
662 for (BPFFastCall &
Call : Calls) {
663 int64_t CurOffset = MinFixedObjOffset;
664 for (MCRegister
Reg : CallerSavedRegs) {
665 if (((1 <<
Reg) &
Call.LiveCallerSavedRegs) == 0)
668 CurOffset -= SlotSize;
688bool BPFMIPreEmitPeepholeImpl::removeMayGotoZero() {
690 MachineBasicBlock *Prev_MBB, *Curr_MBB =
nullptr;
695 if (Prev_MBB ==
nullptr || Curr_MBB->
empty())
698 MachineInstr &
MI = Curr_MBB->
back();
699 if (
MI.getOpcode() != TargetOpcode::INLINEASM_BR)
707 if (AsmPieces.
size() != 1)
713 if (AsmOpPieces.
size() != 2 || AsmOpPieces[0] !=
"may_goto")
716 if (AsmOpPieces[1] !=
"${0:l}" && AsmOpPieces[1] !=
"$0")
728 for (MachineBasicBlock *Pred : Curr_MBB->
predecessors())
729 Pred->replaceSuccessor(Curr_MBB, Prev_MBB);
734 MI.eraseFromParent();
744bool BPFMIPreEmitPeepholeImpl::addExitAfterUnreachable() {
745 MachineBasicBlock &
MBB = MF->
back();
748 !
MBBI->getOperand(0).isGlobal() ||
759 "BPF PreEmit Peephole Optimization",
false,
false)
761char BPFMIPreEmitPeepholeLegacy::ID = 0;
763 return new BPFMIPreEmitPeepholeLegacy();
766bool BPFMIPreEmitPeepholeLegacy::runOnMachineFunction(
MachineFunction &MF) {
769 BPFMIPreEmitPeepholeImpl Impl;
770 return Impl.runOnMachineFunction(MF);
776 BPFMIPreEmitPeepholeImpl Impl;
777 return Impl.runOnMachineFunction(MF)
789 for (
auto It =
MBB.begin(),
End =
MBB.end(); It !=
End;) {
793 switch (
MI.getOpcode()) {
797 case BPF::LOAD_STACK_ARG_PSEUDO: {
799 int16_t
Off =
MI.getOperand(1).getImm();
804 MI.eraseFromParent();
809 case BPF::STORE_STACK_ARG_PSEUDO: {
810 int16_t
Off =
MI.getOperand(0).getImm();
813 bool IsKill = SrcMO.
isKill();
819 MI.eraseFromParent();
824 case BPF::STORE_STACK_ARG_IMM_PSEUDO: {
825 int16_t
Off =
MI.getOperand(0).getImm();
826 int32_t Val =
MI.getOperand(1).getImm();
832 MI.eraseFromParent();
843class BPFMIExpandStackArgPseudosLegacy :
public MachineFunctionPass {
846 BPFMIExpandStackArgPseudosLegacy() : MachineFunctionPass(
ID) {}
853 "bpf-mi-expand-stack-arg-pseudos",
854 "BPF Stack argument psuedo expansion",
false,
false)
856char BPFMIExpandStackArgPseudosLegacy::ID = 0;
858 return new BPFMIExpandStackArgPseudosLegacy();
861bool BPFMIExpandStackArgPseudosLegacy::runOnMachineFunction(
863 return expandStackArgPseudos(MF);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
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
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Represents analyses that only rely on functions' control flow.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
iterator_range< iterator > terminators()
iterator_range< pred_iterator > predecessors()
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
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.
BasicBlockListType::iterator iterator
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate 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.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
MachineBasicBlock * getMBB() const
void setMBB(MachineBasicBlock *MBB)
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
void push_back(const T &Elt)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
Pass manager infrastructure for declaring and invalidating analyses.
@ BasicBlock
Various leaf nodes.
initializer< Ty > init(const Ty &Val)
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.
constexpr RegState getKillRegState(bool B)
FunctionPass * createBPFMIPeepholeLegacyPass()
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI void SplitString(StringRef Source, SmallVectorImpl< StringRef > &OutFragments, StringRef Delimiters=" \t\n\v\f\r")
SplitString - Split up the specified string according to the specified delimiters,...
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
FunctionPass * createBPFMIPreEmitPeepholeLegacyPass()
@ End
Run the machine verifier once, at the end of the pipeline.
FunctionPass * createBPFMIExpandStackArgPseudosLegacyPass()