1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/backend/instruction-scheduler.h"
6
7namespace v8 {
8namespace internal {
9namespace compiler {
10
11bool InstructionScheduler::SchedulerSupported() { return true; }
12
13int InstructionScheduler::GetTargetInstructionFlags(
14 const Instruction* instr) const {
15 switch (instr->arch_opcode()) {
16 case kX64Add:
17 case kX64Add32:
18 case kX64And:
19 case kX64And32:
20 case kX64Cmp:
21 case kX64Cmp32:
22 case kX64Cmp16:
23 case kX64Cmp8:
24 case kX64Test:
25 case kX64Test32:
26 case kX64Test16:
27 case kX64Test8:
28 case kX64Or:
29 case kX64Or32:
30 case kX64Xor:
31 case kX64Xor32:
32 case kX64Sub:
33 case kX64Sub32:
34 case kX64Imul:
35 case kX64Imul32:
36 case kX64ImulHigh32:
37 case kX64UmulHigh32:
38 case kX64Not:
39 case kX64Not32:
40 case kX64Neg:
41 case kX64Neg32:
42 case kX64Shl:
43 case kX64Shl32:
44 case kX64Shr:
45 case kX64Shr32:
46 case kX64Sar:
47 case kX64Sar32:
48 case kX64Ror:
49 case kX64Ror32:
50 case kX64Lzcnt:
51 case kX64Lzcnt32:
52 case kX64Tzcnt:
53 case kX64Tzcnt32:
54 case kX64Popcnt:
55 case kX64Popcnt32:
56 case kX64Bswap:
57 case kX64Bswap32:
58 case kSSEFloat32Cmp:
59 case kSSEFloat32Add:
60 case kSSEFloat32Sub:
61 case kSSEFloat32Mul:
62 case kSSEFloat32Div:
63 case kSSEFloat32Abs:
64 case kSSEFloat32Neg:
65 case kSSEFloat32Sqrt:
66 case kSSEFloat32Round:
67 case kSSEFloat32ToFloat64:
68 case kSSEFloat64Cmp:
69 case kSSEFloat64Add:
70 case kSSEFloat64Sub:
71 case kSSEFloat64Mul:
72 case kSSEFloat64Div:
73 case kSSEFloat64Mod:
74 case kSSEFloat64Abs:
75 case kSSEFloat64Neg:
76 case kSSEFloat64Sqrt:
77 case kSSEFloat64Round:
78 case kSSEFloat32Max:
79 case kSSEFloat64Max:
80 case kSSEFloat32Min:
81 case kSSEFloat64Min:
82 case kSSEFloat64ToFloat32:
83 case kSSEFloat32ToInt32:
84 case kSSEFloat32ToUint32:
85 case kSSEFloat64ToInt32:
86 case kSSEFloat64ToUint32:
87 case kSSEFloat64ToInt64:
88 case kSSEFloat32ToInt64:
89 case kSSEFloat64ToUint64:
90 case kSSEFloat32ToUint64:
91 case kSSEInt32ToFloat64:
92 case kSSEInt32ToFloat32:
93 case kSSEInt64ToFloat32:
94 case kSSEInt64ToFloat64:
95 case kSSEUint64ToFloat32:
96 case kSSEUint64ToFloat64:
97 case kSSEUint32ToFloat64:
98 case kSSEUint32ToFloat32:
99 case kSSEFloat64ExtractLowWord32:
100 case kSSEFloat64ExtractHighWord32:
101 case kSSEFloat64InsertLowWord32:
102 case kSSEFloat64InsertHighWord32:
103 case kSSEFloat64LoadLowWord32:
104 case kSSEFloat64SilenceNaN:
105 case kAVXFloat32Cmp:
106 case kAVXFloat32Add:
107 case kAVXFloat32Sub:
108 case kAVXFloat32Mul:
109 case kAVXFloat32Div:
110 case kAVXFloat64Cmp:
111 case kAVXFloat64Add:
112 case kAVXFloat64Sub:
113 case kAVXFloat64Mul:
114 case kAVXFloat64Div:
115 case kAVXFloat64Abs:
116 case kAVXFloat64Neg:
117 case kAVXFloat32Abs:
118 case kAVXFloat32Neg:
119 case kX64BitcastFI:
120 case kX64BitcastDL:
121 case kX64BitcastIF:
122 case kX64BitcastLD:
123 case kX64Lea32:
124 case kX64Lea:
125 case kX64Dec32:
126 case kX64Inc32:
127 case kX64F32x4Splat:
128 case kX64F32x4ExtractLane:
129 case kX64F32x4ReplaceLane:
130 case kX64F32x4SConvertI32x4:
131 case kX64F32x4UConvertI32x4:
132 case kX64F32x4RecipApprox:
133 case kX64F32x4RecipSqrtApprox:
134 case kX64F32x4Abs:
135 case kX64F32x4Neg:
136 case kX64F32x4Add:
137 case kX64F32x4AddHoriz:
138 case kX64F32x4Sub:
139 case kX64F32x4Mul:
140 case kX64F32x4Min:
141 case kX64F32x4Max:
142 case kX64F32x4Eq:
143 case kX64F32x4Ne:
144 case kX64F32x4Lt:
145 case kX64F32x4Le:
146 case kX64I32x4Splat:
147 case kX64I32x4ExtractLane:
148 case kX64I32x4ReplaceLane:
149 case kX64I32x4SConvertF32x4:
150 case kX64I32x4SConvertI16x8Low:
151 case kX64I32x4SConvertI16x8High:
152 case kX64I32x4Neg:
153 case kX64I32x4Shl:
154 case kX64I32x4ShrS:
155 case kX64I32x4Add:
156 case kX64I32x4AddHoriz:
157 case kX64I32x4Sub:
158 case kX64I32x4Mul:
159 case kX64I32x4MinS:
160 case kX64I32x4MaxS:
161 case kX64I32x4Eq:
162 case kX64I32x4Ne:
163 case kX64I32x4GtS:
164 case kX64I32x4GeS:
165 case kX64I32x4UConvertF32x4:
166 case kX64I32x4UConvertI16x8Low:
167 case kX64I32x4UConvertI16x8High:
168 case kX64I32x4ShrU:
169 case kX64I32x4MinU:
170 case kX64I32x4MaxU:
171 case kX64I32x4GtU:
172 case kX64I32x4GeU:
173 case kX64I16x8Splat:
174 case kX64I16x8ExtractLane:
175 case kX64I16x8ReplaceLane:
176 case kX64I16x8SConvertI8x16Low:
177 case kX64I16x8SConvertI8x16High:
178 case kX64I16x8Neg:
179 case kX64I16x8Shl:
180 case kX64I16x8ShrS:
181 case kX64I16x8SConvertI32x4:
182 case kX64I16x8Add:
183 case kX64I16x8AddSaturateS:
184 case kX64I16x8AddHoriz:
185 case kX64I16x8Sub:
186 case kX64I16x8SubSaturateS:
187 case kX64I16x8Mul:
188 case kX64I16x8MinS:
189 case kX64I16x8MaxS:
190 case kX64I16x8Eq:
191 case kX64I16x8Ne:
192 case kX64I16x8GtS:
193 case kX64I16x8GeS:
194 case kX64I16x8UConvertI8x16Low:
195 case kX64I16x8UConvertI8x16High:
196 case kX64I16x8UConvertI32x4:
197 case kX64I16x8ShrU:
198 case kX64I16x8AddSaturateU:
199 case kX64I16x8SubSaturateU:
200 case kX64I16x8MinU:
201 case kX64I16x8MaxU:
202 case kX64I16x8GtU:
203 case kX64I16x8GeU:
204 case kX64I8x16Splat:
205 case kX64I8x16ExtractLane:
206 case kX64I8x16ReplaceLane:
207 case kX64I8x16SConvertI16x8:
208 case kX64I8x16Neg:
209 case kX64I8x16Shl:
210 case kX64I8x16ShrS:
211 case kX64I8x16Add:
212 case kX64I8x16AddSaturateS:
213 case kX64I8x16Sub:
214 case kX64I8x16SubSaturateS:
215 case kX64I8x16Mul:
216 case kX64I8x16MinS:
217 case kX64I8x16MaxS:
218 case kX64I8x16Eq:
219 case kX64I8x16Ne:
220 case kX64I8x16GtS:
221 case kX64I8x16GeS:
222 case kX64I8x16UConvertI16x8:
223 case kX64I8x16AddSaturateU:
224 case kX64I8x16SubSaturateU:
225 case kX64I8x16ShrU:
226 case kX64I8x16MinU:
227 case kX64I8x16MaxU:
228 case kX64I8x16GtU:
229 case kX64I8x16GeU:
230 case kX64S128And:
231 case kX64S128Or:
232 case kX64S128Xor:
233 case kX64S128Not:
234 case kX64S128Select:
235 case kX64S128Zero:
236 case kX64S1x4AnyTrue:
237 case kX64S1x4AllTrue:
238 case kX64S1x8AnyTrue:
239 case kX64S1x8AllTrue:
240 case kX64S8x16Shuffle:
241 case kX64S32x4Swizzle:
242 case kX64S32x4Shuffle:
243 case kX64S16x8Blend:
244 case kX64S16x8HalfShuffle1:
245 case kX64S16x8HalfShuffle2:
246 case kX64S8x16Alignr:
247 case kX64S16x8Dup:
248 case kX64S8x16Dup:
249 case kX64S16x8UnzipHigh:
250 case kX64S16x8UnzipLow:
251 case kX64S8x16UnzipHigh:
252 case kX64S8x16UnzipLow:
253 case kX64S64x2UnpackHigh:
254 case kX64S32x4UnpackHigh:
255 case kX64S16x8UnpackHigh:
256 case kX64S8x16UnpackHigh:
257 case kX64S64x2UnpackLow:
258 case kX64S32x4UnpackLow:
259 case kX64S16x8UnpackLow:
260 case kX64S8x16UnpackLow:
261 case kX64S8x16TransposeLow:
262 case kX64S8x16TransposeHigh:
263 case kX64S8x8Reverse:
264 case kX64S8x4Reverse:
265 case kX64S8x2Reverse:
266 case kX64S1x16AnyTrue:
267 case kX64S1x16AllTrue:
268 case kX64DecompressSigned:
269 case kX64DecompressPointer:
270 case kX64DecompressAny:
271 case kX64CompressSigned:
272 case kX64CompressPointer:
273 case kX64CompressAny:
274 return (instr->addressing_mode() == kMode_None)
275 ? kNoOpcodeFlags
276 : kIsLoadOperation | kHasSideEffect;
277
278 case kX64Idiv:
279 case kX64Idiv32:
280 case kX64Udiv:
281 case kX64Udiv32:
282 return (instr->addressing_mode() == kMode_None)
283 ? kMayNeedDeoptOrTrapCheck
284 : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect;
285
286 case kX64Movsxbl:
287 case kX64Movzxbl:
288 case kX64Movsxbq:
289 case kX64Movzxbq:
290 case kX64Movsxwl:
291 case kX64Movzxwl:
292 case kX64Movsxwq:
293 case kX64Movzxwq:
294 case kX64Movsxlq:
295 DCHECK_LE(1, instr->InputCount());
296 return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
297 : kIsLoadOperation;
298
299 case kX64Movb:
300 case kX64Movw:
301 return kHasSideEffect;
302
303 case kX64Movl:
304 if (instr->HasOutput()) {
305 DCHECK_LE(1, instr->InputCount());
306 return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
307 : kIsLoadOperation;
308 } else {
309 return kHasSideEffect;
310 }
311
312 case kX64MovqDecompressTaggedSigned:
313 case kX64MovqDecompressTaggedPointer:
314 case kX64MovqDecompressAnyTagged:
315 case kX64MovqCompressTagged:
316 case kX64Movq:
317 case kX64Movsd:
318 case kX64Movss:
319 case kX64Movdqu:
320 return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
321
322 case kX64StackCheck:
323 case kX64Peek:
324 return kIsLoadOperation;
325
326 case kX64Push:
327 case kX64Poke:
328 return kHasSideEffect;
329
330 case kLFence:
331 return kHasSideEffect;
332
333 case kX64Word64AtomicLoadUint8:
334 case kX64Word64AtomicLoadUint16:
335 case kX64Word64AtomicLoadUint32:
336 case kX64Word64AtomicLoadUint64:
337 return kIsLoadOperation;
338
339 case kX64Word64AtomicStoreWord8:
340 case kX64Word64AtomicStoreWord16:
341 case kX64Word64AtomicStoreWord32:
342 case kX64Word64AtomicStoreWord64:
343 case kX64Word64AtomicAddUint8:
344 case kX64Word64AtomicAddUint16:
345 case kX64Word64AtomicAddUint32:
346 case kX64Word64AtomicAddUint64:
347 case kX64Word64AtomicSubUint8:
348 case kX64Word64AtomicSubUint16:
349 case kX64Word64AtomicSubUint32:
350 case kX64Word64AtomicSubUint64:
351 case kX64Word64AtomicAndUint8:
352 case kX64Word64AtomicAndUint16:
353 case kX64Word64AtomicAndUint32:
354 case kX64Word64AtomicAndUint64:
355 case kX64Word64AtomicOrUint8:
356 case kX64Word64AtomicOrUint16:
357 case kX64Word64AtomicOrUint32:
358 case kX64Word64AtomicOrUint64:
359 case kX64Word64AtomicXorUint8:
360 case kX64Word64AtomicXorUint16:
361 case kX64Word64AtomicXorUint32:
362 case kX64Word64AtomicXorUint64:
363 case kX64Word64AtomicExchangeUint8:
364 case kX64Word64AtomicExchangeUint16:
365 case kX64Word64AtomicExchangeUint32:
366 case kX64Word64AtomicExchangeUint64:
367 case kX64Word64AtomicCompareExchangeUint8:
368 case kX64Word64AtomicCompareExchangeUint16:
369 case kX64Word64AtomicCompareExchangeUint32:
370 case kX64Word64AtomicCompareExchangeUint64:
371 return kHasSideEffect;
372
373#define CASE(Name) case k##Name:
374 COMMON_ARCH_OPCODE_LIST(CASE)
375#undef CASE
376 // Already covered in architecture independent code.
377 UNREACHABLE();
378 }
379
380 UNREACHABLE();
381}
382
383int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
384 // Basic latency modeling for x64 instructions. They have been determined
385 // in an empirical way.
386 switch (instr->arch_opcode()) {
387 case kSSEFloat64Mul:
388 return 5;
389 case kX64Imul:
390 case kX64Imul32:
391 case kX64ImulHigh32:
392 case kX64UmulHigh32:
393 case kSSEFloat32Cmp:
394 case kSSEFloat32Add:
395 case kSSEFloat32Sub:
396 case kSSEFloat32Abs:
397 case kSSEFloat32Neg:
398 case kSSEFloat64Cmp:
399 case kSSEFloat64Add:
400 case kSSEFloat64Sub:
401 case kSSEFloat64Max:
402 case kSSEFloat64Min:
403 case kSSEFloat64Abs:
404 case kSSEFloat64Neg:
405 return 3;
406 case kSSEFloat32Mul:
407 case kSSEFloat32ToFloat64:
408 case kSSEFloat64ToFloat32:
409 case kSSEFloat32Round:
410 case kSSEFloat64Round:
411 case kSSEFloat32ToInt32:
412 case kSSEFloat32ToUint32:
413 case kSSEFloat64ToInt32:
414 case kSSEFloat64ToUint32:
415 return 4;
416 case kX64Idiv:
417 return 49;
418 case kX64Idiv32:
419 return 35;
420 case kX64Udiv:
421 return 38;
422 case kX64Udiv32:
423 return 26;
424 case kSSEFloat32Div:
425 case kSSEFloat64Div:
426 case kSSEFloat32Sqrt:
427 case kSSEFloat64Sqrt:
428 return 13;
429 case kSSEFloat32ToInt64:
430 case kSSEFloat64ToInt64:
431 case kSSEFloat32ToUint64:
432 case kSSEFloat64ToUint64:
433 return 10;
434 case kSSEFloat64Mod:
435 return 50;
436 case kArchTruncateDoubleToI:
437 return 6;
438 default:
439 return 1;
440 }
441}
442
443} // namespace compiler
444} // namespace internal
445} // namespace v8
446