LLVM: lib/Target/RISCV/RISCVVMV0Elimination.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
34#ifndef NDEBUG
36#endif
38
39using namespace llvm;
40
41#define DEBUG_TYPE "riscv-vmv0-elimination"
42
43namespace {
44
46public:
47 static char ID;
49
51
52 void getAnalysisUsage(AnalysisUsage &AU) const override {
55 }
56
58
59
60
62 }
63};
64
65}
66
67char RISCVVMV0Elimination::ID = 0;
68
70 false, false)
71
73 return new RISCVVMV0Elimination();
74}
75
77 return MCOI.RegClass == RISCV::VMV0RegClassID;
78}
79
80bool RISCVVMV0Elimination::runOnMachineFunction(MachineFunction &MF) {
81
82 const RISCVSubtarget *ST = &MF.getSubtarget();
83 if (->hasVInstructions())
84 return false;
85
87 const TargetInstrInfo *TII = ST->getInstrInfo();
88
89#ifndef NDEBUG
90
91
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))
100 V0Clobbered = false;
101
103 V0Clobbered = true;
104 }
105
106 assert(!(V0Clobbered &&
108 [](auto *Succ) { return Succ->isLiveIn(RISCV::V0); })) &&
109 "Clobbered a v0 used in a successor");
110 }
111#endif
112
113 bool MadeChange = false;
115
116
117 for (MachineBasicBlock &MBB : MF) {
118 for (MachineInstr &MI : MBB) {
120 "Expected only one or zero vmv0 operands");
121
122 for (auto [OpNo, MCOI] : enumerate(MI.getDesc().operands())) {
124 MachineOperand &MO = MI.getOperand(OpNo);
127 Src.isVirtual() && "vmv0 use in unexpected form");
128
129
130 if (MachineInstr *SrcMI = MRI.getVRegDef(Src);
131 SrcMI->isCopy() && SrcMI->getOperand(1).getReg().isVirtual() &&
132 SrcMI->getOperand(1).getSubReg() == RISCV::NoSubRegister) {
133
134 if (MRI.hasOneNonDBGUse(Src))
136 Src = SrcMI->getOperand(1).getReg();
137 }
138
139 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::COPY), RISCV::V0)
141
142 MO.setReg(RISCV::V0);
143 MadeChange = true;
144 break;
145 }
146 }
147 }
148 }
149
150 for (MachineInstr *MI : DeadCopies)
151 MI->eraseFromParent();
152
153 if (!MadeChange)
154 return false;
155
156
157
158
159 for (MachineBasicBlock &MBB : MF) {
160 for (MachineInstr &MI : MBB) {
161 for (MachineOperand &MO : MI.uses()) {
163 MRI.getRegClass(MO.getReg()) == &RISCV::VMV0RegClass) {
164 MRI.recomputeRegClass(MO.getReg());
165 assert((MRI.getRegClass(MO.getReg()) != &RISCV::VMV0RegClass ||
166 MI.isInlineAsm() ||
167 MRI.getVRegDef(MO.getReg())->isInlineAsm()) &&
168 "Non-inline-asm use of vmv0 left behind");
169 }
170 }
171 }
172 }
173
174 return true;
175}
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)
Definition RISCVVMV0Elimination.cpp:76
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...