]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r301441, and update
[FreeBSD/FreeBSD.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 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/IR/Function.h"
22
23 using namespace llvm;
24
25 #define GET_INSTRINFO_CTOR_DTOR
26 #include "NVPTXGenInstrInfo.inc"
27
28 // Pin the vtable to this file.
29 void NVPTXInstrInfo::anchor() {}
30
31 NVPTXInstrInfo::NVPTXInstrInfo() : NVPTXGenInstrInfo(), RegInfo() {}
32
33 void NVPTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
34                                  MachineBasicBlock::iterator I,
35                                  const DebugLoc &DL, unsigned DestReg,
36                                  unsigned SrcReg, bool KillSrc) const {
37   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
38   const TargetRegisterClass *DestRC = MRI.getRegClass(DestReg);
39   const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
40
41   if (RegInfo.getRegSizeInBits(*DestRC) != RegInfo.getRegSizeInBits(*SrcRC))
42     report_fatal_error("Copy one register into another with a different width");
43
44   unsigned Op;
45   if (DestRC == &NVPTX::Int1RegsRegClass) {
46     Op = NVPTX::IMOV1rr;
47   } else if (DestRC == &NVPTX::Int16RegsRegClass) {
48     Op = NVPTX::IMOV16rr;
49   } else if (DestRC == &NVPTX::Int32RegsRegClass) {
50     Op = (SrcRC == &NVPTX::Int32RegsRegClass ? NVPTX::IMOV32rr
51                                              : NVPTX::BITCONVERT_32_F2I);
52   } else if (DestRC == &NVPTX::Int64RegsRegClass) {
53     Op = (SrcRC == &NVPTX::Int64RegsRegClass ? NVPTX::IMOV64rr
54                                              : NVPTX::BITCONVERT_64_F2I);
55   } else if (DestRC == &NVPTX::Float16RegsRegClass) {
56     Op = (SrcRC == &NVPTX::Float16RegsRegClass ? NVPTX::FMOV16rr
57                                                : NVPTX::BITCONVERT_16_I2F);
58   } else if (DestRC == &NVPTX::Float16x2RegsRegClass) {
59     Op = NVPTX::IMOV32rr;
60   } else if (DestRC == &NVPTX::Float32RegsRegClass) {
61     Op = (SrcRC == &NVPTX::Float32RegsRegClass ? NVPTX::FMOV32rr
62                                                : NVPTX::BITCONVERT_32_I2F);
63   } else if (DestRC == &NVPTX::Float64RegsRegClass) {
64     Op = (SrcRC == &NVPTX::Float64RegsRegClass ? NVPTX::FMOV64rr
65                                                : NVPTX::BITCONVERT_64_I2F);
66   } else {
67     llvm_unreachable("Bad register copy");
68   }
69   BuildMI(MBB, I, DL, get(Op), DestReg)
70       .addReg(SrcReg, getKillRegState(KillSrc));
71 }
72
73 bool NVPTXInstrInfo::isMoveInstr(const MachineInstr &MI, unsigned &SrcReg,
74                                  unsigned &DestReg) const {
75   // Look for the appropriate part of TSFlags
76   bool isMove = false;
77
78   unsigned TSFlags =
79       (MI.getDesc().TSFlags & NVPTX::SimpleMoveMask) >> NVPTX::SimpleMoveShift;
80   isMove = (TSFlags == 1);
81
82   if (isMove) {
83     MachineOperand dest = MI.getOperand(0);
84     MachineOperand src = MI.getOperand(1);
85     assert(dest.isReg() && "dest of a movrr is not a reg");
86     assert(src.isReg() && "src of a movrr is not a reg");
87
88     SrcReg = src.getReg();
89     DestReg = dest.getReg();
90     return true;
91   }
92
93   return false;
94 }
95
96 bool NVPTXInstrInfo::isLoadInstr(const MachineInstr &MI,
97                                  unsigned &AddrSpace) const {
98   bool isLoad = false;
99   unsigned TSFlags =
100       (MI.getDesc().TSFlags & NVPTX::isLoadMask) >> NVPTX::isLoadShift;
101   isLoad = (TSFlags == 1);
102   if (isLoad)
103     AddrSpace = getLdStCodeAddrSpace(MI);
104   return isLoad;
105 }
106
107 bool NVPTXInstrInfo::isStoreInstr(const MachineInstr &MI,
108                                   unsigned &AddrSpace) const {
109   bool isStore = false;
110   unsigned TSFlags =
111       (MI.getDesc().TSFlags & NVPTX::isStoreMask) >> NVPTX::isStoreShift;
112   isStore = (TSFlags == 1);
113   if (isStore)
114     AddrSpace = getLdStCodeAddrSpace(MI);
115   return isStore;
116 }
117
118 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
119 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
120 /// implemented for a target).  Upon success, this returns false and returns
121 /// with the following information in various cases:
122 ///
123 /// 1. If this block ends with no branches (it just falls through to its succ)
124 ///    just return false, leaving TBB/FBB null.
125 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
126 ///    the destination block.
127 /// 3. If this block ends with an conditional branch and it falls through to
128 ///    an successor block, it sets TBB to be the branch destination block and a
129 ///    list of operands that evaluate the condition. These
130 ///    operands can be passed to other TargetInstrInfo methods to create new
131 ///    branches.
132 /// 4. If this block ends with an conditional branch and an unconditional
133 ///    block, it returns the 'true' destination in TBB, the 'false' destination
134 ///    in FBB, and a list of operands that evaluate the condition. These
135 ///    operands can be passed to other TargetInstrInfo methods to create new
136 ///    branches.
137 ///
138 /// Note that removeBranch and insertBranch must be implemented to support
139 /// cases where this method returns success.
140 ///
141 bool NVPTXInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
142                                    MachineBasicBlock *&TBB,
143                                    MachineBasicBlock *&FBB,
144                                    SmallVectorImpl<MachineOperand> &Cond,
145                                    bool AllowModify) const {
146   // If the block has no terminators, it just falls into the block after it.
147   MachineBasicBlock::iterator I = MBB.end();
148   if (I == MBB.begin() || !isUnpredicatedTerminator(*--I))
149     return false;
150
151   // Get the last instruction in the block.
152   MachineInstr &LastInst = *I;
153
154   // If there is only one terminator instruction, process it.
155   if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
156     if (LastInst.getOpcode() == NVPTX::GOTO) {
157       TBB = LastInst.getOperand(0).getMBB();
158       return false;
159     } else if (LastInst.getOpcode() == NVPTX::CBranch) {
160       // Block ends with fall-through condbranch.
161       TBB = LastInst.getOperand(1).getMBB();
162       Cond.push_back(LastInst.getOperand(0));
163       return false;
164     }
165     // Otherwise, don't know what this is.
166     return true;
167   }
168
169   // Get the instruction before it if it's a terminator.
170   MachineInstr &SecondLastInst = *I;
171
172   // If there are three terminators, we don't know what sort of block this is.
173   if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
174     return true;
175
176   // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
177   if (SecondLastInst.getOpcode() == NVPTX::CBranch &&
178       LastInst.getOpcode() == NVPTX::GOTO) {
179     TBB = SecondLastInst.getOperand(1).getMBB();
180     Cond.push_back(SecondLastInst.getOperand(0));
181     FBB = LastInst.getOperand(0).getMBB();
182     return false;
183   }
184
185   // If the block ends with two NVPTX:GOTOs, handle it.  The second one is not
186   // executed, so remove it.
187   if (SecondLastInst.getOpcode() == NVPTX::GOTO &&
188       LastInst.getOpcode() == NVPTX::GOTO) {
189     TBB = SecondLastInst.getOperand(0).getMBB();
190     I = LastInst;
191     if (AllowModify)
192       I->eraseFromParent();
193     return false;
194   }
195
196   // Otherwise, can't handle this.
197   return true;
198 }
199
200 unsigned NVPTXInstrInfo::removeBranch(MachineBasicBlock &MBB,
201                                       int *BytesRemoved) const {
202   assert(!BytesRemoved && "code size not handled");
203   MachineBasicBlock::iterator I = MBB.end();
204   if (I == MBB.begin())
205     return 0;
206   --I;
207   if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)
208     return 0;
209
210   // Remove the branch.
211   I->eraseFromParent();
212
213   I = MBB.end();
214
215   if (I == MBB.begin())
216     return 1;
217   --I;
218   if (I->getOpcode() != NVPTX::CBranch)
219     return 1;
220
221   // Remove the branch.
222   I->eraseFromParent();
223   return 2;
224 }
225
226 unsigned NVPTXInstrInfo::insertBranch(MachineBasicBlock &MBB,
227                                       MachineBasicBlock *TBB,
228                                       MachineBasicBlock *FBB,
229                                       ArrayRef<MachineOperand> Cond,
230                                       const DebugLoc &DL,
231                                       int *BytesAdded) const {
232   assert(!BytesAdded && "code size not handled");
233
234   // Shouldn't be a fall through.
235   assert(TBB && "insertBranch must not be told to insert a fallthrough");
236   assert((Cond.size() == 1 || Cond.size() == 0) &&
237          "NVPTX branch conditions have two components!");
238
239   // One-way branch.
240   if (!FBB) {
241     if (Cond.empty()) // Unconditional branch
242       BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);
243     else // Conditional branch
244       BuildMI(&MBB, DL, get(NVPTX::CBranch)).addReg(Cond[0].getReg())
245           .addMBB(TBB);
246     return 1;
247   }
248
249   // Two-way Conditional Branch.
250   BuildMI(&MBB, DL, get(NVPTX::CBranch)).addReg(Cond[0].getReg()).addMBB(TBB);
251   BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);
252   return 2;
253 }