]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / lib / Target / NVPTX / NVPTXInstrInfo.cpp
1 //===- NVPTXInstrInfo.cpp - NVPTX Instruction Information -----------------===//
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 // This file contains the NVPTX implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "NVPTX.h"
15 #include "NVPTXInstrInfo.h"
16 #include "NVPTXTargetMachine.h"
17 #define GET_INSTRINFO_CTOR
18 #include "NVPTXGenInstrInfo.inc"
19 #include "llvm/Function.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include <cstdio>
25
26
27 using namespace llvm;
28
29 // FIXME: Add the subtarget support on this constructor.
30 NVPTXInstrInfo::NVPTXInstrInfo(NVPTXTargetMachine &tm)
31 : NVPTXGenInstrInfo(),
32   TM(tm),
33   RegInfo(*this, *TM.getSubtargetImpl()) {}
34
35
36 void NVPTXInstrInfo::copyPhysReg (MachineBasicBlock &MBB,
37                                   MachineBasicBlock::iterator I, DebugLoc DL,
38                                   unsigned DestReg, unsigned SrcReg,
39                                   bool KillSrc) const {
40   if (NVPTX::Int32RegsRegClass.contains(DestReg) &&
41       NVPTX::Int32RegsRegClass.contains(SrcReg))
42     BuildMI(MBB, I, DL, get(NVPTX::IMOV32rr), DestReg)
43     .addReg(SrcReg, getKillRegState(KillSrc));
44   else if (NVPTX::Int8RegsRegClass.contains(DestReg) &&
45       NVPTX::Int8RegsRegClass.contains(SrcReg))
46     BuildMI(MBB, I, DL, get(NVPTX::IMOV8rr), DestReg)
47     .addReg(SrcReg, getKillRegState(KillSrc));
48   else if (NVPTX::Int1RegsRegClass.contains(DestReg) &&
49       NVPTX::Int1RegsRegClass.contains(SrcReg))
50     BuildMI(MBB, I, DL, get(NVPTX::IMOV1rr), DestReg)
51     .addReg(SrcReg, getKillRegState(KillSrc));
52   else if (NVPTX::Float32RegsRegClass.contains(DestReg) &&
53       NVPTX::Float32RegsRegClass.contains(SrcReg))
54     BuildMI(MBB, I, DL, get(NVPTX::FMOV32rr), DestReg)
55     .addReg(SrcReg, getKillRegState(KillSrc));
56   else if (NVPTX::Int16RegsRegClass.contains(DestReg) &&
57       NVPTX::Int16RegsRegClass.contains(SrcReg))
58     BuildMI(MBB, I, DL, get(NVPTX::IMOV16rr), DestReg)
59     .addReg(SrcReg, getKillRegState(KillSrc));
60   else if (NVPTX::Int64RegsRegClass.contains(DestReg) &&
61       NVPTX::Int64RegsRegClass.contains(SrcReg))
62     BuildMI(MBB, I, DL, get(NVPTX::IMOV64rr), DestReg)
63     .addReg(SrcReg, getKillRegState(KillSrc));
64   else if (NVPTX::Float64RegsRegClass.contains(DestReg) &&
65       NVPTX::Float64RegsRegClass.contains(SrcReg))
66     BuildMI(MBB, I, DL, get(NVPTX::FMOV64rr), DestReg)
67     .addReg(SrcReg, getKillRegState(KillSrc));
68   else if (NVPTX::V4F32RegsRegClass.contains(DestReg) &&
69       NVPTX::V4F32RegsRegClass.contains(SrcReg))
70     BuildMI(MBB, I, DL, get(NVPTX::V4f32Mov), DestReg)
71     .addReg(SrcReg, getKillRegState(KillSrc));
72   else if (NVPTX::V4I32RegsRegClass.contains(DestReg) &&
73       NVPTX::V4I32RegsRegClass.contains(SrcReg))
74     BuildMI(MBB, I, DL, get(NVPTX::V4i32Mov), DestReg)
75     .addReg(SrcReg, getKillRegState(KillSrc));
76   else if (NVPTX::V2F32RegsRegClass.contains(DestReg) &&
77       NVPTX::V2F32RegsRegClass.contains(SrcReg))
78     BuildMI(MBB, I, DL, get(NVPTX::V2f32Mov), DestReg)
79     .addReg(SrcReg, getKillRegState(KillSrc));
80   else if (NVPTX::V2I32RegsRegClass.contains(DestReg) &&
81       NVPTX::V2I32RegsRegClass.contains(SrcReg))
82     BuildMI(MBB, I, DL, get(NVPTX::V2i32Mov), DestReg)
83     .addReg(SrcReg, getKillRegState(KillSrc));
84   else if (NVPTX::V4I8RegsRegClass.contains(DestReg) &&
85       NVPTX::V4I8RegsRegClass.contains(SrcReg))
86     BuildMI(MBB, I, DL, get(NVPTX::V4i8Mov), DestReg)
87     .addReg(SrcReg, getKillRegState(KillSrc));
88   else if (NVPTX::V2I8RegsRegClass.contains(DestReg) &&
89       NVPTX::V2I8RegsRegClass.contains(SrcReg))
90     BuildMI(MBB, I, DL, get(NVPTX::V2i8Mov), DestReg)
91     .addReg(SrcReg, getKillRegState(KillSrc));
92   else if (NVPTX::V4I16RegsRegClass.contains(DestReg) &&
93       NVPTX::V4I16RegsRegClass.contains(SrcReg))
94     BuildMI(MBB, I, DL, get(NVPTX::V4i16Mov), DestReg)
95     .addReg(SrcReg, getKillRegState(KillSrc));
96   else if (NVPTX::V2I16RegsRegClass.contains(DestReg) &&
97       NVPTX::V2I16RegsRegClass.contains(SrcReg))
98     BuildMI(MBB, I, DL, get(NVPTX::V2i16Mov), DestReg)
99     .addReg(SrcReg, getKillRegState(KillSrc));
100   else if (NVPTX::V2I64RegsRegClass.contains(DestReg) &&
101       NVPTX::V2I64RegsRegClass.contains(SrcReg))
102     BuildMI(MBB, I, DL, get(NVPTX::V2i64Mov), DestReg)
103     .addReg(SrcReg, getKillRegState(KillSrc));
104   else if (NVPTX::V2F64RegsRegClass.contains(DestReg) &&
105       NVPTX::V2F64RegsRegClass.contains(SrcReg))
106     BuildMI(MBB, I, DL, get(NVPTX::V2f64Mov), DestReg)
107     .addReg(SrcReg, getKillRegState(KillSrc));
108   else {
109     llvm_unreachable("Don't know how to copy a register");
110   }
111 }
112
113 bool NVPTXInstrInfo::isMoveInstr(const MachineInstr &MI,
114                                  unsigned &SrcReg,
115                                  unsigned &DestReg) const {
116   // Look for the appropriate part of TSFlags
117   bool isMove = false;
118
119   unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::SimpleMoveMask) >>
120       NVPTX::SimpleMoveShift;
121   isMove = (TSFlags == 1);
122
123   if (isMove) {
124     MachineOperand dest = MI.getOperand(0);
125     MachineOperand src = MI.getOperand(1);
126     assert(dest.isReg() && "dest of a movrr is not a reg");
127     assert(src.isReg() && "src of a movrr is not a reg");
128
129     SrcReg = src.getReg();
130     DestReg = dest.getReg();
131     return true;
132   }
133
134   return false;
135 }
136
137 bool  NVPTXInstrInfo::isReadSpecialReg(MachineInstr &MI) const
138 {
139   switch (MI.getOpcode()) {
140   default: return false;
141   case NVPTX::INT_PTX_SREG_NTID_X:
142   case NVPTX::INT_PTX_SREG_NTID_Y:
143   case NVPTX::INT_PTX_SREG_NTID_Z:
144   case NVPTX::INT_PTX_SREG_TID_X:
145   case NVPTX::INT_PTX_SREG_TID_Y:
146   case NVPTX::INT_PTX_SREG_TID_Z:
147   case NVPTX::INT_PTX_SREG_CTAID_X:
148   case NVPTX::INT_PTX_SREG_CTAID_Y:
149   case NVPTX::INT_PTX_SREG_CTAID_Z:
150   case NVPTX::INT_PTX_SREG_NCTAID_X:
151   case NVPTX::INT_PTX_SREG_NCTAID_Y:
152   case NVPTX::INT_PTX_SREG_NCTAID_Z:
153   case NVPTX::INT_PTX_SREG_WARPSIZE:
154     return true;
155   }
156 }
157
158
159 bool NVPTXInstrInfo::isLoadInstr(const MachineInstr &MI,
160                                  unsigned &AddrSpace) const {
161   bool isLoad = false;
162   unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::isLoadMask) >>
163       NVPTX::isLoadShift;
164   isLoad = (TSFlags == 1);
165   if (isLoad)
166     AddrSpace = getLdStCodeAddrSpace(MI);
167   return isLoad;
168 }
169
170 bool NVPTXInstrInfo::isStoreInstr(const MachineInstr &MI,
171                                   unsigned &AddrSpace) const {
172   bool isStore = false;
173   unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::isStoreMask) >>
174       NVPTX::isStoreShift;
175   isStore = (TSFlags == 1);
176   if (isStore)
177     AddrSpace = getLdStCodeAddrSpace(MI);
178   return isStore;
179 }
180
181
182 bool NVPTXInstrInfo::CanTailMerge(const MachineInstr *MI) const {
183   unsigned addrspace = 0;
184   if (MI->getOpcode() == NVPTX::INT_CUDA_SYNCTHREADS)
185     return false;
186   if (isLoadInstr(*MI, addrspace))
187     if (addrspace == NVPTX::PTXLdStInstCode::SHARED)
188       return false;
189   if (isStoreInstr(*MI, addrspace))
190     if (addrspace == NVPTX::PTXLdStInstCode::SHARED)
191       return false;
192   return true;
193 }
194
195
196 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
197 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
198 /// implemented for a target).  Upon success, this returns false and returns
199 /// with the following information in various cases:
200 ///
201 /// 1. If this block ends with no branches (it just falls through to its succ)
202 ///    just return false, leaving TBB/FBB null.
203 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
204 ///    the destination block.
205 /// 3. If this block ends with an conditional branch and it falls through to
206 ///    an successor block, it sets TBB to be the branch destination block and a
207 ///    list of operands that evaluate the condition. These
208 ///    operands can be passed to other TargetInstrInfo methods to create new
209 ///    branches.
210 /// 4. If this block ends with an conditional branch and an unconditional
211 ///    block, it returns the 'true' destination in TBB, the 'false' destination
212 ///    in FBB, and a list of operands that evaluate the condition. These
213 ///    operands can be passed to other TargetInstrInfo methods to create new
214 ///    branches.
215 ///
216 /// Note that RemoveBranch and InsertBranch must be implemented to support
217 /// cases where this method returns success.
218 ///
219 bool NVPTXInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
220                                    MachineBasicBlock *&TBB,
221                                    MachineBasicBlock *&FBB,
222                                    SmallVectorImpl<MachineOperand> &Cond,
223                                    bool AllowModify) const {
224   // If the block has no terminators, it just falls into the block after it.
225   MachineBasicBlock::iterator I = MBB.end();
226   if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
227     return false;
228
229   // Get the last instruction in the block.
230   MachineInstr *LastInst = I;
231
232   // If there is only one terminator instruction, process it.
233   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
234     if (LastInst->getOpcode() == NVPTX::GOTO) {
235       TBB = LastInst->getOperand(0).getMBB();
236       return false;
237     } else if (LastInst->getOpcode() == NVPTX::CBranch) {
238       // Block ends with fall-through condbranch.
239       TBB = LastInst->getOperand(1).getMBB();
240       Cond.push_back(LastInst->getOperand(0));
241       return false;
242     }
243     // Otherwise, don't know what this is.
244     return true;
245   }
246
247   // Get the instruction before it if it's a terminator.
248   MachineInstr *SecondLastInst = I;
249
250   // If there are three terminators, we don't know what sort of block this is.
251   if (SecondLastInst && I != MBB.begin() &&
252       isUnpredicatedTerminator(--I))
253     return true;
254
255   // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
256   if (SecondLastInst->getOpcode() == NVPTX::CBranch &&
257       LastInst->getOpcode() == NVPTX::GOTO) {
258     TBB =  SecondLastInst->getOperand(1).getMBB();
259     Cond.push_back(SecondLastInst->getOperand(0));
260     FBB = LastInst->getOperand(0).getMBB();
261     return false;
262   }
263
264   // If the block ends with two NVPTX:GOTOs, handle it.  The second one is not
265   // executed, so remove it.
266   if (SecondLastInst->getOpcode() == NVPTX::GOTO &&
267       LastInst->getOpcode() == NVPTX::GOTO) {
268     TBB = SecondLastInst->getOperand(0).getMBB();
269     I = LastInst;
270     if (AllowModify)
271       I->eraseFromParent();
272     return false;
273   }
274
275   // Otherwise, can't handle this.
276   return true;
277 }
278
279 unsigned NVPTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
280   MachineBasicBlock::iterator I = MBB.end();
281   if (I == MBB.begin()) return 0;
282   --I;
283   if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)
284     return 0;
285
286   // Remove the branch.
287   I->eraseFromParent();
288
289   I = MBB.end();
290
291   if (I == MBB.begin()) return 1;
292   --I;
293   if (I->getOpcode() != NVPTX::CBranch)
294     return 1;
295
296   // Remove the branch.
297   I->eraseFromParent();
298   return 2;
299 }
300
301 unsigned
302 NVPTXInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
303                              MachineBasicBlock *FBB,
304                              const SmallVectorImpl<MachineOperand> &Cond,
305                              DebugLoc DL) const {
306   // Shouldn't be a fall through.
307   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
308   assert((Cond.size() == 1 || Cond.size() == 0) &&
309          "NVPTX branch conditions have two components!");
310
311   // One-way branch.
312   if (FBB == 0) {
313     if (Cond.empty())   // Unconditional branch
314       BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);
315     else                // Conditional branch
316       BuildMI(&MBB, DL, get(NVPTX::CBranch))
317       .addReg(Cond[0].getReg()).addMBB(TBB);
318     return 1;
319   }
320
321   // Two-way Conditional Branch.
322   BuildMI(&MBB, DL, get(NVPTX::CBranch))
323   .addReg(Cond[0].getReg()).addMBB(TBB);
324   BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);
325   return 2;
326 }