1 //===- NVPTXInstrInfo.cpp - NVPTX Instruction Information -----------------===//
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 // This file contains the NVPTX implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 #include "NVPTXInstrInfo.h"
16 #include "NVPTXTargetMachine.h"
17 #define GET_INSTRINFO_CTOR
18 #include "NVPTXGenInstrInfo.inc"
19 #include "llvm/IR/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"
29 // FIXME: Add the subtarget support on this constructor.
30 NVPTXInstrInfo::NVPTXInstrInfo(NVPTXTargetMachine &tm)
31 : NVPTXGenInstrInfo(),
33 RegInfo(*this, *TM.getSubtargetImpl()) {}
36 void NVPTXInstrInfo::copyPhysReg (MachineBasicBlock &MBB,
37 MachineBasicBlock::iterator I, DebugLoc DL,
38 unsigned DestReg, unsigned SrcReg,
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));
69 llvm_unreachable("Don't know how to copy a register");
73 bool NVPTXInstrInfo::isMoveInstr(const MachineInstr &MI,
75 unsigned &DestReg) const {
76 // Look for the appropriate part of TSFlags
79 unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::SimpleMoveMask) >>
80 NVPTX::SimpleMoveShift;
81 isMove = (TSFlags == 1);
84 MachineOperand dest = MI.getOperand(0);
85 MachineOperand src = MI.getOperand(1);
86 assert(dest.isReg() && "dest of a movrr is not a reg");
87 assert(src.isReg() && "src of a movrr is not a reg");
89 SrcReg = src.getReg();
90 DestReg = dest.getReg();
97 bool NVPTXInstrInfo::isReadSpecialReg(MachineInstr &MI) const
99 switch (MI.getOpcode()) {
100 default: return false;
101 case NVPTX::INT_PTX_SREG_NTID_X:
102 case NVPTX::INT_PTX_SREG_NTID_Y:
103 case NVPTX::INT_PTX_SREG_NTID_Z:
104 case NVPTX::INT_PTX_SREG_TID_X:
105 case NVPTX::INT_PTX_SREG_TID_Y:
106 case NVPTX::INT_PTX_SREG_TID_Z:
107 case NVPTX::INT_PTX_SREG_CTAID_X:
108 case NVPTX::INT_PTX_SREG_CTAID_Y:
109 case NVPTX::INT_PTX_SREG_CTAID_Z:
110 case NVPTX::INT_PTX_SREG_NCTAID_X:
111 case NVPTX::INT_PTX_SREG_NCTAID_Y:
112 case NVPTX::INT_PTX_SREG_NCTAID_Z:
113 case NVPTX::INT_PTX_SREG_WARPSIZE:
119 bool NVPTXInstrInfo::isLoadInstr(const MachineInstr &MI,
120 unsigned &AddrSpace) const {
122 unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::isLoadMask) >>
124 isLoad = (TSFlags == 1);
126 AddrSpace = getLdStCodeAddrSpace(MI);
130 bool NVPTXInstrInfo::isStoreInstr(const MachineInstr &MI,
131 unsigned &AddrSpace) const {
132 bool isStore = false;
133 unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::isStoreMask) >>
135 isStore = (TSFlags == 1);
137 AddrSpace = getLdStCodeAddrSpace(MI);
142 bool NVPTXInstrInfo::CanTailMerge(const MachineInstr *MI) const {
143 unsigned addrspace = 0;
144 if (MI->getOpcode() == NVPTX::INT_CUDA_SYNCTHREADS)
146 if (isLoadInstr(*MI, addrspace))
147 if (addrspace == NVPTX::PTXLdStInstCode::SHARED)
149 if (isStoreInstr(*MI, addrspace))
150 if (addrspace == NVPTX::PTXLdStInstCode::SHARED)
156 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
157 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
158 /// implemented for a target). Upon success, this returns false and returns
159 /// with the following information in various cases:
161 /// 1. If this block ends with no branches (it just falls through to its succ)
162 /// just return false, leaving TBB/FBB null.
163 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
164 /// the destination block.
165 /// 3. If this block ends with an conditional branch and it falls through to
166 /// an successor block, it sets TBB to be the branch destination block and a
167 /// list of operands that evaluate the condition. These
168 /// operands can be passed to other TargetInstrInfo methods to create new
170 /// 4. If this block ends with an conditional branch and an unconditional
171 /// block, it returns the 'true' destination in TBB, the 'false' destination
172 /// in FBB, and a list of operands that evaluate the condition. These
173 /// operands can be passed to other TargetInstrInfo methods to create new
176 /// Note that RemoveBranch and InsertBranch must be implemented to support
177 /// cases where this method returns success.
179 bool NVPTXInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
180 MachineBasicBlock *&TBB,
181 MachineBasicBlock *&FBB,
182 SmallVectorImpl<MachineOperand> &Cond,
183 bool AllowModify) const {
184 // If the block has no terminators, it just falls into the block after it.
185 MachineBasicBlock::iterator I = MBB.end();
186 if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
189 // Get the last instruction in the block.
190 MachineInstr *LastInst = I;
192 // If there is only one terminator instruction, process it.
193 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
194 if (LastInst->getOpcode() == NVPTX::GOTO) {
195 TBB = LastInst->getOperand(0).getMBB();
197 } else if (LastInst->getOpcode() == NVPTX::CBranch) {
198 // Block ends with fall-through condbranch.
199 TBB = LastInst->getOperand(1).getMBB();
200 Cond.push_back(LastInst->getOperand(0));
203 // Otherwise, don't know what this is.
207 // Get the instruction before it if it's a terminator.
208 MachineInstr *SecondLastInst = I;
210 // If there are three terminators, we don't know what sort of block this is.
211 if (SecondLastInst && I != MBB.begin() &&
212 isUnpredicatedTerminator(--I))
215 // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
216 if (SecondLastInst->getOpcode() == NVPTX::CBranch &&
217 LastInst->getOpcode() == NVPTX::GOTO) {
218 TBB = SecondLastInst->getOperand(1).getMBB();
219 Cond.push_back(SecondLastInst->getOperand(0));
220 FBB = LastInst->getOperand(0).getMBB();
224 // If the block ends with two NVPTX:GOTOs, handle it. The second one is not
225 // executed, so remove it.
226 if (SecondLastInst->getOpcode() == NVPTX::GOTO &&
227 LastInst->getOpcode() == NVPTX::GOTO) {
228 TBB = SecondLastInst->getOperand(0).getMBB();
231 I->eraseFromParent();
235 // Otherwise, can't handle this.
239 unsigned NVPTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
240 MachineBasicBlock::iterator I = MBB.end();
241 if (I == MBB.begin()) return 0;
243 if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)
246 // Remove the branch.
247 I->eraseFromParent();
251 if (I == MBB.begin()) return 1;
253 if (I->getOpcode() != NVPTX::CBranch)
256 // Remove the branch.
257 I->eraseFromParent();
262 NVPTXInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
263 MachineBasicBlock *FBB,
264 const SmallVectorImpl<MachineOperand> &Cond,
266 // Shouldn't be a fall through.
267 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
268 assert((Cond.size() == 1 || Cond.size() == 0) &&
269 "NVPTX branch conditions have two components!");
273 if (Cond.empty()) // Unconditional branch
274 BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);
275 else // Conditional branch
276 BuildMI(&MBB, DL, get(NVPTX::CBranch))
277 .addReg(Cond[0].getReg()).addMBB(TBB);
281 // Two-way Conditional Branch.
282 BuildMI(&MBB, DL, get(NVPTX::CBranch))
283 .addReg(Cond[0].getReg()).addMBB(TBB);
284 BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);