1 //===-- TargetInstrInfo.cpp - Target Instruction Information --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Target/TargetInstrInfo.h"
15 #include "llvm/Target/TargetRegisterInfo.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCInstrItineraries.h"
18 #include "llvm/Support/ErrorHandling.h"
22 //===----------------------------------------------------------------------===//
24 //===----------------------------------------------------------------------===//
26 TargetInstrInfo::~TargetInstrInfo() {
29 const TargetRegisterClass*
30 TargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum,
31 const TargetRegisterInfo *TRI,
32 const MachineFunction &MF) const {
33 if (OpNum >= MCID.getNumOperands())
36 short RegClass = MCID.OpInfo[OpNum].RegClass;
37 if (MCID.OpInfo[OpNum].isLookupPtrRegClass())
38 return TRI->getPointerRegClass(MF, RegClass);
40 // Instructions like INSERT_SUBREG do not have fixed register classes.
44 // Otherwise just look it up normally.
45 return TRI->getRegClass(RegClass);
49 TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
50 const MachineInstr *MI) const {
51 if (!ItinData || ItinData->isEmpty())
54 unsigned Class = MI->getDesc().getSchedClass();
55 unsigned UOps = ItinData->Itineraries[Class].NumMicroOps;
59 // The # of u-ops is dynamically determined. The specific target should
60 // override this function to return the right number.
64 /// Return the default expected latency for a def based on it's opcode.
65 unsigned TargetInstrInfo::defaultDefLatency(const InstrItineraryData *ItinData,
66 const MachineInstr *DefMI) const {
68 return ItinData->Props.LoadLatency;
69 if (isHighLatencyDef(DefMI->getOpcode()))
70 return ItinData->Props.HighLatency;
74 /// Both DefMI and UseMI must be valid. By default, call directly to the
75 /// itinerary. This may be overriden by the target.
77 TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
78 const MachineInstr *DefMI, unsigned DefIdx,
79 const MachineInstr *UseMI,
80 unsigned UseIdx) const {
81 unsigned DefClass = DefMI->getDesc().getSchedClass();
82 unsigned UseClass = UseMI->getDesc().getSchedClass();
83 return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
86 /// If we can determine the operand latency from the def only, without itinerary
87 /// lookup, do so. Otherwise return -1.
88 static int computeDefOperandLatency(
89 const TargetInstrInfo *TII, const InstrItineraryData *ItinData,
90 const MachineInstr *DefMI, bool FindMin) {
92 // Let the target hook getInstrLatency handle missing itineraries.
94 return TII->getInstrLatency(ItinData, DefMI);
96 // Return a latency based on the itinerary properties and defining instruction
97 // if possible. Some common subtargets don't require per-operand latency,
98 // especially for minimum latencies.
100 // If MinLatency is valid, call getInstrLatency. This uses Stage latency if
101 // it exists before defaulting to MinLatency.
102 if (ItinData->Props.MinLatency >= 0)
103 return TII->getInstrLatency(ItinData, DefMI);
105 // If MinLatency is invalid, OperandLatency is interpreted as MinLatency.
106 // For empty itineraries, short-cirtuit the check and default to one cycle.
107 if (ItinData->isEmpty())
110 else if(ItinData->isEmpty())
111 return TII->defaultDefLatency(ItinData, DefMI);
113 // ...operand lookup required
117 /// computeOperandLatency - Compute and return the latency of the given data
118 /// dependent def and use when the operand indices are already known.
120 /// FindMin may be set to get the minimum vs. expected latency.
121 unsigned TargetInstrInfo::
122 computeOperandLatency(const InstrItineraryData *ItinData,
123 const MachineInstr *DefMI, unsigned DefIdx,
124 const MachineInstr *UseMI, unsigned UseIdx,
125 bool FindMin) const {
127 int DefLatency = computeDefOperandLatency(this, ItinData, DefMI, FindMin);
131 assert(ItinData && !ItinData->isEmpty() && "computeDefOperandLatency fail");
133 int OperLatency = getOperandLatency(ItinData, DefMI, DefIdx, UseMI, UseIdx);
134 if (OperLatency >= 0)
137 // No operand latency was found.
138 unsigned InstrLatency = getInstrLatency(ItinData, DefMI);
140 // Expected latency is the max of the stage latency and itinerary props.
142 InstrLatency = std::max(InstrLatency, defaultDefLatency(ItinData, DefMI));
146 /// computeOperandLatency - Compute and return the latency of the given data
147 /// dependent def and use. DefMI must be a valid def. UseMI may be NULL for an
148 /// unknown use. Depending on the subtarget's itinerary properties, this may or
149 /// may not need to call getOperandLatency().
151 /// FindMin may be set to get the minimum vs. expected latency. Minimum
152 /// latency is used for scheduling groups, while expected latency is for
153 /// instruction cost and critical path.
155 /// For most subtargets, we don't need DefIdx or UseIdx to compute min latency.
156 /// DefMI must be a valid definition, but UseMI may be NULL for an unknown use.
157 unsigned TargetInstrInfo::
158 computeOperandLatency(const InstrItineraryData *ItinData,
159 const TargetRegisterInfo *TRI,
160 const MachineInstr *DefMI, const MachineInstr *UseMI,
161 unsigned Reg, bool FindMin) const {
163 int DefLatency = computeDefOperandLatency(this, ItinData, DefMI, FindMin);
167 assert(ItinData && !ItinData->isEmpty() && "computeDefOperandLatency fail");
169 // Find the definition of the register in the defining instruction.
170 int DefIdx = DefMI->findRegisterDefOperandIdx(Reg);
172 const MachineOperand &MO = DefMI->getOperand(DefIdx);
173 if (MO.isReg() && MO.isImplicit() &&
174 DefIdx >= (int)DefMI->getDesc().getNumOperands()) {
175 // This is an implicit def, getOperandLatency() won't return the correct
177 // %D6<def>, %D7<def> = VLD1q16 %R2<kill>, 0, ..., %Q3<imp-def>
178 // %Q1<def> = VMULv8i16 %Q1<kill>, %Q3<kill>, ...
179 // What we want is to compute latency between def of %D6/%D7 and use of
181 unsigned Op2 = DefMI->findRegisterDefOperandIdx(Reg, false, true, TRI);
182 if (DefMI->getOperand(Op2).isReg())
185 // For all uses of the register, calculate the maxmimum latency
186 int OperLatency = -1;
188 // UseMI is null, then it must be a scheduling barrier.
190 unsigned DefClass = DefMI->getDesc().getSchedClass();
191 OperLatency = ItinData->getOperandCycle(DefClass, DefIdx);
194 for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) {
195 const MachineOperand &MO = UseMI->getOperand(i);
196 if (!MO.isReg() || !MO.isUse())
198 unsigned MOReg = MO.getReg();
202 int UseCycle = getOperandLatency(ItinData, DefMI, DefIdx, UseMI, i);
203 OperLatency = std::max(OperLatency, UseCycle);
206 // If we found an operand latency, we're done.
207 if (OperLatency >= 0)
210 // No operand latency was found.
211 unsigned InstrLatency = getInstrLatency(ItinData, DefMI);
213 // Expected latency is the max of the stage latency and itinerary props.
215 InstrLatency = std::max(InstrLatency, defaultDefLatency(ItinData, DefMI));
219 unsigned TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
220 const MachineInstr *MI,
221 unsigned *PredCost) const {
222 // Default to one cycle for no itinerary. However, an "empty" itinerary may
223 // still have a MinLatency property, which getStageLatency checks.
225 return MI->mayLoad() ? 2 : 1;
227 return ItinData->getStageLatency(MI->getDesc().getSchedClass());
230 bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
231 const MachineInstr *DefMI,
232 unsigned DefIdx) const {
233 if (!ItinData || ItinData->isEmpty())
236 unsigned DefClass = DefMI->getDesc().getSchedClass();
237 int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
238 return (DefCycle != -1 && DefCycle <= 1);
241 /// insertNoop - Insert a noop into the instruction stream at the specified
243 void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
244 MachineBasicBlock::iterator MI) const {
245 llvm_unreachable("Target didn't implement insertNoop!");
249 /// Measure the specified inline asm to determine an approximation of its
251 /// Comments (which run till the next SeparatorString or newline) do not
252 /// count as an instruction.
253 /// Any other non-whitespace text is considered an instruction, with
254 /// multiple instructions separated by SeparatorString or newlines.
255 /// Variable-length instructions are not handled here; this function
256 /// may be overloaded in the target code to do that.
257 unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
258 const MCAsmInfo &MAI) const {
261 // Count the number of instructions in the asm.
262 bool atInsnStart = true;
264 for (; *Str; ++Str) {
265 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
266 strlen(MAI.getSeparatorString())) == 0)
268 if (atInsnStart && !std::isspace(*Str)) {
269 Length += MAI.getMaxInstLength();
272 if (atInsnStart && strncmp(Str, MAI.getCommentString(),
273 strlen(MAI.getCommentString())) == 0)