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> 21using namespace llvm; 22 23//===----------------------------------------------------------------------===// 24// TargetInstrInfo 25//===----------------------------------------------------------------------===// 26 27TargetInstrInfo::~TargetInstrInfo() { 28} 29 30const TargetRegisterClass* 31TargetInstrInfo::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 48unsigned 49TargetInstrInfo::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 64int 65TargetInstrInfo::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 76int 77TargetInstrInfo::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 93int 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 102int 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 113bool 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. 126void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB, 127 MachineBasicBlock::iterator MI) const { 128 llvm_unreachable("Target didn't implement insertNoop!"); 129} 130 131 132bool 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. 153unsigned 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