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