613efea73182484ef0d38ad83232df6a2f66de4b
[oota-llvm.git] / lib / Target / TargetInstrInfo.cpp
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/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCInstrItineraries.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include <cctype>
20 using namespace llvm;
21
22 //===----------------------------------------------------------------------===//
23 //  TargetInstrInfo
24 //===----------------------------------------------------------------------===//
25
26 TargetInstrInfo::~TargetInstrInfo() {
27 }
28
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())
34     return 0;
35
36   short RegClass = MCID.OpInfo[OpNum].RegClass;
37   if (MCID.OpInfo[OpNum].isLookupPtrRegClass())
38     return TRI->getPointerRegClass(MF, 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 /// 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 {
67   if (DefMI->mayLoad())
68     return ItinData->Props.LoadLatency;
69   if (isHighLatencyDef(DefMI->getOpcode()))
70     return ItinData->Props.HighLatency;
71   return 1;
72 }
73
74 /// Both DefMI and UseMI must be valid.  By default, call directly to the
75 /// itinerary. This may be overriden by the target.
76 int
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);
84 }
85
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) {
91
92   // Let the target hook getInstrLatency handle missing itineraries.
93   if (!ItinData)
94     return TII->getInstrLatency(ItinData, DefMI);
95
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.
99   if (FindMin) {
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);
104
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())
108       return 1;
109   }
110   else if(ItinData->isEmpty())
111     return TII->defaultDefLatency(ItinData, DefMI);
112
113   // ...operand lookup required
114 return -1;
115 }
116
117 /// computeOperandLatency - Compute and return the latency of the given data
118 /// dependent def and use when the operand indices are already known.
119 ///
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 {
126
127   int DefLatency = computeDefOperandLatency(this, ItinData, DefMI, FindMin);
128   if (DefLatency >= 0)
129     return DefLatency;
130
131   assert(ItinData && !ItinData->isEmpty() && "computeDefOperandLatency fail");
132
133   int OperLatency = getOperandLatency(ItinData, DefMI, DefIdx, UseMI, UseIdx);
134   if (OperLatency >= 0)
135     return OperLatency;
136
137   // No operand latency was found.
138   unsigned InstrLatency = getInstrLatency(ItinData, DefMI);
139
140   // Expected latency is the max of the stage latency and itinerary props.
141   if (!FindMin)
142     InstrLatency = std::max(InstrLatency, defaultDefLatency(ItinData, DefMI));
143   return InstrLatency;
144 }
145
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().
150 ///
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.
154 ///
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 {
162
163   int DefLatency = computeDefOperandLatency(this, ItinData, DefMI, FindMin);
164   if (DefLatency >= 0)
165     return DefLatency;
166
167   assert(ItinData && !ItinData->isEmpty() && "computeDefOperandLatency fail");
168
169   // Find the definition of the register in the defining instruction.
170   int DefIdx = DefMI->findRegisterDefOperandIdx(Reg);
171   if (DefIdx != -1) {
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
176       // latency. e.g.
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
180       // %Q3 instead.
181       unsigned Op2 = DefMI->findRegisterDefOperandIdx(Reg, false, true, TRI);
182       if (DefMI->getOperand(Op2).isReg())
183         DefIdx = Op2;
184     }
185     // For all uses of the register, calculate the maxmimum latency
186     int OperLatency = -1;
187
188     // UseMI is null, then it must be a scheduling barrier.
189     if (!UseMI) {
190       unsigned DefClass = DefMI->getDesc().getSchedClass();
191       OperLatency = ItinData->getOperandCycle(DefClass, DefIdx);
192     }
193     else {
194       for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) {
195         const MachineOperand &MO = UseMI->getOperand(i);
196         if (!MO.isReg() || !MO.isUse())
197           continue;
198         unsigned MOReg = MO.getReg();
199         if (MOReg != Reg)
200           continue;
201
202         int UseCycle = getOperandLatency(ItinData, DefMI, DefIdx, UseMI, i);
203         OperLatency = std::max(OperLatency, UseCycle);
204       }
205     }
206     // If we found an operand latency, we're done.
207     if (OperLatency >= 0)
208       return OperLatency;
209   }
210   // No operand latency was found.
211   unsigned InstrLatency = getInstrLatency(ItinData, DefMI);
212
213   // Expected latency is the max of the stage latency and itinerary props.
214   if (!FindMin)
215     InstrLatency = std::max(InstrLatency, defaultDefLatency(ItinData, DefMI));
216   return InstrLatency;
217 }
218
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.
224   if (!ItinData)
225     return MI->mayLoad() ? 2 : 1;
226
227   return ItinData->getStageLatency(MI->getDesc().getSchedClass());
228 }
229
230 bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
231                                        const MachineInstr *DefMI,
232                                        unsigned DefIdx) const {
233   if (!ItinData || ItinData->isEmpty())
234     return false;
235
236   unsigned DefClass = DefMI->getDesc().getSchedClass();
237   int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
238   return (DefCycle != -1 && DefCycle <= 1);
239 }
240
241 /// insertNoop - Insert a noop into the instruction stream at the specified
242 /// point.
243 void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
244                                  MachineBasicBlock::iterator MI) const {
245   llvm_unreachable("Target didn't implement insertNoop!");
246 }
247
248
249 /// Measure the specified inline asm to determine an approximation of its
250 /// length.
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 {
259
260
261   // Count the number of instructions in the asm.
262   bool atInsnStart = true;
263   unsigned Length = 0;
264   for (; *Str; ++Str) {
265     if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
266                                 strlen(MAI.getSeparatorString())) == 0)
267       atInsnStart = true;
268     if (atInsnStart && !std::isspace(*Str)) {
269       Length += MAI.getMaxInstLength();
270       atInsnStart = false;
271     }
272     if (atInsnStart && strncmp(Str, MAI.getCommentString(),
273                                strlen(MAI.getCommentString())) == 0)
274       atInsnStart = false;
275   }
276
277   return Length;
278 }