blob: e33a504745d3ac2363084b52e46920e999773b0f [file] [log] [blame]
Bob Wilson70cd88f2009-08-05 23:12:45 +00001//===-- 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"
Evan Cheng826bdfa2010-05-04 20:38:12 +000015#include "llvm/CodeGen/MachineRegisterInfo.h"
Bob Wilson70cd88f2009-08-05 23:12:45 +000016#include "llvm/CodeGen/MachineFunctionPass.h"
17using namespace llvm;
18
19namespace {
Nick Lewycky6726b6d2009-10-25 06:33:48 +000020 class NEONPreAllocPass : public MachineFunctionPass {
Bob Wilson70cd88f2009-08-05 23:12:45 +000021 const TargetInstrInfo *TII;
Evan Cheng826bdfa2010-05-04 20:38:12 +000022 MachineRegisterInfo *MRI;
Bob Wilson70cd88f2009-08-05 23:12:45 +000023
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:
Evan Cheng826bdfa2010-05-04 20:38:12 +000035 bool FormsRegSequence(MachineInstr *MI,
Evan Cheng5c6aba22010-05-14 18:54:59 +000036 unsigned FirstOpnd, unsigned NumRegs,
37 unsigned Offset, unsigned Stride) const;
Bob Wilson70cd88f2009-08-05 23:12:45 +000038 bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
39 };
40
41 char NEONPreAllocPass::ID = 0;
42}
43
Bob Wilsonff8952e2009-10-07 17:24:55 +000044static 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
Bob Wilson70cd88f2009-08-05 23:12:45 +000050 switch (Opcode) {
51 default:
52 break;
53
Bob Wilson621f1952010-03-23 05:25:43 +000054 case ARM::VLD1q8:
55 case ARM::VLD1q16:
56 case ARM::VLD1q32:
57 case ARM::VLD1q64:
Bob Wilson70cd88f2009-08-05 23:12:45 +000058 case ARM::VLD2d8:
59 case ARM::VLD2d16:
60 case ARM::VLD2d32:
Bob Wilson243fcc52009-09-01 04:26:28 +000061 case ARM::VLD2LNd8:
62 case ARM::VLD2LNd16:
63 case ARM::VLD2LNd32:
Bob Wilson70cd88f2009-08-05 23:12:45 +000064 FirstOpnd = 0;
65 NumRegs = 2;
66 return true;
67
Bob Wilson0bf7d992009-10-08 22:27:33 +000068 case ARM::VLD2q8:
69 case ARM::VLD2q16:
70 case ARM::VLD2q32:
71 FirstOpnd = 0;
72 NumRegs = 4;
73 return true;
74
Bob Wilson95ffecd2010-03-20 18:35:24 +000075 case ARM::VLD2LNq16:
76 case ARM::VLD2LNq32:
Bob Wilson30aea9d2009-10-08 18:56:10 +000077 FirstOpnd = 0;
78 NumRegs = 2;
79 Offset = 0;
80 Stride = 2;
81 return true;
82
Bob Wilson95ffecd2010-03-20 18:35:24 +000083 case ARM::VLD2LNq16odd:
84 case ARM::VLD2LNq32odd:
Bob Wilson30aea9d2009-10-08 18:56:10 +000085 FirstOpnd = 0;
86 NumRegs = 2;
87 Offset = 1;
88 Stride = 2;
89 return true;
90
Bob Wilson70cd88f2009-08-05 23:12:45 +000091 case ARM::VLD3d8:
92 case ARM::VLD3d16:
93 case ARM::VLD3d32:
Bob Wilsona6979752010-03-22 18:13:18 +000094 case ARM::VLD1d64T:
Bob Wilson243fcc52009-09-01 04:26:28 +000095 case ARM::VLD3LNd8:
96 case ARM::VLD3LNd16:
97 case ARM::VLD3LNd32:
Bob Wilson70cd88f2009-08-05 23:12:45 +000098 FirstOpnd = 0;
99 NumRegs = 3;
100 return true;
101
Bob Wilson95ffecd2010-03-20 18:35:24 +0000102 case ARM::VLD3q8_UPD:
103 case ARM::VLD3q16_UPD:
104 case ARM::VLD3q32_UPD:
Bob Wilsonff8952e2009-10-07 17:24:55 +0000105 FirstOpnd = 0;
106 NumRegs = 3;
107 Offset = 0;
108 Stride = 2;
109 return true;
110
Bob Wilson95ffecd2010-03-20 18:35:24 +0000111 case ARM::VLD3q8odd_UPD:
112 case ARM::VLD3q16odd_UPD:
113 case ARM::VLD3q32odd_UPD:
Bob Wilsonff8952e2009-10-07 17:24:55 +0000114 FirstOpnd = 0;
115 NumRegs = 3;
116 Offset = 1;
117 Stride = 2;
118 return true;
119
Bob Wilson95ffecd2010-03-20 18:35:24 +0000120 case ARM::VLD3LNq16:
121 case ARM::VLD3LNq32:
Bob Wilson0bf7d992009-10-08 22:27:33 +0000122 FirstOpnd = 0;
123 NumRegs = 3;
124 Offset = 0;
125 Stride = 2;
126 return true;
127
Bob Wilson95ffecd2010-03-20 18:35:24 +0000128 case ARM::VLD3LNq16odd:
129 case ARM::VLD3LNq32odd:
Bob Wilson0bf7d992009-10-08 22:27:33 +0000130 FirstOpnd = 0;
131 NumRegs = 3;
132 Offset = 1;
133 Stride = 2;
134 return true;
135
Bob Wilson70cd88f2009-08-05 23:12:45 +0000136 case ARM::VLD4d8:
137 case ARM::VLD4d16:
138 case ARM::VLD4d32:
Bob Wilsona6979752010-03-22 18:13:18 +0000139 case ARM::VLD1d64Q:
Bob Wilson243fcc52009-09-01 04:26:28 +0000140 case ARM::VLD4LNd8:
141 case ARM::VLD4LNd16:
142 case ARM::VLD4LNd32:
Bob Wilson70cd88f2009-08-05 23:12:45 +0000143 FirstOpnd = 0;
144 NumRegs = 4;
145 return true;
Bob Wilsonb36ec862009-08-06 18:47:44 +0000146
Bob Wilson95ffecd2010-03-20 18:35:24 +0000147 case ARM::VLD4q8_UPD:
148 case ARM::VLD4q16_UPD:
149 case ARM::VLD4q32_UPD:
Bob Wilson7708c222009-10-07 18:09:32 +0000150 FirstOpnd = 0;
151 NumRegs = 4;
152 Offset = 0;
153 Stride = 2;
154 return true;
155
Bob Wilson95ffecd2010-03-20 18:35:24 +0000156 case ARM::VLD4q8odd_UPD:
157 case ARM::VLD4q16odd_UPD:
158 case ARM::VLD4q32odd_UPD:
Bob Wilson7708c222009-10-07 18:09:32 +0000159 FirstOpnd = 0;
160 NumRegs = 4;
161 Offset = 1;
162 Stride = 2;
163 return true;
164
Bob Wilson95ffecd2010-03-20 18:35:24 +0000165 case ARM::VLD4LNq16:
166 case ARM::VLD4LNq32:
Bob Wilson62e053e2009-10-08 22:53:57 +0000167 FirstOpnd = 0;
168 NumRegs = 4;
169 Offset = 0;
170 Stride = 2;
171 return true;
172
Bob Wilson95ffecd2010-03-20 18:35:24 +0000173 case ARM::VLD4LNq16odd:
174 case ARM::VLD4LNq32odd:
Bob Wilson62e053e2009-10-08 22:53:57 +0000175 FirstOpnd = 0;
176 NumRegs = 4;
177 Offset = 1;
178 Stride = 2;
179 return true;
180
Bob Wilson11d98992010-03-23 06:20:33 +0000181 case ARM::VST1q8:
182 case ARM::VST1q16:
183 case ARM::VST1q32:
184 case ARM::VST1q64:
Bob Wilsonb36ec862009-08-06 18:47:44 +0000185 case ARM::VST2d8:
186 case ARM::VST2d16:
187 case ARM::VST2d32:
Bob Wilson8a3198b2009-09-01 18:51:56 +0000188 case ARM::VST2LNd8:
189 case ARM::VST2LNd16:
190 case ARM::VST2LNd32:
Bob Wilson226036e2010-03-20 22:13:40 +0000191 FirstOpnd = 2;
Bob Wilsonb36ec862009-08-06 18:47:44 +0000192 NumRegs = 2;
193 return true;
194
Bob Wilsond2855752009-10-07 18:47:39 +0000195 case ARM::VST2q8:
196 case ARM::VST2q16:
197 case ARM::VST2q32:
Bob Wilson226036e2010-03-20 22:13:40 +0000198 FirstOpnd = 2;
Bob Wilsond2855752009-10-07 18:47:39 +0000199 NumRegs = 4;
200 return true;
201
Bob Wilson95ffecd2010-03-20 18:35:24 +0000202 case ARM::VST2LNq16:
203 case ARM::VST2LNq32:
Bob Wilson226036e2010-03-20 22:13:40 +0000204 FirstOpnd = 2;
Bob Wilsonc5c6edb2009-10-08 23:38:24 +0000205 NumRegs = 2;
206 Offset = 0;
207 Stride = 2;
208 return true;
209
Bob Wilson95ffecd2010-03-20 18:35:24 +0000210 case ARM::VST2LNq16odd:
211 case ARM::VST2LNq32odd:
Bob Wilson226036e2010-03-20 22:13:40 +0000212 FirstOpnd = 2;
Bob Wilsonc5c6edb2009-10-08 23:38:24 +0000213 NumRegs = 2;
214 Offset = 1;
215 Stride = 2;
216 return true;
217
Bob Wilsonb36ec862009-08-06 18:47:44 +0000218 case ARM::VST3d8:
219 case ARM::VST3d16:
220 case ARM::VST3d32:
Bob Wilsona6979752010-03-22 18:13:18 +0000221 case ARM::VST1d64T:
Bob Wilson8a3198b2009-09-01 18:51:56 +0000222 case ARM::VST3LNd8:
223 case ARM::VST3LNd16:
224 case ARM::VST3LNd32:
Bob Wilson226036e2010-03-20 22:13:40 +0000225 FirstOpnd = 2;
Bob Wilsonb36ec862009-08-06 18:47:44 +0000226 NumRegs = 3;
227 return true;
228
Bob Wilson95ffecd2010-03-20 18:35:24 +0000229 case ARM::VST3q8_UPD:
230 case ARM::VST3q16_UPD:
231 case ARM::VST3q32_UPD:
Bob Wilson226036e2010-03-20 22:13:40 +0000232 FirstOpnd = 4;
Bob Wilson66a70632009-10-07 20:30:08 +0000233 NumRegs = 3;
234 Offset = 0;
235 Stride = 2;
236 return true;
237
Bob Wilson95ffecd2010-03-20 18:35:24 +0000238 case ARM::VST3q8odd_UPD:
239 case ARM::VST3q16odd_UPD:
240 case ARM::VST3q32odd_UPD:
Bob Wilson226036e2010-03-20 22:13:40 +0000241 FirstOpnd = 4;
Bob Wilson66a70632009-10-07 20:30:08 +0000242 NumRegs = 3;
243 Offset = 1;
244 Stride = 2;
245 return true;
246
Bob Wilson95ffecd2010-03-20 18:35:24 +0000247 case ARM::VST3LNq16:
248 case ARM::VST3LNq32:
Bob Wilson226036e2010-03-20 22:13:40 +0000249 FirstOpnd = 2;
Bob Wilson8cdb2692009-10-08 23:51:31 +0000250 NumRegs = 3;
251 Offset = 0;
252 Stride = 2;
253 return true;
254
Bob Wilson95ffecd2010-03-20 18:35:24 +0000255 case ARM::VST3LNq16odd:
256 case ARM::VST3LNq32odd:
Bob Wilson226036e2010-03-20 22:13:40 +0000257 FirstOpnd = 2;
Bob Wilson8cdb2692009-10-08 23:51:31 +0000258 NumRegs = 3;
259 Offset = 1;
260 Stride = 2;
261 return true;
262
Bob Wilsonb36ec862009-08-06 18:47:44 +0000263 case ARM::VST4d8:
264 case ARM::VST4d16:
265 case ARM::VST4d32:
Bob Wilsona6979752010-03-22 18:13:18 +0000266 case ARM::VST1d64Q:
Bob Wilson8a3198b2009-09-01 18:51:56 +0000267 case ARM::VST4LNd8:
268 case ARM::VST4LNd16:
269 case ARM::VST4LNd32:
Bob Wilson226036e2010-03-20 22:13:40 +0000270 FirstOpnd = 2;
Bob Wilsonb36ec862009-08-06 18:47:44 +0000271 NumRegs = 4;
272 return true;
Bob Wilson114a2662009-08-12 20:51:55 +0000273
Bob Wilson95ffecd2010-03-20 18:35:24 +0000274 case ARM::VST4q8_UPD:
275 case ARM::VST4q16_UPD:
276 case ARM::VST4q32_UPD:
Bob Wilson226036e2010-03-20 22:13:40 +0000277 FirstOpnd = 4;
Bob Wilson63c90632009-10-07 20:49:18 +0000278 NumRegs = 4;
279 Offset = 0;
280 Stride = 2;
281 return true;
282
Bob Wilson95ffecd2010-03-20 18:35:24 +0000283 case ARM::VST4q8odd_UPD:
284 case ARM::VST4q16odd_UPD:
285 case ARM::VST4q32odd_UPD:
Bob Wilson226036e2010-03-20 22:13:40 +0000286 FirstOpnd = 4;
Bob Wilson63c90632009-10-07 20:49:18 +0000287 NumRegs = 4;
288 Offset = 1;
289 Stride = 2;
290 return true;
291
Bob Wilson95ffecd2010-03-20 18:35:24 +0000292 case ARM::VST4LNq16:
293 case ARM::VST4LNq32:
Bob Wilson226036e2010-03-20 22:13:40 +0000294 FirstOpnd = 2;
Bob Wilson56311392009-10-09 00:01:36 +0000295 NumRegs = 4;
296 Offset = 0;
297 Stride = 2;
298 return true;
299
Bob Wilson95ffecd2010-03-20 18:35:24 +0000300 case ARM::VST4LNq16odd:
301 case ARM::VST4LNq32odd:
Bob Wilson226036e2010-03-20 22:13:40 +0000302 FirstOpnd = 2;
Bob Wilson56311392009-10-09 00:01:36 +0000303 NumRegs = 4;
304 Offset = 1;
305 Stride = 2;
306 return true;
307
Bob Wilson114a2662009-08-12 20:51:55 +0000308 case ARM::VTBL2:
309 FirstOpnd = 1;
310 NumRegs = 2;
311 return true;
312
313 case ARM::VTBL3:
314 FirstOpnd = 1;
315 NumRegs = 3;
316 return true;
317
318 case ARM::VTBL4:
319 FirstOpnd = 1;
320 NumRegs = 4;
321 return true;
322
323 case ARM::VTBX2:
324 FirstOpnd = 2;
325 NumRegs = 2;
326 return true;
327
328 case ARM::VTBX3:
329 FirstOpnd = 2;
330 NumRegs = 3;
331 return true;
332
333 case ARM::VTBX4:
334 FirstOpnd = 2;
335 NumRegs = 4;
336 return true;
Bob Wilson70cd88f2009-08-05 23:12:45 +0000337 }
338
339 return false;
340}
341
Evan Chenge9e2ba02010-05-10 21:26:24 +0000342bool
343NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
Evan Cheng5c6aba22010-05-14 18:54:59 +0000344 unsigned FirstOpnd, unsigned NumRegs,
345 unsigned Offset, unsigned Stride) const {
Evan Chenge9e2ba02010-05-10 21:26:24 +0000346 MachineOperand &FMO = MI->getOperand(FirstOpnd);
347 assert(FMO.isReg() && FMO.getSubReg() == 0 && "unexpected operand");
348 unsigned VirtReg = FMO.getReg();
Daniel Dunbar1860e7d2010-05-13 03:19:36 +0000349 (void)VirtReg;
Evan Chenge9e2ba02010-05-10 21:26:24 +0000350 assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
351 "expected a virtual register");
Evan Cheng5c6aba22010-05-14 18:54:59 +0000352
353 unsigned LastSubIdx = 0;
Evan Chenge9e2ba02010-05-10 21:26:24 +0000354 if (FMO.isDef()) {
355 MachineInstr *RegSeq = 0;
356 for (unsigned R = 0; R < NumRegs; ++R) {
357 const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
358 assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
359 unsigned VirtReg = MO.getReg();
360 assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
361 "expected a virtual register");
Evan Cheng676b2df2010-05-05 22:15:40 +0000362 // Feeding into a REG_SEQUENCE.
363 if (!MRI->hasOneNonDBGUse(VirtReg))
364 return false;
365 MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg);
366 if (!UseMI->isRegSequence())
367 return false;
368 if (RegSeq && RegSeq != UseMI)
369 return false;
Evan Cheng5c6aba22010-05-14 18:54:59 +0000370 unsigned OpIdx = 1 + (Offset + R * Stride) * 2;
371 if (UseMI->getOperand(OpIdx).getReg() != VirtReg)
372 llvm_unreachable("Malformed REG_SEQUENCE instruction!");
373 unsigned SubIdx = UseMI->getOperand(OpIdx + 1).getImm();
374 if (LastSubIdx) {
375 if (LastSubIdx != SubIdx-Stride)
376 return false;
377 } else {
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000378 // Must start from dsub_0 or qsub_0.
379 if (SubIdx != (ARM::dsub_0+Offset) &&
380 SubIdx != (ARM::qsub_0+Offset))
Evan Cheng5c6aba22010-05-14 18:54:59 +0000381 return false;
382 }
Evan Cheng676b2df2010-05-05 22:15:40 +0000383 RegSeq = UseMI;
Evan Cheng5c6aba22010-05-14 18:54:59 +0000384 LastSubIdx = SubIdx;
Evan Cheng676b2df2010-05-05 22:15:40 +0000385 }
Evan Chenge9e2ba02010-05-10 21:26:24 +0000386
Evan Cheng5c6aba22010-05-14 18:54:59 +0000387 // In the case of vld3, etc., make sure the trailing operand of
388 // REG_SEQUENCE is an undef.
389 if (NumRegs == 3) {
390 unsigned OpIdx = 1 + (Offset + 3 * Stride) * 2;
391 const MachineOperand &MO = RegSeq->getOperand(OpIdx);
Evan Chenge9e2ba02010-05-10 21:26:24 +0000392 unsigned VirtReg = MO.getReg();
393 MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
394 if (!DefMI || !DefMI->isImplicitDef())
395 return false;
396 }
397 return true;
398 }
399
400 unsigned LastSrcReg = 0;
Evan Cheng5bdc2aa2010-05-12 01:42:50 +0000401 SmallVector<unsigned, 4> SubIds;
Evan Chenge9e2ba02010-05-10 21:26:24 +0000402 for (unsigned R = 0; R < NumRegs; ++R) {
403 const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
404 assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
405 unsigned VirtReg = MO.getReg();
406 assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
407 "expected a virtual register");
408 // Extracting from a Q or QQ register.
409 MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
Jakob Stoklund Olesen0bc25f42010-07-08 16:40:22 +0000410 if (!DefMI || !DefMI->isCopy() || !DefMI->getOperand(1).getSubReg())
Evan Chenge9e2ba02010-05-10 21:26:24 +0000411 return false;
412 VirtReg = DefMI->getOperand(1).getReg();
413 if (LastSrcReg && LastSrcReg != VirtReg)
414 return false;
Evan Cheng0ce537a2010-05-11 01:19:40 +0000415 LastSrcReg = VirtReg;
Evan Chenge9e2ba02010-05-10 21:26:24 +0000416 const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
Evan Chengb990a2f2010-05-14 23:21:14 +0000417 if (RC != ARM::QPRRegisterClass &&
418 RC != ARM::QQPRRegisterClass &&
419 RC != ARM::QQQQPRRegisterClass)
Evan Chenge9e2ba02010-05-10 21:26:24 +0000420 return false;
Jakob Stoklund Olesen0bc25f42010-07-08 16:40:22 +0000421 unsigned SubIdx = DefMI->getOperand(1).getSubReg();
Evan Cheng0ce537a2010-05-11 01:19:40 +0000422 if (LastSubIdx) {
Evan Cheng5c6aba22010-05-14 18:54:59 +0000423 if (LastSubIdx != SubIdx-Stride)
Evan Cheng0ce537a2010-05-11 01:19:40 +0000424 return false;
425 } else {
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000426 // Must start from dsub_0 or qsub_0.
427 if (SubIdx != (ARM::dsub_0+Offset) &&
428 SubIdx != (ARM::qsub_0+Offset))
Evan Cheng0ce537a2010-05-11 01:19:40 +0000429 return false;
430 }
Evan Cheng5bdc2aa2010-05-12 01:42:50 +0000431 SubIds.push_back(SubIdx);
Evan Chenge9e2ba02010-05-10 21:26:24 +0000432 LastSubIdx = SubIdx;
Evan Cheng826bdfa2010-05-04 20:38:12 +0000433 }
Evan Cheng5bdc2aa2010-05-12 01:42:50 +0000434
435 // FIXME: Update the uses of EXTRACT_SUBREG from REG_SEQUENCE is
436 // currently required for correctness. e.g.
Bob Wilsondd726e52010-06-08 00:42:08 +0000437 // %reg1041<def> = REG_SEQUENCE %reg1040<kill>, 5, %reg1035<kill>, 6
Evan Cheng5bdc2aa2010-05-12 01:42:50 +0000438 // %reg1042<def> = EXTRACT_SUBREG %reg1041, 6
439 // %reg1043<def> = EXTRACT_SUBREG %reg1041, 5
440 // VST1q16 %reg1025<kill>, 0, %reg1043<kill>, %reg1042<kill>,
Bob Wilsondd726e52010-06-08 00:42:08 +0000441 // reg1042 and reg1043 should be replaced with reg1041:6 and reg1041:5
Evan Cheng5bdc2aa2010-05-12 01:42:50 +0000442 // respectively.
443 // We need to change how we model uses of REG_SEQUENCE.
444 for (unsigned R = 0; R < NumRegs; ++R) {
445 MachineOperand &MO = MI->getOperand(FirstOpnd + R);
446 unsigned OldReg = MO.getReg();
447 MachineInstr *DefMI = MRI->getVRegDef(OldReg);
Jakob Stoklund Olesen0bc25f42010-07-08 16:40:22 +0000448 assert(DefMI->isCopy());
Evan Cheng5bdc2aa2010-05-12 01:42:50 +0000449 MO.setReg(LastSrcReg);
450 MO.setSubReg(SubIds[R]);
Jakob Stoklund Olesena2846b42010-06-16 22:11:08 +0000451 MO.setIsKill(false);
Evan Cheng5bdc2aa2010-05-12 01:42:50 +0000452 // Delete the EXTRACT_SUBREG if its result is now dead.
453 if (MRI->use_empty(OldReg))
454 DefMI->eraseFromParent();
455 }
456
Evan Cheng826bdfa2010-05-04 20:38:12 +0000457 return true;
458}
459
Bob Wilson70cd88f2009-08-05 23:12:45 +0000460bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
461 bool Modified = false;
462
463 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
464 for (; MBBI != E; ++MBBI) {
465 MachineInstr *MI = &*MBBI;
Bob Wilsonff8952e2009-10-07 17:24:55 +0000466 unsigned FirstOpnd, NumRegs, Offset, Stride;
467 if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
Bob Wilson70cd88f2009-08-05 23:12:45 +0000468 continue;
Bob Wilson07f6e802010-06-16 21:34:01 +0000469 if (FormsRegSequence(MI, FirstOpnd, NumRegs, Offset, Stride))
Evan Cheng826bdfa2010-05-04 20:38:12 +0000470 continue;
Bob Wilson70cd88f2009-08-05 23:12:45 +0000471
Chris Lattner7896c9f2009-12-03 00:50:42 +0000472 MachineBasicBlock::iterator NextI = llvm::next(MBBI);
Bob Wilson70cd88f2009-08-05 23:12:45 +0000473 for (unsigned R = 0; R < NumRegs; ++R) {
474 MachineOperand &MO = MI->getOperand(FirstOpnd + R);
475 assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
476 unsigned VirtReg = MO.getReg();
477 assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
478 "expected a virtual register");
479
480 // For now, just assign a fixed set of adjacent registers.
481 // This leaves plenty of room for future improvements.
482 static const unsigned NEONDRegs[] = {
Bob Wilsonff8952e2009-10-07 17:24:55 +0000483 ARM::D0, ARM::D1, ARM::D2, ARM::D3,
484 ARM::D4, ARM::D5, ARM::D6, ARM::D7
Bob Wilson70cd88f2009-08-05 23:12:45 +0000485 };
Bob Wilsonff8952e2009-10-07 17:24:55 +0000486 MO.setReg(NEONDRegs[Offset + R * Stride]);
Bob Wilson70cd88f2009-08-05 23:12:45 +0000487
488 if (MO.isUse()) {
489 // Insert a copy from VirtReg.
Bob Wilson349d82d2009-10-06 22:01:15 +0000490 TII->copyRegToReg(MBB, MBBI, MO.getReg(), VirtReg,
Dan Gohman34dcc6f2010-05-06 20:33:48 +0000491 ARM::DPRRegisterClass, ARM::DPRRegisterClass,
492 DebugLoc());
Bob Wilson70cd88f2009-08-05 23:12:45 +0000493 if (MO.isKill()) {
494 MachineInstr *CopyMI = prior(MBBI);
495 CopyMI->findRegisterUseOperand(VirtReg)->setIsKill();
496 }
497 MO.setIsKill();
498 } else if (MO.isDef() && !MO.isDead()) {
499 // Add a copy to VirtReg.
Bob Wilson349d82d2009-10-06 22:01:15 +0000500 TII->copyRegToReg(MBB, NextI, VirtReg, MO.getReg(),
Dan Gohman34dcc6f2010-05-06 20:33:48 +0000501 ARM::DPRRegisterClass, ARM::DPRRegisterClass,
502 DebugLoc());
Bob Wilson70cd88f2009-08-05 23:12:45 +0000503 }
504 }
505 }
506
507 return Modified;
508}
509
510bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) {
511 TII = MF.getTarget().getInstrInfo();
Evan Cheng826bdfa2010-05-04 20:38:12 +0000512 MRI = &MF.getRegInfo();
Bob Wilson70cd88f2009-08-05 23:12:45 +0000513
514 bool Modified = false;
515 for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
516 ++MFI) {
517 MachineBasicBlock &MBB = *MFI;
518 Modified |= PreAllocNEONRegisters(MBB);
519 }
520
521 return Modified;
522}
523
524/// createNEONPreAllocPass - returns an instance of the NEON register
525/// pre-allocation pass.
526FunctionPass *llvm::createNEONPreAllocPass() {
527 return new NEONPreAllocPass();
528}