Home | History | Annotate | Download | only in Target
      1 //===-- TargetInstrInfo.cpp - Target 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 implements the TargetInstrInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/Target/TargetInstrInfo.h"
     15 #include "llvm/Target/TargetRegisterInfo.h"
     16 #include "llvm/CodeGen/SelectionDAGNodes.h"
     17 #include "llvm/MC/MCAsmInfo.h"
     18 #include "llvm/MC/MCInstrItineraries.h"
     19 #include "llvm/Support/ErrorHandling.h"
     20 #include <cctype>
     21 using namespace llvm;
     22 
     23 //===----------------------------------------------------------------------===//
     24 //  TargetInstrInfo
     25 //===----------------------------------------------------------------------===//
     26 
     27 TargetInstrInfo::~TargetInstrInfo() {
     28 }
     29 
     30 const TargetRegisterClass*
     31 TargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum,
     32                              const TargetRegisterInfo *TRI) const {
     33   if (OpNum >= MCID.getNumOperands())
     34     return 0;
     35 
     36   short RegClass = MCID.OpInfo[OpNum].RegClass;
     37   if (MCID.OpInfo[OpNum].isLookupPtrRegClass())
     38     return TRI->getPointerRegClass(RegClass);
     39 
     40   // Instructions like INSERT_SUBREG do not have fixed register classes.
     41   if (RegClass < 0)
     42     return 0;
     43 
     44   // Otherwise just look it up normally.
     45   return TRI->getRegClass(RegClass);
     46 }
     47 
     48 unsigned
     49 TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
     50                                 const MachineInstr *MI) const {
     51   if (!ItinData || ItinData->isEmpty())
     52     return 1;
     53 
     54   unsigned Class = MI->getDesc().getSchedClass();
     55   unsigned UOps = ItinData->Itineraries[Class].NumMicroOps;
     56   if (UOps)
     57     return UOps;
     58 
     59   // The # of u-ops is dynamically determined. The specific target should
     60   // override this function to return the right number.
     61   return 1;
     62 }
     63 
     64 int
     65 TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
     66                              const MachineInstr *DefMI, unsigned DefIdx,
     67                              const MachineInstr *UseMI, unsigned UseIdx) const {
     68   if (!ItinData || ItinData->isEmpty())
     69     return -1;
     70 
     71   unsigned DefClass = DefMI->getDesc().getSchedClass();
     72   unsigned UseClass = UseMI->getDesc().getSchedClass();
     73   return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
     74 }
     75 
     76 int
     77 TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
     78                                    SDNode *DefNode, unsigned DefIdx,
     79                                    SDNode *UseNode, unsigned UseIdx) const {
     80   if (!ItinData || ItinData->isEmpty())
     81     return -1;
     82 
     83   if (!DefNode->isMachineOpcode())
     84     return -1;
     85 
     86   unsigned DefClass = get(DefNode->getMachineOpcode()).getSchedClass();
     87   if (!UseNode->isMachineOpcode())
     88     return ItinData->getOperandCycle(DefClass, DefIdx);
     89   unsigned UseClass = get(UseNode->getMachineOpcode()).getSchedClass();
     90   return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
     91 }
     92 
     93 int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
     94                                      const MachineInstr *MI,
     95                                      unsigned *PredCost) const {
     96   if (!ItinData || ItinData->isEmpty())
     97     return 1;
     98 
     99   return ItinData->getStageLatency(MI->getDesc().getSchedClass());
    100 }
    101 
    102 int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
    103                                      SDNode *N) const {
    104   if (!ItinData || ItinData->isEmpty())
    105     return 1;
    106 
    107   if (!N->isMachineOpcode())
    108     return 1;
    109 
    110   return ItinData->getStageLatency(get(N->getMachineOpcode()).getSchedClass());
    111 }
    112 
    113 bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
    114                                        const MachineInstr *DefMI,
    115                                        unsigned DefIdx) const {
    116   if (!ItinData || ItinData->isEmpty())
    117     return false;
    118 
    119   unsigned DefClass = DefMI->getDesc().getSchedClass();
    120   int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
    121   return (DefCycle != -1 && DefCycle <= 1);
    122 }
    123 
    124 /// insertNoop - Insert a noop into the instruction stream at the specified
    125 /// point.
    126 void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
    127                                  MachineBasicBlock::iterator MI) const {
    128   llvm_unreachable("Target didn't implement insertNoop!");
    129 }
    130 
    131 
    132 bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
    133   const MCInstrDesc &MCID = MI->getDesc();
    134   if (!MCID.isTerminator()) return false;
    135 
    136   // Conditional branch is a special case.
    137   if (MCID.isBranch() && !MCID.isBarrier())
    138     return true;
    139   if (!MCID.isPredicable())
    140     return true;
    141   return !isPredicated(MI);
    142 }
    143 
    144 
    145 /// Measure the specified inline asm to determine an approximation of its
    146 /// length.
    147 /// Comments (which run till the next SeparatorString or newline) do not
    148 /// count as an instruction.
    149 /// Any other non-whitespace text is considered an instruction, with
    150 /// multiple instructions separated by SeparatorString or newlines.
    151 /// Variable-length instructions are not handled here; this function
    152 /// may be overloaded in the target code to do that.
    153 unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
    154                                              const MCAsmInfo &MAI) const {
    155 
    156 
    157   // Count the number of instructions in the asm.
    158   bool atInsnStart = true;
    159   unsigned Length = 0;
    160   for (; *Str; ++Str) {
    161     if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
    162                                 strlen(MAI.getSeparatorString())) == 0)
    163       atInsnStart = true;
    164     if (atInsnStart && !std::isspace(*Str)) {
    165       Length += MAI.getMaxInstLength();
    166       atInsnStart = false;
    167     }
    168     if (atInsnStart && strncmp(Str, MAI.getCommentString(),
    169                                strlen(MAI.getCommentString())) == 0)
    170       atInsnStart = false;
    171   }
    172 
    173   return Length;
    174 }
    175