Line data Source code
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 :
11 589423 : bool InstructionScheduler::SchedulerSupported() { return true; }
12 :
13 193329 : int InstructionScheduler::GetTargetInstructionFlags(
14 : const Instruction* instr) const {
15 193329 : 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 68475 : : 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 132 : : 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 18556 : : kIsLoadOperation;
298 :
299 : case kX64Movb:
300 : case kX64Movw:
301 : return kHasSideEffect;
302 :
303 : case kX64Movl:
304 11312 : if (instr->HasOutput()) {
305 : DCHECK_LE(1, instr->InputCount());
306 : return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
307 5884 : : 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 86363 : return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
321 :
322 : case kX64StackCheck:
323 : case kX64Peek:
324 0 : 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 0 : 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 0 : UNREACHABLE();
378 : }
379 :
380 0 : UNREACHABLE();
381 : }
382 :
383 325421 : int 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 121996 : } // namespace v8
|