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