41#define DEBUG_TYPE "riscv-vmv0-elimination"
67char RISCVVMV0Elimination::ID = 0;
73 return new RISCVVMV0Elimination();
77 return MCOI.RegClass == RISCV::VMV0RegClassID;
83 if (!
ST->hasVInstructions())
87 const TargetInstrInfo *
TII =
ST->getInstrInfo();
92 const TargetRegisterInfo *
TRI =
MRI.getTargetRegisterInfo();
93 ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.
begin());
94 for (MachineBasicBlock *
MBB : RPOT) {
95 bool V0Clobbered =
false;
96 for (MachineInstr &
MI : *
MBB) {
97 assert(!(
MI.readsRegister(RISCV::V0,
TRI) && V0Clobbered) &&
98 "Inserting a copy to v0 would clobber a read");
99 if (
MI.modifiesRegister(RISCV::V0,
TRI))
108 [](
auto *Succ) { return Succ->isLiveIn(RISCV::V0); })) &&
109 "Clobbered a v0 used in a successor");
113 bool MadeChange =
false;
117 for (MachineBasicBlock &
MBB : MF) {
118 for (MachineInstr &
MI :
MBB) {
120 "Expected only one or zero vmv0 operands");
122 for (
auto [OpNo, MCOI] :
enumerate(
MI.getDesc().operands())) {
124 MachineOperand &MO =
MI.getOperand(OpNo);
127 Src.isVirtual() &&
"vmv0 use in unexpected form");
130 if (MachineInstr *SrcMI =
MRI.getVRegDef(Src);
131 SrcMI->isCopy() && SrcMI->getOperand(1).getReg().isVirtual() &&
132 SrcMI->getOperand(1).getSubReg() == RISCV::NoSubRegister) {
134 if (
MRI.hasOneNonDBGUse(Src))
136 Src = SrcMI->getOperand(1).getReg();
150 for (MachineInstr *
MI : DeadCopies)
151 MI->eraseFromParent();
159 for (MachineBasicBlock &
MBB : MF) {
160 for (MachineInstr &
MI :
MBB) {
161 for (MachineOperand &MO :
MI.uses()) {
163 MRI.getRegClass(MO.
getReg()) == &RISCV::VMV0RegClass) {
167 MRI.getVRegDef(MO.
getReg())->isInlineAsm()) &&
168 "Non-inline-asm use of vmv0 left behind");
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static bool isVMV0(const MCOperandInfo &MCOI)
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
This holds information about one operand of a machine instruction, indicating the register class for ...
iterator_range< succ_iterator > successors()
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.
Properties which a MachineFunction may have at a given point in time.
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.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
void push_back(const T &Elt)
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.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
FunctionPass * createRISCVVMV0EliminationPass()
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...