Add a DebugLoc argument to TargetInstrInfo::copyRegToReg, so that it
[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     bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
38   };
39
40   char NEONPreAllocPass::ID = 0;
41 }
42
43 static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
44                              unsigned &Offset, unsigned &Stride) {
45   // Default to unit stride with no offset.
46   Stride = 1;
47   Offset = 0;
48
49   switch (Opcode) {
50   default:
51     break;
52
53   case ARM::VLD1q8:
54   case ARM::VLD1q16:
55   case ARM::VLD1q32:
56   case ARM::VLD1q64:
57   case ARM::VLD2d8:
58   case ARM::VLD2d16:
59   case ARM::VLD2d32:
60   case ARM::VLD2LNd8:
61   case ARM::VLD2LNd16:
62   case ARM::VLD2LNd32:
63     FirstOpnd = 0;
64     NumRegs = 2;
65     return true;
66
67   case ARM::VLD2q8:
68   case ARM::VLD2q16:
69   case ARM::VLD2q32:
70     FirstOpnd = 0;
71     NumRegs = 4;
72     return true;
73
74   case ARM::VLD2LNq16:
75   case ARM::VLD2LNq32:
76     FirstOpnd = 0;
77     NumRegs = 2;
78     Offset = 0;
79     Stride = 2;
80     return true;
81
82   case ARM::VLD2LNq16odd:
83   case ARM::VLD2LNq32odd:
84     FirstOpnd = 0;
85     NumRegs = 2;
86     Offset = 1;
87     Stride = 2;
88     return true;
89
90   case ARM::VLD3d8:
91   case ARM::VLD3d16:
92   case ARM::VLD3d32:
93   case ARM::VLD1d64T:
94   case ARM::VLD3LNd8:
95   case ARM::VLD3LNd16:
96   case ARM::VLD3LNd32:
97     FirstOpnd = 0;
98     NumRegs = 3;
99     return true;
100
101   case ARM::VLD3q8_UPD:
102   case ARM::VLD3q16_UPD:
103   case ARM::VLD3q32_UPD:
104     FirstOpnd = 0;
105     NumRegs = 3;
106     Offset = 0;
107     Stride = 2;
108     return true;
109
110   case ARM::VLD3q8odd_UPD:
111   case ARM::VLD3q16odd_UPD:
112   case ARM::VLD3q32odd_UPD:
113     FirstOpnd = 0;
114     NumRegs = 3;
115     Offset = 1;
116     Stride = 2;
117     return true;
118
119   case ARM::VLD3LNq16:
120   case ARM::VLD3LNq32:
121     FirstOpnd = 0;
122     NumRegs = 3;
123     Offset = 0;
124     Stride = 2;
125     return true;
126
127   case ARM::VLD3LNq16odd:
128   case ARM::VLD3LNq32odd:
129     FirstOpnd = 0;
130     NumRegs = 3;
131     Offset = 1;
132     Stride = 2;
133     return true;
134
135   case ARM::VLD4d8:
136   case ARM::VLD4d16:
137   case ARM::VLD4d32:
138   case ARM::VLD1d64Q:
139   case ARM::VLD4LNd8:
140   case ARM::VLD4LNd16:
141   case ARM::VLD4LNd32:
142     FirstOpnd = 0;
143     NumRegs = 4;
144     return true;
145
146   case ARM::VLD4q8_UPD:
147   case ARM::VLD4q16_UPD:
148   case ARM::VLD4q32_UPD:
149     FirstOpnd = 0;
150     NumRegs = 4;
151     Offset = 0;
152     Stride = 2;
153     return true;
154
155   case ARM::VLD4q8odd_UPD:
156   case ARM::VLD4q16odd_UPD:
157   case ARM::VLD4q32odd_UPD:
158     FirstOpnd = 0;
159     NumRegs = 4;
160     Offset = 1;
161     Stride = 2;
162     return true;
163
164   case ARM::VLD4LNq16:
165   case ARM::VLD4LNq32:
166     FirstOpnd = 0;
167     NumRegs = 4;
168     Offset = 0;
169     Stride = 2;
170     return true;
171
172   case ARM::VLD4LNq16odd:
173   case ARM::VLD4LNq32odd:
174     FirstOpnd = 0;
175     NumRegs = 4;
176     Offset = 1;
177     Stride = 2;
178     return true;
179
180   case ARM::VST1q8:
181   case ARM::VST1q16:
182   case ARM::VST1q32:
183   case ARM::VST1q64:
184   case ARM::VST2d8:
185   case ARM::VST2d16:
186   case ARM::VST2d32:
187   case ARM::VST2LNd8:
188   case ARM::VST2LNd16:
189   case ARM::VST2LNd32:
190     FirstOpnd = 2;
191     NumRegs = 2;
192     return true;
193
194   case ARM::VST2q8:
195   case ARM::VST2q16:
196   case ARM::VST2q32:
197     FirstOpnd = 2;
198     NumRegs = 4;
199     return true;
200
201   case ARM::VST2LNq16:
202   case ARM::VST2LNq32:
203     FirstOpnd = 2;
204     NumRegs = 2;
205     Offset = 0;
206     Stride = 2;
207     return true;
208
209   case ARM::VST2LNq16odd:
210   case ARM::VST2LNq32odd:
211     FirstOpnd = 2;
212     NumRegs = 2;
213     Offset = 1;
214     Stride = 2;
215     return true;
216
217   case ARM::VST3d8:
218   case ARM::VST3d16:
219   case ARM::VST3d32:
220   case ARM::VST1d64T:
221   case ARM::VST3LNd8:
222   case ARM::VST3LNd16:
223   case ARM::VST3LNd32:
224     FirstOpnd = 2;
225     NumRegs = 3;
226     return true;
227
228   case ARM::VST3q8_UPD:
229   case ARM::VST3q16_UPD:
230   case ARM::VST3q32_UPD:
231     FirstOpnd = 4;
232     NumRegs = 3;
233     Offset = 0;
234     Stride = 2;
235     return true;
236
237   case ARM::VST3q8odd_UPD:
238   case ARM::VST3q16odd_UPD:
239   case ARM::VST3q32odd_UPD:
240     FirstOpnd = 4;
241     NumRegs = 3;
242     Offset = 1;
243     Stride = 2;
244     return true;
245
246   case ARM::VST3LNq16:
247   case ARM::VST3LNq32:
248     FirstOpnd = 2;
249     NumRegs = 3;
250     Offset = 0;
251     Stride = 2;
252     return true;
253
254   case ARM::VST3LNq16odd:
255   case ARM::VST3LNq32odd:
256     FirstOpnd = 2;
257     NumRegs = 3;
258     Offset = 1;
259     Stride = 2;
260     return true;
261
262   case ARM::VST4d8:
263   case ARM::VST4d16:
264   case ARM::VST4d32:
265   case ARM::VST1d64Q:
266   case ARM::VST4LNd8:
267   case ARM::VST4LNd16:
268   case ARM::VST4LNd32:
269     FirstOpnd = 2;
270     NumRegs = 4;
271     return true;
272
273   case ARM::VST4q8_UPD:
274   case ARM::VST4q16_UPD:
275   case ARM::VST4q32_UPD:
276     FirstOpnd = 4;
277     NumRegs = 4;
278     Offset = 0;
279     Stride = 2;
280     return true;
281
282   case ARM::VST4q8odd_UPD:
283   case ARM::VST4q16odd_UPD:
284   case ARM::VST4q32odd_UPD:
285     FirstOpnd = 4;
286     NumRegs = 4;
287     Offset = 1;
288     Stride = 2;
289     return true;
290
291   case ARM::VST4LNq16:
292   case ARM::VST4LNq32:
293     FirstOpnd = 2;
294     NumRegs = 4;
295     Offset = 0;
296     Stride = 2;
297     return true;
298
299   case ARM::VST4LNq16odd:
300   case ARM::VST4LNq32odd:
301     FirstOpnd = 2;
302     NumRegs = 4;
303     Offset = 1;
304     Stride = 2;
305     return true;
306
307   case ARM::VTBL2:
308     FirstOpnd = 1;
309     NumRegs = 2;
310     return true;
311
312   case ARM::VTBL3:
313     FirstOpnd = 1;
314     NumRegs = 3;
315     return true;
316
317   case ARM::VTBL4:
318     FirstOpnd = 1;
319     NumRegs = 4;
320     return true;
321
322   case ARM::VTBX2:
323     FirstOpnd = 2;
324     NumRegs = 2;
325     return true;
326
327   case ARM::VTBX3:
328     FirstOpnd = 2;
329     NumRegs = 3;
330     return true;
331
332   case ARM::VTBX4:
333     FirstOpnd = 2;
334     NumRegs = 4;
335     return true;
336   }
337
338   return false;
339 }
340
341 bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
342                                         unsigned FirstOpnd, unsigned NumRegs) {
343   MachineInstr *RegSeq = 0;
344   unsigned LastSrcReg = 0;
345   unsigned LastSubIdx = 0;
346   for (unsigned R = 0; R < NumRegs; ++R) {
347     MachineOperand &MO = MI->getOperand(FirstOpnd + R);
348     assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
349     unsigned VirtReg = MO.getReg();
350     assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
351            "expected a virtual register");
352     if (MO.isDef()) {
353       // Feeding into a REG_SEQUENCE.
354       if (!MRI->hasOneNonDBGUse(VirtReg))
355         return false;
356       MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg);
357       if (!UseMI->isRegSequence())
358         return false;
359       if (RegSeq && RegSeq != UseMI)
360         return false;
361       RegSeq = UseMI;
362     } else {
363       // Extracting from a Q register.
364       MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
365       if (!DefMI || !DefMI->isExtractSubreg())
366         return false;
367       VirtReg = DefMI->getOperand(1).getReg();
368       if (LastSrcReg && LastSrcReg != VirtReg)
369         return false;
370       const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
371       if (RC != ARM::QPRRegisterClass)
372         return false;
373       unsigned SubIdx = DefMI->getOperand(2).getImm();
374       if (LastSubIdx && LastSubIdx != SubIdx-1)
375         return false;
376       LastSubIdx = SubIdx;
377     }
378   }
379   return true;
380 }
381
382 bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
383   bool Modified = false;
384
385   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
386   for (; MBBI != E; ++MBBI) {
387     MachineInstr *MI = &*MBBI;
388     unsigned FirstOpnd, NumRegs, Offset, Stride;
389     if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
390       continue;
391     if (FormsRegSequence(MI, FirstOpnd, NumRegs))
392       continue;
393
394     MachineBasicBlock::iterator NextI = llvm::next(MBBI);
395     for (unsigned R = 0; R < NumRegs; ++R) {
396       MachineOperand &MO = MI->getOperand(FirstOpnd + R);
397       assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
398       unsigned VirtReg = MO.getReg();
399       assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
400              "expected a virtual register");
401
402       // For now, just assign a fixed set of adjacent registers.
403       // This leaves plenty of room for future improvements.
404       static const unsigned NEONDRegs[] = {
405         ARM::D0, ARM::D1, ARM::D2, ARM::D3,
406         ARM::D4, ARM::D5, ARM::D6, ARM::D7
407       };
408       MO.setReg(NEONDRegs[Offset + R * Stride]);
409
410       if (MO.isUse()) {
411         // Insert a copy from VirtReg.
412         TII->copyRegToReg(MBB, MBBI, MO.getReg(), VirtReg,
413                           ARM::DPRRegisterClass, ARM::DPRRegisterClass,
414                           DebugLoc());
415         if (MO.isKill()) {
416           MachineInstr *CopyMI = prior(MBBI);
417           CopyMI->findRegisterUseOperand(VirtReg)->setIsKill();
418         }
419         MO.setIsKill();
420       } else if (MO.isDef() && !MO.isDead()) {
421         // Add a copy to VirtReg.
422         TII->copyRegToReg(MBB, NextI, VirtReg, MO.getReg(),
423                           ARM::DPRRegisterClass, ARM::DPRRegisterClass,
424                           DebugLoc());
425       }
426     }
427   }
428
429   return Modified;
430 }
431
432 bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) {
433   TII = MF.getTarget().getInstrInfo();
434   MRI = &MF.getRegInfo();
435
436   bool Modified = false;
437   for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
438        ++MFI) {
439     MachineBasicBlock &MBB = *MFI;
440     Modified |= PreAllocNEONRegisters(MBB);
441   }
442
443   return Modified;
444 }
445
446 /// createNEONPreAllocPass - returns an instance of the NEON register
447 /// pre-allocation pass.
448 FunctionPass *llvm::createNEONPreAllocPass() {
449   return new NEONPreAllocPass();
450 }