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/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" 24#include <cstdio> 25 26 27using namespace llvm; 28 29// FIXME: Add the subtarget support on this constructor. 30NVPTXInstrInfo::NVPTXInstrInfo(NVPTXTargetMachine &tm) 31: NVPTXGenInstrInfo(), 32 TM(tm), 33 RegInfo(*this, *TM.getSubtargetImpl()) {} 34 35 36void 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 { 69 llvm_unreachable("Don't know how to copy a register"); 70 } 71} 72 73bool NVPTXInstrInfo::isMoveInstr(const MachineInstr &MI, 74 unsigned &SrcReg, 75 unsigned &DestReg) const { 76 // Look for the appropriate part of TSFlags 77 bool isMove = false; 78 79 unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::SimpleMoveMask) >> 80 NVPTX::SimpleMoveShift; 81 isMove = (TSFlags == 1); 82 83 if (isMove) { 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"); 88 89 SrcReg = src.getReg(); 90 DestReg = dest.getReg(); 91 return true; 92 } 93 94 return false; 95} 96 97bool NVPTXInstrInfo::isReadSpecialReg(MachineInstr &MI) const 98{ 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: 114 return true; 115 } 116} 117 118 119bool NVPTXInstrInfo::isLoadInstr(const MachineInstr &MI, 120 unsigned &AddrSpace) const { 121 bool isLoad = false; 122 unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::isLoadMask) >> 123 NVPTX::isLoadShift; 124 isLoad = (TSFlags == 1); 125 if (isLoad) 126 AddrSpace = getLdStCodeAddrSpace(MI); 127 return isLoad; 128} 129 130bool NVPTXInstrInfo::isStoreInstr(const MachineInstr &MI, 131 unsigned &AddrSpace) const { 132 bool isStore = false; 133 unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::isStoreMask) >> 134 NVPTX::isStoreShift; 135 isStore = (TSFlags == 1); 136 if (isStore) 137 AddrSpace = getLdStCodeAddrSpace(MI); 138 return isStore; 139} 140 141 142bool NVPTXInstrInfo::CanTailMerge(const MachineInstr *MI) const { 143 unsigned addrspace = 0; 144 if (MI->getOpcode() == NVPTX::INT_CUDA_SYNCTHREADS) 145 return false; 146 if (isLoadInstr(*MI, addrspace)) 147 if (addrspace == NVPTX::PTXLdStInstCode::SHARED) 148 return false; 149 if (isStoreInstr(*MI, addrspace)) 150 if (addrspace == NVPTX::PTXLdStInstCode::SHARED) 151 return false; 152 return true; 153} 154 155 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: 160/// 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 169/// branches. 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 174/// branches. 175/// 176/// Note that RemoveBranch and InsertBranch must be implemented to support 177/// cases where this method returns success. 178/// 179bool 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)) 187 return false; 188 189 // Get the last instruction in the block. 190 MachineInstr *LastInst = I; 191 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(); 196 return false; 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)); 201 return false; 202 } 203 // Otherwise, don't know what this is. 204 return true; 205 } 206 207 // Get the instruction before it if it's a terminator. 208 MachineInstr *SecondLastInst = I; 209 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)) 213 return true; 214 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(); 221 return false; 222 } 223 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(); 229 I = LastInst; 230 if (AllowModify) 231 I->eraseFromParent(); 232 return false; 233 } 234 235 // Otherwise, can't handle this. 236 return true; 237} 238 239unsigned NVPTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 240 MachineBasicBlock::iterator I = MBB.end(); 241 if (I == MBB.begin()) return 0; 242 --I; 243 if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch) 244 return 0; 245 246 // Remove the branch. 247 I->eraseFromParent(); 248 249 I = MBB.end(); 250 251 if (I == MBB.begin()) return 1; 252 --I; 253 if (I->getOpcode() != NVPTX::CBranch) 254 return 1; 255 256 // Remove the branch. 257 I->eraseFromParent(); 258 return 2; 259} 260 261unsigned 262NVPTXInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 263 MachineBasicBlock *FBB, 264 const SmallVectorImpl<MachineOperand> &Cond, 265 DebugLoc DL) const { 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!"); 270 271 // One-way branch. 272 if (FBB == 0) { 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); 278 return 1; 279 } 280 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); 285 return 2; 286} 287