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);
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) {
223 if (!isMovFrom32Def(MovMI)) {
225 <<
" One ZExt elim sequence failed qualifying elim.\n");
253bool BPFMIPeepholeImpl::eliminateZExt() {
254 MachineInstr* ToErase =
nullptr;
255 bool Eliminated =
false;
257 for (MachineBasicBlock &
MBB : *MF) {
258 for (MachineInstr &
MI :
MBB) {
265 if (
MI.getOpcode() != BPF::MOV_32_64)
278 if (!isMovFrom32Def(&
MI))
302 "BPF MachineSSA Peephole Optimization For ZEXT Eliminate",
305char BPFMIPeepholeLegacy::ID = 0;
307 return new BPFMIPeepholeLegacy();
314 BPFMIPeepholeImpl Impl;
315 return Impl.runOnMachineFunction(MF);
320 BPFMIPeepholeImpl Impl;
321 return Impl.runOnMachineFunction(MF)
327STATISTIC(RedundantMovElemNum,
"Number of redundant moves eliminated");
331struct BPFMIPreEmitPeepholeImpl {
341 bool in16BitRange(
int Num);
342 bool eliminateRedundantMov();
344 bool insertMissingCallerSavedSpills();
345 bool removeMayGotoZero();
346 bool addExitAfterUnreachable();
353 bool Changed = eliminateRedundantMov();
356 Changed |= insertMissingCallerSavedSpills();
357 Changed |= removeMayGotoZero();
358 Changed |= addExitAfterUnreachable();
363class BPFMIPreEmitPeepholeLegacy :
public MachineFunctionPass {
366 BPFMIPreEmitPeepholeLegacy() : MachineFunctionPass(
ID) {}
375 SupportGotol = MF->
getSubtarget<BPFSubtarget>().hasGotol();
379bool BPFMIPreEmitPeepholeImpl::eliminateRedundantMov() {
380 MachineInstr* ToErase =
nullptr;
381 bool Eliminated =
false;
383 for (MachineBasicBlock &
MBB : *MF) {
384 for (MachineInstr &
MI :
MBB) {
402 unsigned Opcode =
MI.getOpcode();
403 if (Opcode == BPF::MOV_rr) {
411 RedundantMovElemNum++;
420bool BPFMIPreEmitPeepholeImpl::in16BitRange(
int Num) {
439bool BPFMIPreEmitPeepholeImpl::adjustBranch() {
441 int CurrNumInsns = 0;
442 DenseMap<MachineBasicBlock *, int> SoFarNumInsns;
443 DenseMap<MachineBasicBlock *, MachineBasicBlock *> FollowThroughBB;
444 std::vector<MachineBasicBlock *> MBBs;
446 MachineBasicBlock *PrevBB =
nullptr;
447 for (MachineBasicBlock &
MBB : *MF) {
453 CurrNumInsns += (int)
MBB.
size();
454 SoFarNumInsns[&
MBB] = CurrNumInsns;
455 if (PrevBB !=
nullptr)
456 FollowThroughBB[PrevBB] = &
MBB;
459 MBBs.push_back(&
MBB);
461 FollowThroughBB[PrevBB] =
nullptr;
463 for (
unsigned i = 0; i < MBBs.size(); i++) {
469 MachineInstr *CondJmp =
nullptr, *UncondJmp =
nullptr;
471 MachineBasicBlock *
MBB = MBBs[i];
473 if (
Term.isConditionalBranch()) {
474 assert(CondJmp ==
nullptr);
476 }
else if (
Term.isUnconditionalBranch()) {
477 assert(UncondJmp ==
nullptr);
483 if (!CondJmp && !UncondJmp)
486 MachineBasicBlock *CondTargetBB, *JmpBB;
487 CurrNumInsns = SoFarNumInsns[
MBB];
490 if (!CondJmp && UncondJmp) {
491 JmpBB = UncondJmp->getOperand(0).getMBB();
492 if (in16BitRange(SoFarNumInsns[JmpBB] - JmpBB->
size() - CurrNumInsns))
504 MachineOperand &CondTarget =
510 CondTargetBB = CondTarget.
getMBB();
511 MachineBasicBlock *FollowBB = FollowThroughBB[
MBB];
512 Dist = SoFarNumInsns[CondTargetBB] - CondTargetBB->
size() - CurrNumInsns;
513 if (in16BitRange(Dist))
530 MachineBasicBlock *New_B0 = MF->CreateMachineBasicBlock(TermBB);
531 MachineBasicBlock *New_B1 = MF->CreateMachineBasicBlock(TermBB);
535 MF->insert(MBB_I, New_B0);
536 MF->insert(MBB_I, New_B1);
539 CondTarget.
setMBB(New_B1);
560 CondTargetBB = CondTarget.
getMBB();
561 JmpBB = UncondJmp->getOperand(0).getMBB();
581 Dist = SoFarNumInsns[CondTargetBB] - CondTargetBB->
size() - CurrNumInsns;
582 if (!in16BitRange(Dist)) {
583 MachineBasicBlock *New_B = MF->CreateMachineBasicBlock(TermBB);
591 if (CondTargetBB != JmpBB)
602 if (!in16BitRange(SoFarNumInsns[JmpBB] - CurrNumInsns)) {
612static const unsigned CallerSavedRegs[] = {BPF::R0, BPF::R1, BPF::R2,
613 BPF::R3, BPF::R4, BPF::R5};
617 unsigned LiveCallerSavedRegs;
620static void collectBPFFastCalls(
const TargetRegisterInfo *
TRI,
621 LivePhysRegs &LiveRegs, MachineBasicBlock &BB,
622 SmallVectorImpl<BPFFastCall> &Calls) {
624 LiveRegs.addLiveOuts(BB);
628 unsigned LiveCallerSavedRegs = 0;
629 for (MCRegister R : CallerSavedRegs) {
630 bool DoSpillFill =
false;
632 DoSpillFill |= !
MI.definesRegister(SR,
TRI) && LiveRegs.contains(SR);
635 LiveCallerSavedRegs |= 1 <<
R;
637 if (LiveCallerSavedRegs)
640 LiveRegs.stepBackward(
MI);
644static int64_t computeMinFixedObjOffset(MachineFrameInfo &MFI,
646 int64_t MinFixedObjOffset = 0;
654 (SlotSize + MinFixedObjOffset % SlotSize) & (SlotSize - 1);
655 return MinFixedObjOffset;
658bool BPFMIPreEmitPeepholeImpl::insertMissingCallerSavedSpills() {
659 MachineFrameInfo &MFI = MF->getFrameInfo();
661 LivePhysRegs LiveRegs;
662 const unsigned SlotSize = 8;
663 int64_t MinFixedObjOffset = computeMinFixedObjOffset(MFI, SlotSize);
665 for (MachineBasicBlock &BB : *MF) {
666 collectBPFFastCalls(
TRI, LiveRegs, BB, Calls);
668 for (BPFFastCall &
Call : Calls) {
669 int64_t CurOffset = MinFixedObjOffset;
670 for (MCRegister
Reg : CallerSavedRegs) {
671 if (((1 <<
Reg) &
Call.LiveCallerSavedRegs) == 0)
674 CurOffset -= SlotSize;
694bool BPFMIPreEmitPeepholeImpl::removeMayGotoZero() {
696 MachineBasicBlock *Prev_MBB, *Curr_MBB =
nullptr;
701 if (Prev_MBB ==
nullptr || Curr_MBB->
empty())
704 MachineInstr &
MI = Curr_MBB->
back();
705 if (
MI.getOpcode() != TargetOpcode::INLINEASM_BR)
713 if (AsmPieces.
size() != 1)
719 if (AsmOpPieces.
size() != 2 || AsmOpPieces[0] !=
"may_goto")
722 if (AsmOpPieces[1] !=
"${0:l}" && AsmOpPieces[1] !=
"$0")
734 for (MachineBasicBlock *Pred : Curr_MBB->
predecessors())
735 Pred->replaceSuccessor(Curr_MBB, Prev_MBB);
740 MI.eraseFromParent();
750bool BPFMIPreEmitPeepholeImpl::addExitAfterUnreachable() {
751 MachineBasicBlock &
MBB = MF->
back();
754 !
MBBI->getOperand(0).isGlobal() ||
765 "BPF PreEmit Peephole Optimization",
false,
false)
767char BPFMIPreEmitPeepholeLegacy::ID = 0;
769 return new BPFMIPreEmitPeepholeLegacy();
772bool BPFMIPreEmitPeepholeLegacy::runOnMachineFunction(
MachineFunction &MF) {
775 BPFMIPreEmitPeepholeImpl Impl;
776 return Impl.runOnMachineFunction(MF);
782 BPFMIPreEmitPeepholeImpl Impl;
783 return Impl.runOnMachineFunction(MF)
795 for (
auto It =
MBB.begin(),
End =
MBB.end(); It !=
End;) {
799 switch (
MI.getOpcode()) {
803 case BPF::LOAD_STACK_ARG_PSEUDO: {
805 int16_t
Off =
MI.getOperand(1).getImm();
810 MI.eraseFromParent();
815 case BPF::STORE_STACK_ARG_PSEUDO: {
816 int16_t
Off =
MI.getOperand(0).getImm();
819 bool IsKill = SrcMO.
isKill();
825 MI.eraseFromParent();
830 case BPF::STORE_STACK_ARG_IMM_PSEUDO: {
831 int16_t
Off =
MI.getOperand(0).getImm();
832 int32_t Val =
MI.getOperand(1).getImm();
838 MI.eraseFromParent();
849class BPFMIExpandStackArgPseudosLegacy :
public MachineFunctionPass {
852 BPFMIExpandStackArgPseudosLegacy() : MachineFunctionPass(
ID) {}
859 "bpf-mi-expand-stack-arg-pseudos",
860 "BPF Stack argument psuedo expansion",
false,
false)
862char BPFMIExpandStackArgPseudosLegacy::ID = 0;
864 return new BPFMIExpandStackArgPseudosLegacy();
867bool BPFMIExpandStackArgPseudosLegacy::runOnMachineFunction(
869 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)
MachineRegisterInfo & MRI
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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
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()