99// This file contains a pass that performs move related peephole optimizations
1010// as Zcmp has specified. This pass should be run after register allocation.
1111//
12+ // This pass also supports Xqccmp, which has identical instructions.
13+ //
1214// ===----------------------------------------------------------------------===//
1315
1416#include " RISCVInstrInfo.h"
15- #include " RISCVMachineFunctionInfo .h"
17+ #include " RISCVSubtarget .h"
1618
1719using namespace llvm ;
1820
@@ -43,7 +45,7 @@ struct RISCVMoveMerge : public MachineFunctionPass {
4345 MachineBasicBlock::iterator
4446 findMatchingInst (MachineBasicBlock::iterator &MBBI, unsigned InstOpcode,
4547 const DestSourcePair &RegPair);
46- bool mergeMoveSARegPair (MachineBasicBlock &MBB);
48+ bool mergeMoveSARegPair (const RISCVSubtarget &STI, MachineBasicBlock &MBB);
4749 bool runOnMachineFunction (MachineFunction &Fn) override ;
4850
4951 StringRef getPassName () const override { return RISCV_MOVE_MERGE_NAME; }
@@ -56,6 +58,46 @@ char RISCVMoveMerge::ID = 0;
5658INITIALIZE_PASS (RISCVMoveMerge, " riscv-move-merge" , RISCV_MOVE_MERGE_NAME,
5759 false , false )
5860
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+
59101// Check if registers meet CM.MVA01S constraints.
60102bool RISCVMoveMerge::isCandidateToMergeMVA01S (const DestSourcePair &RegPair) {
61103 Register Destination = RegPair.Destination ->getReg ();
@@ -87,7 +129,7 @@ RISCVMoveMerge::mergePairedInsns(MachineBasicBlock::iterator I,
87129 MachineBasicBlock::iterator NextI = next_nodbg (I, E);
88130 DestSourcePair FirstPair = TII->isCopyInstrImpl (*I).value ();
89131 DestSourcePair PairedRegs = TII->isCopyInstrImpl (*Paired).value ();
90- Register ARegInFirstPair = Opcode == RISCV::CM_MVA01S
132+ Register ARegInFirstPair = isMoveFromAToS ( Opcode)
91133 ? FirstPair.Destination ->getReg ()
92134 : FirstPair.Source ->getReg ();
93135
@@ -104,7 +146,7 @@ RISCVMoveMerge::mergePairedInsns(MachineBasicBlock::iterator I,
104146 // mv a0, s2
105147 // mv a1, s1 => cm.mva01s s2,s1
106148 bool StartWithX10 = ARegInFirstPair == RISCV::X10;
107- if (Opcode == RISCV::CM_MVA01S ) {
149+ if (isMoveFromAToS ( Opcode) ) {
108150 Sreg1 = StartWithX10 ? FirstPair.Source : PairedRegs.Source ;
109151 Sreg2 = StartWithX10 ? PairedRegs.Source : FirstPair.Source ;
110152 } else {
@@ -139,8 +181,7 @@ RISCVMoveMerge::findMatchingInst(MachineBasicBlock::iterator &MBBI,
139181 Register SourceReg = SecondPair->Source ->getReg ();
140182 Register DestReg = SecondPair->Destination ->getReg ();
141183
142- if (InstOpcode == RISCV::CM_MVA01S &&
143- isCandidateToMergeMVA01S (*SecondPair)) {
184+ if (isMoveFromAToS (InstOpcode) && isCandidateToMergeMVA01S (*SecondPair)) {
144185 // If register pair is valid and destination registers are different.
145186 if ((RegPair.Destination ->getReg () == DestReg))
146187 return E;
@@ -154,7 +195,7 @@ RISCVMoveMerge::findMatchingInst(MachineBasicBlock::iterator &MBBI,
154195 return E;
155196
156197 return I;
157- } else if (InstOpcode == RISCV::CM_MVSA01 &&
198+ } else if (isMoveFromSToA ( InstOpcode) &&
158199 isCandidateToMergeMVSA01 (*SecondPair)) {
159200 if ((RegPair.Source ->getReg () == SourceReg) ||
160201 (RegPair.Destination ->getReg () == DestReg))
@@ -176,7 +217,8 @@ RISCVMoveMerge::findMatchingInst(MachineBasicBlock::iterator &MBBI,
176217
177218// Finds instructions, which could be represented as C.MV instructions and
178219// merged into CM.MVA01S or CM.MVSA01.
179- bool RISCVMoveMerge::mergeMoveSARegPair (MachineBasicBlock &MBB) {
220+ bool RISCVMoveMerge::mergeMoveSARegPair (const RISCVSubtarget &STI,
221+ MachineBasicBlock &MBB) {
180222 bool Modified = false ;
181223
182224 for (MachineBasicBlock::iterator MBBI = MBB.begin (), E = MBB.end ();
@@ -188,9 +230,9 @@ bool RISCVMoveMerge::mergeMoveSARegPair(MachineBasicBlock &MBB) {
188230 unsigned Opcode = 0 ;
189231
190232 if (isCandidateToMergeMVA01S (*RegPair))
191- Opcode = RISCV::CM_MVA01S ;
233+ Opcode = getMoveFromAToSOpcode (STI) ;
192234 else if (isCandidateToMergeMVSA01 (*RegPair))
193- Opcode = RISCV::CM_MVSA01 ;
235+ Opcode = getMoveFromSToAOpcode (STI) ;
194236 else {
195237 ++MBBI;
196238 continue ;
@@ -215,7 +257,7 @@ bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
215257 return false ;
216258
217259 const RISCVSubtarget *Subtarget = &Fn.getSubtarget <RISCVSubtarget>();
218- if (!Subtarget->hasStdExtZcmp ())
260+ if (!( Subtarget->hasStdExtZcmp () || Subtarget-> hasVendorXqccmp () ))
219261 return false ;
220262
221263 TII = Subtarget->getInstrInfo ();
@@ -227,7 +269,7 @@ bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
227269 UsedRegUnits.init (*TRI);
228270 bool Modified = false ;
229271 for (auto &MBB : Fn)
230- Modified |= mergeMoveSARegPair (MBB);
272+ Modified |= mergeMoveSARegPair (*Subtarget, MBB);
231273 return Modified;
232274}
233275
0 commit comments