Add an MVT::x86mmx type. It will take the place of all current MMX vector types.
[oota-llvm.git] / lib / Target / ARM / NEONPreAllocPass.cpp
1 //===-- NEONPreAllocPass.cpp - Allocate adjacent NEON registers--*- C++ -*-===//
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 #define DEBUG_TYPE "neon-prealloc"
11 #include "ARM.h"
12 #include "ARMInstrInfo.h"
13 #include "llvm/CodeGen/MachineInstr.h"
14 #include "llvm/CodeGen/MachineInstrBuilder.h"
15 #include "llvm/CodeGen/MachineRegisterInfo.h"
16 #include "llvm/CodeGen/MachineFunctionPass.h"
17 using namespace llvm;
18
19 namespace {
20   class NEONPreAllocPass : public MachineFunctionPass {
21     const TargetInstrInfo *TII;
22     MachineRegisterInfo *MRI;
23
24   public:
25     static char ID;
26     NEONPreAllocPass() : MachineFunctionPass(ID) {}
27
28     virtual bool runOnMachineFunction(MachineFunction &MF);
29
30     virtual const char *getPassName() const {
31       return "NEON register pre-allocation pass";
32     }
33
34   private:
35     bool FormsRegSequence(MachineInstr *MI,
36                           unsigned FirstOpnd, unsigned NumRegs,
37                           unsigned Offset, unsigned Stride) const;
38     bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
39   };
40
41   char NEONPreAllocPass::ID = 0;
42 }
43
44 static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
45                              unsigned &Offset, unsigned &Stride) {
46   // Default to unit stride with no offset.
47   Stride = 1;
48   Offset = 0;
49
50   switch (Opcode) {
51   default:
52     break;
53
54   case ARM::VLD2LNd8:
55   case ARM::VLD2LNd16:
56   case ARM::VLD2LNd32:
57     FirstOpnd = 0;
58     NumRegs = 2;
59     return true;
60
61   case ARM::VLD2LNq16:
62   case ARM::VLD2LNq32:
63     FirstOpnd = 0;
64     NumRegs = 2;
65     Offset = 0;
66     Stride = 2;
67     return true;
68
69   case ARM::VLD2LNq16odd:
70   case ARM::VLD2LNq32odd:
71     FirstOpnd = 0;
72     NumRegs = 2;
73     Offset = 1;
74     Stride = 2;
75     return true;
76
77   case ARM::VLD3LNd8:
78   case ARM::VLD3LNd16:
79   case ARM::VLD3LNd32:
80     FirstOpnd = 0;
81     NumRegs = 3;
82     return true;
83
84   case ARM::VLD3LNq16:
85   case ARM::VLD3LNq32:
86     FirstOpnd = 0;
87     NumRegs = 3;
88     Offset = 0;
89     Stride = 2;
90     return true;
91
92   case ARM::VLD3LNq16odd:
93   case ARM::VLD3LNq32odd:
94     FirstOpnd = 0;
95     NumRegs = 3;
96     Offset = 1;
97     Stride = 2;
98     return true;
99
100   case ARM::VLD4LNd8:
101   case ARM::VLD4LNd16:
102   case ARM::VLD4LNd32:
103     FirstOpnd = 0;
104     NumRegs = 4;
105     return true;
106
107   case ARM::VLD4LNq16:
108   case ARM::VLD4LNq32:
109     FirstOpnd = 0;
110     NumRegs = 4;
111     Offset = 0;
112     Stride = 2;
113     return true;
114
115   case ARM::VLD4LNq16odd:
116   case ARM::VLD4LNq32odd:
117     FirstOpnd = 0;
118     NumRegs = 4;
119     Offset = 1;
120     Stride = 2;
121     return true;
122
123   case ARM::VST2LNd8:
124   case ARM::VST2LNd16:
125   case ARM::VST2LNd32:
126     FirstOpnd = 2;
127     NumRegs = 2;
128     return true;
129
130   case ARM::VST2LNq16:
131   case ARM::VST2LNq32:
132     FirstOpnd = 2;
133     NumRegs = 2;
134     Offset = 0;
135     Stride = 2;
136     return true;
137
138   case ARM::VST2LNq16odd:
139   case ARM::VST2LNq32odd:
140     FirstOpnd = 2;
141     NumRegs = 2;
142     Offset = 1;
143     Stride = 2;
144     return true;
145
146   case ARM::VST3LNd8:
147   case ARM::VST3LNd16:
148   case ARM::VST3LNd32:
149     FirstOpnd = 2;
150     NumRegs = 3;
151     return true;
152
153   case ARM::VST3LNq16:
154   case ARM::VST3LNq32:
155     FirstOpnd = 2;
156     NumRegs = 3;
157     Offset = 0;
158     Stride = 2;
159     return true;
160
161   case ARM::VST3LNq16odd:
162   case ARM::VST3LNq32odd:
163     FirstOpnd = 2;
164     NumRegs = 3;
165     Offset = 1;
166     Stride = 2;
167     return true;
168
169   case ARM::VST4LNd8:
170   case ARM::VST4LNd16:
171   case ARM::VST4LNd32:
172     FirstOpnd = 2;
173     NumRegs = 4;
174     return true;
175
176   case ARM::VST4LNq16:
177   case ARM::VST4LNq32:
178     FirstOpnd = 2;
179     NumRegs = 4;
180     Offset = 0;
181     Stride = 2;
182     return true;
183
184   case ARM::VST4LNq16odd:
185   case ARM::VST4LNq32odd:
186     FirstOpnd = 2;
187     NumRegs = 4;
188     Offset = 1;
189     Stride = 2;
190     return true;
191
192   case ARM::VTBL2:
193     FirstOpnd = 1;
194     NumRegs = 2;
195     return true;
196
197   case ARM::VTBL3:
198     FirstOpnd = 1;
199     NumRegs = 3;
200     return true;
201
202   case ARM::VTBL4:
203     FirstOpnd = 1;
204     NumRegs = 4;
205     return true;
206
207   case ARM::VTBX2:
208     FirstOpnd = 2;
209     NumRegs = 2;
210     return true;
211
212   case ARM::VTBX3:
213     FirstOpnd = 2;
214     NumRegs = 3;
215     return true;
216
217   case ARM::VTBX4:
218     FirstOpnd = 2;
219     NumRegs = 4;
220     return true;
221   }
222
223   return false;
224 }
225
226 bool
227 NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
228                                    unsigned FirstOpnd, unsigned NumRegs,
229                                    unsigned Offset, unsigned Stride) const {
230   MachineOperand &FMO = MI->getOperand(FirstOpnd);
231   assert(FMO.isReg() && FMO.getSubReg() == 0 && "unexpected operand");
232   unsigned VirtReg = FMO.getReg();
233   (void)VirtReg;
234   assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
235          "expected a virtual register");
236
237   unsigned LastSubIdx = 0;
238   if (FMO.isDef()) {
239     MachineInstr *RegSeq = 0;
240     for (unsigned R = 0; R < NumRegs; ++R) {
241       const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
242       assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
243       unsigned VirtReg = MO.getReg();
244       assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
245              "expected a virtual register");
246       // Feeding into a REG_SEQUENCE.
247       if (!MRI->hasOneNonDBGUse(VirtReg))
248         return false;
249       MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg);
250       if (!UseMI->isRegSequence())
251         return false;
252       if (RegSeq && RegSeq != UseMI)
253         return false;
254       unsigned OpIdx = 1 + (Offset + R * Stride) * 2;
255       if (UseMI->getOperand(OpIdx).getReg() != VirtReg)
256         llvm_unreachable("Malformed REG_SEQUENCE instruction!");
257       unsigned SubIdx = UseMI->getOperand(OpIdx + 1).getImm();
258       if (LastSubIdx) {
259         if (LastSubIdx != SubIdx-Stride)
260           return false;
261       } else {
262         // Must start from dsub_0 or qsub_0.
263         if (SubIdx != (ARM::dsub_0+Offset) &&
264             SubIdx != (ARM::qsub_0+Offset))
265           return false;
266       }
267       RegSeq = UseMI;
268       LastSubIdx = SubIdx;
269     }
270
271     // In the case of vld3, etc., make sure the trailing operand of
272     // REG_SEQUENCE is an undef.
273     if (NumRegs == 3) {
274       unsigned OpIdx = 1 + (Offset + 3 * Stride) * 2;
275       const MachineOperand &MO = RegSeq->getOperand(OpIdx);
276       unsigned VirtReg = MO.getReg();
277       MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
278       if (!DefMI || !DefMI->isImplicitDef())
279         return false;
280     }
281     return true;
282   }
283
284   unsigned LastSrcReg = 0;
285   SmallVector<unsigned, 4> SubIds;
286   for (unsigned R = 0; R < NumRegs; ++R) {
287     const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
288     assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
289     unsigned VirtReg = MO.getReg();
290     assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
291            "expected a virtual register");
292     // Extracting from a Q or QQ register.
293     MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
294     if (!DefMI || !DefMI->isCopy() || !DefMI->getOperand(1).getSubReg())
295       return false;
296     VirtReg = DefMI->getOperand(1).getReg();
297     if (LastSrcReg && LastSrcReg != VirtReg)
298       return false;
299     LastSrcReg = VirtReg;
300     const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
301     if (RC != ARM::QPRRegisterClass &&
302         RC != ARM::QQPRRegisterClass &&
303         RC != ARM::QQQQPRRegisterClass)
304       return false;
305     unsigned SubIdx = DefMI->getOperand(1).getSubReg();
306     if (LastSubIdx) {
307       if (LastSubIdx != SubIdx-Stride)
308         return false;
309     } else {
310       // Must start from dsub_0 or qsub_0.
311       if (SubIdx != (ARM::dsub_0+Offset) &&
312           SubIdx != (ARM::qsub_0+Offset))
313         return false;
314     }
315     SubIds.push_back(SubIdx);
316     LastSubIdx = SubIdx;
317   }
318
319   // FIXME: Update the uses of EXTRACT_SUBREG from REG_SEQUENCE is
320   // currently required for correctness. e.g.
321   //  %reg1041<def> = REG_SEQUENCE %reg1040<kill>, 5, %reg1035<kill>, 6
322   //  %reg1042<def> = EXTRACT_SUBREG %reg1041, 6
323   //  %reg1043<def> = EXTRACT_SUBREG %reg1041, 5
324   //  VST1q16 %reg1025<kill>, 0, %reg1043<kill>, %reg1042<kill>,
325   // reg1042 and reg1043 should be replaced with reg1041:6 and reg1041:5
326   // respectively.
327   // We need to change how we model uses of REG_SEQUENCE.
328   for (unsigned R = 0; R < NumRegs; ++R) {
329     MachineOperand &MO = MI->getOperand(FirstOpnd + R);
330     unsigned OldReg = MO.getReg();
331     MachineInstr *DefMI = MRI->getVRegDef(OldReg);
332     assert(DefMI->isCopy());
333     MO.setReg(LastSrcReg);
334     MO.setSubReg(SubIds[R]);
335     MO.setIsKill(false);
336     // Delete the EXTRACT_SUBREG if its result is now dead.
337     if (MRI->use_empty(OldReg))
338       DefMI->eraseFromParent();
339   }
340
341   return true;
342 }
343
344 bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
345   bool Modified = false;
346
347   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
348   for (; MBBI != E; ++MBBI) {
349     MachineInstr *MI = &*MBBI;
350     unsigned FirstOpnd, NumRegs, Offset, Stride;
351     if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
352       continue;
353     if (FormsRegSequence(MI, FirstOpnd, NumRegs, Offset, Stride))
354       continue;
355
356     MachineBasicBlock::iterator NextI = llvm::next(MBBI);
357     for (unsigned R = 0; R < NumRegs; ++R) {
358       MachineOperand &MO = MI->getOperand(FirstOpnd + R);
359       assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
360       unsigned VirtReg = MO.getReg();
361       assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
362              "expected a virtual register");
363
364       // For now, just assign a fixed set of adjacent registers.
365       // This leaves plenty of room for future improvements.
366       static const unsigned NEONDRegs[] = {
367         ARM::D0, ARM::D1, ARM::D2, ARM::D3,
368         ARM::D4, ARM::D5, ARM::D6, ARM::D7
369       };
370       MO.setReg(NEONDRegs[Offset + R * Stride]);
371
372       if (MO.isUse()) {
373         // Insert a copy from VirtReg.
374         BuildMI(MBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),MO.getReg())
375           .addReg(VirtReg, getKillRegState(MO.isKill()));
376         MO.setIsKill();
377       } else if (MO.isDef() && !MO.isDead()) {
378         // Add a copy to VirtReg.
379         BuildMI(MBB, NextI, DebugLoc(), TII->get(TargetOpcode::COPY), VirtReg)
380           .addReg(MO.getReg());
381       }
382     }
383   }
384
385   return Modified;
386 }
387
388 bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) {
389   TII = MF.getTarget().getInstrInfo();
390   MRI = &MF.getRegInfo();
391
392   bool Modified = false;
393   for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
394        ++MFI) {
395     MachineBasicBlock &MBB = *MFI;
396     Modified |= PreAllocNEONRegisters(MBB);
397   }
398
399   return Modified;
400 }
401
402 /// createNEONPreAllocPass - returns an instance of the NEON register
403 /// pre-allocation pass.
404 FunctionPass *llvm::createNEONPreAllocPass() {
405   return new NEONPreAllocPass();
406 }