LLVM API Documentation
00001 //===- NVPTXInstrInfo.cpp - NVPTX Instruction Information -----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the NVPTX implementation of the TargetInstrInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "NVPTX.h" 00015 #include "NVPTXInstrInfo.h" 00016 #include "NVPTXTargetMachine.h" 00017 #include "llvm/IR/Function.h" 00018 #include "llvm/ADT/STLExtras.h" 00019 #include "llvm/CodeGen/MachineFunction.h" 00020 #include "llvm/CodeGen/MachineInstrBuilder.h" 00021 #include "llvm/CodeGen/MachineRegisterInfo.h" 00022 00023 using namespace llvm; 00024 00025 #define GET_INSTRINFO_CTOR_DTOR 00026 #include "NVPTXGenInstrInfo.inc" 00027 00028 // Pin the vtable to this file. 00029 void NVPTXInstrInfo::anchor() {} 00030 00031 // FIXME: Add the subtarget support on this constructor. 00032 NVPTXInstrInfo::NVPTXInstrInfo(NVPTXSubtarget &STI) 00033 : NVPTXGenInstrInfo(), RegInfo(STI) {} 00034 00035 void NVPTXInstrInfo::copyPhysReg( 00036 MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, 00037 unsigned DestReg, unsigned SrcReg, bool KillSrc) const { 00038 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 00039 const TargetRegisterClass *DestRC = MRI.getRegClass(DestReg); 00040 const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg); 00041 00042 if (DestRC != SrcRC) 00043 report_fatal_error("Attempted to created cross-class register copy"); 00044 00045 if (DestRC == &NVPTX::Int32RegsRegClass) 00046 BuildMI(MBB, I, DL, get(NVPTX::IMOV32rr), DestReg) 00047 .addReg(SrcReg, getKillRegState(KillSrc)); 00048 else if (DestRC == &NVPTX::Int1RegsRegClass) 00049 BuildMI(MBB, I, DL, get(NVPTX::IMOV1rr), DestReg) 00050 .addReg(SrcReg, getKillRegState(KillSrc)); 00051 else if (DestRC == &NVPTX::Float32RegsRegClass) 00052 BuildMI(MBB, I, DL, get(NVPTX::FMOV32rr), DestReg) 00053 .addReg(SrcReg, getKillRegState(KillSrc)); 00054 else if (DestRC == &NVPTX::Int16RegsRegClass) 00055 BuildMI(MBB, I, DL, get(NVPTX::IMOV16rr), DestReg) 00056 .addReg(SrcReg, getKillRegState(KillSrc)); 00057 else if (DestRC == &NVPTX::Int64RegsRegClass) 00058 BuildMI(MBB, I, DL, get(NVPTX::IMOV64rr), DestReg) 00059 .addReg(SrcReg, getKillRegState(KillSrc)); 00060 else if (DestRC == &NVPTX::Float64RegsRegClass) 00061 BuildMI(MBB, I, DL, get(NVPTX::FMOV64rr), DestReg) 00062 .addReg(SrcReg, getKillRegState(KillSrc)); 00063 else { 00064 llvm_unreachable("Bad register copy"); 00065 } 00066 } 00067 00068 bool NVPTXInstrInfo::isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, 00069 unsigned &DestReg) const { 00070 // Look for the appropriate part of TSFlags 00071 bool isMove = false; 00072 00073 unsigned TSFlags = 00074 (MI.getDesc().TSFlags & NVPTX::SimpleMoveMask) >> NVPTX::SimpleMoveShift; 00075 isMove = (TSFlags == 1); 00076 00077 if (isMove) { 00078 MachineOperand dest = MI.getOperand(0); 00079 MachineOperand src = MI.getOperand(1); 00080 assert(dest.isReg() && "dest of a movrr is not a reg"); 00081 assert(src.isReg() && "src of a movrr is not a reg"); 00082 00083 SrcReg = src.getReg(); 00084 DestReg = dest.getReg(); 00085 return true; 00086 } 00087 00088 return false; 00089 } 00090 00091 bool NVPTXInstrInfo::isReadSpecialReg(MachineInstr &MI) const { 00092 switch (MI.getOpcode()) { 00093 default: 00094 return false; 00095 case NVPTX::INT_PTX_SREG_NTID_X: 00096 case NVPTX::INT_PTX_SREG_NTID_Y: 00097 case NVPTX::INT_PTX_SREG_NTID_Z: 00098 case NVPTX::INT_PTX_SREG_TID_X: 00099 case NVPTX::INT_PTX_SREG_TID_Y: 00100 case NVPTX::INT_PTX_SREG_TID_Z: 00101 case NVPTX::INT_PTX_SREG_CTAID_X: 00102 case NVPTX::INT_PTX_SREG_CTAID_Y: 00103 case NVPTX::INT_PTX_SREG_CTAID_Z: 00104 case NVPTX::INT_PTX_SREG_NCTAID_X: 00105 case NVPTX::INT_PTX_SREG_NCTAID_Y: 00106 case NVPTX::INT_PTX_SREG_NCTAID_Z: 00107 case NVPTX::INT_PTX_SREG_WARPSIZE: 00108 return true; 00109 } 00110 } 00111 00112 bool NVPTXInstrInfo::isLoadInstr(const MachineInstr &MI, 00113 unsigned &AddrSpace) const { 00114 bool isLoad = false; 00115 unsigned TSFlags = 00116 (MI.getDesc().TSFlags & NVPTX::isLoadMask) >> NVPTX::isLoadShift; 00117 isLoad = (TSFlags == 1); 00118 if (isLoad) 00119 AddrSpace = getLdStCodeAddrSpace(MI); 00120 return isLoad; 00121 } 00122 00123 bool NVPTXInstrInfo::isStoreInstr(const MachineInstr &MI, 00124 unsigned &AddrSpace) const { 00125 bool isStore = false; 00126 unsigned TSFlags = 00127 (MI.getDesc().TSFlags & NVPTX::isStoreMask) >> NVPTX::isStoreShift; 00128 isStore = (TSFlags == 1); 00129 if (isStore) 00130 AddrSpace = getLdStCodeAddrSpace(MI); 00131 return isStore; 00132 } 00133 00134 bool NVPTXInstrInfo::CanTailMerge(const MachineInstr *MI) const { 00135 unsigned addrspace = 0; 00136 if (MI->getOpcode() == NVPTX::INT_CUDA_SYNCTHREADS) 00137 return false; 00138 if (isLoadInstr(*MI, addrspace)) 00139 if (addrspace == NVPTX::PTXLdStInstCode::SHARED) 00140 return false; 00141 if (isStoreInstr(*MI, addrspace)) 00142 if (addrspace == NVPTX::PTXLdStInstCode::SHARED) 00143 return false; 00144 return true; 00145 } 00146 00147 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning 00148 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't 00149 /// implemented for a target). Upon success, this returns false and returns 00150 /// with the following information in various cases: 00151 /// 00152 /// 1. If this block ends with no branches (it just falls through to its succ) 00153 /// just return false, leaving TBB/FBB null. 00154 /// 2. If this block ends with only an unconditional branch, it sets TBB to be 00155 /// the destination block. 00156 /// 3. If this block ends with an conditional branch and it falls through to 00157 /// an successor block, it sets TBB to be the branch destination block and a 00158 /// list of operands that evaluate the condition. These 00159 /// operands can be passed to other TargetInstrInfo methods to create new 00160 /// branches. 00161 /// 4. If this block ends with an conditional branch and an unconditional 00162 /// block, it returns the 'true' destination in TBB, the 'false' destination 00163 /// in FBB, and a list of operands that evaluate the condition. These 00164 /// operands can be passed to other TargetInstrInfo methods to create new 00165 /// branches. 00166 /// 00167 /// Note that RemoveBranch and InsertBranch must be implemented to support 00168 /// cases where this method returns success. 00169 /// 00170 bool NVPTXInstrInfo::AnalyzeBranch( 00171 MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, 00172 SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const { 00173 // If the block has no terminators, it just falls into the block after it. 00174 MachineBasicBlock::iterator I = MBB.end(); 00175 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 00176 return false; 00177 00178 // Get the last instruction in the block. 00179 MachineInstr *LastInst = I; 00180 00181 // If there is only one terminator instruction, process it. 00182 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 00183 if (LastInst->getOpcode() == NVPTX::GOTO) { 00184 TBB = LastInst->getOperand(0).getMBB(); 00185 return false; 00186 } else if (LastInst->getOpcode() == NVPTX::CBranch) { 00187 // Block ends with fall-through condbranch. 00188 TBB = LastInst->getOperand(1).getMBB(); 00189 Cond.push_back(LastInst->getOperand(0)); 00190 return false; 00191 } 00192 // Otherwise, don't know what this is. 00193 return true; 00194 } 00195 00196 // Get the instruction before it if it's a terminator. 00197 MachineInstr *SecondLastInst = I; 00198 00199 // If there are three terminators, we don't know what sort of block this is. 00200 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 00201 return true; 00202 00203 // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it. 00204 if (SecondLastInst->getOpcode() == NVPTX::CBranch && 00205 LastInst->getOpcode() == NVPTX::GOTO) { 00206 TBB = SecondLastInst->getOperand(1).getMBB(); 00207 Cond.push_back(SecondLastInst->getOperand(0)); 00208 FBB = LastInst->getOperand(0).getMBB(); 00209 return false; 00210 } 00211 00212 // If the block ends with two NVPTX:GOTOs, handle it. The second one is not 00213 // executed, so remove it. 00214 if (SecondLastInst->getOpcode() == NVPTX::GOTO && 00215 LastInst->getOpcode() == NVPTX::GOTO) { 00216 TBB = SecondLastInst->getOperand(0).getMBB(); 00217 I = LastInst; 00218 if (AllowModify) 00219 I->eraseFromParent(); 00220 return false; 00221 } 00222 00223 // Otherwise, can't handle this. 00224 return true; 00225 } 00226 00227 unsigned NVPTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 00228 MachineBasicBlock::iterator I = MBB.end(); 00229 if (I == MBB.begin()) 00230 return 0; 00231 --I; 00232 if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch) 00233 return 0; 00234 00235 // Remove the branch. 00236 I->eraseFromParent(); 00237 00238 I = MBB.end(); 00239 00240 if (I == MBB.begin()) 00241 return 1; 00242 --I; 00243 if (I->getOpcode() != NVPTX::CBranch) 00244 return 1; 00245 00246 // Remove the branch. 00247 I->eraseFromParent(); 00248 return 2; 00249 } 00250 00251 unsigned NVPTXInstrInfo::InsertBranch( 00252 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, 00253 const SmallVectorImpl<MachineOperand> &Cond, DebugLoc DL) const { 00254 // Shouldn't be a fall through. 00255 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 00256 assert((Cond.size() == 1 || Cond.size() == 0) && 00257 "NVPTX branch conditions have two components!"); 00258 00259 // One-way branch. 00260 if (!FBB) { 00261 if (Cond.empty()) // Unconditional branch 00262 BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB); 00263 else // Conditional branch 00264 BuildMI(&MBB, DL, get(NVPTX::CBranch)).addReg(Cond[0].getReg()) 00265 .addMBB(TBB); 00266 return 1; 00267 } 00268 00269 // Two-way Conditional Branch. 00270 BuildMI(&MBB, DL, get(NVPTX::CBranch)).addReg(Cond[0].getReg()).addMBB(TBB); 00271 BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB); 00272 return 2; 00273 }