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