summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/backend/ia32/instruction-scheduler-ia32.cc
blob: a30b4fc6a3d78ed135fd342fcb0749fb4830ced8 (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
// 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/base/logging.h"
#include "src/compiler/backend/instruction-codes.h"
#include "src/compiler/backend/instruction-scheduler.h"
#include "src/compiler/backend/instruction.h"

namespace v8 {
namespace internal {
namespace compiler {

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

int InstructionScheduler::GetTargetInstructionFlags(
    const Instruction* instr) const {
  switch (instr->arch_opcode()) {
    case kIA32Add:
    case kIA32And:
    case kIA32Cmp:
    case kIA32Cmp16:
    case kIA32Cmp8:
    case kIA32Test:
    case kIA32Test16:
    case kIA32Test8:
    case kIA32Or:
    case kIA32Xor:
    case kIA32Sub:
    case kIA32Imul:
    case kIA32ImulHigh:
    case kIA32UmulHigh:
    case kIA32Not:
    case kIA32Neg:
    case kIA32Shl:
    case kIA32Shr:
    case kIA32Sar:
    case kIA32AddPair:
    case kIA32SubPair:
    case kIA32MulPair:
    case kIA32ShlPair:
    case kIA32ShrPair:
    case kIA32SarPair:
    case kIA32Rol:
    case kIA32Ror:
    case kIA32Lzcnt:
    case kIA32Tzcnt:
    case kIA32Popcnt:
    case kIA32Bswap:
    case kIA32Lea:
    case kIA32Float32Cmp:
    case kIA32Float32Sqrt:
    case kIA32Float32Round:
    case kIA32Float64Cmp:
    case kIA32Float64Mod:
    case kIA32Float32Max:
    case kIA32Float64Max:
    case kIA32Float32Min:
    case kIA32Float64Min:
    case kIA32Float64Sqrt:
    case kIA32Float64Round:
    case kIA32Float32ToFloat64:
    case kIA32Float64ToFloat32:
    case kIA32Float32ToInt32:
    case kIA32Float32ToUint32:
    case kIA32Float64ToInt32:
    case kIA32Float64ToUint32:
    case kSSEInt32ToFloat32:
    case kIA32Uint32ToFloat32:
    case kSSEInt32ToFloat64:
    case kIA32Uint32ToFloat64:
    case kIA32Float64ExtractLowWord32:
    case kIA32Float64ExtractHighWord32:
    case kIA32Float64InsertLowWord32:
    case kIA32Float64InsertHighWord32:
    case kIA32Float64LoadLowWord32:
    case kIA32Float64SilenceNaN:
    case kFloat32Add:
    case kFloat32Sub:
    case kFloat64Add:
    case kFloat64Sub:
    case kFloat32Mul:
    case kFloat32Div:
    case kFloat64Mul:
    case kFloat64Div:
    case kFloat64Abs:
    case kFloat64Neg:
    case kFloat32Abs:
    case kFloat32Neg:
    case kIA32BitcastFI:
    case kIA32BitcastIF:
    case kIA32Pblendvb:
    case kIA32Cvttps2dq:
    case kIA32Cvttpd2dq:
    case kIA32I32x4TruncF32x4U:
    case kIA32I32x4TruncF64x2UZero:
    case kIA32F64x2Splat:
    case kIA32F64x2ExtractLane:
    case kIA32F64x2ReplaceLane:
    case kIA32F64x2Sqrt:
    case kIA32F64x2Add:
    case kIA32F64x2Sub:
    case kIA32F64x2Mul:
    case kIA32F64x2Div:
    case kIA32F64x2Min:
    case kIA32F64x2Max:
    case kIA32F64x2Eq:
    case kIA32F64x2Ne:
    case kIA32F64x2Lt:
    case kIA32F64x2Le:
    case kIA32F64x2Qfma:
    case kIA32F64x2Qfms:
    case kIA32Minpd:
    case kIA32Maxpd:
    case kIA32F64x2Round:
    case kIA32F64x2ConvertLowI32x4S:
    case kIA32F64x2ConvertLowI32x4U:
    case kIA32F64x2PromoteLowF32x4:
    case kIA32I64x2SplatI32Pair:
    case kIA32I64x2ReplaceLaneI32Pair:
    case kIA32I64x2Abs:
    case kIA32I64x2Neg:
    case kIA32I64x2Shl:
    case kIA32I64x2ShrS:
    case kIA32I64x2Add:
    case kIA32I64x2Sub:
    case kIA32I64x2Mul:
    case kIA32I64x2ShrU:
    case kIA32I64x2BitMask:
    case kIA32I64x2Eq:
    case kIA32I64x2Ne:
    case kIA32I64x2GtS:
    case kIA32I64x2GeS:
    case kIA32I64x2ExtMulLowI32x4S:
    case kIA32I64x2ExtMulHighI32x4S:
    case kIA32I64x2ExtMulLowI32x4U:
    case kIA32I64x2ExtMulHighI32x4U:
    case kIA32I64x2SConvertI32x4Low:
    case kIA32I64x2SConvertI32x4High:
    case kIA32I64x2UConvertI32x4Low:
    case kIA32I64x2UConvertI32x4High:
    case kIA32F32x4Splat:
    case kIA32F32x4ExtractLane:
    case kIA32Insertps:
    case kIA32F32x4SConvertI32x4:
    case kIA32F32x4UConvertI32x4:
    case kIA32F32x4Sqrt:
    case kIA32F32x4Add:
    case kIA32F32x4Sub:
    case kIA32F32x4Mul:
    case kIA32F32x4Div:
    case kIA32F32x4Min:
    case kIA32F32x4Max:
    case kIA32F32x4Eq:
    case kIA32F32x4Ne:
    case kIA32F32x4Lt:
    case kIA32F32x4Le:
    case kIA32F32x4Qfma:
    case kIA32F32x4Qfms:
    case kIA32Minps:
    case kIA32Maxps:
    case kIA32F32x4Round:
    case kIA32F32x4DemoteF64x2Zero:
    case kIA32I32x4Splat:
    case kIA32I32x4ExtractLane:
    case kIA32I32x4SConvertF32x4:
    case kIA32I32x4SConvertI16x8Low:
    case kIA32I32x4SConvertI16x8High:
    case kIA32I32x4Neg:
    case kIA32I32x4Shl:
    case kIA32I32x4ShrS:
    case kIA32I32x4Add:
    case kIA32I32x4Sub:
    case kIA32I32x4Mul:
    case kIA32I32x4MinS:
    case kIA32I32x4MaxS:
    case kIA32I32x4Eq:
    case kIA32I32x4Ne:
    case kIA32I32x4GtS:
    case kIA32I32x4GeS:
    case kSSEI32x4UConvertF32x4:
    case kAVXI32x4UConvertF32x4:
    case kIA32I32x4UConvertI16x8Low:
    case kIA32I32x4UConvertI16x8High:
    case kIA32I32x4ShrU:
    case kIA32I32x4MinU:
    case kIA32I32x4MaxU:
    case kSSEI32x4GtU:
    case kAVXI32x4GtU:
    case kSSEI32x4GeU:
    case kAVXI32x4GeU:
    case kIA32I32x4Abs:
    case kIA32I32x4BitMask:
    case kIA32I32x4DotI16x8S:
    case kIA32I32x4ExtMulLowI16x8S:
    case kIA32I32x4ExtMulHighI16x8S:
    case kIA32I32x4ExtMulLowI16x8U:
    case kIA32I32x4ExtMulHighI16x8U:
    case kIA32I32x4ExtAddPairwiseI16x8S:
    case kIA32I32x4ExtAddPairwiseI16x8U:
    case kIA32I32x4TruncSatF64x2SZero:
    case kIA32I32x4TruncSatF64x2UZero:
    case kIA32I16x8Splat:
    case kIA32I16x8ExtractLaneS:
    case kIA32I16x8SConvertI8x16Low:
    case kIA32I16x8SConvertI8x16High:
    case kIA32I16x8Neg:
    case kIA32I16x8Shl:
    case kIA32I16x8ShrS:
    case kIA32I16x8SConvertI32x4:
    case kIA32I16x8Add:
    case kIA32I16x8AddSatS:
    case kIA32I16x8Sub:
    case kIA32I16x8SubSatS:
    case kIA32I16x8Mul:
    case kIA32I16x8MinS:
    case kIA32I16x8MaxS:
    case kIA32I16x8Eq:
    case kSSEI16x8Ne:
    case kAVXI16x8Ne:
    case kIA32I16x8GtS:
    case kSSEI16x8GeS:
    case kAVXI16x8GeS:
    case kIA32I16x8UConvertI8x16Low:
    case kIA32I16x8UConvertI8x16High:
    case kIA32I16x8ShrU:
    case kIA32I16x8UConvertI32x4:
    case kIA32I16x8AddSatU:
    case kIA32I16x8SubSatU:
    case kIA32I16x8MinU:
    case kIA32I16x8MaxU:
    case kSSEI16x8GtU:
    case kAVXI16x8GtU:
    case kSSEI16x8GeU:
    case kAVXI16x8GeU:
    case kIA32I16x8RoundingAverageU:
    case kIA32I16x8Abs:
    case kIA32I16x8BitMask:
    case kIA32I16x8ExtMulLowI8x16S:
    case kIA32I16x8ExtMulHighI8x16S:
    case kIA32I16x8ExtMulLowI8x16U:
    case kIA32I16x8ExtMulHighI8x16U:
    case kIA32I16x8ExtAddPairwiseI8x16S:
    case kIA32I16x8ExtAddPairwiseI8x16U:
    case kIA32I16x8Q15MulRSatS:
    case kIA32I16x8RelaxedQ15MulRS:
    case kIA32I16x8DotI8x16I7x16S:
    case kIA32I8x16Splat:
    case kIA32I8x16ExtractLaneS:
    case kIA32Pinsrb:
    case kIA32Pinsrw:
    case kIA32Pinsrd:
    case kIA32Pextrb:
    case kIA32Pextrw:
    case kIA32S128Store32Lane:
    case kIA32I8x16SConvertI16x8:
    case kIA32I8x16Neg:
    case kIA32I8x16Shl:
    case kIA32I8x16ShrS:
    case kIA32I8x16Add:
    case kIA32I8x16AddSatS:
    case kIA32I8x16Sub:
    case kIA32I8x16SubSatS:
    case kIA32I8x16MinS:
    case kIA32I8x16MaxS:
    case kIA32I8x16Eq:
    case kSSEI8x16Ne:
    case kAVXI8x16Ne:
    case kIA32I8x16GtS:
    case kSSEI8x16GeS:
    case kAVXI8x16GeS:
    case kIA32I8x16UConvertI16x8:
    case kIA32I8x16AddSatU:
    case kIA32I8x16SubSatU:
    case kIA32I8x16ShrU:
    case kIA32I8x16MinU:
    case kIA32I8x16MaxU:
    case kSSEI8x16GtU:
    case kAVXI8x16GtU:
    case kSSEI8x16GeU:
    case kAVXI8x16GeU:
    case kIA32I8x16RoundingAverageU:
    case kIA32I8x16Abs:
    case kIA32I8x16BitMask:
    case kIA32I8x16Popcnt:
    case kIA32S128Const:
    case kIA32S128Zero:
    case kIA32S128AllOnes:
    case kIA32S128Not:
    case kIA32S128And:
    case kIA32S128Or:
    case kIA32S128Xor:
    case kIA32S128Select:
    case kIA32S128AndNot:
    case kIA32I8x16Swizzle:
    case kIA32I8x16Shuffle:
    case kIA32S32x4Rotate:
    case kIA32S32x4Swizzle:
    case kIA32S32x4Shuffle:
    case kIA32S16x8Blend:
    case kIA32S16x8HalfShuffle1:
    case kIA32S16x8HalfShuffle2:
    case kIA32S8x16Alignr:
    case kIA32S16x8Dup:
    case kIA32S8x16Dup:
    case kSSES16x8UnzipHigh:
    case kAVXS16x8UnzipHigh:
    case kSSES16x8UnzipLow:
    case kAVXS16x8UnzipLow:
    case kSSES8x16UnzipHigh:
    case kAVXS8x16UnzipHigh:
    case kSSES8x16UnzipLow:
    case kAVXS8x16UnzipLow:
    case kIA32S64x2UnpackHigh:
    case kIA32S32x4UnpackHigh:
    case kIA32S16x8UnpackHigh:
    case kIA32S8x16UnpackHigh:
    case kIA32S64x2UnpackLow:
    case kIA32S32x4UnpackLow:
    case kIA32S16x8UnpackLow:
    case kIA32S8x16UnpackLow:
    case kSSES8x16TransposeLow:
    case kAVXS8x16TransposeLow:
    case kSSES8x16TransposeHigh:
    case kAVXS8x16TransposeHigh:
    case kSSES8x8Reverse:
    case kAVXS8x8Reverse:
    case kSSES8x4Reverse:
    case kAVXS8x4Reverse:
    case kSSES8x2Reverse:
    case kAVXS8x2Reverse:
    case kIA32S128AnyTrue:
    case kIA32I64x2AllTrue:
    case kIA32I32x4AllTrue:
    case kIA32I16x8AllTrue:
    case kIA32I8x16AllTrue:
      return (instr->addressing_mode() == kMode_None)
                 ? kNoOpcodeFlags
                 : kIsLoadOperation | kHasSideEffect;

    case kIA32Idiv:
    case kIA32Udiv:
      return (instr->addressing_mode() == kMode_None)
                 ? kMayNeedDeoptOrTrapCheck
                 : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect;

    case kIA32Movsxbl:
    case kIA32Movzxbl:
    case kIA32Movb:
    case kIA32Movsxwl:
    case kIA32Movzxwl:
    case kIA32Movw:
    case kIA32Movl:
    case kIA32Movss:
    case kIA32Movsd:
    case kIA32Movdqu:
    case kIA32Movlps:
    case kIA32Movhps:
    // Moves are used for memory load/store operations.
    case kIA32S128Load8Splat:
    case kIA32S128Load16Splat:
    case kIA32S128Load32Splat:
    case kIA32S128Load64Splat:
    case kIA32S128Load8x8S:
    case kIA32S128Load8x8U:
    case kIA32S128Load16x4S:
    case kIA32S128Load16x4U:
    case kIA32S128Load32x2S:
    case kIA32S128Load32x2U:
      return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;

    case kIA32Peek:
      return kIsLoadOperation;

    case kIA32Push:
    case kIA32Poke:
    case kIA32MFence:
    case kIA32LFence:
      return kHasSideEffect;

    case kIA32Word32AtomicPairLoad:
      return kIsLoadOperation;

    case kIA32Word32ReleasePairStore:
    case kIA32Word32SeqCstPairStore:
    case kIA32Word32AtomicPairAdd:
    case kIA32Word32AtomicPairSub:
    case kIA32Word32AtomicPairAnd:
    case kIA32Word32AtomicPairOr:
    case kIA32Word32AtomicPairXor:
    case kIA32Word32AtomicPairExchange:
    case kIA32Word32AtomicPairCompareExchange:
      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 ia32 instructions. They have been determined
  // in an empirical way.
  switch (instr->arch_opcode()) {
    case kFloat64Mul:
      return 5;
    case kIA32Imul:
    case kIA32ImulHigh:
      return 5;
    case kIA32Float32Cmp:
    case kIA32Float64Cmp:
      return 9;
    case kFloat32Add:
    case kFloat32Sub:
    case kFloat64Add:
    case kFloat64Sub:
    case kFloat32Abs:
    case kFloat32Neg:
    case kIA32Float64Max:
    case kIA32Float64Min:
    case kFloat64Abs:
    case kFloat64Neg:
      return 5;
    case kFloat32Mul:
      return 4;
    case kIA32Float32ToFloat64:
    case kIA32Float64ToFloat32:
      return 6;
    case kIA32Float32Round:
    case kIA32Float64Round:
    case kIA32Float32ToInt32:
    case kIA32Float64ToInt32:
      return 8;
    case kIA32Float32ToUint32:
      return 21;
    case kIA32Float64ToUint32:
      return 15;
    case kIA32Idiv:
      return 33;
    case kIA32Udiv:
      return 26;
    case kFloat32Div:
      return 35;
    case kFloat64Div:
      return 63;
    case kIA32Float32Sqrt:
    case kIA32Float64Sqrt:
      return 25;
    case kIA32Float64Mod:
      return 50;
    case kArchTruncateDoubleToI:
      return 9;
    default:
      return 1;
  }
}

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