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 
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10 
SchedulerSupported()11 bool InstructionScheduler::SchedulerSupported() { return true; }
12 
GetTargetInstructionFlags( const Instruction* instr) const13 int 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 kX64Rol:
49     case kX64Rol32:
50     case kX64Ror:
51     case kX64Ror32:
52     case kX64Lzcnt:
53     case kX64Lzcnt32:
54     case kX64Tzcnt:
55     case kX64Tzcnt32:
56     case kX64Popcnt:
57     case kX64Popcnt32:
58     case kX64Bswap:
59     case kX64Bswap32:
60     case kSSEFloat32Cmp:
61     case kSSEFloat32Add:
62     case kSSEFloat32Sub:
63     case kSSEFloat32Mul:
64     case kSSEFloat32Div:
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 kSSEFloat64Sqrt:
75     case kSSEFloat64Round:
76     case kSSEFloat32Max:
77     case kSSEFloat64Max:
78     case kSSEFloat32Min:
79     case kSSEFloat64Min:
80     case kSSEFloat64ToFloat32:
81     case kSSEFloat32ToInt32:
82     case kSSEFloat32ToUint32:
83     case kSSEFloat64ToInt32:
84     case kSSEFloat64ToUint32:
85     case kSSEFloat64ToInt64:
86     case kSSEFloat32ToInt64:
87     case kSSEFloat64ToUint64:
88     case kSSEFloat32ToUint64:
89     case kSSEInt32ToFloat64:
90     case kSSEInt32ToFloat32:
91     case kSSEInt64ToFloat32:
92     case kSSEInt64ToFloat64:
93     case kSSEUint64ToFloat32:
94     case kSSEUint64ToFloat64:
95     case kSSEUint32ToFloat64:
96     case kSSEUint32ToFloat32:
97     case kSSEFloat64ExtractLowWord32:
98     case kSSEFloat64ExtractHighWord32:
99     case kSSEFloat64InsertLowWord32:
100     case kSSEFloat64InsertHighWord32:
101     case kSSEFloat64LoadLowWord32:
102     case kSSEFloat64SilenceNaN:
103     case kAVXFloat32Cmp:
104     case kAVXFloat32Add:
105     case kAVXFloat32Sub:
106     case kAVXFloat32Mul:
107     case kAVXFloat32Div:
108     case kAVXFloat64Cmp:
109     case kAVXFloat64Add:
110     case kAVXFloat64Sub:
111     case kAVXFloat64Mul:
112     case kAVXFloat64Div:
113     case kX64Float64Abs:
114     case kX64Float64Neg:
115     case kX64Float32Abs:
116     case kX64Float32Neg:
117     case kX64BitcastFI:
118     case kX64BitcastDL:
119     case kX64BitcastIF:
120     case kX64BitcastLD:
121     case kX64Lea32:
122     case kX64Lea:
123     case kX64Dec32:
124     case kX64Inc32:
125     case kX64Pinsrb:
126     case kX64Pinsrw:
127     case kX64Pinsrd:
128     case kX64Pinsrq:
129     case kX64Cvttps2dq:
130     case kX64Cvttpd2dq:
131     case kX64I32x4TruncF64x2UZero:
132     case kX64I32x4TruncF32x4U:
133     case kX64F64x2Splat:
134     case kX64F64x2ExtractLane:
135     case kX64F64x2ReplaceLane:
136     case kX64F64x2Abs:
137     case kX64F64x2Neg:
138     case kX64F64x2Sqrt:
139     case kX64F64x2Add:
140     case kX64F64x2Sub:
141     case kX64F64x2Mul:
142     case kX64F64x2Div:
143     case kX64F64x2Min:
144     case kX64F64x2Max:
145     case kX64F64x2Eq:
146     case kX64F64x2Ne:
147     case kX64F64x2Lt:
148     case kX64F64x2Le:
149     case kX64F64x2Qfma:
150     case kX64F64x2Qfms:
151     case kX64Minpd:
152     case kX64Maxpd:
153     case kX64F64x2Round:
154     case kX64F64x2ConvertLowI32x4S:
155     case kX64F64x2ConvertLowI32x4U:
156     case kX64F64x2PromoteLowF32x4:
157     case kX64F32x4Splat:
158     case kX64F32x4ExtractLane:
159     case kX64F32x4ReplaceLane:
160     case kX64F32x4SConvertI32x4:
161     case kX64F32x4UConvertI32x4:
162     case kX64F32x4RecipApprox:
163     case kX64F32x4RecipSqrtApprox:
164     case kX64F32x4Abs:
165     case kX64F32x4Neg:
166     case kX64F32x4Sqrt:
167     case kX64F32x4Add:
168     case kX64F32x4Sub:
169     case kX64F32x4Mul:
170     case kX64F32x4Div:
171     case kX64F32x4Min:
172     case kX64F32x4Max:
173     case kX64F32x4Eq:
174     case kX64F32x4Ne:
175     case kX64F32x4Lt:
176     case kX64F32x4Le:
177     case kX64F32x4Qfma:
178     case kX64F32x4Qfms:
179     case kX64Minps:
180     case kX64Maxps:
181     case kX64F32x4Round:
182     case kX64F32x4DemoteF64x2Zero:
183     case kX64I64x2Splat:
184     case kX64I64x2ExtractLane:
185     case kX64I64x2Abs:
186     case kX64I64x2Neg:
187     case kX64I64x2BitMask:
188     case kX64I64x2Shl:
189     case kX64I64x2ShrS:
190     case kX64I64x2Add:
191     case kX64I64x2Sub:
192     case kX64I64x2Mul:
193     case kX64I64x2Eq:
194     case kX64I64x2GtS:
195     case kX64I64x2GeS:
196     case kX64I64x2Ne:
197     case kX64I64x2ShrU:
198     case kX64I64x2ExtMulLowI32x4S:
199     case kX64I64x2ExtMulHighI32x4S:
200     case kX64I64x2ExtMulLowI32x4U:
201     case kX64I64x2ExtMulHighI32x4U:
202     case kX64I64x2SConvertI32x4Low:
203     case kX64I64x2SConvertI32x4High:
204     case kX64I64x2UConvertI32x4Low:
205     case kX64I64x2UConvertI32x4High:
206     case kX64I32x4Splat:
207     case kX64I32x4ExtractLane:
208     case kX64I32x4SConvertF32x4:
209     case kX64I32x4SConvertI16x8Low:
210     case kX64I32x4SConvertI16x8High:
211     case kX64I32x4Neg:
212     case kX64I32x4Shl:
213     case kX64I32x4ShrS:
214     case kX64I32x4Add:
215     case kX64I32x4Sub:
216     case kX64I32x4Mul:
217     case kX64I32x4MinS:
218     case kX64I32x4MaxS:
219     case kX64I32x4Eq:
220     case kX64I32x4Ne:
221     case kX64I32x4GtS:
222     case kX64I32x4GeS:
223     case kX64I32x4UConvertF32x4:
224     case kX64I32x4UConvertI16x8Low:
225     case kX64I32x4UConvertI16x8High:
226     case kX64I32x4ShrU:
227     case kX64I32x4MinU:
228     case kX64I32x4MaxU:
229     case kX64I32x4GtU:
230     case kX64I32x4GeU:
231     case kX64I32x4Abs:
232     case kX64I32x4BitMask:
233     case kX64I32x4DotI16x8S:
234     case kX64I32x4ExtMulLowI16x8S:
235     case kX64I32x4ExtMulHighI16x8S:
236     case kX64I32x4ExtMulLowI16x8U:
237     case kX64I32x4ExtMulHighI16x8U:
238     case kX64I32x4ExtAddPairwiseI16x8S:
239     case kX64I32x4ExtAddPairwiseI16x8U:
240     case kX64I32x4TruncSatF64x2SZero:
241     case kX64I32x4TruncSatF64x2UZero:
242     case kX64I16x8Splat:
243     case kX64I16x8ExtractLaneS:
244     case kX64I16x8SConvertI8x16Low:
245     case kX64I16x8SConvertI8x16High:
246     case kX64I16x8Neg:
247     case kX64I16x8Shl:
248     case kX64I16x8ShrS:
249     case kX64I16x8SConvertI32x4:
250     case kX64I16x8Add:
251     case kX64I16x8AddSatS:
252     case kX64I16x8Sub:
253     case kX64I16x8SubSatS:
254     case kX64I16x8Mul:
255     case kX64I16x8MinS:
256     case kX64I16x8MaxS:
257     case kX64I16x8Eq:
258     case kX64I16x8Ne:
259     case kX64I16x8GtS:
260     case kX64I16x8GeS:
261     case kX64I16x8UConvertI8x16Low:
262     case kX64I16x8UConvertI8x16High:
263     case kX64I16x8UConvertI32x4:
264     case kX64I16x8ShrU:
265     case kX64I16x8AddSatU:
266     case kX64I16x8SubSatU:
267     case kX64I16x8MinU:
268     case kX64I16x8MaxU:
269     case kX64I16x8GtU:
270     case kX64I16x8GeU:
271     case kX64I16x8RoundingAverageU:
272     case kX64I16x8Abs:
273     case kX64I16x8BitMask:
274     case kX64I16x8ExtMulLowI8x16S:
275     case kX64I16x8ExtMulHighI8x16S:
276     case kX64I16x8ExtMulLowI8x16U:
277     case kX64I16x8ExtMulHighI8x16U:
278     case kX64I16x8ExtAddPairwiseI8x16S:
279     case kX64I16x8ExtAddPairwiseI8x16U:
280     case kX64I16x8Q15MulRSatS:
281     case kX64I8x16Splat:
282     case kX64I8x16ExtractLaneS:
283     case kX64I8x16SConvertI16x8:
284     case kX64I8x16Neg:
285     case kX64I8x16Shl:
286     case kX64I8x16ShrS:
287     case kX64I8x16Add:
288     case kX64I8x16AddSatS:
289     case kX64I8x16Sub:
290     case kX64I8x16SubSatS:
291     case kX64I8x16MinS:
292     case kX64I8x16MaxS:
293     case kX64I8x16Eq:
294     case kX64I8x16Ne:
295     case kX64I8x16GtS:
296     case kX64I8x16GeS:
297     case kX64I8x16UConvertI16x8:
298     case kX64I8x16AddSatU:
299     case kX64I8x16SubSatU:
300     case kX64I8x16ShrU:
301     case kX64I8x16MinU:
302     case kX64I8x16MaxU:
303     case kX64I8x16GtU:
304     case kX64I8x16GeU:
305     case kX64I8x16RoundingAverageU:
306     case kX64I8x16Abs:
307     case kX64I8x16BitMask:
308     case kX64S128And:
309     case kX64S128Or:
310     case kX64S128Xor:
311     case kX64S128Not:
312     case kX64S128Select:
313     case kX64S128Const:
314     case kX64S128Zero:
315     case kX64S128AllOnes:
316     case kX64S128AndNot:
317     case kX64I64x2AllTrue:
318     case kX64I32x4AllTrue:
319     case kX64I16x8AllTrue:
320     case kX64I8x16Swizzle:
321     case kX64I8x16Shuffle:
322     case kX64I8x16Popcnt:
323     case kX64Shufps:
324     case kX64S32x4Rotate:
325     case kX64S32x4Swizzle:
326     case kX64S32x4Shuffle:
327     case kX64S16x8Blend:
328     case kX64S16x8HalfShuffle1:
329     case kX64S16x8HalfShuffle2:
330     case kX64S8x16Alignr:
331     case kX64S16x8Dup:
332     case kX64S8x16Dup:
333     case kX64S16x8UnzipHigh:
334     case kX64S16x8UnzipLow:
335     case kX64S8x16UnzipHigh:
336     case kX64S8x16UnzipLow:
337     case kX64S64x2UnpackHigh:
338     case kX64S32x4UnpackHigh:
339     case kX64S16x8UnpackHigh:
340     case kX64S8x16UnpackHigh:
341     case kX64S64x2UnpackLow:
342     case kX64S32x4UnpackLow:
343     case kX64S16x8UnpackLow:
344     case kX64S8x16UnpackLow:
345     case kX64S8x16TransposeLow:
346     case kX64S8x16TransposeHigh:
347     case kX64S8x8Reverse:
348     case kX64S8x4Reverse:
349     case kX64S8x2Reverse:
350     case kX64V128AnyTrue:
351     case kX64I8x16AllTrue:
352     case kX64Pblendvb:
353       return (instr->addressing_mode() == kMode_None)
354                  ? kNoOpcodeFlags
355                  : kIsLoadOperation | kHasSideEffect;
356 
357     case kX64Idiv:
358     case kX64Idiv32:
359     case kX64Udiv:
360     case kX64Udiv32:
361       return (instr->addressing_mode() == kMode_None)
362                  ? kMayNeedDeoptOrTrapCheck
363                  : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect;
364 
365     case kX64Movsxbl:
366     case kX64Movzxbl:
367     case kX64Movsxbq:
368     case kX64Movzxbq:
369     case kX64Movsxwl:
370     case kX64Movzxwl:
371     case kX64Movsxwq:
372     case kX64Movzxwq:
373     case kX64Movsxlq:
374       DCHECK_LE(1, instr->InputCount());
375       return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
376                                              : kIsLoadOperation;
377 
378     case kX64Movb:
379     case kX64Movw:
380     case kX64S128Store32Lane:
381     case kX64S128Store64Lane:
382       return kHasSideEffect;
383 
384     case kX64Pextrb:
385     case kX64Pextrw:
386     case kX64Movl:
387       if (instr->HasOutput()) {
388         DCHECK_LE(1, instr->InputCount());
389         return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
390                                                : kIsLoadOperation;
391       } else {
392         return kHasSideEffect;
393       }
394 
395     case kX64MovqDecompressTaggedSigned:
396     case kX64MovqDecompressTaggedPointer:
397     case kX64MovqDecompressAnyTagged:
398     case kX64MovqCompressTagged:
399     case kX64MovqDecodeSandboxedPointer:
400     case kX64MovqEncodeSandboxedPointer:
401     case kX64Movq:
402     case kX64Movsd:
403     case kX64Movss:
404     case kX64Movdqu:
405     case kX64S128Load8Splat:
406     case kX64S128Load16Splat:
407     case kX64S128Load32Splat:
408     case kX64S128Load64Splat:
409     case kX64S128Load8x8S:
410     case kX64S128Load8x8U:
411     case kX64S128Load16x4S:
412     case kX64S128Load16x4U:
413     case kX64S128Load32x2S:
414     case kX64S128Load32x2U:
415       return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
416 
417     case kX64Peek:
418       return kIsLoadOperation;
419 
420     case kX64Push:
421     case kX64Poke:
422       return kHasSideEffect;
423 
424     case kX64MFence:
425     case kX64LFence:
426       return kHasSideEffect;
427 
428     case kX64Word64AtomicStoreWord64:
429     case kX64Word64AtomicAddUint64:
430     case kX64Word64AtomicSubUint64:
431     case kX64Word64AtomicAndUint64:
432     case kX64Word64AtomicOrUint64:
433     case kX64Word64AtomicXorUint64:
434     case kX64Word64AtomicExchangeUint64:
435     case kX64Word64AtomicCompareExchangeUint64:
436       return kHasSideEffect;
437 
438 #define CASE(Name) case k##Name:
439       COMMON_ARCH_OPCODE_LIST(CASE)
440 #undef CASE
441       // Already covered in architecture independent code.
442       UNREACHABLE();
443   }
444 
445   UNREACHABLE();
446 }
447 
GetInstructionLatency(const Instruction* instr)448 int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
449   // Basic latency modeling for x64 instructions. They have been determined
450   // in an empirical way.
451   switch (instr->arch_opcode()) {
452     case kSSEFloat64Mul:
453       return 5;
454     case kX64Imul:
455     case kX64Imul32:
456     case kX64ImulHigh32:
457     case kX64UmulHigh32:
458     case kX64Float32Abs:
459     case kX64Float32Neg:
460     case kX64Float64Abs:
461     case kX64Float64Neg:
462     case kSSEFloat32Cmp:
463     case kSSEFloat32Add:
464     case kSSEFloat32Sub:
465     case kSSEFloat64Cmp:
466     case kSSEFloat64Add:
467     case kSSEFloat64Sub:
468     case kSSEFloat64Max:
469     case kSSEFloat64Min:
470       return 3;
471     case kSSEFloat32Mul:
472     case kSSEFloat32ToFloat64:
473     case kSSEFloat64ToFloat32:
474     case kSSEFloat32Round:
475     case kSSEFloat64Round:
476     case kSSEFloat32ToInt32:
477     case kSSEFloat32ToUint32:
478     case kSSEFloat64ToInt32:
479     case kSSEFloat64ToUint32:
480       return 4;
481     case kX64Idiv:
482       return 49;
483     case kX64Idiv32:
484       return 35;
485     case kX64Udiv:
486       return 38;
487     case kX64Udiv32:
488       return 26;
489     case kSSEFloat32Div:
490     case kSSEFloat64Div:
491     case kSSEFloat32Sqrt:
492     case kSSEFloat64Sqrt:
493       return 13;
494     case kSSEFloat32ToInt64:
495     case kSSEFloat64ToInt64:
496     case kSSEFloat32ToUint64:
497     case kSSEFloat64ToUint64:
498       return 10;
499     case kSSEFloat64Mod:
500       return 50;
501     case kArchTruncateDoubleToI:
502       return 6;
503     default:
504       return 1;
505   }
506 }
507 
508 }  // namespace compiler
509 }  // namespace internal
510 }  // namespace v8
511