1
//===-- NEONPreAllocPass.cpp - Allocate adjacent NEON registers--*- C++ -*-===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
#define DEBUG_TYPE "neon-prealloc"
12
#include "ARMInstrInfo.h"
13
#include "llvm/CodeGen/MachineInstr.h"
14
#include "llvm/CodeGen/MachineInstrBuilder.h"
15
#include "llvm/CodeGen/MachineFunctionPass.h"
19
class NEONPreAllocPass : public MachineFunctionPass {
20
const TargetInstrInfo *TII;
24
NEONPreAllocPass() : MachineFunctionPass(&ID) {}
26
virtual bool runOnMachineFunction(MachineFunction &MF);
28
virtual const char *getPassName() const {
29
return "NEON register pre-allocation pass";
33
bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
36
char NEONPreAllocPass::ID = 0;
39
static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
40
unsigned &Offset, unsigned &Stride) {
41
// Default to unit stride with no offset.
112
case ARM::VLD3LNq16a:
113
case ARM::VLD3LNq32a:
120
case ARM::VLD3LNq16b:
121
case ARM::VLD3LNq32b:
157
case ARM::VLD4LNq16a:
158
case ARM::VLD4LNq32a:
165
case ARM::VLD4LNq16b:
166
case ARM::VLD4LNq32b:
191
case ARM::VST2LNq16a:
192
case ARM::VST2LNq32a:
199
case ARM::VST2LNq16b:
200
case ARM::VST2LNq32b:
236
case ARM::VST3LNq16a:
237
case ARM::VST3LNq32a:
244
case ARM::VST3LNq16b:
245
case ARM::VST3LNq32b:
281
case ARM::VST4LNq16a:
282
case ARM::VST4LNq32a:
289
case ARM::VST4LNq16b:
290
case ARM::VST4LNq32b:
331
bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
332
bool Modified = false;
334
MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
335
for (; MBBI != E; ++MBBI) {
336
MachineInstr *MI = &*MBBI;
337
unsigned FirstOpnd, NumRegs, Offset, Stride;
338
if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
341
MachineBasicBlock::iterator NextI = llvm::next(MBBI);
342
for (unsigned R = 0; R < NumRegs; ++R) {
343
MachineOperand &MO = MI->getOperand(FirstOpnd + R);
344
assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
345
unsigned VirtReg = MO.getReg();
346
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
347
"expected a virtual register");
349
// For now, just assign a fixed set of adjacent registers.
350
// This leaves plenty of room for future improvements.
351
static const unsigned NEONDRegs[] = {
352
ARM::D0, ARM::D1, ARM::D2, ARM::D3,
353
ARM::D4, ARM::D5, ARM::D6, ARM::D7
355
MO.setReg(NEONDRegs[Offset + R * Stride]);
358
// Insert a copy from VirtReg.
359
TII->copyRegToReg(MBB, MBBI, MO.getReg(), VirtReg,
360
ARM::DPRRegisterClass, ARM::DPRRegisterClass);
362
MachineInstr *CopyMI = prior(MBBI);
363
CopyMI->findRegisterUseOperand(VirtReg)->setIsKill();
366
} else if (MO.isDef() && !MO.isDead()) {
367
// Add a copy to VirtReg.
368
TII->copyRegToReg(MBB, NextI, VirtReg, MO.getReg(),
369
ARM::DPRRegisterClass, ARM::DPRRegisterClass);
377
bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) {
378
TII = MF.getTarget().getInstrInfo();
380
bool Modified = false;
381
for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
383
MachineBasicBlock &MBB = *MFI;
384
Modified |= PreAllocNEONRegisters(MBB);
390
/// createNEONPreAllocPass - returns an instance of the NEON register
391
/// pre-allocation pass.
392
FunctionPass *llvm::createNEONPreAllocPass() {
393
return new NEONPreAllocPass();