Home | History | Annotate | Download | only in PTX
      1 //===- PTXInstrInfo.cpp - PTX 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 PTX implementation of the TargetInstrInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #define DEBUG_TYPE "ptx-instrinfo"
     15 
     16 #include "PTX.h"
     17 #include "PTXInstrInfo.h"
     18 #include "llvm/CodeGen/MachineInstrBuilder.h"
     19 #include "llvm/CodeGen/MachineRegisterInfo.h"
     20 #include "llvm/CodeGen/SelectionDAG.h"
     21 #include "llvm/CodeGen/SelectionDAGNodes.h"
     22 #include "llvm/Support/Debug.h"
     23 #include "llvm/Support/TargetRegistry.h"
     24 #include "llvm/Support/raw_ostream.h"
     25 
     26 #define GET_INSTRINFO_CTOR
     27 #include "PTXGenInstrInfo.inc"
     28 
     29 using namespace llvm;
     30 
     31 PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
     32   : PTXGenInstrInfo(),
     33     RI(_TM, *this), TM(_TM) {}
     34 
     35 static const struct map_entry {
     36   const TargetRegisterClass *cls;
     37   const int opcode;
     38 } map[] = {
     39   { &PTX::RegI16RegClass, PTX::MOVU16rr },
     40   { &PTX::RegI32RegClass, PTX::MOVU32rr },
     41   { &PTX::RegI64RegClass, PTX::MOVU64rr },
     42   { &PTX::RegF32RegClass, PTX::MOVF32rr },
     43   { &PTX::RegF64RegClass, PTX::MOVF64rr },
     44   { &PTX::RegPredRegClass,   PTX::MOVPREDrr }
     45 };
     46 
     47 void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     48                                MachineBasicBlock::iterator I, DebugLoc DL,
     49                                unsigned DstReg, unsigned SrcReg,
     50                                bool KillSrc) const {
     51 
     52   const MachineRegisterInfo& MRI = MBB.getParent()->getRegInfo();
     53   //assert(MRI.getRegClass(SrcReg) == MRI.getRegClass(DstReg) &&
     54   //  "Invalid register copy between two register classes");
     55 
     56   for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++i) {
     57     if (map[i].cls == MRI.getRegClass(DstReg)) {
     58       const MCInstrDesc &MCID = get(map[i].opcode);
     59       MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).
     60         addReg(SrcReg, getKillRegState(KillSrc));
     61       AddDefaultPredicate(MI);
     62       return;
     63     }
     64   }
     65 
     66   llvm_unreachable("Impossible reg-to-reg copy");
     67 }
     68 
     69 bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
     70                                 MachineBasicBlock::iterator I,
     71                                 unsigned DstReg, unsigned SrcReg,
     72                                 const TargetRegisterClass *DstRC,
     73                                 const TargetRegisterClass *SrcRC,
     74                                 DebugLoc DL) const {
     75   if (DstRC != SrcRC)
     76     return false;
     77 
     78   for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
     79     if (DstRC == map[i].cls) {
     80       const MCInstrDesc &MCID = get(map[i].opcode);
     81       MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).addReg(SrcReg);
     82       AddDefaultPredicate(MI);
     83       return true;
     84     }
     85 
     86   return false;
     87 }
     88 
     89 bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
     90                                unsigned &SrcReg, unsigned &DstReg,
     91                                unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
     92   switch (MI.getOpcode()) {
     93     default:
     94       return false;
     95     case PTX::MOVU16rr:
     96     case PTX::MOVU32rr:
     97     case PTX::MOVU64rr:
     98     case PTX::MOVF32rr:
     99     case PTX::MOVF64rr:
    100     case PTX::MOVPREDrr:
    101       assert(MI.getNumOperands() >= 2 &&
    102              MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
    103              "Invalid register-register move instruction");
    104       SrcSubIdx = DstSubIdx = 0; // No sub-registers
    105       DstReg = MI.getOperand(0).getReg();
    106       SrcReg = MI.getOperand(1).getReg();
    107       return true;
    108   }
    109 }
    110 
    111 // predicate support
    112 
    113 bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
    114   int i = MI->findFirstPredOperandIdx();
    115   return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister;
    116 }
    117 
    118 bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
    119   return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
    120 }
    121 
    122 bool PTXInstrInfo::
    123 PredicateInstruction(MachineInstr *MI,
    124                      const SmallVectorImpl<MachineOperand> &Pred) const {
    125   if (Pred.size() < 2)
    126     llvm_unreachable("lesser than 2 predicate operands are provided");
    127 
    128   int i = MI->findFirstPredOperandIdx();
    129   if (i == -1)
    130     llvm_unreachable("missing predicate operand");
    131 
    132   MI->getOperand(i).setReg(Pred[0].getReg());
    133   MI->getOperand(i+1).setImm(Pred[1].getImm());
    134 
    135   return true;
    136 }
    137 
    138 bool PTXInstrInfo::
    139 SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
    140                   const SmallVectorImpl<MachineOperand> &Pred2) const {
    141   const MachineOperand &PredReg1 = Pred1[0];
    142   const MachineOperand &PredReg2 = Pred2[0];
    143   if (PredReg1.getReg() != PredReg2.getReg())
    144     return false;
    145 
    146   const MachineOperand &PredOp1 = Pred1[1];
    147   const MachineOperand &PredOp2 = Pred2[1];
    148   if (PredOp1.getImm() != PredOp2.getImm())
    149     return false;
    150 
    151   return true;
    152 }
    153 
    154 bool PTXInstrInfo::
    155 DefinesPredicate(MachineInstr *MI,
    156                  std::vector<MachineOperand> &Pred) const {
    157   // If an instruction sets a predicate register, it defines a predicate.
    158 
    159   // TODO supprot 5-operand format of setp instruction
    160 
    161   if (MI->getNumOperands() < 1)
    162     return false;
    163 
    164   const MachineOperand &MO = MI->getOperand(0);
    165 
    166   if (!MO.isReg() || RI.getRegClass(MO.getReg()) != &PTX::RegPredRegClass)
    167     return false;
    168 
    169   Pred.push_back(MO);
    170   Pred.push_back(MachineOperand::CreateImm(PTXPredicate::None));
    171   return true;
    172 }
    173 
    174 // branch support
    175 
    176 bool PTXInstrInfo::
    177 AnalyzeBranch(MachineBasicBlock &MBB,
    178               MachineBasicBlock *&TBB,
    179               MachineBasicBlock *&FBB,
    180               SmallVectorImpl<MachineOperand> &Cond,
    181               bool AllowModify) const {
    182   // TODO implement cases when AllowModify is true
    183 
    184   if (MBB.empty())
    185     return true;
    186 
    187   MachineBasicBlock::const_iterator iter = MBB.end();
    188   const MachineInstr& instLast1 = *--iter;
    189   const MCInstrDesc &desc1 = instLast1.getDesc();
    190   // for special case that MBB has only 1 instruction
    191   const bool IsSizeOne = MBB.size() == 1;
    192   // if IsSizeOne is true, *--iter and instLast2 are invalid
    193   // we put a dummy value in instLast2 and desc2 since they are used
    194   const MachineInstr& instLast2 = IsSizeOne ? instLast1 : *--iter;
    195   const MCInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc();
    196 
    197   DEBUG(dbgs() << "\n");
    198   DEBUG(dbgs() << "AnalyzeBranch: opcode: " << instLast1.getOpcode() << "\n");
    199   DEBUG(dbgs() << "AnalyzeBranch: MBB:    " << MBB.getName().str() << "\n");
    200   DEBUG(dbgs() << "AnalyzeBranch: TBB:    " << TBB << "\n");
    201   DEBUG(dbgs() << "AnalyzeBranch: FBB:    " << FBB << "\n");
    202 
    203   // this block ends with no branches
    204   if (!IsAnyKindOfBranch(instLast1)) {
    205     DEBUG(dbgs() << "AnalyzeBranch: ends with no branch\n");
    206     return false;
    207   }
    208 
    209   // this block ends with only an unconditional branch
    210   if (desc1.isUnconditionalBranch() &&
    211       // when IsSizeOne is true, it "absorbs" the evaluation of instLast2
    212       (IsSizeOne || !IsAnyKindOfBranch(instLast2))) {
    213     DEBUG(dbgs() << "AnalyzeBranch: ends with only uncond branch\n");
    214     TBB = GetBranchTarget(instLast1);
    215     return false;
    216   }
    217 
    218   // this block ends with a conditional branch and
    219   // it falls through to a successor block
    220   if (desc1.isConditionalBranch() &&
    221       IsAnySuccessorAlsoLayoutSuccessor(MBB)) {
    222     DEBUG(dbgs() << "AnalyzeBranch: ends with cond branch and fall through\n");
    223     TBB = GetBranchTarget(instLast1);
    224     int i = instLast1.findFirstPredOperandIdx();
    225     Cond.push_back(instLast1.getOperand(i));
    226     Cond.push_back(instLast1.getOperand(i+1));
    227     return false;
    228   }
    229 
    230   // when IsSizeOne is true, we are done
    231   if (IsSizeOne)
    232     return true;
    233 
    234   // this block ends with a conditional branch
    235   // followed by an unconditional branch
    236   if (desc2.isConditionalBranch() &&
    237       desc1.isUnconditionalBranch()) {
    238     DEBUG(dbgs() << "AnalyzeBranch: ends with cond and uncond branch\n");
    239     TBB = GetBranchTarget(instLast2);
    240     FBB = GetBranchTarget(instLast1);
    241     int i = instLast2.findFirstPredOperandIdx();
    242     Cond.push_back(instLast2.getOperand(i));
    243     Cond.push_back(instLast2.getOperand(i+1));
    244     return false;
    245   }
    246 
    247   // branch cannot be understood
    248   DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n");
    249   return true;
    250 }
    251 
    252 unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
    253   unsigned count = 0;
    254   while (!MBB.empty())
    255     if (IsAnyKindOfBranch(MBB.back())) {
    256       MBB.pop_back();
    257       ++count;
    258     } else
    259       break;
    260   DEBUG(dbgs() << "RemoveBranch: MBB:   " << MBB.getName().str() << "\n");
    261   DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
    262   return count;
    263 }
    264 
    265 unsigned PTXInstrInfo::
    266 InsertBranch(MachineBasicBlock &MBB,
    267              MachineBasicBlock *TBB,
    268              MachineBasicBlock *FBB,
    269              const SmallVectorImpl<MachineOperand> &Cond,
    270              DebugLoc DL) const {
    271   DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
    272   DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
    273                         << "\n";
    274         else     dbgs() << "InsertBranch: TBB: (NULL)\n");
    275   DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
    276                         << "\n";
    277         else     dbgs() << "InsertBranch: FBB: (NULL)\n");
    278   DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
    279 
    280   assert(TBB && "TBB is NULL");
    281 
    282   if (FBB) {
    283     BuildMI(&MBB, DL, get(PTX::BRAdp))
    284       .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
    285     BuildMI(&MBB, DL, get(PTX::BRAd))
    286       .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTXPredicate::None);
    287     return 2;
    288   } else if (Cond.size()) {
    289     BuildMI(&MBB, DL, get(PTX::BRAdp))
    290       .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
    291     return 1;
    292   } else {
    293     BuildMI(&MBB, DL, get(PTX::BRAd))
    294       .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTXPredicate::None);
    295     return 1;
    296   }
    297 }
    298 
    299 // Memory operand folding for spills
    300 void PTXInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
    301                                        MachineBasicBlock::iterator MII,
    302                                      unsigned SrcReg, bool isKill, int FrameIdx,
    303                                        const TargetRegisterClass *RC,
    304                                        const TargetRegisterInfo *TRI) const {
    305   assert(false && "storeRegToStackSlot should not be called for PTX");
    306 }
    307 
    308 void PTXInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
    309                                         MachineBasicBlock::iterator MII,
    310                                         unsigned DestReg, int FrameIdx,
    311                                         const TargetRegisterClass *RC,
    312                                         const TargetRegisterInfo *TRI) const {
    313   assert(false && "loadRegFromStackSlot should not be called for PTX");
    314 }
    315 
    316 // static helper routines
    317 
    318 MachineSDNode *PTXInstrInfo::
    319 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
    320                   DebugLoc dl, EVT VT, SDValue Op1) {
    321   SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
    322   SDValue predOp = DAG->getTargetConstant(PTXPredicate::None, MVT::i32);
    323   SDValue ops[] = { Op1, predReg, predOp };
    324   return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
    325 }
    326 
    327 MachineSDNode *PTXInstrInfo::
    328 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
    329                   DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
    330   SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
    331   SDValue predOp = DAG->getTargetConstant(PTXPredicate::None, MVT::i32);
    332   SDValue ops[] = { Op1, Op2, predReg, predOp };
    333   return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
    334 }
    335 
    336 void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
    337   if (MI->findFirstPredOperandIdx() == -1) {
    338     MI->addOperand(MachineOperand::CreateReg(PTX::NoRegister, /*IsDef=*/false));
    339     MI->addOperand(MachineOperand::CreateImm(PTXPredicate::None));
    340   }
    341 }
    342 
    343 bool PTXInstrInfo::IsAnyKindOfBranch(const MachineInstr& inst) {
    344   const MCInstrDesc &desc = inst.getDesc();
    345   return desc.isTerminator() || desc.isBranch() || desc.isIndirectBranch();
    346 }
    347 
    348 bool PTXInstrInfo::
    349 IsAnySuccessorAlsoLayoutSuccessor(const MachineBasicBlock& MBB) {
    350   for (MachineBasicBlock::const_succ_iterator
    351       i = MBB.succ_begin(), e = MBB.succ_end(); i != e; ++i)
    352     if (MBB.isLayoutSuccessor((const MachineBasicBlock*) &*i))
    353       return true;
    354   return false;
    355 }
    356 
    357 MachineBasicBlock *PTXInstrInfo::GetBranchTarget(const MachineInstr& inst) {
    358   // FIXME So far all branch instructions put destination in 1st operand
    359   const MachineOperand& target = inst.getOperand(0);
    360   assert(target.isMBB() && "FIXME: detect branch target operand");
    361   return target.getMBB();
    362 }
    363