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