26#define RISCV_PUSH_POP_OPT_NAME "RISC-V Zcmp Push/Pop optimization pass"
44class RISCVPushPopOptImpl {
59char RISCVPushPopOptLegacy::ID = 0;
66static
bool isPop(
unsigned Opcode) {
69 case RISCV::QC_CM_POP:
77 assert(
isPop(PopOpcode) &&
"Unexpected Pop Opcode");
81 return IsReturnZero ? RISCV::CM_POPRETZ : RISCV::CM_POPRET;
82 case RISCV::QC_CM_POP:
83 return IsReturnZero ? RISCV::QC_CM_POPRETZ : RISCV::QC_CM_POPRET;
96 MachineInstrBuilder PopRetBuilder =
104 const MCInstrDesc &PopDesc =
MBBI->getDesc();
108 for (
unsigned i = FirstNonDeclaredOp; i <
MBBI->getNumOperands(); ++i)
109 PopRetBuilder.
add(
MBBI->getOperand(i));
112 NextI->eraseFromParent();
122 ModifiedRegUnits.
clear();
123 UsedRegUnits.
clear();
129 MachineInstr &
MI = *
I;
130 if (
auto OperandPair =
TII->isCopyInstrImpl(
MI)) {
131 Register DestReg = OperandPair->Destination->getReg();
133 if (DestReg == RISCV::X10 && Source == RISCV::X0) {
134 MI.removeFromParent();
142 if (!ModifiedRegUnits.
available(RISCV::X10) ||
151 const RISCVSubtarget *Subtarget = &MF.
getSubtarget<RISCVSubtarget>();
152 if (!Subtarget->hasStdExtZcmp() && !Subtarget->hasVendorXqccmp())
160 Subtarget->hasStdExtZimop()) ||
174 for (
auto &
MBB : MF) {
177 if (RetMBBI ==
MBB.
end() || RetMBBI->getOpcode() != RISCV::PseudoRET ||
183 if (
isPop(PopMBBI->getOpcode()) &&
185 Modified |= usePopRet(PopMBBI, RetMBBI, adjustRetVal(PopMBBI));
194 return new RISCVPushPopOptLegacy();
200 RISCVPushPopOptImpl Impl;
201 return Impl.runOnMachineFunction(MF);
207 RISCVPushPopOptImpl Impl;
208 return Impl.runOnMachineFunction(MF)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool isPop(unsigned Opcode)
#define RISCV_PUSH_POP_OPT_NAME
static unsigned getPopRetOpcode(unsigned PopOpcode, bool IsReturnZero)
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
FunctionPass class - This class is used to implement most global optimizations.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
A set of register units used to track register liveness.
static void accumulateUsedDefed(const MachineInstr &MI, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
For a machine instruction MI, adds all register units used in UsedRegUnits and defined or clobbered i...
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
void init(const TargetRegisterInfo &TRI)
Initialize and clear the set.
void clear()
Clears the set.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & add(const MachineOperand &MO) const
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It, then continue incrementing it while it points to a debug instruction.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
FunctionPass * createRISCVPushPopOptLegacyPass()
createRISCVPushPopOptimizationPass - returns an instance of the Push/Pop optimization pass.
IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp=true)
Decrement It, then continue decrementing it while it points to a debug instruction.