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