149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===- NVPTXInstrInfo.cpp - NVPTX Instruction Information -----------------===// 249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// The LLVM Compiler Infrastructure 449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file is distributed under the University of Illinois Open Source 649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// License. See LICENSE.TXT for details. 749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file contains the NVPTX implementation of the TargetInstrInfo class. 1149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 1349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTX.h" 1549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXInstrInfo.h" 1649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXTargetMachine.h" 1749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#define GET_INSTRINFO_CTOR 1849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXGenInstrInfo.inc" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 2049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/ADT/STLExtras.h" 2149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/MachineFunction.h" 2249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/MachineInstrBuilder.h" 2349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/MachineRegisterInfo.h" 2449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include <cstdio> 2549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiusing namespace llvm; 2849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// FIXME: Add the subtarget support on this constructor. 3049683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiNVPTXInstrInfo::NVPTXInstrInfo(NVPTXTargetMachine &tm) 3149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski: NVPTXGenInstrInfo(), 3249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski TM(tm), 3349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski RegInfo(*this, *TM.getSubtargetImpl()) {} 3449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 3549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 3649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid NVPTXInstrInfo::copyPhysReg (MachineBasicBlock &MBB, 3749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineBasicBlock::iterator I, DebugLoc DL, 3849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned DestReg, unsigned SrcReg, 3949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool KillSrc) const { 4049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (NVPTX::Int32RegsRegClass.contains(DestReg) && 4149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::Int32RegsRegClass.contains(SrcReg)) 4249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(MBB, I, DL, get(NVPTX::IMOV32rr), DestReg) 4349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(SrcReg, getKillRegState(KillSrc)); 4449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (NVPTX::Int8RegsRegClass.contains(DestReg) && 4549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::Int8RegsRegClass.contains(SrcReg)) 4649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(MBB, I, DL, get(NVPTX::IMOV8rr), DestReg) 4749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(SrcReg, getKillRegState(KillSrc)); 4849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (NVPTX::Int1RegsRegClass.contains(DestReg) && 4949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::Int1RegsRegClass.contains(SrcReg)) 5049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(MBB, I, DL, get(NVPTX::IMOV1rr), DestReg) 5149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(SrcReg, getKillRegState(KillSrc)); 5249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (NVPTX::Float32RegsRegClass.contains(DestReg) && 5349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::Float32RegsRegClass.contains(SrcReg)) 5449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(MBB, I, DL, get(NVPTX::FMOV32rr), DestReg) 5549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(SrcReg, getKillRegState(KillSrc)); 5649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (NVPTX::Int16RegsRegClass.contains(DestReg) && 5749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::Int16RegsRegClass.contains(SrcReg)) 5849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(MBB, I, DL, get(NVPTX::IMOV16rr), DestReg) 5949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(SrcReg, getKillRegState(KillSrc)); 6049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (NVPTX::Int64RegsRegClass.contains(DestReg) && 6149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::Int64RegsRegClass.contains(SrcReg)) 6249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(MBB, I, DL, get(NVPTX::IMOV64rr), DestReg) 6349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(SrcReg, getKillRegState(KillSrc)); 6449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (NVPTX::Float64RegsRegClass.contains(DestReg) && 6549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::Float64RegsRegClass.contains(SrcReg)) 6649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(MBB, I, DL, get(NVPTX::FMOV64rr), DestReg) 6749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(SrcReg, getKillRegState(KillSrc)); 6849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else { 696366361998599a63a74ee7cc5f4ba900711c7e7aCraig Topper llvm_unreachable("Don't know how to copy a register"); 7049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 7149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 7249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 7349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXInstrInfo::isMoveInstr(const MachineInstr &MI, 7449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned &SrcReg, 7549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned &DestReg) const { 7649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Look for the appropriate part of TSFlags 7749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool isMove = false; 7849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 7949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::SimpleMoveMask) >> 8049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::SimpleMoveShift; 8149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski isMove = (TSFlags == 1); 8249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (isMove) { 8449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineOperand dest = MI.getOperand(0); 8549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineOperand src = MI.getOperand(1); 8649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(dest.isReg() && "dest of a movrr is not a reg"); 8749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(src.isReg() && "src of a movrr is not a reg"); 8849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SrcReg = src.getReg(); 9049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski DestReg = dest.getReg(); 9149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 9249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 9349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 9549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 9649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXInstrInfo::isReadSpecialReg(MachineInstr &MI) const 9849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski{ 9949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (MI.getOpcode()) { 10049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return false; 10149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_NTID_X: 10249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_NTID_Y: 10349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_NTID_Z: 10449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_TID_X: 10549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_TID_Y: 10649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_TID_Z: 10749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_CTAID_X: 10849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_CTAID_Y: 10949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_CTAID_Z: 11049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_NCTAID_X: 11149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_NCTAID_Y: 11249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_NCTAID_Z: 11349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case NVPTX::INT_PTX_SREG_WARPSIZE: 11449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 11549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 11649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 11749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 11849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 11949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXInstrInfo::isLoadInstr(const MachineInstr &MI, 12049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned &AddrSpace) const { 12149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool isLoad = false; 12249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::isLoadMask) >> 12349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::isLoadShift; 12449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski isLoad = (TSFlags == 1); 12549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (isLoad) 12649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski AddrSpace = getLdStCodeAddrSpace(MI); 12749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return isLoad; 12849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 12949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 13049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXInstrInfo::isStoreInstr(const MachineInstr &MI, 13149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned &AddrSpace) const { 13249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool isStore = false; 13349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned TSFlags = (MI.getDesc().TSFlags & NVPTX::isStoreMask) >> 13449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTX::isStoreShift; 13549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski isStore = (TSFlags == 1); 13649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (isStore) 13749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski AddrSpace = getLdStCodeAddrSpace(MI); 13849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return isStore; 13949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 14049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 14149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 14249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXInstrInfo::CanTailMerge(const MachineInstr *MI) const { 14349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned addrspace = 0; 14449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (MI->getOpcode() == NVPTX::INT_CUDA_SYNCTHREADS) 14549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 14649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (isLoadInstr(*MI, addrspace)) 14749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (addrspace == NVPTX::PTXLdStInstCode::SHARED) 14849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 14949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (isStoreInstr(*MI, addrspace)) 15049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (addrspace == NVPTX::PTXLdStInstCode::SHARED) 15149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 15249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 15349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 15449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 15549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 15649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning 15749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// true if it cannot be understood (e.g. it's a switch dispatch or isn't 15849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// implemented for a target). Upon success, this returns false and returns 15949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// with the following information in various cases: 16049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// 16149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// 1. If this block ends with no branches (it just falls through to its succ) 16249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// just return false, leaving TBB/FBB null. 16349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// 2. If this block ends with only an unconditional branch, it sets TBB to be 16449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// the destination block. 16549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// 3. If this block ends with an conditional branch and it falls through to 16649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// an successor block, it sets TBB to be the branch destination block and a 16749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// list of operands that evaluate the condition. These 16849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// operands can be passed to other TargetInstrInfo methods to create new 16949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// branches. 17049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// 4. If this block ends with an conditional branch and an unconditional 17149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// block, it returns the 'true' destination in TBB, the 'false' destination 17249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// in FBB, and a list of operands that evaluate the condition. These 17349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// operands can be passed to other TargetInstrInfo methods to create new 17449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// branches. 17549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// 17649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// Note that RemoveBranch and InsertBranch must be implemented to support 17749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// cases where this method returns success. 17849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// 17949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 18049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineBasicBlock *&TBB, 18149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineBasicBlock *&FBB, 18249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SmallVectorImpl<MachineOperand> &Cond, 18349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool AllowModify) const { 18449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If the block has no terminators, it just falls into the block after it. 18549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineBasicBlock::iterator I = MBB.end(); 18649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 18749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 18849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 18949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Get the last instruction in the block. 19049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineInstr *LastInst = I; 19149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 19249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If there is only one terminator instruction, process it. 19349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 19449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (LastInst->getOpcode() == NVPTX::GOTO) { 19549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski TBB = LastInst->getOperand(0).getMBB(); 19649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 19749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else if (LastInst->getOpcode() == NVPTX::CBranch) { 19849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Block ends with fall-through condbranch. 19949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski TBB = LastInst->getOperand(1).getMBB(); 20049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Cond.push_back(LastInst->getOperand(0)); 20149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 20249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 20349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Otherwise, don't know what this is. 20449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 20549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 20649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 20749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Get the instruction before it if it's a terminator. 20849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineInstr *SecondLastInst = I; 20949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 21049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If there are three terminators, we don't know what sort of block this is. 21149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SecondLastInst && I != MBB.begin() && 21249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski isUnpredicatedTerminator(--I)) 21349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 21449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 21549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it. 21649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SecondLastInst->getOpcode() == NVPTX::CBranch && 21749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski LastInst->getOpcode() == NVPTX::GOTO) { 21849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski TBB = SecondLastInst->getOperand(1).getMBB(); 21949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Cond.push_back(SecondLastInst->getOperand(0)); 22049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski FBB = LastInst->getOperand(0).getMBB(); 22149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 22249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 22349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 22449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If the block ends with two NVPTX:GOTOs, handle it. The second one is not 22549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // executed, so remove it. 22649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SecondLastInst->getOpcode() == NVPTX::GOTO && 22749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski LastInst->getOpcode() == NVPTX::GOTO) { 22849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski TBB = SecondLastInst->getOperand(0).getMBB(); 22949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski I = LastInst; 23049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (AllowModify) 23149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski I->eraseFromParent(); 23249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 23349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 23449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 23549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Otherwise, can't handle this. 23649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 23749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 23849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 23949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiunsigned NVPTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 24049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineBasicBlock::iterator I = MBB.end(); 24149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (I == MBB.begin()) return 0; 24249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski --I; 24349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch) 24449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return 0; 24549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 24649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Remove the branch. 24749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski I->eraseFromParent(); 24849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 24949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski I = MBB.end(); 25049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 25149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (I == MBB.begin()) return 1; 25249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski --I; 25349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (I->getOpcode() != NVPTX::CBranch) 25449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return 1; 25549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 25649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Remove the branch. 25749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski I->eraseFromParent(); 25849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return 2; 25949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 26049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 26149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiunsigned 26249683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiNVPTXInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 26349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineBasicBlock *FBB, 26449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const SmallVectorImpl<MachineOperand> &Cond, 26549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski DebugLoc DL) const { 26649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Shouldn't be a fall through. 26749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 26849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert((Cond.size() == 1 || Cond.size() == 0) && 26949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski "NVPTX branch conditions have two components!"); 27049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 27149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // One-way branch. 27249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (FBB == 0) { 27349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Cond.empty()) // Unconditional branch 27449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB); 27549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else // Conditional branch 27649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(&MBB, DL, get(NVPTX::CBranch)) 27749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(Cond[0].getReg()).addMBB(TBB); 27849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return 1; 27949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 28049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 28149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Two-way Conditional Branch. 28249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(&MBB, DL, get(NVPTX::CBranch)) 28349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski .addReg(Cond[0].getReg()).addMBB(TBB); 28449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB); 28549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return 2; 28649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 287