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