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 VISIBILITY_HIDDEN 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
,
139 bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock
&MBB
) {
140 bool Modified
= false;
142 MachineBasicBlock::iterator MBBI
= MBB
.begin(), E
= MBB
.end();
143 for (; MBBI
!= E
; ++MBBI
) {
144 MachineInstr
*MI
= &*MBBI
;
145 unsigned FirstOpnd
, NumRegs
;
146 if (!isNEONMultiRegOp(MI
->getOpcode(), FirstOpnd
, NumRegs
))
149 MachineBasicBlock::iterator NextI
= next(MBBI
);
150 for (unsigned R
= 0; R
< NumRegs
; ++R
) {
151 MachineOperand
&MO
= MI
->getOperand(FirstOpnd
+ R
);
152 assert(MO
.isReg() && MO
.getSubReg() == 0 && "unexpected operand");
153 unsigned VirtReg
= MO
.getReg();
154 assert(TargetRegisterInfo::isVirtualRegister(VirtReg
) &&
155 "expected a virtual register");
157 // For now, just assign a fixed set of adjacent registers.
158 // This leaves plenty of room for future improvements.
159 static const unsigned NEONDRegs
[] = {
160 ARM::D0
, ARM::D1
, ARM::D2
, ARM::D3
162 MO
.setReg(NEONDRegs
[R
]);
165 // Insert a copy from VirtReg.
166 AddDefaultPred(BuildMI(MBB
, MBBI
, MI
->getDebugLoc(),
167 TII
->get(ARM::FCPYD
), MO
.getReg())
170 MachineInstr
*CopyMI
= prior(MBBI
);
171 CopyMI
->findRegisterUseOperand(VirtReg
)->setIsKill();
174 } else if (MO
.isDef() && !MO
.isDead()) {
175 // Add a copy to VirtReg.
176 AddDefaultPred(BuildMI(MBB
, NextI
, MI
->getDebugLoc(),
177 TII
->get(ARM::FCPYD
), VirtReg
)
178 .addReg(MO
.getReg()));
186 bool NEONPreAllocPass::runOnMachineFunction(MachineFunction
&MF
) {
187 TII
= MF
.getTarget().getInstrInfo();
189 bool Modified
= false;
190 for (MachineFunction::iterator MFI
= MF
.begin(), E
= MF
.end(); MFI
!= E
;
192 MachineBasicBlock
&MBB
= *MFI
;
193 Modified
|= PreAllocNEONRegisters(MBB
);
199 /// createNEONPreAllocPass - returns an instance of the NEON register
200 /// pre-allocation pass.
201 FunctionPass
*llvm::createNEONPreAllocPass() {
202 return new NEONPreAllocPass();