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"
44
+ #include " llvm/CodeGen/MachineFunction.h"
47
45
#include " llvm/CodeGen/MachineFunctionPass.h"
46
+ #include " llvm/CodeGen/MachineRegisterInfo.h"
47
+ #include " llvm/CodeGen/TargetInstrInfo.h"
48
+ #include " llvm/CodeGen/TargetRegisterInfo.h"
49
+ #include " llvm/CodeGen/TargetSubtargetInfo.h"
50
+ #include " llvm/InitializePasses.h"
51
+ #include " llvm/Pass.h"
52
+
48
53
using namespace llvm ;
49
54
50
- #define DEBUG_TYPE " riscv- init-undef"
51
- #define RISCV_INIT_UNDEF_NAME " RISC-V init undef pass "
55
+ #define DEBUG_TYPE " init-undef"
56
+ #define INIT_UNDEF_NAME " Init Undef Pass "
52
57
53
58
namespace {
54
59
55
- class RISCVInitUndef : public MachineFunctionPass {
60
+ class InitUndef : public MachineFunctionPass {
56
61
const TargetInstrInfo *TII;
57
62
MachineRegisterInfo *MRI;
58
- const RISCVSubtarget *ST;
63
+ const TargetSubtargetInfo *ST;
59
64
const TargetRegisterInfo *TRI;
60
65
61
66
// Newly added vregs, assumed to be fully rewritten
@@ -65,22 +70,19 @@ class RISCVInitUndef : public MachineFunctionPass {
65
70
public:
66
71
static char ID;
67
72
68
- RISCVInitUndef () : MachineFunctionPass(ID) {}
73
+ InitUndef () : MachineFunctionPass(ID) {}
69
74
bool runOnMachineFunction (MachineFunction &MF) override ;
70
75
71
76
void getAnalysisUsage (AnalysisUsage &AU) const override {
72
77
AU.setPreservesCFG ();
73
78
MachineFunctionPass::getAnalysisUsage (AU);
74
79
}
75
80
76
- StringRef getPassName () const override { return RISCV_INIT_UNDEF_NAME ; }
81
+ StringRef getPassName () const override { return INIT_UNDEF_NAME ; }
77
82
78
83
private:
79
84
bool processBasicBlock (MachineFunction &MF, MachineBasicBlock &MBB,
80
85
const DeadLaneDetector &DLD);
81
- bool isVectorRegClass (const Register R);
82
- const TargetRegisterClass *
83
- getVRLargestSuperClass (const TargetRegisterClass *RC) const ;
84
86
bool handleSubReg (MachineFunction &MF, MachineInstr &MI,
85
87
const DeadLaneDetector &DLD);
86
88
bool fixupIllOperand (MachineInstr *MI, MachineOperand &MO);
@@ -89,45 +91,9 @@ class RISCVInitUndef : public MachineFunctionPass {
89
91
90
92
} // end anonymous namespace
91
93
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
- }
94
+ char InitUndef::ID = 0 ;
95
+ INITIALIZE_PASS (InitUndef, DEBUG_TYPE, INIT_UNDEF_NAME, false , false )
96
+ char &llvm::InitUndefID = InitUndef::ID;
131
97
132
98
static bool isEarlyClobberMI (MachineInstr &MI) {
133
99
return llvm::any_of (MI.defs (), [](const MachineOperand &DefMO) {
@@ -143,7 +109,7 @@ static bool findImplictDefMIFromReg(Register Reg, MachineRegisterInfo *MRI) {
143
109
return false ;
144
110
}
145
111
146
- bool RISCVInitUndef ::handleReg (MachineInstr *MI) {
112
+ bool InitUndef ::handleReg (MachineInstr *MI) {
147
113
bool Changed = false ;
148
114
for (auto &UseMO : MI->uses ()) {
149
115
if (!UseMO.isReg ())
@@ -152,7 +118,7 @@ bool RISCVInitUndef::handleReg(MachineInstr *MI) {
152
118
continue ;
153
119
if (!UseMO.getReg ().isVirtual ())
154
120
continue ;
155
- if (!isVectorRegClass (UseMO.getReg ()))
121
+ if (!TII-> isVectorRegClass (MRI-> getRegClass ( UseMO.getReg () )))
156
122
continue ;
157
123
158
124
if (UseMO.isUndef () || findImplictDefMIFromReg (UseMO.getReg (), MRI))
@@ -161,8 +127,8 @@ bool RISCVInitUndef::handleReg(MachineInstr *MI) {
161
127
return Changed;
162
128
}
163
129
164
- bool RISCVInitUndef ::handleSubReg (MachineFunction &MF, MachineInstr &MI,
165
- const DeadLaneDetector &DLD) {
130
+ bool InitUndef ::handleSubReg (MachineFunction &MF, MachineInstr &MI,
131
+ const DeadLaneDetector &DLD) {
166
132
bool Changed = false ;
167
133
168
134
for (MachineOperand &UseMO : MI.uses ()) {
@@ -183,7 +149,7 @@ bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
183
149
continue ;
184
150
185
151
const TargetRegisterClass *TargetRegClass =
186
- getVRLargestSuperClass (MRI->getRegClass (Reg));
152
+ TII-> getVRLargestSuperClass (MRI->getRegClass (Reg));
187
153
188
154
LaneBitmask NeedDef = Info.UsedLanes & ~Info.DefinedLanes ;
189
155
@@ -202,11 +168,11 @@ bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
202
168
Register LatestReg = Reg;
203
169
for (auto ind : SubRegIndexNeedInsert) {
204
170
Changed = true ;
205
- const TargetRegisterClass *SubRegClass =
206
- getVRLargestSuperClass ( TRI->getSubRegisterClass (TargetRegClass, ind));
171
+ const TargetRegisterClass *SubRegClass = TII-> getVRLargestSuperClass (
172
+ TRI->getSubRegisterClass (TargetRegClass, ind));
207
173
Register TmpInitSubReg = MRI->createVirtualRegister (SubRegClass);
208
174
BuildMI (*MI.getParent (), &MI, MI.getDebugLoc (),
209
- TII->get (getUndefInitOpcode (SubRegClass->getID ())),
175
+ TII->get (TII-> getUndefInitOpcode (SubRegClass->getID ())),
210
176
TmpInitSubReg);
211
177
Register NewReg = MRI->createVirtualRegister (TargetRegClass);
212
178
BuildMI (*MI.getParent (), &MI, MI.getDebugLoc (),
@@ -223,15 +189,16 @@ bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
223
189
return Changed;
224
190
}
225
191
226
- bool RISCVInitUndef ::fixupIllOperand (MachineInstr *MI, MachineOperand &MO) {
192
+ bool InitUndef ::fixupIllOperand (MachineInstr *MI, MachineOperand &MO) {
227
193
228
194
LLVM_DEBUG (
229
- dbgs () << " Emitting PseudoRVVInitUndef for implicit vector register "
230
- << MO.getReg () << ' \n ' );
195
+ dbgs ()
196
+ << " Emitting PseudoInitUndef Instruction for implicit vector register "
197
+ << MO.getReg () << ' \n ' );
231
198
232
199
const TargetRegisterClass *TargetRegClass =
233
- getVRLargestSuperClass (MRI->getRegClass (MO.getReg ()));
234
- unsigned Opcode = getUndefInitOpcode (TargetRegClass->getID ());
200
+ TII-> getVRLargestSuperClass (MRI->getRegClass (MO.getReg ()));
201
+ unsigned Opcode = TII-> getUndefInitOpcode (TargetRegClass->getID ());
235
202
Register NewReg = MRI->createVirtualRegister (TargetRegClass);
236
203
BuildMI (*MI->getParent (), MI, MI->getDebugLoc (), TII->get (Opcode), NewReg);
237
204
MO.setReg (NewReg);
@@ -240,9 +207,8 @@ bool RISCVInitUndef::fixupIllOperand(MachineInstr *MI, MachineOperand &MO) {
240
207
return true ;
241
208
}
242
209
243
- bool RISCVInitUndef::processBasicBlock (MachineFunction &MF,
244
- MachineBasicBlock &MBB,
245
- const DeadLaneDetector &DLD) {
210
+ bool InitUndef::processBasicBlock (MachineFunction &MF, MachineBasicBlock &MBB,
211
+ const DeadLaneDetector &DLD) {
246
212
bool Changed = false ;
247
213
for (MachineBasicBlock::iterator I = MBB.begin (); I != MBB.end (); ++I) {
248
214
MachineInstr &MI = *I;
@@ -252,15 +218,15 @@ bool RISCVInitUndef::processBasicBlock(MachineFunction &MF,
252
218
unsigned UseOpIdx;
253
219
if (MI.getNumDefs () != 0 && MI.isRegTiedToUseOperand (0 , &UseOpIdx)) {
254
220
MachineOperand &UseMO = MI.getOperand (UseOpIdx);
255
- if (UseMO.getReg () == RISCV::NoRegister ) {
221
+ if (UseMO.getReg () == TII-> getNoRegisterValue () ) {
256
222
const TargetRegisterClass *RC =
257
- TII->getRegClass (MI.getDesc (), UseOpIdx, TRI, MF);
223
+ TII->getRegClass (MI.getDesc (), UseOpIdx, TRI, MF);
258
224
Register NewDest = MRI->createVirtualRegister (RC);
259
225
// We don't have a way to update dead lanes, so keep track of the
260
226
// new register so that we avoid querying it later.
261
227
NewRegs.insert (NewDest);
262
- BuildMI (MBB, I, I->getDebugLoc (),
263
- TII-> get (TargetOpcode::IMPLICIT_DEF), NewDest);
228
+ BuildMI (MBB, I, I->getDebugLoc (), TII-> get (TargetOpcode::IMPLICIT_DEF),
229
+ NewDest);
264
230
UseMO.setReg (NewDest);
265
231
Changed = true ;
266
232
}
@@ -275,8 +241,14 @@ bool RISCVInitUndef::processBasicBlock(MachineFunction &MF,
275
241
return Changed;
276
242
}
277
243
278
- bool RISCVInitUndef::runOnMachineFunction (MachineFunction &MF) {
279
- ST = &MF.getSubtarget <RISCVSubtarget>();
244
+ bool InitUndef::runOnMachineFunction (MachineFunction &MF) {
245
+ ST = &MF.getSubtarget ();
246
+
247
+ // This checks to ensure that the Subtarget being used has support for Vector
248
+ // Instructions. The pass will exit if this is not the case, and provides
249
+ // protection against unnecessary changing register definitions where this is
250
+ // not needed. By default hasVInstructions will return false, only in the
251
+ // Architecture specific subtarget override function can this return true.
280
252
if (!ST->hasVInstructions ())
281
253
return false ;
282
254
@@ -297,5 +269,3 @@ bool RISCVInitUndef::runOnMachineFunction(MachineFunction &MF) {
297
269
298
270
return Changed;
299
271
}
300
-
301
- FunctionPass *llvm::createRISCVInitUndefPass () { return new RISCVInitUndef (); }
0 commit comments