summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/x64/instruction-scheduler-x64.cc
blob: b1f380badf3ac91f7907ec63682ce9d799dc9fae (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
// 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/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 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 kX64F32x4Splat:
    case kX64F32x4ExtractLane:
    case kX64F32x4ReplaceLane:
    case kX64F32x4RecipApprox:
    case kX64F32x4RecipSqrtApprox:
    case kX64F32x4Abs:
    case kX64F32x4Neg:
    case kX64F32x4Add:
    case kX64F32x4AddHoriz:
    case kX64F32x4Sub:
    case kX64F32x4Mul:
    case kX64F32x4Min:
    case kX64F32x4Max:
    case kX64F32x4Eq:
    case kX64F32x4Ne:
    case kX64F32x4Lt:
    case kX64F32x4Le:
    case kX64I32x4Splat:
    case kX64I32x4ExtractLane:
    case kX64I32x4ReplaceLane:
    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 kX64I32x4ShrU:
    case kX64I32x4MinU:
    case kX64I32x4MaxU:
    case kX64I32x4GtU:
    case kX64I32x4GeU:
    case kX64I16x8Splat:
    case kX64I16x8ExtractLane:
    case kX64I16x8ReplaceLane:
    case kX64I16x8Neg:
    case kX64I16x8Shl:
    case kX64I16x8ShrS:
    case kX64I16x8Add:
    case kX64I16x8AddSaturateS:
    case kX64I16x8AddHoriz:
    case kX64I16x8Sub:
    case kX64I16x8SubSaturateS:
    case kX64I16x8Mul:
    case kX64I16x8MinS:
    case kX64I16x8MaxS:
    case kX64I16x8Eq:
    case kX64I16x8Ne:
    case kX64I16x8GtS:
    case kX64I16x8GeS:
    case kX64I16x8ShrU:
    case kX64I16x8AddSaturateU:
    case kX64I16x8SubSaturateU:
    case kX64I16x8MinU:
    case kX64I16x8MaxU:
    case kX64I16x8GtU:
    case kX64I16x8GeU:
    case kX64I8x16Splat:
    case kX64I8x16ExtractLane:
    case kX64I8x16ReplaceLane:
    case kX64I8x16Neg:
    case kX64I8x16Add:
    case kX64I8x16AddSaturateS:
    case kX64I8x16Sub:
    case kX64I8x16SubSaturateS:
    case kX64I8x16MinS:
    case kX64I8x16MaxS:
    case kX64I8x16Eq:
    case kX64I8x16Ne:
    case kX64I8x16GtS:
    case kX64I8x16GeS:
    case kX64I8x16AddSaturateU:
    case kX64I8x16SubSaturateU:
    case kX64I8x16MinU:
    case kX64I8x16MaxU:
    case kX64I8x16GtU:
    case kX64I8x16GeU:
    case kX64S128And:
    case kX64S128Or:
    case kX64S128Xor:
    case kX64S128Not:
    case kX64S128Select:
    case kX64S128Zero:
      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:
      return kHasSideEffect;

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

    case kX64Movq:
    case kX64Movsd:
    case kX64Movss:
    case kX64Movdqu:
      return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;

    case kX64StackCheck:
    case kX64Peek:
      return kIsLoadOperation;

    case kX64Push:
    case kX64Poke:
      return kHasSideEffect;

    case kLFence:
      return kHasSideEffect;

    case kX64Word64AtomicLoadUint8:
    case kX64Word64AtomicLoadUint16:
    case kX64Word64AtomicLoadUint32:
    case kX64Word64AtomicLoadUint64:
      return kIsLoadOperation;

    case kX64Word64AtomicStoreWord8:
    case kX64Word64AtomicStoreWord16:
    case kX64Word64AtomicStoreWord32:
    case kX64Word64AtomicStoreWord64:
    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