1
- // ===- RISCVRVVInitUndef .cpp - Initialize undef vector value to pseudo ----===//
1
+ // ===- InitUndef .cpp - Initialize undef vector value to pseudo ----===//
2
2
//
3
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
4
// See https://llvm.org/LICENSE.txt for license information.
7
7
// ===----------------------------------------------------------------------===//
8
8
//
9
9
// This file implements a function pass that initializes undef vector value to
10
- // temporary pseudo instruction and remove it in expandpseudo pass to prevent
11
- // register allocation resulting in a constraint violated result for vector
12
- // instruction. It also rewrites the NoReg tied operand back to an
13
- // IMPLICIT_DEF.
10
+ // temporary pseudo instruction to prevent register allocation resulting in a
11
+ // constraint violated result for vector instructions. It also rewrites the
12
+ // NoReg tied operand back to an IMPLICIT_DEF.
14
13
//
15
- // RISC-V vector instruction has register overlapping constraint for certain
16
- // instructions, and will cause illegal instruction trap if violated, we use
17
- // early clobber to model this constraint, but it can't prevent register
18
- // allocator allocated same or overlapped if the input register is undef value,
19
- // so convert IMPLICIT_DEF to temporary pseudo instruction and remove it later
20
- // could prevent that happen, it's not best way to resolve this, and it might
14
+ // Certain vector instructions have register overlapping constraints, and
15
+ // will cause illegal instruction trap if violated, we use early clobber to
16
+ // model this constraint, but it can't prevent register allocator allocating
17
+ // same or overlapped if the input register is undef value, so convert
18
+ // IMPLICIT_DEF to temporary pseudo instruction and remove it later could
19
+ // prevent that happen, it's not best way to resolve this, and it might
21
20
// change the order of program or increase the register pressure, so ideally we
22
21
// should model the constraint right, but before we model the constraint right,
23
22
// it's the only way to prevent that happen.
24
23
//
25
- // When we enable the subregister liveness option, it will also trigger same
24
+ // When we enable the subregister liveness option, it will also trigger the same
26
25
// issue due to the partial of register is undef. If we pseudoinit the whole
27
26
// register, then it will generate redundant COPY instruction. Currently, it
28
27
// will generate INSERT_SUBREG to make sure the whole register is occupied
39
38
//
40
39
// ===----------------------------------------------------------------------===//
41
40
42
- #include " RISCV.h"
43
- #include " RISCVSubtarget.h"
44
41
#include " llvm/ADT/SmallSet.h"
45
42
#include " llvm/ADT/SmallVector.h"
46
43
#include " llvm/CodeGen/DetectDeadLanes.h"
47
44
#include " llvm/CodeGen/MachineFunctionPass.h"
45
+ #include " llvm/CodeGen/MachineRegisterInfo.h"
46
+ #include " llvm/CodeGen/TargetInstrInfo.h"
47
+ #include " llvm/CodeGen/TargetRegisterInfo.h"
48
+ #include " llvm/CodeGen/TargetSubtargetInfo.h"
49
+ #include " llvm/InitializePasses.h"
50
+ #include " llvm/Pass.h"
51
+
48
52
using namespace llvm ;
49
53
50
- #define DEBUG_TYPE " riscv- init-undef"
51
- #define RISCV_INIT_UNDEF_NAME " RISC-V init undef pass"
54
+ #define DEBUG_TYPE " init-undef"
55
+ #define INIT_UNDEF_NAME " init- undef- pass"
52
56
53
57
namespace {
54
58
55
- class RISCVInitUndef : public MachineFunctionPass {
59
+ class InitUndef : public MachineFunctionPass {
56
60
const TargetInstrInfo *TII;
57
61
MachineRegisterInfo *MRI;
58
- const RISCVSubtarget *ST;
62
+ const TargetSubtargetInfo *ST;
59
63
const TargetRegisterInfo *TRI;
60
64
61
65
// Newly added vregs, assumed to be fully rewritten
@@ -65,22 +69,19 @@ class RISCVInitUndef : public MachineFunctionPass {
65
69
public:
66
70
static char ID;
67
71
68
- RISCVInitUndef () : MachineFunctionPass(ID) {}
72
+ InitUndef () : MachineFunctionPass(ID) {}
69
73
bool runOnMachineFunction (MachineFunction &MF) override ;
70
74
71
75
void getAnalysisUsage (AnalysisUsage &AU) const override {
72
76
AU.setPreservesCFG ();
73
77
MachineFunctionPass::getAnalysisUsage (AU);
74
78
}
75
79
76
- StringRef getPassName () const override { return RISCV_INIT_UNDEF_NAME ; }
80
+ StringRef getPassName () const override { return INIT_UNDEF_NAME ; }
77
81
78
82
private:
79
83
bool processBasicBlock (MachineFunction &MF, MachineBasicBlock &MBB,
80
84
const DeadLaneDetector &DLD);
81
- bool isVectorRegClass (const Register R);
82
- const TargetRegisterClass *
83
- getVRLargestSuperClass (const TargetRegisterClass *RC) const ;
84
85
bool handleSubReg (MachineFunction &MF, MachineInstr &MI,
85
86
const DeadLaneDetector &DLD);
86
87
bool fixupIllOperand (MachineInstr *MI, MachineOperand &MO);
@@ -89,45 +90,9 @@ class RISCVInitUndef : public MachineFunctionPass {
89
90
90
91
} // end anonymous namespace
91
92
92
- char RISCVInitUndef::ID = 0 ;
93
- INITIALIZE_PASS (RISCVInitUndef, DEBUG_TYPE, RISCV_INIT_UNDEF_NAME, false , false )
94
- char &llvm::RISCVInitUndefID = RISCVInitUndef::ID;
95
-
96
- const TargetRegisterClass *
97
- RISCVInitUndef::getVRLargestSuperClass (const TargetRegisterClass *RC) const {
98
- if (RISCV::VRM8RegClass.hasSubClassEq (RC))
99
- return &RISCV::VRM8RegClass;
100
- if (RISCV::VRM4RegClass.hasSubClassEq (RC))
101
- return &RISCV::VRM4RegClass;
102
- if (RISCV::VRM2RegClass.hasSubClassEq (RC))
103
- return &RISCV::VRM2RegClass;
104
- if (RISCV::VRRegClass.hasSubClassEq (RC))
105
- return &RISCV::VRRegClass;
106
- return RC;
107
- }
108
-
109
- bool RISCVInitUndef::isVectorRegClass (const Register R) {
110
- const TargetRegisterClass *RC = MRI->getRegClass (R);
111
- return RISCV::VRRegClass.hasSubClassEq (RC) ||
112
- RISCV::VRM2RegClass.hasSubClassEq (RC) ||
113
- RISCV::VRM4RegClass.hasSubClassEq (RC) ||
114
- RISCV::VRM8RegClass.hasSubClassEq (RC);
115
- }
116
-
117
- static unsigned getUndefInitOpcode (unsigned RegClassID) {
118
- switch (RegClassID) {
119
- case RISCV::VRRegClassID:
120
- return RISCV::PseudoRVVInitUndefM1;
121
- case RISCV::VRM2RegClassID:
122
- return RISCV::PseudoRVVInitUndefM2;
123
- case RISCV::VRM4RegClassID:
124
- return RISCV::PseudoRVVInitUndefM4;
125
- case RISCV::VRM8RegClassID:
126
- return RISCV::PseudoRVVInitUndefM8;
127
- default :
128
- llvm_unreachable (" Unexpected register class." );
129
- }
130
- }
93
+ char InitUndef::ID = 0 ;
94
+ INITIALIZE_PASS (InitUndef, DEBUG_TYPE, INIT_UNDEF_NAME, false , false )
95
+ char &llvm::InitUndefID = InitUndef::ID;
131
96
132
97
static bool isEarlyClobberMI (MachineInstr &MI) {
133
98
return llvm::any_of (MI.defs (), [](const MachineOperand &DefMO) {
@@ -143,7 +108,7 @@ static bool findImplictDefMIFromReg(Register Reg, MachineRegisterInfo *MRI) {
143
108
return false ;
144
109
}
145
110
146
- bool RISCVInitUndef ::handleReg (MachineInstr *MI) {
111
+ bool InitUndef ::handleReg (MachineInstr *MI) {
147
112
bool Changed = false ;
148
113
for (auto &UseMO : MI->uses ()) {
149
114
if (!UseMO.isReg ())
@@ -152,7 +117,7 @@ bool RISCVInitUndef::handleReg(MachineInstr *MI) {
152
117
continue ;
153
118
if (!UseMO.getReg ().isVirtual ())
154
119
continue ;
155
- if (!isVectorRegClass (UseMO.getReg ()))
120
+ if (!TII-> isVectorRegClass (MRI-> getRegClass ( UseMO.getReg () )))
156
121
continue ;
157
122
158
123
if (UseMO.isUndef () || findImplictDefMIFromReg (UseMO.getReg (), MRI))
@@ -161,7 +126,7 @@ bool RISCVInitUndef::handleReg(MachineInstr *MI) {
161
126
return Changed;
162
127
}
163
128
164
- bool RISCVInitUndef ::handleSubReg (MachineFunction &MF, MachineInstr &MI,
129
+ bool InitUndef ::handleSubReg (MachineFunction &MF, MachineInstr &MI,
165
130
const DeadLaneDetector &DLD) {
166
131
bool Changed = false ;
167
132
@@ -183,7 +148,7 @@ bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
183
148
continue ;
184
149
185
150
const TargetRegisterClass *TargetRegClass =
186
- getVRLargestSuperClass (MRI->getRegClass (Reg));
151
+ TII-> getVRLargestSuperClass (MRI->getRegClass (Reg));
187
152
188
153
LaneBitmask NeedDef = Info.UsedLanes & ~Info.DefinedLanes ;
189
154
@@ -202,11 +167,11 @@ bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
202
167
Register LatestReg = Reg;
203
168
for (auto ind : SubRegIndexNeedInsert) {
204
169
Changed = true ;
205
- const TargetRegisterClass *SubRegClass =
206
- getVRLargestSuperClass ( TRI->getSubRegisterClass (TargetRegClass, ind));
170
+ const TargetRegisterClass *SubRegClass = TII-> getVRLargestSuperClass (
171
+ TRI->getSubRegisterClass (TargetRegClass, ind));
207
172
Register TmpInitSubReg = MRI->createVirtualRegister (SubRegClass);
208
173
BuildMI (*MI.getParent (), &MI, MI.getDebugLoc (),
209
- TII->get (getUndefInitOpcode (SubRegClass->getID ())),
174
+ TII->get (TII-> getUndefInitOpcode (SubRegClass->getID ())),
210
175
TmpInitSubReg);
211
176
Register NewReg = MRI->createVirtualRegister (TargetRegClass);
212
177
BuildMI (*MI.getParent (), &MI, MI.getDebugLoc (),
@@ -223,15 +188,15 @@ bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
223
188
return Changed;
224
189
}
225
190
226
- bool RISCVInitUndef ::fixupIllOperand (MachineInstr *MI, MachineOperand &MO) {
191
+ bool InitUndef ::fixupIllOperand (MachineInstr *MI, MachineOperand &MO) {
227
192
228
193
LLVM_DEBUG (
229
- dbgs () << " Emitting PseudoRVVInitUndef for implicit vector register "
194
+ dbgs () << " Emitting PseudoInitUndef Instruction for implicit vector register "
230
195
<< MO.getReg () << ' \n ' );
231
196
232
197
const TargetRegisterClass *TargetRegClass =
233
- getVRLargestSuperClass (MRI->getRegClass (MO.getReg ()));
234
- unsigned Opcode = getUndefInitOpcode (TargetRegClass->getID ());
198
+ TII-> getVRLargestSuperClass (MRI->getRegClass (MO.getReg ()));
199
+ unsigned Opcode = TII-> getUndefInitOpcode (TargetRegClass->getID ());
235
200
Register NewReg = MRI->createVirtualRegister (TargetRegClass);
236
201
BuildMI (*MI->getParent (), MI, MI->getDebugLoc (), TII->get (Opcode), NewReg);
237
202
MO.setReg (NewReg);
@@ -240,7 +205,7 @@ bool RISCVInitUndef::fixupIllOperand(MachineInstr *MI, MachineOperand &MO) {
240
205
return true ;
241
206
}
242
207
243
- bool RISCVInitUndef ::processBasicBlock (MachineFunction &MF,
208
+ bool InitUndef ::processBasicBlock (MachineFunction &MF,
244
209
MachineBasicBlock &MBB,
245
210
const DeadLaneDetector &DLD) {
246
211
bool Changed = false ;
@@ -252,7 +217,7 @@ bool RISCVInitUndef::processBasicBlock(MachineFunction &MF,
252
217
unsigned UseOpIdx;
253
218
if (MI.getNumDefs () != 0 && MI.isRegTiedToUseOperand (0 , &UseOpIdx)) {
254
219
MachineOperand &UseMO = MI.getOperand (UseOpIdx);
255
- if (UseMO.getReg () == RISCV::NoRegister ) {
220
+ if (UseMO.getReg () == TII-> getNoRegisterValue () ) {
256
221
const TargetRegisterClass *RC =
257
222
TII->getRegClass (MI.getDesc (), UseOpIdx, TRI, MF);
258
223
Register NewDest = MRI->createVirtualRegister (RC);
@@ -275,9 +240,15 @@ bool RISCVInitUndef::processBasicBlock(MachineFunction &MF,
275
240
return Changed;
276
241
}
277
242
278
- bool RISCVInitUndef::runOnMachineFunction (MachineFunction &MF) {
279
- ST = &MF.getSubtarget <RISCVSubtarget>();
280
- if (!ST->hasVInstructions ())
243
+ bool InitUndef::runOnMachineFunction (MachineFunction &MF) {
244
+ ST = &MF.getSubtarget ();
245
+
246
+ // This checks to ensure that the Subtarget being used has support for Vector
247
+ // Instructions. The pass will exit if this is not the case, and provides
248
+ // protection against unnecessary changing register definitions where this is
249
+ // not needed. By default hasVectorInstructions will return false, only in the
250
+ // Architecture specific subtarget override function can this return true.
251
+ if (!ST->hasVectorInstructions ())
281
252
return false ;
282
253
283
254
MRI = &MF.getRegInfo ();
@@ -298,4 +269,4 @@ bool RISCVInitUndef::runOnMachineFunction(MachineFunction &MF) {
298
269
return Changed;
299
270
}
300
271
301
- FunctionPass *llvm::createRISCVInitUndefPass () { return new RISCVInitUndef (); }
272
+ FunctionPass *llvm::createInitUndefPass () { return new InitUndef (); }
0 commit comments