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 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 { 69 llvm_unreachable("Don't know how to copy a register"); 70 } 71 } 72 73 bool 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 97 bool 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 119 bool 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 130 bool 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 142 bool 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 /// 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)) 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 239 unsigned 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 261 unsigned 262 NVPTXInstrInfo::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