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