9
9
// This file contains a pass that performs move related peephole optimizations
10
10
// as Zcmp has specified. This pass should be run after register allocation.
11
11
//
12
+ // This pass also supports Xqccmp, which has identical instructions.
13
+ //
12
14
// ===----------------------------------------------------------------------===//
13
15
14
16
#include " RISCVInstrInfo.h"
15
- #include " RISCVMachineFunctionInfo .h"
17
+ #include " RISCVSubtarget .h"
16
18
17
19
using namespace llvm ;
18
20
@@ -43,7 +45,7 @@ struct RISCVMoveMerge : public MachineFunctionPass {
43
45
MachineBasicBlock::iterator
44
46
findMatchingInst (MachineBasicBlock::iterator &MBBI, unsigned InstOpcode,
45
47
const DestSourcePair &RegPair);
46
- bool mergeMoveSARegPair (MachineBasicBlock &MBB);
48
+ bool mergeMoveSARegPair (const RISCVSubtarget &STI, MachineBasicBlock &MBB);
47
49
bool runOnMachineFunction (MachineFunction &Fn) override ;
48
50
49
51
StringRef getPassName () const override { return RISCV_MOVE_MERGE_NAME; }
@@ -56,6 +58,46 @@ char RISCVMoveMerge::ID = 0;
56
58
INITIALIZE_PASS (RISCVMoveMerge, " riscv-move-merge" , RISCV_MOVE_MERGE_NAME,
57
59
false , false )
58
60
61
+ static bool isMoveFromAToS(unsigned Opcode) {
62
+ switch (Opcode) {
63
+ case RISCV::CM_MVA01S:
64
+ case RISCV::QC_CM_MVA01S:
65
+ return true ;
66
+ default :
67
+ return false ;
68
+ }
69
+ }
70
+
71
+ static unsigned getMoveFromAToSOpcode (const RISCVSubtarget &STI) {
72
+ if (STI.hasStdExtZcmp ())
73
+ return RISCV::CM_MVA01S;
74
+
75
+ if (STI.hasVendorXqccmp ())
76
+ return RISCV::QC_CM_MVA01S;
77
+
78
+ llvm_unreachable (" Unhandled subtarget with paired A to S move." );
79
+ }
80
+
81
+ static bool isMoveFromSToA (unsigned Opcode) {
82
+ switch (Opcode) {
83
+ case RISCV::CM_MVSA01:
84
+ case RISCV::QC_CM_MVSA01:
85
+ return true ;
86
+ default :
87
+ return false ;
88
+ }
89
+ }
90
+
91
+ static unsigned getMoveFromSToAOpcode (const RISCVSubtarget &STI) {
92
+ if (STI.hasStdExtZcmp ())
93
+ return RISCV::CM_MVSA01;
94
+
95
+ if (STI.hasVendorXqccmp ())
96
+ return RISCV::QC_CM_MVSA01;
97
+
98
+ llvm_unreachable (" Unhandled subtarget with paired S to A move" );
99
+ }
100
+
59
101
// Check if registers meet CM.MVA01S constraints.
60
102
bool RISCVMoveMerge::isCandidateToMergeMVA01S (const DestSourcePair &RegPair) {
61
103
Register Destination = RegPair.Destination ->getReg ();
@@ -87,7 +129,7 @@ RISCVMoveMerge::mergePairedInsns(MachineBasicBlock::iterator I,
87
129
MachineBasicBlock::iterator NextI = next_nodbg (I, E);
88
130
DestSourcePair FirstPair = TII->isCopyInstrImpl (*I).value ();
89
131
DestSourcePair PairedRegs = TII->isCopyInstrImpl (*Paired).value ();
90
- Register ARegInFirstPair = Opcode == RISCV::CM_MVA01S
132
+ Register ARegInFirstPair = isMoveFromAToS ( Opcode)
91
133
? FirstPair.Destination ->getReg ()
92
134
: FirstPair.Source ->getReg ();
93
135
@@ -104,7 +146,7 @@ RISCVMoveMerge::mergePairedInsns(MachineBasicBlock::iterator I,
104
146
// mv a0, s2
105
147
// mv a1, s1 => cm.mva01s s2,s1
106
148
bool StartWithX10 = ARegInFirstPair == RISCV::X10;
107
- if (Opcode == RISCV::CM_MVA01S ) {
149
+ if (isMoveFromAToS ( Opcode) ) {
108
150
Sreg1 = StartWithX10 ? FirstPair.Source : PairedRegs.Source ;
109
151
Sreg2 = StartWithX10 ? PairedRegs.Source : FirstPair.Source ;
110
152
} else {
@@ -139,8 +181,7 @@ RISCVMoveMerge::findMatchingInst(MachineBasicBlock::iterator &MBBI,
139
181
Register SourceReg = SecondPair->Source ->getReg ();
140
182
Register DestReg = SecondPair->Destination ->getReg ();
141
183
142
- if (InstOpcode == RISCV::CM_MVA01S &&
143
- isCandidateToMergeMVA01S (*SecondPair)) {
184
+ if (isMoveFromAToS (InstOpcode) && isCandidateToMergeMVA01S (*SecondPair)) {
144
185
// If register pair is valid and destination registers are different.
145
186
if ((RegPair.Destination ->getReg () == DestReg))
146
187
return E;
@@ -154,7 +195,7 @@ RISCVMoveMerge::findMatchingInst(MachineBasicBlock::iterator &MBBI,
154
195
return E;
155
196
156
197
return I;
157
- } else if (InstOpcode == RISCV::CM_MVSA01 &&
198
+ } else if (isMoveFromSToA ( InstOpcode) &&
158
199
isCandidateToMergeMVSA01 (*SecondPair)) {
159
200
if ((RegPair.Source ->getReg () == SourceReg) ||
160
201
(RegPair.Destination ->getReg () == DestReg))
@@ -176,7 +217,8 @@ RISCVMoveMerge::findMatchingInst(MachineBasicBlock::iterator &MBBI,
176
217
177
218
// Finds instructions, which could be represented as C.MV instructions and
178
219
// merged into CM.MVA01S or CM.MVSA01.
179
- bool RISCVMoveMerge::mergeMoveSARegPair (MachineBasicBlock &MBB) {
220
+ bool RISCVMoveMerge::mergeMoveSARegPair (const RISCVSubtarget &STI,
221
+ MachineBasicBlock &MBB) {
180
222
bool Modified = false ;
181
223
182
224
for (MachineBasicBlock::iterator MBBI = MBB.begin (), E = MBB.end ();
@@ -188,9 +230,9 @@ bool RISCVMoveMerge::mergeMoveSARegPair(MachineBasicBlock &MBB) {
188
230
unsigned Opcode = 0 ;
189
231
190
232
if (isCandidateToMergeMVA01S (*RegPair))
191
- Opcode = RISCV::CM_MVA01S ;
233
+ Opcode = getMoveFromAToSOpcode (STI) ;
192
234
else if (isCandidateToMergeMVSA01 (*RegPair))
193
- Opcode = RISCV::CM_MVSA01 ;
235
+ Opcode = getMoveFromSToAOpcode (STI) ;
194
236
else {
195
237
++MBBI;
196
238
continue ;
@@ -215,7 +257,7 @@ bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
215
257
return false ;
216
258
217
259
const RISCVSubtarget *Subtarget = &Fn.getSubtarget <RISCVSubtarget>();
218
- if (!Subtarget->hasStdExtZcmp ())
260
+ if (!( Subtarget->hasStdExtZcmp () || Subtarget-> hasVendorXqccmp () ))
219
261
return false ;
220
262
221
263
TII = Subtarget->getInstrInfo ();
@@ -227,7 +269,7 @@ bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
227
269
UsedRegUnits.init (*TRI);
228
270
bool Modified = false ;
229
271
for (auto &MBB : Fn)
230
- Modified |= mergeMoveSARegPair (MBB);
272
+ Modified |= mergeMoveSARegPair (*Subtarget, MBB);
231
273
return Modified;
232
274
}
233
275
0 commit comments