Mechanically replace LiveInterval* with LiveIntervalMap for intervals being
[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                           unsigned Offset, unsigned Stride) const;
38     bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
39   };
40
41   char NEONPreAllocPass::ID = 0;
42 }
43
44 static 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
50   switch (Opcode) {
51   default:
52     break;
53
54   case ARM::VTBL2:
55     FirstOpnd = 1;
56     NumRegs = 2;
57     return true;
58
59   case ARM::VTBL3:
60     FirstOpnd = 1;
61     NumRegs = 3;
62     return true;
63
64   case ARM::VTBL4:
65     FirstOpnd = 1;
66     NumRegs = 4;
67     return true;
68
69   case ARM::VTBX2:
70     FirstOpnd = 2;
71     NumRegs = 2;
72     return true;
73
74   case ARM::VTBX3:
75     FirstOpnd = 2;
76     NumRegs = 3;
77     return true;
78
79   case ARM::VTBX4:
80     FirstOpnd = 2;
81     NumRegs = 4;
82     return true;
83   }
84
85   return false;
86 }
87
88 bool
89 NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
90                                    unsigned FirstOpnd, unsigned NumRegs,
91                                    unsigned Offset, unsigned Stride) const {
92   MachineOperand &FMO = MI->getOperand(FirstOpnd);
93   assert(FMO.isReg() && FMO.getSubReg() == 0 && "unexpected operand");
94   unsigned VirtReg = FMO.getReg();
95   (void)VirtReg;
96   assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
97          "expected a virtual register");
98
99   unsigned LastSubIdx = 0;
100   if (FMO.isDef()) {
101     MachineInstr *RegSeq = 0;
102     for (unsigned R = 0; R < NumRegs; ++R) {
103       const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
104       assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
105       unsigned VirtReg = MO.getReg();
106       assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
107              "expected a virtual register");
108       // Feeding into a REG_SEQUENCE.
109       if (!MRI->hasOneNonDBGUse(VirtReg))
110         return false;
111       MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg);
112       if (!UseMI->isRegSequence())
113         return false;
114       if (RegSeq && RegSeq != UseMI)
115         return false;
116       unsigned OpIdx = 1 + (Offset + R * Stride) * 2;
117       if (UseMI->getOperand(OpIdx).getReg() != VirtReg)
118         llvm_unreachable("Malformed REG_SEQUENCE instruction!");
119       unsigned SubIdx = UseMI->getOperand(OpIdx + 1).getImm();
120       if (LastSubIdx) {
121         if (LastSubIdx != SubIdx-Stride)
122           return false;
123       } else {
124         // Must start from dsub_0 or qsub_0.
125         if (SubIdx != (ARM::dsub_0+Offset) &&
126             SubIdx != (ARM::qsub_0+Offset))
127           return false;
128       }
129       RegSeq = UseMI;
130       LastSubIdx = SubIdx;
131     }
132
133     // In the case of vld3, etc., make sure the trailing operand of
134     // REG_SEQUENCE is an undef.
135     if (NumRegs == 3) {
136       unsigned OpIdx = 1 + (Offset + 3 * Stride) * 2;
137       const MachineOperand &MO = RegSeq->getOperand(OpIdx);
138       unsigned VirtReg = MO.getReg();
139       MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
140       if (!DefMI || !DefMI->isImplicitDef())
141         return false;
142     }
143     return true;
144   }
145
146   unsigned LastSrcReg = 0;
147   SmallVector<unsigned, 4> SubIds;
148   for (unsigned R = 0; R < NumRegs; ++R) {
149     const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
150     assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
151     unsigned VirtReg = MO.getReg();
152     assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
153            "expected a virtual register");
154     // Extracting from a Q or QQ register.
155     MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
156     if (!DefMI || !DefMI->isCopy() || !DefMI->getOperand(1).getSubReg())
157       return false;
158     VirtReg = DefMI->getOperand(1).getReg();
159     if (LastSrcReg && LastSrcReg != VirtReg)
160       return false;
161     LastSrcReg = VirtReg;
162     const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
163     if (RC != ARM::QPRRegisterClass &&
164         RC != ARM::QQPRRegisterClass &&
165         RC != ARM::QQQQPRRegisterClass)
166       return false;
167     unsigned SubIdx = DefMI->getOperand(1).getSubReg();
168     if (LastSubIdx) {
169       if (LastSubIdx != SubIdx-Stride)
170         return false;
171     } else {
172       // Must start from dsub_0 or qsub_0.
173       if (SubIdx != (ARM::dsub_0+Offset) &&
174           SubIdx != (ARM::qsub_0+Offset))
175         return false;
176     }
177     SubIds.push_back(SubIdx);
178     LastSubIdx = SubIdx;
179   }
180
181   // FIXME: Update the uses of EXTRACT_SUBREG from REG_SEQUENCE is
182   // currently required for correctness. e.g.
183   //  %reg1041<def> = REG_SEQUENCE %reg1040<kill>, 5, %reg1035<kill>, 6
184   //  %reg1042<def> = EXTRACT_SUBREG %reg1041, 6
185   //  %reg1043<def> = EXTRACT_SUBREG %reg1041, 5
186   //  VST1q16 %reg1025<kill>, 0, %reg1043<kill>, %reg1042<kill>,
187   // reg1042 and reg1043 should be replaced with reg1041:6 and reg1041:5
188   // respectively.
189   // We need to change how we model uses of REG_SEQUENCE.
190   for (unsigned R = 0; R < NumRegs; ++R) {
191     MachineOperand &MO = MI->getOperand(FirstOpnd + R);
192     unsigned OldReg = MO.getReg();
193     MachineInstr *DefMI = MRI->getVRegDef(OldReg);
194     assert(DefMI->isCopy());
195     MO.setReg(LastSrcReg);
196     MO.setSubReg(SubIds[R]);
197     MO.setIsKill(false);
198     // Delete the EXTRACT_SUBREG if its result is now dead.
199     if (MRI->use_empty(OldReg))
200       DefMI->eraseFromParent();
201   }
202
203   return true;
204 }
205
206 bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
207   bool Modified = false;
208
209   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
210   for (; MBBI != E; ++MBBI) {
211     MachineInstr *MI = &*MBBI;
212     unsigned FirstOpnd, NumRegs, Offset, Stride;
213     if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
214       continue;
215     if (FormsRegSequence(MI, FirstOpnd, NumRegs, Offset, Stride))
216       continue;
217
218     MachineBasicBlock::iterator NextI = llvm::next(MBBI);
219     for (unsigned R = 0; R < NumRegs; ++R) {
220       MachineOperand &MO = MI->getOperand(FirstOpnd + R);
221       assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
222       unsigned VirtReg = MO.getReg();
223       assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
224              "expected a virtual register");
225
226       // For now, just assign a fixed set of adjacent registers.
227       // This leaves plenty of room for future improvements.
228       static const unsigned NEONDRegs[] = {
229         ARM::D0, ARM::D1, ARM::D2, ARM::D3,
230         ARM::D4, ARM::D5, ARM::D6, ARM::D7
231       };
232       MO.setReg(NEONDRegs[Offset + R * Stride]);
233
234       if (MO.isUse()) {
235         // Insert a copy from VirtReg.
236         BuildMI(MBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),MO.getReg())
237           .addReg(VirtReg, getKillRegState(MO.isKill()));
238         MO.setIsKill();
239       } else if (MO.isDef() && !MO.isDead()) {
240         // Add a copy to VirtReg.
241         BuildMI(MBB, NextI, DebugLoc(), TII->get(TargetOpcode::COPY), VirtReg)
242           .addReg(MO.getReg());
243       }
244     }
245   }
246
247   return Modified;
248 }
249
250 bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) {
251   TII = MF.getTarget().getInstrInfo();
252   MRI = &MF.getRegInfo();
253
254   bool Modified = false;
255   for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
256        ++MFI) {
257     MachineBasicBlock &MBB = *MFI;
258     Modified |= PreAllocNEONRegisters(MBB);
259   }
260
261   return Modified;
262 }
263
264 /// createNEONPreAllocPass - returns an instance of the NEON register
265 /// pre-allocation pass.
266 FunctionPass *llvm::createNEONPreAllocPass() {
267   return new NEONPreAllocPass();
268 }