Call the version of ConvertCostTableLookup that takes a statically sized array rather...
[oota-llvm.git] / lib / Target / AMDGPU / SIFixSGPRCopies.cpp
1 //===-- 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>
26 ///    %vreg5 <vgpr> = VECTOR_INST %vreg4 <vsrc>
27 ///
28 ///
29 /// 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:
46 ///
47 /// 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 ///
58 /// Now this code contains an illegal copy from a VGPR to an SGPR.
59 ///
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
68 #include "AMDGPU.h"
69 #include "AMDGPUSubtarget.h"
70 #include "SIInstrInfo.h"
71 #include "llvm/CodeGen/MachineFunctionPass.h"
72 #include "llvm/CodeGen/MachineInstrBuilder.h"
73 #include "llvm/CodeGen/MachineRegisterInfo.h"
74 #include "llvm/Support/Debug.h"
75 #include "llvm/Support/raw_ostream.h"
76 #include "llvm/Target/TargetMachine.h"
77
78 using namespace llvm;
79
80 #define DEBUG_TYPE "sgpr-copies"
81
82 namespace {
83
84 class SIFixSGPRCopies : public MachineFunctionPass {
85
86 private:
87   static char ID;
88   std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
89   getCopyRegClasses(const MachineInstr &Copy,
90                     const SIRegisterInfo &TRI,
91                     const MachineRegisterInfo &MRI) const;
92
93   bool isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC,
94                         const TargetRegisterClass *DstRC,
95                         const SIRegisterInfo &TRI) const;
96
97   bool isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC,
98                         const TargetRegisterClass *DstRC,
99                         const SIRegisterInfo &TRI) const;
100
101 public:
102   SIFixSGPRCopies(TargetMachine &tm) : MachineFunctionPass(ID) { }
103
104   bool runOnMachineFunction(MachineFunction &MF) override;
105
106   const char *getPassName() const override {
107     return "SI Fix SGPR copies";
108   }
109
110   void getAnalysisUsage(AnalysisUsage &AU) const override {
111     AU.setPreservesCFG();
112     MachineFunctionPass::getAnalysisUsage(AU);
113   }
114 };
115
116 } // End anonymous namespace
117
118 char SIFixSGPRCopies::ID = 0;
119
120 FunctionPass *llvm::createSIFixSGPRCopiesPass(TargetMachine &tm) {
121   return new SIFixSGPRCopies(tm);
122 }
123
124 static 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
137 std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
138 SIFixSGPRCopies::getCopyRegClasses(const MachineInstr &Copy,
139                                    const SIRegisterInfo &TRI,
140                                    const MachineRegisterInfo &MRI) const {
141   unsigned DstReg = Copy.getOperand(0).getReg();
142   unsigned SrcReg = Copy.getOperand(1).getReg();
143
144   const TargetRegisterClass *SrcRC =
145     TargetRegisterInfo::isVirtualRegister(SrcReg) ?
146     MRI.getRegClass(SrcReg) :
147     TRI.getPhysRegClass(SrcReg);
148
149   // We don't really care about the subregister here.
150   // SrcRC = TRI.getSubRegClass(SrcRC, Copy.getOperand(1).getSubReg());
151
152   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
160 bool SIFixSGPRCopies::isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC,
161                                        const TargetRegisterClass *DstRC,
162                                        const SIRegisterInfo &TRI) const {
163   return TRI.isSGPRClass(DstRC) && TRI.hasVGPRs(SrcRC);
164 }
165
166 bool SIFixSGPRCopies::isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC,
167                                        const TargetRegisterClass *DstRC,
168                                        const SIRegisterInfo &TRI) const {
169   return TRI.isSGPRClass(SrcRC) && TRI.hasVGPRs(DstRC);
170 }
171
172 bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
173   MachineRegisterInfo &MRI = MF.getRegInfo();
174   const SIRegisterInfo *TRI =
175       static_cast<const SIRegisterInfo *>(MF.getSubtarget().getRegisterInfo());
176   const SIInstrInfo *TII =
177       static_cast<const SIInstrInfo *>(MF.getSubtarget().getInstrInfo());
178   for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
179                                                   BI != BE; ++BI) {
180
181     MachineBasicBlock &MBB = *BI;
182     for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
183                                                       I != E; ++I) {
184       MachineInstr &MI = *I;
185
186       switch (MI.getOpcode()) {
187       default:
188         continue;
189       case AMDGPU::COPY: {
190         // If the destination register is a physical register there isn't really
191         // much we can do to fix this.
192         if (!TargetRegisterInfo::isVirtualRegister(MI.getOperand(0).getReg()))
193           continue;
194
195         const TargetRegisterClass *SrcRC, *DstRC;
196         std::tie(SrcRC, DstRC) = getCopyRegClasses(MI, *TRI, MRI);
197         if (isVGPRToSGPRCopy(SrcRC, DstRC, *TRI)) {
198           DEBUG(dbgs() << "Fixing VGPR -> SGPR copy: " << MI);
199           TII->moveToVALU(MI);
200         }
201
202         break;
203       }
204       case AMDGPU::PHI: {
205         DEBUG(dbgs() << "Fixing PHI: " << MI);
206         unsigned Reg = MI.getOperand(0).getReg();
207         if (!TRI->isSGPRClass(MRI.getRegClass(Reg)))
208           break;
209
210         // If a PHI node defines an SGPR and any of its operands are VGPRs,
211         // then we need to move it to the VALU.
212         //
213         // Also, if a PHI node defines an SGPR and has all SGPR operands
214         // we must move it to the VALU, because the SGPR operands will
215         // all end up being assigned the same register, which means
216         // there is a potential for a conflict if different threads take
217         // different control flow paths.
218         //
219         // For Example:
220         //
221         // sgpr0 = def;
222         // ...
223         // sgpr1 = def;
224         // ...
225         // sgpr2 = PHI sgpr0, sgpr1
226         // use sgpr2;
227         //
228         // Will Become:
229         //
230         // sgpr2 = def;
231         // ...
232         // sgpr2 = def;
233         // ...
234         // use sgpr2
235         //
236         // FIXME: This is OK if the branching decision is made based on an
237         // SGPR value.
238         bool SGPRBranch = false;
239
240         // The one exception to this rule is when one of the operands
241         // is defined by a SI_BREAK, SI_IF_BREAK, or SI_ELSE_BREAK
242         // instruction.  In this case, there we know the program will
243         // never enter the second block (the loop) without entering
244         // the first block (where the condition is computed), so there
245         // is no chance for values to be over-written.
246
247         bool HasBreakDef = false;
248         for (unsigned i = 1; i < MI.getNumOperands(); i+=2) {
249           unsigned Reg = MI.getOperand(i).getReg();
250           if (TRI->hasVGPRs(MRI.getRegClass(Reg))) {
251             TII->moveToVALU(MI);
252             break;
253           }
254           MachineInstr *DefInstr = MRI.getUniqueVRegDef(Reg);
255           assert(DefInstr);
256           switch(DefInstr->getOpcode()) {
257
258           case AMDGPU::SI_BREAK:
259           case AMDGPU::SI_IF_BREAK:
260           case AMDGPU::SI_ELSE_BREAK:
261           // If we see a PHI instruction that defines an SGPR, then that PHI
262           // instruction has already been considered and should have
263           // a *_BREAK as an operand.
264           case AMDGPU::PHI:
265             HasBreakDef = true;
266             break;
267           }
268         }
269
270         if (!SGPRBranch && !HasBreakDef)
271           TII->moveToVALU(MI);
272         break;
273       }
274       case AMDGPU::REG_SEQUENCE: {
275         if (TRI->hasVGPRs(TII->getOpRegClass(MI, 0)) ||
276             !hasVGPROperands(MI, TRI))
277           continue;
278
279         DEBUG(dbgs() << "Fixing REG_SEQUENCE: " << MI);
280
281         TII->moveToVALU(MI);
282         break;
283       }
284       case AMDGPU::INSERT_SUBREG: {
285         const TargetRegisterClass *DstRC, *Src0RC, *Src1RC;
286         DstRC = MRI.getRegClass(MI.getOperand(0).getReg());
287         Src0RC = MRI.getRegClass(MI.getOperand(1).getReg());
288         Src1RC = MRI.getRegClass(MI.getOperand(2).getReg());
289         if (TRI->isSGPRClass(DstRC) &&
290             (TRI->hasVGPRs(Src0RC) || TRI->hasVGPRs(Src1RC))) {
291           DEBUG(dbgs() << " Fixing INSERT_SUBREG: " << MI);
292           TII->moveToVALU(MI);
293         }
294         break;
295       }
296       }
297     }
298   }
299
300   return true;
301 }