summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc
blob: 2ecbab8f509c260460880e3c2cbc2a8a502c4b1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/compiler/backend/instruction-scheduler.h"

namespace v8 {
namespace internal {
namespace compiler {

bool InstructionScheduler::SchedulerSupported() { return true; }

int InstructionScheduler::GetTargetInstructionFlags(
    const Instruction* instr) const {
  switch (instr->arch_opcode()) {
    case kX64Add:
    case kX64Add32:
    case kX64And:
    case kX64And32:
    case kX64Cmp:
    case kX64Cmp32:
    case kX64Cmp16:
    case kX64Cmp8:
    case kX64Test:
    case kX64Test32:
    case kX64Test16:
    case kX64Test8:
    case kX64Or:
    case kX64Or32:
    case kX64Xor:
    case kX64Xor32:
    case kX64Sub:
    case kX64Sub32:
    case kX64Imul:
    case kX64Imul32:
    case kX64ImulHigh32:
    case kX64UmulHigh32:
    case kX64Not:
    case kX64Not32:
    case kX64Neg:
    case kX64Neg32:
    case kX64Shl:
    case kX64Shl32:
    case kX64Shr:
    case kX64Shr32:
    case kX64Sar:
    case kX64Sar32:
    case kX64Rol:
    case kX64Rol32:
    case kX64Ror:
    case kX64Ror32:
    case kX64Lzcnt:
    case kX64Lzcnt32:
    case kX64Tzcnt:
    case kX64Tzcnt32:
    case kX64Popcnt:
    case kX64Popcnt32:
    case kX64Bswap:
    case kX64Bswap32:
    case kSSEFloat32Cmp:
    case kSSEFloat32Add:
    case kSSEFloat32Sub:
    case kSSEFloat32Mul:
    case kSSEFloat32Div:
    case kSSEFloat32Abs:
    case kSSEFloat32Neg:
    case kSSEFloat32Sqrt:
    case kSSEFloat32Round:
    case kSSEFloat32ToFloat64:
    case kSSEFloat64Cmp:
    case kSSEFloat64Add:
    case kSSEFloat64Sub:
    case kSSEFloat64Mul:
    case kSSEFloat64Div:
    case kSSEFloat64Mod:
    case kSSEFloat64Abs:
    case kSSEFloat64Neg:
    case kSSEFloat64Sqrt:
    case kSSEFloat64Round:
    case kSSEFloat32Max:
    case kSSEFloat64Max:
    case kSSEFloat32Min:
    case kSSEFloat64Min:
    case kSSEFloat64ToFloat32:
    case kSSEFloat32ToInt32:
    case kSSEFloat32ToUint32:
    case kSSEFloat64ToInt32:
    case kSSEFloat64ToUint32:
    case kSSEFloat64ToInt64:
    case kSSEFloat32ToInt64:
    case kSSEFloat64ToUint64:
    case kSSEFloat32ToUint64:
    case kSSEInt32ToFloat64:
    case kSSEInt32ToFloat32:
    case kSSEInt64ToFloat32:
    case kSSEInt64ToFloat64:
    case kSSEUint64ToFloat32:
    case kSSEUint64ToFloat64:
    case kSSEUint32ToFloat64:
    case kSSEUint32ToFloat32:
    case kSSEFloat64ExtractLowWord32:
    case kSSEFloat64ExtractHighWord32:
    case kSSEFloat64InsertLowWord32:
    case kSSEFloat64InsertHighWord32:
    case kSSEFloat64LoadLowWord32:
    case kSSEFloat64SilenceNaN:
    case kAVXFloat32Cmp:
    case kAVXFloat32Add:
    case kAVXFloat32Sub:
    case kAVXFloat32Mul:
    case kAVXFloat32Div:
    case kAVXFloat64Cmp:
    case kAVXFloat64Add:
    case kAVXFloat64Sub:
    case kAVXFloat64Mul:
    case kAVXFloat64Div:
    case kAVXFloat64Abs:
    case kAVXFloat64Neg:
    case kAVXFloat32Abs:
    case kAVXFloat32Neg:
    case kX64BitcastFI:
    case kX64BitcastDL:
    case kX64BitcastIF:
    case kX64BitcastLD:
    case kX64Lea32:
    case kX64Lea:
    case kX64Dec32:
    case kX64Inc32:
    case kX64Pinsrb:
    case kX64Pinsrw:
    case kX64Pinsrd:
    case kX64Pinsrq:
    case kX64F64x2Splat:
    case kX64F64x2ExtractLane:
    case kX64F64x2Abs:
    case kX64F64x2Neg:
    case kX64F64x2Sqrt:
    case kX64F64x2Add:
    case kX64F64x2Sub:
    case kX64F64x2Mul:
    case kX64F64x2Div:
    case kX64F64x2Min:
    case kX64F64x2Max:
    case kX64F64x2Eq:
    case kX64F64x2Ne:
    case kX64F64x2Lt:
    case kX64F64x2Le:
    case kX64F64x2Qfma:
    case kX64F64x2Qfms:
    case kX64F64x2Pmin:
    case kX64F64x2Pmax:
    case kX64F64x2Round:
    case kX64F64x2ConvertLowI32x4S:
    case kX64F64x2ConvertLowI32x4U:
    case kX64F64x2PromoteLowF32x4:
    case kX64F32x4Splat:
    case kX64F32x4ExtractLane:
    case kX64F32x4ReplaceLane:
    case kX64F32x4SConvertI32x4:
    case kX64F32x4UConvertI32x4:
    case kX64F32x4RecipApprox:
    case kX64F32x4RecipSqrtApprox:
    case kX64F32x4Abs:
    case kX64F32x4Neg:
    case kX64F32x4Sqrt:
    case kX64F32x4Add:
    case kX64F32x4AddHoriz:
    case kX64F32x4Sub:
    case kX64F32x4Mul:
    case kX64F32x4Div:
    case kX64F32x4Min:
    case kX64F32x4Max:
    case kX64F32x4Eq:
    case kX64F32x4Ne:
    case kX64F32x4Lt:
    case kX64F32x4Le:
    case kX64F32x4Qfma:
    case kX64F32x4Qfms:
    case kX64F32x4Pmin:
    case kX64F32x4Pmax:
    case kX64F32x4Round:
    case kX64F32x4DemoteF64x2Zero:
    case kX64I64x2Splat:
    case kX64I64x2ExtractLane:
    case kX64I64x2Abs:
    case kX64I64x2Neg:
    case kX64I64x2BitMask:
    case kX64I64x2Shl:
    case kX64I64x2ShrS:
    case kX64I64x2Add:
    case kX64I64x2Sub:
    case kX64I64x2Mul:
    case kX64I64x2Eq:
    case kX64I64x2GtS:
    case kX64I64x2GeS:
    case kX64I64x2Ne:
    case kX64I64x2ShrU:
    case kX64I64x2SignSelect:
    case kX64I64x2ExtMulLowI32x4S:
    case kX64I64x2ExtMulHighI32x4S:
    case kX64I64x2ExtMulLowI32x4U:
    case kX64I64x2ExtMulHighI32x4U:
    case kX64I64x2SConvertI32x4Low:
    case kX64I64x2SConvertI32x4High:
    case kX64I64x2UConvertI32x4Low:
    case kX64I64x2UConvertI32x4High:
    case kX64I32x4Splat:
    case kX64I32x4ExtractLane:
    case kX64I32x4SConvertF32x4:
    case kX64I32x4SConvertI16x8Low:
    case kX64I32x4SConvertI16x8High:
    case kX64I32x4Neg:
    case kX64I32x4Shl:
    case kX64I32x4ShrS:
    case kX64I32x4Add:
    case kX64I32x4AddHoriz:
    case kX64I32x4Sub:
    case kX64I32x4Mul:
    case kX64I32x4MinS:
    case kX64I32x4MaxS:
    case kX64I32x4Eq:
    case kX64I32x4Ne:
    case kX64I32x4GtS:
    case kX64I32x4GeS:
    case kX64I32x4UConvertF32x4:
    case kX64I32x4UConvertI16x8Low:
    case kX64I32x4UConvertI16x8High:
    case kX64I32x4ShrU:
    case kX64I32x4MinU:
    case kX64I32x4MaxU:
    case kX64I32x4GtU:
    case kX64I32x4GeU:
    case kX64I32x4Abs:
    case kX64I32x4BitMask:
    case kX64I32x4DotI16x8S:
    case kX64I32x4SignSelect:
    case kX64I32x4ExtMulLowI16x8S:
    case kX64I32x4ExtMulHighI16x8S:
    case kX64I32x4ExtMulLowI16x8U:
    case kX64I32x4ExtMulHighI16x8U:
    case kX64I32x4ExtAddPairwiseI16x8S:
    case kX64I32x4ExtAddPairwiseI16x8U:
    case kX64I32x4TruncSatF64x2SZero:
    case kX64I32x4TruncSatF64x2UZero:
    case kX64I16x8Splat:
    case kX64I16x8ExtractLaneS:
    case kX64I16x8SConvertI8x16Low:
    case kX64I16x8SConvertI8x16High:
    case kX64I16x8Neg:
    case kX64I16x8Shl:
    case kX64I16x8ShrS:
    case kX64I16x8SConvertI32x4:
    case kX64I16x8Add:
    case kX64I16x8AddSatS:
    case kX64I16x8AddHoriz:
    case kX64I16x8Sub:
    case kX64I16x8SubSatS:
    case kX64I16x8Mul:
    case kX64I16x8MinS:
    case kX64I16x8MaxS:
    case kX64I16x8Eq:
    case kX64I16x8Ne:
    case kX64I16x8GtS:
    case kX64I16x8GeS:
    case kX64I16x8UConvertI8x16Low:
    case kX64I16x8UConvertI8x16High:
    case kX64I16x8UConvertI32x4:
    case kX64I16x8ShrU:
    case kX64I16x8AddSatU:
    case kX64I16x8SubSatU:
    case kX64I16x8MinU:
    case kX64I16x8MaxU:
    case kX64I16x8GtU:
    case kX64I16x8GeU:
    case kX64I16x8RoundingAverageU:
    case kX64I16x8Abs:
    case kX64I16x8BitMask:
    case kX64I16x8SignSelect:
    case kX64I16x8ExtMulLowI8x16S:
    case kX64I16x8ExtMulHighI8x16S:
    case kX64I16x8ExtMulLowI8x16U:
    case kX64I16x8ExtMulHighI8x16U:
    case kX64I16x8ExtAddPairwiseI8x16S:
    case kX64I16x8ExtAddPairwiseI8x16U:
    case kX64I16x8Q15MulRSatS:
    case kX64I8x16Splat:
    case kX64I8x16ExtractLaneS:
    case kX64I8x16SConvertI16x8:
    case kX64I8x16Neg:
    case kX64I8x16Shl:
    case kX64I8x16ShrS:
    case kX64I8x16Add:
    case kX64I8x16AddSatS:
    case kX64I8x16Sub:
    case kX64I8x16SubSatS:
    case kX64I8x16Mul:
    case kX64I8x16MinS:
    case kX64I8x16MaxS:
    case kX64I8x16Eq:
    case kX64I8x16Ne:
    case kX64I8x16GtS:
    case kX64I8x16GeS:
    case kX64I8x16UConvertI16x8:
    case kX64I8x16AddSatU:
    case kX64I8x16SubSatU:
    case kX64I8x16ShrU:
    case kX64I8x16MinU:
    case kX64I8x16MaxU:
    case kX64I8x16GtU:
    case kX64I8x16GeU:
    case kX64I8x16RoundingAverageU:
    case kX64I8x16Abs:
    case kX64I8x16BitMask:
    case kX64I8x16SignSelect:
    case kX64S128And:
    case kX64S128Or:
    case kX64S128Xor:
    case kX64S128Not:
    case kX64S128Select:
    case kX64S128Const:
    case kX64S128Zero:
    case kX64S128AllOnes:
    case kX64S128AndNot:
    case kX64V64x2AllTrue:
    case kX64V32x4AllTrue:
    case kX64V16x8AllTrue:
    case kX64I8x16Swizzle:
    case kX64I8x16Shuffle:
    case kX64I8x16Popcnt:
    case kX64Shufps:
    case kX64S32x4Rotate:
    case kX64S32x4Swizzle:
    case kX64S32x4Shuffle:
    case kX64S16x8Blend:
    case kX64S16x8HalfShuffle1:
    case kX64S16x8HalfShuffle2:
    case kX64S8x16Alignr:
    case kX64S16x8Dup:
    case kX64S8x16Dup:
    case kX64S16x8UnzipHigh:
    case kX64S16x8UnzipLow:
    case kX64S8x16UnzipHigh:
    case kX64S8x16UnzipLow:
    case kX64S64x2UnpackHigh:
    case kX64S32x4UnpackHigh:
    case kX64S16x8UnpackHigh:
    case kX64S8x16UnpackHigh:
    case kX64S64x2UnpackLow:
    case kX64S32x4UnpackLow:
    case kX64S16x8UnpackLow:
    case kX64S8x16UnpackLow:
    case kX64S8x16TransposeLow:
    case kX64S8x16TransposeHigh:
    case kX64S8x8Reverse:
    case kX64S8x4Reverse:
    case kX64S8x2Reverse:
    case kX64V128AnyTrue:
    case kX64V8x16AllTrue:
      return (instr->addressing_mode() == kMode_None)
                 ? kNoOpcodeFlags
                 : kIsLoadOperation | kHasSideEffect;

    case kX64Idiv:
    case kX64Idiv32:
    case kX64Udiv:
    case kX64Udiv32:
      return (instr->addressing_mode() == kMode_None)
                 ? kMayNeedDeoptOrTrapCheck
                 : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect;

    case kX64Movsxbl:
    case kX64Movzxbl:
    case kX64Movsxbq:
    case kX64Movzxbq:
    case kX64Movsxwl:
    case kX64Movzxwl:
    case kX64Movsxwq:
    case kX64Movzxwq:
    case kX64Movsxlq:
      DCHECK_LE(1, instr->InputCount());
      return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
                                             : kIsLoadOperation;

    case kX64Movb:
    case kX64Movw:
    case kX64S128Store32Lane:
    case kX64S128Store64Lane:
      return kHasSideEffect;

    case kX64Pextrb:
    case kX64Pextrw:
    case kX64Movl:
      if (instr->HasOutput()) {
        DCHECK_LE(1, instr->InputCount());
        return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
                                               : kIsLoadOperation;
      } else {
        return kHasSideEffect;
      }

    case kX64MovqDecompressTaggedSigned:
    case kX64MovqDecompressTaggedPointer:
    case kX64MovqDecompressAnyTagged:
    case kX64MovqCompressTagged:
    case kX64Movq:
    case kX64Movsd:
    case kX64Movss:
    case kX64Movdqu:
    case kX64S128Load8Splat:
    case kX64S128Load16Splat:
    case kX64S128Load32Splat:
    case kX64S128Load64Splat:
    case kX64S128Load8x8S:
    case kX64S128Load8x8U:
    case kX64S128Load16x4S:
    case kX64S128Load16x4U:
    case kX64S128Load32x2S:
    case kX64S128Load32x2U:
      return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;

    case kX64Peek:
      return kIsLoadOperation;

    case kX64Push:
    case kX64Poke:
      return kHasSideEffect;

    case kX64MFence:
    case kX64LFence:
    case kX64Prefetch:
    case kX64PrefetchNta:
      return kHasSideEffect;

    case kX64Word64AtomicAddUint8:
    case kX64Word64AtomicAddUint16:
    case kX64Word64AtomicAddUint32:
    case kX64Word64AtomicAddUint64:
    case kX64Word64AtomicSubUint8:
    case kX64Word64AtomicSubUint16:
    case kX64Word64AtomicSubUint32:
    case kX64Word64AtomicSubUint64:
    case kX64Word64AtomicAndUint8:
    case kX64Word64AtomicAndUint16:
    case kX64Word64AtomicAndUint32:
    case kX64Word64AtomicAndUint64:
    case kX64Word64AtomicOrUint8:
    case kX64Word64AtomicOrUint16:
    case kX64Word64AtomicOrUint32:
    case kX64Word64AtomicOrUint64:
    case kX64Word64AtomicXorUint8:
    case kX64Word64AtomicXorUint16:
    case kX64Word64AtomicXorUint32:
    case kX64Word64AtomicXorUint64:
    case kX64Word64AtomicExchangeUint8:
    case kX64Word64AtomicExchangeUint16:
    case kX64Word64AtomicExchangeUint32:
    case kX64Word64AtomicExchangeUint64:
    case kX64Word64AtomicCompareExchangeUint8:
    case kX64Word64AtomicCompareExchangeUint16:
    case kX64Word64AtomicCompareExchangeUint32:
    case kX64Word64AtomicCompareExchangeUint64:
      return kHasSideEffect;

#define CASE(Name) case k##Name:
      COMMON_ARCH_OPCODE_LIST(CASE)
#undef CASE
      // Already covered in architecture independent code.
      UNREACHABLE();
  }

  UNREACHABLE();
}

int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
  // Basic latency modeling for x64 instructions. They have been determined
  // in an empirical way.
  switch (instr->arch_opcode()) {
    case kSSEFloat64Mul:
      return 5;
    case kX64Imul:
    case kX64Imul32:
    case kX64ImulHigh32:
    case kX64UmulHigh32:
    case kSSEFloat32Cmp:
    case kSSEFloat32Add:
    case kSSEFloat32Sub:
    case kSSEFloat32Abs:
    case kSSEFloat32Neg:
    case kSSEFloat64Cmp:
    case kSSEFloat64Add:
    case kSSEFloat64Sub:
    case kSSEFloat64Max:
    case kSSEFloat64Min:
    case kSSEFloat64Abs:
    case kSSEFloat64Neg:
      return 3;
    case kSSEFloat32Mul:
    case kSSEFloat32ToFloat64:
    case kSSEFloat64ToFloat32:
    case kSSEFloat32Round:
    case kSSEFloat64Round:
    case kSSEFloat32ToInt32:
    case kSSEFloat32ToUint32:
    case kSSEFloat64ToInt32:
    case kSSEFloat64ToUint32:
      return 4;
    case kX64Idiv:
      return 49;
    case kX64Idiv32:
      return 35;
    case kX64Udiv:
      return 38;
    case kX64Udiv32:
      return 26;
    case kSSEFloat32Div:
    case kSSEFloat64Div:
    case kSSEFloat32Sqrt:
    case kSSEFloat64Sqrt:
      return 13;
    case kSSEFloat32ToInt64:
    case kSSEFloat64ToInt64:
    case kSSEFloat32ToUint64:
    case kSSEFloat64ToUint64:
      return 10;
    case kSSEFloat64Mod:
      return 50;
    case kArchTruncateDoubleToI:
      return 6;
    default:
      return 1;
  }
}

}  // namespace compiler
}  // namespace internal
}  // namespace v8