blob: f9d258f44a622a6de9ee367d10e3dd8e060e3460 [file] [log] [blame]
Tom Stellard2f7cdda2013-08-06 23:08:28 +00001//===-- SIFixSGPRCopies.cpp - Remove potential VGPR => SGPR copies --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// Copies from VGPR to SGPR registers are illegal and the register coalescer
12/// will sometimes generate these illegal copies in situations like this:
13///
14/// Register Class <vsrc> is the union of <vgpr> and <sgpr>
15///
16/// BB0:
17/// %vreg0 <sgpr> = SCALAR_INST
18/// %vreg1 <vsrc> = COPY %vreg0 <sgpr>
19/// ...
20/// BRANCH %cond BB1, BB2
21/// BB1:
22/// %vreg2 <vgpr> = VECTOR_INST
23/// %vreg3 <vsrc> = COPY %vreg2 <vgpr>
24/// BB2:
25/// %vreg4 <vsrc> = PHI %vreg1 <vsrc>, <BB#0>, %vreg3 <vrsc>, <BB#1>
NAKAMURA Takumi78e80cd2013-11-14 04:05:22 +000026/// %vreg5 <vgpr> = VECTOR_INST %vreg4 <vsrc>
Tom Stellard2f7cdda2013-08-06 23:08:28 +000027///
NAKAMURA Takumi78e80cd2013-11-14 04:05:22 +000028///
Tom Stellard2f7cdda2013-08-06 23:08:28 +000029/// The coalescer will begin at BB0 and eliminate its copy, then the resulting
30/// code will look like this:
31///
32/// BB0:
33/// %vreg0 <sgpr> = SCALAR_INST
34/// ...
35/// BRANCH %cond BB1, BB2
36/// BB1:
37/// %vreg2 <vgpr> = VECTOR_INST
38/// %vreg3 <vsrc> = COPY %vreg2 <vgpr>
39/// BB2:
40/// %vreg4 <sgpr> = PHI %vreg0 <sgpr>, <BB#0>, %vreg3 <vsrc>, <BB#1>
41/// %vreg5 <vgpr> = VECTOR_INST %vreg4 <sgpr>
42///
43/// Now that the result of the PHI instruction is an SGPR, the register
44/// allocator is now forced to constrain the register class of %vreg3 to
45/// <sgpr> so we end up with final code like this:
NAKAMURA Takumi78e80cd2013-11-14 04:05:22 +000046///
Tom Stellard2f7cdda2013-08-06 23:08:28 +000047/// BB0:
48/// %vreg0 <sgpr> = SCALAR_INST
49/// ...
50/// BRANCH %cond BB1, BB2
51/// BB1:
52/// %vreg2 <vgpr> = VECTOR_INST
53/// %vreg3 <sgpr> = COPY %vreg2 <vgpr>
54/// BB2:
55/// %vreg4 <sgpr> = PHI %vreg0 <sgpr>, <BB#0>, %vreg3 <sgpr>, <BB#1>
56/// %vreg5 <vgpr> = VECTOR_INST %vreg4 <sgpr>
57///
NAKAMURA Takumi78e80cd2013-11-14 04:05:22 +000058/// Now this code contains an illegal copy from a VGPR to an SGPR.
Tom Stellard2f7cdda2013-08-06 23:08:28 +000059///
60/// In order to avoid this problem, this pass searches for PHI instructions
61/// which define a <vsrc> register and constrains its definition class to
62/// <vgpr> if the user of the PHI's definition register is a vector instruction.
63/// If the PHI's definition class is constrained to <vgpr> then the coalescer
64/// will be unable to perform the COPY removal from the above example which
65/// ultimately led to the creation of an illegal COPY.
66//===----------------------------------------------------------------------===//
67
Wei Ding74da3502017-04-12 23:51:47 +000068#include "llvm/ADT/DenseSet.h"
Tom Stellard2f7cdda2013-08-06 23:08:28 +000069#include "AMDGPU.h"
Eric Christopherd9134482014-08-04 21:25:23 +000070#include "AMDGPUSubtarget.h"
Tom Stellard2f7cdda2013-08-06 23:08:28 +000071#include "SIInstrInfo.h"
Tom Stellard0bc68812016-11-29 00:46:46 +000072#include "llvm/CodeGen/MachineDominators.h"
Tom Stellard2f7cdda2013-08-06 23:08:28 +000073#include "llvm/CodeGen/MachineFunctionPass.h"
Tom Stellard82166022013-11-13 23:36:37 +000074#include "llvm/CodeGen/MachineInstrBuilder.h"
Tom Stellard2f7cdda2013-08-06 23:08:28 +000075#include "llvm/CodeGen/MachineRegisterInfo.h"
Tom Stellard82166022013-11-13 23:36:37 +000076#include "llvm/Support/Debug.h"
Hans Wennborga74fd702013-11-14 23:24:09 +000077#include "llvm/Support/raw_ostream.h"
Tom Stellard2f7cdda2013-08-06 23:08:28 +000078#include "llvm/Target/TargetMachine.h"
79
80using namespace llvm;
81
Matt Arsenault98f83942016-04-21 18:21:54 +000082#define DEBUG_TYPE "si-fix-sgpr-copies"
Chandler Carruth84e68b22014-04-22 02:41:26 +000083
Tom Stellard2f7cdda2013-08-06 23:08:28 +000084namespace {
85
86class SIFixSGPRCopies : public MachineFunctionPass {
Tom Stellard0bc68812016-11-29 00:46:46 +000087
88 MachineDominatorTree *MDT;
89
Matt Arsenault782c03b2015-11-03 22:30:13 +000090public:
Tom Stellard2f7cdda2013-08-06 23:08:28 +000091 static char ID;
Tom Stellard2f7cdda2013-08-06 23:08:28 +000092
Matt Arsenault782c03b2015-11-03 22:30:13 +000093 SIFixSGPRCopies() : MachineFunctionPass(ID) { }
Tom Stellard2f7cdda2013-08-06 23:08:28 +000094
Craig Topper5656db42014-04-29 07:57:24 +000095 bool runOnMachineFunction(MachineFunction &MF) override;
Tom Stellard2f7cdda2013-08-06 23:08:28 +000096
Mehdi Amini117296c2016-10-01 02:56:57 +000097 StringRef getPassName() const override { return "SI Fix SGPR copies"; }
Tom Stellard2f7cdda2013-08-06 23:08:28 +000098
Matt Arsenault0cb85172015-09-25 17:21:28 +000099 void getAnalysisUsage(AnalysisUsage &AU) const override {
Tom Stellard0bc68812016-11-29 00:46:46 +0000100 AU.addRequired<MachineDominatorTree>();
101 AU.addPreserved<MachineDominatorTree>();
Matt Arsenault0cb85172015-09-25 17:21:28 +0000102 AU.setPreservesCFG();
103 MachineFunctionPass::getAnalysisUsage(AU);
104 }
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000105};
106
107} // End anonymous namespace
108
Tom Stellard0bc68812016-11-29 00:46:46 +0000109INITIALIZE_PASS_BEGIN(SIFixSGPRCopies, DEBUG_TYPE,
110 "SI Fix SGPR copies", false, false)
111INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
112INITIALIZE_PASS_END(SIFixSGPRCopies, DEBUG_TYPE,
113 "SI Fix SGPR copies", false, false)
114
Matt Arsenault782c03b2015-11-03 22:30:13 +0000115
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000116char SIFixSGPRCopies::ID = 0;
117
Matt Arsenault782c03b2015-11-03 22:30:13 +0000118char &llvm::SIFixSGPRCopiesID = SIFixSGPRCopies::ID;
119
120FunctionPass *llvm::createSIFixSGPRCopiesPass() {
121 return new SIFixSGPRCopies();
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000122}
123
Tom Stellard82166022013-11-13 23:36:37 +0000124static bool hasVGPROperands(const MachineInstr &MI, const SIRegisterInfo *TRI) {
125 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
126 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
127 if (!MI.getOperand(i).isReg() ||
128 !TargetRegisterInfo::isVirtualRegister(MI.getOperand(i).getReg()))
129 continue;
130
131 if (TRI->hasVGPRs(MRI.getRegClass(MI.getOperand(i).getReg())))
132 return true;
133 }
134 return false;
135}
136
Matt Arsenault0de924b2015-11-02 23:15:42 +0000137static std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
138getCopyRegClasses(const MachineInstr &Copy,
139 const SIRegisterInfo &TRI,
140 const MachineRegisterInfo &MRI) {
Tom Stellard82166022013-11-13 23:36:37 +0000141 unsigned DstReg = Copy.getOperand(0).getReg();
142 unsigned SrcReg = Copy.getOperand(1).getReg();
Matt Arsenault120a0c92014-12-03 05:22:39 +0000143
Matt Arsenaultf0d9e472015-10-13 00:07:54 +0000144 const TargetRegisterClass *SrcRC =
145 TargetRegisterInfo::isVirtualRegister(SrcReg) ?
146 MRI.getRegClass(SrcReg) :
147 TRI.getPhysRegClass(SrcReg);
Tom Stellardd33d7f12015-05-12 14:18:11 +0000148
Matt Arsenaultf0d9e472015-10-13 00:07:54 +0000149 // We don't really care about the subregister here.
150 // SrcRC = TRI.getSubRegClass(SrcRC, Copy.getOperand(1).getSubReg());
Tom Stellard82166022013-11-13 23:36:37 +0000151
Matt Arsenaultf0d9e472015-10-13 00:07:54 +0000152 const TargetRegisterClass *DstRC =
153 TargetRegisterInfo::isVirtualRegister(DstReg) ?
154 MRI.getRegClass(DstReg) :
155 TRI.getPhysRegClass(DstReg);
156
157 return std::make_pair(SrcRC, DstRC);
158}
159
Matt Arsenault0de924b2015-11-02 23:15:42 +0000160static bool isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC,
161 const TargetRegisterClass *DstRC,
162 const SIRegisterInfo &TRI) {
Matt Arsenaultf0d9e472015-10-13 00:07:54 +0000163 return TRI.isSGPRClass(DstRC) && TRI.hasVGPRs(SrcRC);
164}
165
Matt Arsenault0de924b2015-11-02 23:15:42 +0000166static bool isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC,
167 const TargetRegisterClass *DstRC,
168 const SIRegisterInfo &TRI) {
Matt Arsenaultf0d9e472015-10-13 00:07:54 +0000169 return TRI.isSGPRClass(SrcRC) && TRI.hasVGPRs(DstRC);
Tom Stellard82166022013-11-13 23:36:37 +0000170}
171
Matt Arsenault0de924b2015-11-02 23:15:42 +0000172// Distribute an SGPR->VGPR copy of a REG_SEQUENCE into a VGPR REG_SEQUENCE.
173//
174// SGPRx = ...
175// SGPRy = REG_SEQUENCE SGPRx, sub0 ...
176// VGPRz = COPY SGPRy
177//
178// ==>
179//
180// VGPRx = COPY SGPRx
181// VGPRz = REG_SEQUENCE VGPRx, sub0
182//
183// This exposes immediate folding opportunities when materializing 64-bit
184// immediates.
185static bool foldVGPRCopyIntoRegSequence(MachineInstr &MI,
186 const SIRegisterInfo *TRI,
187 const SIInstrInfo *TII,
188 MachineRegisterInfo &MRI) {
189 assert(MI.isRegSequence());
190
191 unsigned DstReg = MI.getOperand(0).getReg();
192 if (!TRI->isSGPRClass(MRI.getRegClass(DstReg)))
193 return false;
194
195 if (!MRI.hasOneUse(DstReg))
196 return false;
197
198 MachineInstr &CopyUse = *MRI.use_instr_begin(DstReg);
199 if (!CopyUse.isCopy())
200 return false;
201
Matt Arsenaultfe78ffb2017-04-11 22:29:19 +0000202 // It is illegal to have vreg inputs to a physreg defining reg_sequence.
203 if (TargetRegisterInfo::isPhysicalRegister(CopyUse.getOperand(0).getReg()))
204 return false;
205
Matt Arsenault0de924b2015-11-02 23:15:42 +0000206 const TargetRegisterClass *SrcRC, *DstRC;
207 std::tie(SrcRC, DstRC) = getCopyRegClasses(CopyUse, *TRI, MRI);
208
209 if (!isSGPRToVGPRCopy(SrcRC, DstRC, *TRI))
210 return false;
211
212 // TODO: Could have multiple extracts?
213 unsigned SubReg = CopyUse.getOperand(1).getSubReg();
214 if (SubReg != AMDGPU::NoSubRegister)
215 return false;
216
217 MRI.setRegClass(DstReg, DstRC);
218
219 // SGPRx = ...
220 // SGPRy = REG_SEQUENCE SGPRx, sub0 ...
221 // VGPRz = COPY SGPRy
222
223 // =>
224 // VGPRx = COPY SGPRx
225 // VGPRz = REG_SEQUENCE VGPRx, sub0
226
227 MI.getOperand(0).setReg(CopyUse.getOperand(0).getReg());
228
229 for (unsigned I = 1, N = MI.getNumOperands(); I != N; I += 2) {
230 unsigned SrcReg = MI.getOperand(I).getReg();
Nicolai Haehnle82fc9622016-01-07 17:10:29 +0000231 unsigned SrcSubReg = MI.getOperand(I).getSubReg();
Matt Arsenault0de924b2015-11-02 23:15:42 +0000232
233 const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
234 assert(TRI->isSGPRClass(SrcRC) &&
235 "Expected SGPR REG_SEQUENCE to only have SGPR inputs");
236
237 SrcRC = TRI->getSubRegClass(SrcRC, SrcSubReg);
238 const TargetRegisterClass *NewSrcRC = TRI->getEquivalentVGPRClass(SrcRC);
239
240 unsigned TmpReg = MRI.createVirtualRegister(NewSrcRC);
241
Diana Picus116bbab2017-01-13 09:58:52 +0000242 BuildMI(*MI.getParent(), &MI, MI.getDebugLoc(), TII->get(AMDGPU::COPY),
243 TmpReg)
244 .add(MI.getOperand(I));
Matt Arsenault0de924b2015-11-02 23:15:42 +0000245
246 MI.getOperand(I).setReg(TmpReg);
247 }
248
249 CopyUse.eraseFromParent();
250 return true;
251}
252
Tom Stellard9fdbec82016-11-11 23:35:42 +0000253static bool phiHasVGPROperands(const MachineInstr &PHI,
254 const MachineRegisterInfo &MRI,
255 const SIRegisterInfo *TRI,
256 const SIInstrInfo *TII) {
257
258 for (unsigned i = 1; i < PHI.getNumOperands(); i += 2) {
259 unsigned Reg = PHI.getOperand(i).getReg();
260 if (TRI->hasVGPRs(MRI.getRegClass(Reg)))
261 return true;
262 }
263 return false;
264}
265static bool phiHasBreakDef(const MachineInstr &PHI,
266 const MachineRegisterInfo &MRI,
267 SmallSet<unsigned, 8> &Visited) {
268
269 for (unsigned i = 1; i < PHI.getNumOperands(); i += 2) {
270 unsigned Reg = PHI.getOperand(i).getReg();
271 if (Visited.count(Reg))
272 continue;
273
274 Visited.insert(Reg);
275
276 MachineInstr *DefInstr = MRI.getUniqueVRegDef(Reg);
277 assert(DefInstr);
278 switch (DefInstr->getOpcode()) {
279 default:
280 break;
281 case AMDGPU::SI_BREAK:
282 case AMDGPU::SI_IF_BREAK:
283 case AMDGPU::SI_ELSE_BREAK:
284 return true;
285 case AMDGPU::PHI:
286 if (phiHasBreakDef(*DefInstr, MRI, Visited))
287 return true;
288 }
289 }
290 return false;
291}
292
Tom Stellard0bc68812016-11-29 00:46:46 +0000293static bool hasTerminatorThatModifiesExec(const MachineBasicBlock &MBB,
294 const TargetRegisterInfo &TRI) {
295 for (MachineBasicBlock::const_iterator I = MBB.getFirstTerminator(),
296 E = MBB.end(); I != E; ++I) {
297 if (I->modifiesRegister(AMDGPU::EXEC, &TRI))
298 return true;
299 }
300 return false;
301}
302
Tom Stellard00cfa742016-12-06 21:13:30 +0000303static bool isSafeToFoldImmIntoCopy(const MachineInstr *Copy,
304 const MachineInstr *MoveImm,
305 const SIInstrInfo *TII,
306 unsigned &SMovOp,
307 int64_t &Imm) {
308
309 if (!MoveImm->isMoveImmediate())
310 return false;
311
312 const MachineOperand *ImmOp =
313 TII->getNamedOperand(*MoveImm, AMDGPU::OpName::src0);
314 if (!ImmOp->isImm())
315 return false;
316
317 // FIXME: Handle copies with sub-regs.
318 if (Copy->getOperand(0).getSubReg())
319 return false;
320
321 switch (MoveImm->getOpcode()) {
322 default:
323 return false;
324 case AMDGPU::V_MOV_B32_e32:
325 SMovOp = AMDGPU::S_MOV_B32;
326 break;
327 case AMDGPU::V_MOV_B64_PSEUDO:
328 SMovOp = AMDGPU::S_MOV_B64;
329 break;
330 }
331 Imm = ImmOp->getImm();
332 return true;
333}
334
Wei Ding74da3502017-04-12 23:51:47 +0000335static bool predsHasDivergentTerminator(MachineBasicBlock *MBB,
336 const TargetRegisterInfo *TRI) {
337 DenseSet<MachineBasicBlock*> Visited;
338 SmallVector<MachineBasicBlock*, 4> Worklist(MBB->pred_begin(),
339 MBB->pred_end());
340
341 while (!Worklist.empty()) {
342 MachineBasicBlock *mbb = Worklist.back();
343 Worklist.pop_back();
344
345 if (!Visited.insert(mbb).second)
346 continue;
347 if (hasTerminatorThatModifiesExec(*mbb, *TRI))
348 return true;
349
350 Worklist.insert(Worklist.end(), mbb->pred_begin(), mbb->pred_end());
351 }
352
353 return false;
354}
355
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000356bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000357 const SISubtarget &ST = MF.getSubtarget<SISubtarget>();
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000358 MachineRegisterInfo &MRI = MF.getRegInfo();
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000359 const SIRegisterInfo *TRI = ST.getRegisterInfo();
360 const SIInstrInfo *TII = ST.getInstrInfo();
Tom Stellard0bc68812016-11-29 00:46:46 +0000361 MDT = &getAnalysis<MachineDominatorTree>();
Matt Arsenaultf1aebbf2015-11-02 23:30:48 +0000362
363 SmallVector<MachineInstr *, 16> Worklist;
364
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000365 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
366 BI != BE; ++BI) {
367
368 MachineBasicBlock &MBB = *BI;
369 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
Matt Arsenaultf1aebbf2015-11-02 23:30:48 +0000370 I != E; ++I) {
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000371 MachineInstr &MI = *I;
Tom Stellard82166022013-11-13 23:36:37 +0000372
373 switch (MI.getOpcode()) {
Matt Arsenault85441dd2015-09-21 16:27:22 +0000374 default:
375 continue;
376 case AMDGPU::COPY: {
Matt Arsenaultf0d9e472015-10-13 00:07:54 +0000377 // If the destination register is a physical register there isn't really
378 // much we can do to fix this.
379 if (!TargetRegisterInfo::isVirtualRegister(MI.getOperand(0).getReg()))
380 continue;
381
382 const TargetRegisterClass *SrcRC, *DstRC;
383 std::tie(SrcRC, DstRC) = getCopyRegClasses(MI, *TRI, MRI);
384 if (isVGPRToSGPRCopy(SrcRC, DstRC, *TRI)) {
Tom Stellard00cfa742016-12-06 21:13:30 +0000385 MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(1).getReg());
386 unsigned SMovOp;
387 int64_t Imm;
388 // If we are just copying an immediate, we can replace the copy with
389 // s_mov_b32.
390 if (isSafeToFoldImmIntoCopy(&MI, DefMI, TII, SMovOp, Imm)) {
391 MI.getOperand(1).ChangeToImmediate(Imm);
392 MI.addImplicitDefUseOperands(MF);
393 MI.setDesc(TII->get(SMovOp));
394 break;
395 }
Matt Arsenault85441dd2015-09-21 16:27:22 +0000396 TII->moveToVALU(MI);
397 }
398
399 break;
400 }
Tom Stellard82166022013-11-13 23:36:37 +0000401 case AMDGPU::PHI: {
Tom Stellard82166022013-11-13 23:36:37 +0000402 unsigned Reg = MI.getOperand(0).getReg();
Tom Stellard82166022013-11-13 23:36:37 +0000403 if (!TRI->isSGPRClass(MRI.getRegClass(Reg)))
404 break;
405
Tom Stellard0bc68812016-11-29 00:46:46 +0000406 // We don't need to fix the PHI if the common dominator of the
407 // two incoming blocks terminates with a uniform branch.
408 if (MI.getNumExplicitOperands() == 5) {
409 MachineBasicBlock *MBB0 = MI.getOperand(2).getMBB();
410 MachineBasicBlock *MBB1 = MI.getOperand(4).getMBB();
411
Wei Ding74da3502017-04-12 23:51:47 +0000412 if (!predsHasDivergentTerminator(MBB0, TRI) &&
413 !predsHasDivergentTerminator(MBB1, TRI)) {
Tom Stellard0bc68812016-11-29 00:46:46 +0000414 DEBUG(dbgs() << "Not fixing PHI for uniform branch: " << MI << '\n');
415 break;
416 }
417 }
418
Tom Stellard82166022013-11-13 23:36:37 +0000419 // If a PHI node defines an SGPR and any of its operands are VGPRs,
420 // then we need to move it to the VALU.
Tom Stellarddeb3f9e2014-09-24 01:33:26 +0000421 //
422 // Also, if a PHI node defines an SGPR and has all SGPR operands
423 // we must move it to the VALU, because the SGPR operands will
424 // all end up being assigned the same register, which means
425 // there is a potential for a conflict if different threads take
Matt Arsenaultbfaab762014-10-17 00:36:20 +0000426 // different control flow paths.
Tom Stellarddeb3f9e2014-09-24 01:33:26 +0000427 //
428 // For Example:
429 //
430 // sgpr0 = def;
431 // ...
432 // sgpr1 = def;
433 // ...
434 // sgpr2 = PHI sgpr0, sgpr1
435 // use sgpr2;
436 //
437 // Will Become:
438 //
439 // sgpr2 = def;
440 // ...
441 // sgpr2 = def;
442 // ...
443 // use sgpr2
444 //
Tom Stellarddeb3f9e2014-09-24 01:33:26 +0000445 // The one exception to this rule is when one of the operands
446 // is defined by a SI_BREAK, SI_IF_BREAK, or SI_ELSE_BREAK
447 // instruction. In this case, there we know the program will
448 // never enter the second block (the loop) without entering
449 // the first block (where the condition is computed), so there
450 // is no chance for values to be over-written.
451
Tom Stellard9fdbec82016-11-11 23:35:42 +0000452 SmallSet<unsigned, 8> Visited;
453 if (phiHasVGPROperands(MI, MRI, TRI, TII) ||
Tom Stellard0bc68812016-11-29 00:46:46 +0000454 !phiHasBreakDef(MI, MRI, Visited)) {
455 DEBUG(dbgs() << "Fixing PHI: " << MI);
Tom Stellarddeb3f9e2014-09-24 01:33:26 +0000456 TII->moveToVALU(MI);
Tom Stellard9fdbec82016-11-11 23:35:42 +0000457 }
Tom Stellard82166022013-11-13 23:36:37 +0000458 break;
459 }
460 case AMDGPU::REG_SEQUENCE: {
461 if (TRI->hasVGPRs(TII->getOpRegClass(MI, 0)) ||
Matt Arsenault0de924b2015-11-02 23:15:42 +0000462 !hasVGPROperands(MI, TRI)) {
463 foldVGPRCopyIntoRegSequence(MI, TRI, TII, MRI);
Tom Stellard82166022013-11-13 23:36:37 +0000464 continue;
Matt Arsenault0de924b2015-11-02 23:15:42 +0000465 }
Tom Stellard82166022013-11-13 23:36:37 +0000466
Matt Arsenaultbfaab762014-10-17 00:36:20 +0000467 DEBUG(dbgs() << "Fixing REG_SEQUENCE: " << MI);
Tom Stellard82166022013-11-13 23:36:37 +0000468
469 TII->moveToVALU(MI);
Tom Stellard82166022013-11-13 23:36:37 +0000470 break;
471 }
Tom Stellard204e61b2014-04-07 19:45:45 +0000472 case AMDGPU::INSERT_SUBREG: {
Tom Stellarda5687382014-05-15 14:41:55 +0000473 const TargetRegisterClass *DstRC, *Src0RC, *Src1RC;
Tom Stellard204e61b2014-04-07 19:45:45 +0000474 DstRC = MRI.getRegClass(MI.getOperand(0).getReg());
Tom Stellarda5687382014-05-15 14:41:55 +0000475 Src0RC = MRI.getRegClass(MI.getOperand(1).getReg());
476 Src1RC = MRI.getRegClass(MI.getOperand(2).getReg());
477 if (TRI->isSGPRClass(DstRC) &&
478 (TRI->hasVGPRs(Src0RC) || TRI->hasVGPRs(Src1RC))) {
Matt Arsenaultbfaab762014-10-17 00:36:20 +0000479 DEBUG(dbgs() << " Fixing INSERT_SUBREG: " << MI);
Tom Stellarda5687382014-05-15 14:41:55 +0000480 TII->moveToVALU(MI);
481 }
482 break;
Tom Stellard204e61b2014-04-07 19:45:45 +0000483 }
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000484 }
485 }
486 }
Matt Arsenault6f679782014-11-17 21:11:34 +0000487
488 return true;
Tom Stellard2f7cdda2013-08-06 23:08:28 +0000489}