blob: 59e3280434d9db438d3369c1cb3127d25412cfe4 [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,
36 unsigned FirstOpnd, unsigned NumRegs);
Bob Wilson70cd88f2009-08-05 23:12:45 +000037 bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
38 };
39
40 char NEONPreAllocPass::ID = 0;
41}
42
Bob Wilsonff8952e2009-10-07 17:24:55 +000043static 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
Bob Wilson70cd88f2009-08-05 23:12:45 +000049 switch (Opcode) {
50 default:
51 break;
52
Bob Wilson621f1952010-03-23 05:25:43 +000053 case ARM::VLD1q8:
54 case ARM::VLD1q16:
55 case ARM::VLD1q32:
56 case ARM::VLD1q64:
Bob Wilson70cd88f2009-08-05 23:12:45 +000057 case ARM::VLD2d8:
58 case ARM::VLD2d16:
59 case ARM::VLD2d32:
Bob Wilson243fcc52009-09-01 04:26:28 +000060 case ARM::VLD2LNd8:
61 case ARM::VLD2LNd16:
62 case ARM::VLD2LNd32:
Bob Wilson70cd88f2009-08-05 23:12:45 +000063 FirstOpnd = 0;
64 NumRegs = 2;
65 return true;
66
Bob Wilson0bf7d992009-10-08 22:27:33 +000067 case ARM::VLD2q8:
68 case ARM::VLD2q16:
69 case ARM::VLD2q32:
70 FirstOpnd = 0;
71 NumRegs = 4;
72 return true;
73
Bob Wilson95ffecd2010-03-20 18:35:24 +000074 case ARM::VLD2LNq16:
75 case ARM::VLD2LNq32:
Bob Wilson30aea9d2009-10-08 18:56:10 +000076 FirstOpnd = 0;
77 NumRegs = 2;
78 Offset = 0;
79 Stride = 2;
80 return true;
81
Bob Wilson95ffecd2010-03-20 18:35:24 +000082 case ARM::VLD2LNq16odd:
83 case ARM::VLD2LNq32odd:
Bob Wilson30aea9d2009-10-08 18:56:10 +000084 FirstOpnd = 0;
85 NumRegs = 2;
86 Offset = 1;
87 Stride = 2;
88 return true;
89
Bob Wilson70cd88f2009-08-05 23:12:45 +000090 case ARM::VLD3d8:
91 case ARM::VLD3d16:
92 case ARM::VLD3d32:
Bob Wilsona6979752010-03-22 18:13:18 +000093 case ARM::VLD1d64T:
Bob Wilson243fcc52009-09-01 04:26:28 +000094 case ARM::VLD3LNd8:
95 case ARM::VLD3LNd16:
96 case ARM::VLD3LNd32:
Bob Wilson70cd88f2009-08-05 23:12:45 +000097 FirstOpnd = 0;
98 NumRegs = 3;
99 return true;
100
Bob Wilson95ffecd2010-03-20 18:35:24 +0000101 case ARM::VLD3q8_UPD:
102 case ARM::VLD3q16_UPD:
103 case ARM::VLD3q32_UPD:
Bob Wilsonff8952e2009-10-07 17:24:55 +0000104 FirstOpnd = 0;
105 NumRegs = 3;
106 Offset = 0;
107 Stride = 2;
108 return true;
109
Bob Wilson95ffecd2010-03-20 18:35:24 +0000110 case ARM::VLD3q8odd_UPD:
111 case ARM::VLD3q16odd_UPD:
112 case ARM::VLD3q32odd_UPD:
Bob Wilsonff8952e2009-10-07 17:24:55 +0000113 FirstOpnd = 0;
114 NumRegs = 3;
115 Offset = 1;
116 Stride = 2;
117 return true;
118
Bob Wilson95ffecd2010-03-20 18:35:24 +0000119 case ARM::VLD3LNq16:
120 case ARM::VLD3LNq32:
Bob Wilson0bf7d992009-10-08 22:27:33 +0000121 FirstOpnd = 0;
122 NumRegs = 3;
123 Offset = 0;
124 Stride = 2;
125 return true;
126
Bob Wilson95ffecd2010-03-20 18:35:24 +0000127 case ARM::VLD3LNq16odd:
128 case ARM::VLD3LNq32odd:
Bob Wilson0bf7d992009-10-08 22:27:33 +0000129 FirstOpnd = 0;
130 NumRegs = 3;
131 Offset = 1;
132 Stride = 2;
133 return true;
134
Bob Wilson70cd88f2009-08-05 23:12:45 +0000135 case ARM::VLD4d8:
136 case ARM::VLD4d16:
137 case ARM::VLD4d32:
Bob Wilsona6979752010-03-22 18:13:18 +0000138 case ARM::VLD1d64Q:
Bob Wilson243fcc52009-09-01 04:26:28 +0000139 case ARM::VLD4LNd8:
140 case ARM::VLD4LNd16:
141 case ARM::VLD4LNd32:
Bob Wilson70cd88f2009-08-05 23:12:45 +0000142 FirstOpnd = 0;
143 NumRegs = 4;
144 return true;
Bob Wilsonb36ec862009-08-06 18:47:44 +0000145
Bob Wilson95ffecd2010-03-20 18:35:24 +0000146 case ARM::VLD4q8_UPD:
147 case ARM::VLD4q16_UPD:
148 case ARM::VLD4q32_UPD:
Bob Wilson7708c222009-10-07 18:09:32 +0000149 FirstOpnd = 0;
150 NumRegs = 4;
151 Offset = 0;
152 Stride = 2;
153 return true;
154
Bob Wilson95ffecd2010-03-20 18:35:24 +0000155 case ARM::VLD4q8odd_UPD:
156 case ARM::VLD4q16odd_UPD:
157 case ARM::VLD4q32odd_UPD:
Bob Wilson7708c222009-10-07 18:09:32 +0000158 FirstOpnd = 0;
159 NumRegs = 4;
160 Offset = 1;
161 Stride = 2;
162 return true;
163
Bob Wilson95ffecd2010-03-20 18:35:24 +0000164 case ARM::VLD4LNq16:
165 case ARM::VLD4LNq32:
Bob Wilson62e053e2009-10-08 22:53:57 +0000166 FirstOpnd = 0;
167 NumRegs = 4;
168 Offset = 0;
169 Stride = 2;
170 return true;
171
Bob Wilson95ffecd2010-03-20 18:35:24 +0000172 case ARM::VLD4LNq16odd:
173 case ARM::VLD4LNq32odd:
Bob Wilson62e053e2009-10-08 22:53:57 +0000174 FirstOpnd = 0;
175 NumRegs = 4;
176 Offset = 1;
177 Stride = 2;
178 return true;
179
Bob Wilson11d98992010-03-23 06:20:33 +0000180 case ARM::VST1q8:
181 case ARM::VST1q16:
182 case ARM::VST1q32:
183 case ARM::VST1q64:
Bob Wilsonb36ec862009-08-06 18:47:44 +0000184 case ARM::VST2d8:
185 case ARM::VST2d16:
186 case ARM::VST2d32:
Bob Wilson8a3198b2009-09-01 18:51:56 +0000187 case ARM::VST2LNd8:
188 case ARM::VST2LNd16:
189 case ARM::VST2LNd32:
Bob Wilson226036e2010-03-20 22:13:40 +0000190 FirstOpnd = 2;
Bob Wilsonb36ec862009-08-06 18:47:44 +0000191 NumRegs = 2;
192 return true;
193
Bob Wilsond2855752009-10-07 18:47:39 +0000194 case ARM::VST2q8:
195 case ARM::VST2q16:
196 case ARM::VST2q32:
Bob Wilson226036e2010-03-20 22:13:40 +0000197 FirstOpnd = 2;
Bob Wilsond2855752009-10-07 18:47:39 +0000198 NumRegs = 4;
199 return true;
200
Bob Wilson95ffecd2010-03-20 18:35:24 +0000201 case ARM::VST2LNq16:
202 case ARM::VST2LNq32:
Bob Wilson226036e2010-03-20 22:13:40 +0000203 FirstOpnd = 2;
Bob Wilsonc5c6edb2009-10-08 23:38:24 +0000204 NumRegs = 2;
205 Offset = 0;
206 Stride = 2;
207 return true;
208
Bob Wilson95ffecd2010-03-20 18:35:24 +0000209 case ARM::VST2LNq16odd:
210 case ARM::VST2LNq32odd:
Bob Wilson226036e2010-03-20 22:13:40 +0000211 FirstOpnd = 2;
Bob Wilsonc5c6edb2009-10-08 23:38:24 +0000212 NumRegs = 2;
213 Offset = 1;
214 Stride = 2;
215 return true;
216
Bob Wilsonb36ec862009-08-06 18:47:44 +0000217 case ARM::VST3d8:
218 case ARM::VST3d16:
219 case ARM::VST3d32:
Bob Wilsona6979752010-03-22 18:13:18 +0000220 case ARM::VST1d64T:
Bob Wilson8a3198b2009-09-01 18:51:56 +0000221 case ARM::VST3LNd8:
222 case ARM::VST3LNd16:
223 case ARM::VST3LNd32:
Bob Wilson226036e2010-03-20 22:13:40 +0000224 FirstOpnd = 2;
Bob Wilsonb36ec862009-08-06 18:47:44 +0000225 NumRegs = 3;
226 return true;
227
Bob Wilson95ffecd2010-03-20 18:35:24 +0000228 case ARM::VST3q8_UPD:
229 case ARM::VST3q16_UPD:
230 case ARM::VST3q32_UPD:
Bob Wilson226036e2010-03-20 22:13:40 +0000231 FirstOpnd = 4;
Bob Wilson66a70632009-10-07 20:30:08 +0000232 NumRegs = 3;
233 Offset = 0;
234 Stride = 2;
235 return true;
236
Bob Wilson95ffecd2010-03-20 18:35:24 +0000237 case ARM::VST3q8odd_UPD:
238 case ARM::VST3q16odd_UPD:
239 case ARM::VST3q32odd_UPD:
Bob Wilson226036e2010-03-20 22:13:40 +0000240 FirstOpnd = 4;
Bob Wilson66a70632009-10-07 20:30:08 +0000241 NumRegs = 3;
242 Offset = 1;
243 Stride = 2;
244 return true;
245
Bob Wilson95ffecd2010-03-20 18:35:24 +0000246 case ARM::VST3LNq16:
247 case ARM::VST3LNq32:
Bob Wilson226036e2010-03-20 22:13:40 +0000248 FirstOpnd = 2;
Bob Wilson8cdb2692009-10-08 23:51:31 +0000249 NumRegs = 3;
250 Offset = 0;
251 Stride = 2;
252 return true;
253
Bob Wilson95ffecd2010-03-20 18:35:24 +0000254 case ARM::VST3LNq16odd:
255 case ARM::VST3LNq32odd:
Bob Wilson226036e2010-03-20 22:13:40 +0000256 FirstOpnd = 2;
Bob Wilson8cdb2692009-10-08 23:51:31 +0000257 NumRegs = 3;
258 Offset = 1;
259 Stride = 2;
260 return true;
261
Bob Wilsonb36ec862009-08-06 18:47:44 +0000262 case ARM::VST4d8:
263 case ARM::VST4d16:
264 case ARM::VST4d32:
Bob Wilsona6979752010-03-22 18:13:18 +0000265 case ARM::VST1d64Q:
Bob Wilson8a3198b2009-09-01 18:51:56 +0000266 case ARM::VST4LNd8:
267 case ARM::VST4LNd16:
268 case ARM::VST4LNd32:
Bob Wilson226036e2010-03-20 22:13:40 +0000269 FirstOpnd = 2;
Bob Wilsonb36ec862009-08-06 18:47:44 +0000270 NumRegs = 4;
271 return true;
Bob Wilson114a2662009-08-12 20:51:55 +0000272
Bob Wilson95ffecd2010-03-20 18:35:24 +0000273 case ARM::VST4q8_UPD:
274 case ARM::VST4q16_UPD:
275 case ARM::VST4q32_UPD:
Bob Wilson226036e2010-03-20 22:13:40 +0000276 FirstOpnd = 4;
Bob Wilson63c90632009-10-07 20:49:18 +0000277 NumRegs = 4;
278 Offset = 0;
279 Stride = 2;
280 return true;
281
Bob Wilson95ffecd2010-03-20 18:35:24 +0000282 case ARM::VST4q8odd_UPD:
283 case ARM::VST4q16odd_UPD:
284 case ARM::VST4q32odd_UPD:
Bob Wilson226036e2010-03-20 22:13:40 +0000285 FirstOpnd = 4;
Bob Wilson63c90632009-10-07 20:49:18 +0000286 NumRegs = 4;
287 Offset = 1;
288 Stride = 2;
289 return true;
290
Bob Wilson95ffecd2010-03-20 18:35:24 +0000291 case ARM::VST4LNq16:
292 case ARM::VST4LNq32:
Bob Wilson226036e2010-03-20 22:13:40 +0000293 FirstOpnd = 2;
Bob Wilson56311392009-10-09 00:01:36 +0000294 NumRegs = 4;
295 Offset = 0;
296 Stride = 2;
297 return true;
298
Bob Wilson95ffecd2010-03-20 18:35:24 +0000299 case ARM::VST4LNq16odd:
300 case ARM::VST4LNq32odd:
Bob Wilson226036e2010-03-20 22:13:40 +0000301 FirstOpnd = 2;
Bob Wilson56311392009-10-09 00:01:36 +0000302 NumRegs = 4;
303 Offset = 1;
304 Stride = 2;
305 return true;
306
Bob Wilson114a2662009-08-12 20:51:55 +0000307 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;
Bob Wilson70cd88f2009-08-05 23:12:45 +0000336 }
337
338 return false;
339}
340
Evan Cheng826bdfa2010-05-04 20:38:12 +0000341bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
342 unsigned FirstOpnd, unsigned NumRegs) {
343 MachineInstr *RegSeq = 0;
Evan Cheng676b2df2010-05-05 22:15:40 +0000344 unsigned LastSrcReg = 0;
345 unsigned LastSubIdx = 0;
Evan Cheng826bdfa2010-05-04 20:38:12 +0000346 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");
Evan Cheng676b2df2010-05-05 22:15:40 +0000352 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 }
Evan Cheng826bdfa2010-05-04 20:38:12 +0000378 }
379 return true;
380}
381
Bob Wilson70cd88f2009-08-05 23:12:45 +0000382bool 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;
Bob Wilsonff8952e2009-10-07 17:24:55 +0000388 unsigned FirstOpnd, NumRegs, Offset, Stride;
389 if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
Bob Wilson70cd88f2009-08-05 23:12:45 +0000390 continue;
Evan Cheng826bdfa2010-05-04 20:38:12 +0000391 if (FormsRegSequence(MI, FirstOpnd, NumRegs))
392 continue;
Bob Wilson70cd88f2009-08-05 23:12:45 +0000393
Chris Lattner7896c9f2009-12-03 00:50:42 +0000394 MachineBasicBlock::iterator NextI = llvm::next(MBBI);
Bob Wilson70cd88f2009-08-05 23:12:45 +0000395 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[] = {
Bob Wilsonff8952e2009-10-07 17:24:55 +0000405 ARM::D0, ARM::D1, ARM::D2, ARM::D3,
406 ARM::D4, ARM::D5, ARM::D6, ARM::D7
Bob Wilson70cd88f2009-08-05 23:12:45 +0000407 };
Bob Wilsonff8952e2009-10-07 17:24:55 +0000408 MO.setReg(NEONDRegs[Offset + R * Stride]);
Bob Wilson70cd88f2009-08-05 23:12:45 +0000409
410 if (MO.isUse()) {
411 // Insert a copy from VirtReg.
Bob Wilson349d82d2009-10-06 22:01:15 +0000412 TII->copyRegToReg(MBB, MBBI, MO.getReg(), VirtReg,
413 ARM::DPRRegisterClass, ARM::DPRRegisterClass);
Bob Wilson70cd88f2009-08-05 23:12:45 +0000414 if (MO.isKill()) {
415 MachineInstr *CopyMI = prior(MBBI);
416 CopyMI->findRegisterUseOperand(VirtReg)->setIsKill();
417 }
418 MO.setIsKill();
419 } else if (MO.isDef() && !MO.isDead()) {
420 // Add a copy to VirtReg.
Bob Wilson349d82d2009-10-06 22:01:15 +0000421 TII->copyRegToReg(MBB, NextI, VirtReg, MO.getReg(),
422 ARM::DPRRegisterClass, ARM::DPRRegisterClass);
Bob Wilson70cd88f2009-08-05 23:12:45 +0000423 }
424 }
425 }
426
427 return Modified;
428}
429
430bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) {
431 TII = MF.getTarget().getInstrInfo();
Evan Cheng826bdfa2010-05-04 20:38:12 +0000432 MRI = &MF.getRegInfo();
Bob Wilson70cd88f2009-08-05 23:12:45 +0000433
434 bool Modified = false;
435 for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
436 ++MFI) {
437 MachineBasicBlock &MBB = *MFI;
438 Modified |= PreAllocNEONRegisters(MBB);
439 }
440
441 return Modified;
442}
443
444/// createNEONPreAllocPass - returns an instance of the NEON register
445/// pre-allocation pass.
446FunctionPass *llvm::createNEONPreAllocPass() {
447 return new NEONPreAllocPass();
448}