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 581603 : bool InstructionScheduler::SchedulerSupported() { return true; }
12 :
13 196945 : int InstructionScheduler::GetTargetInstructionFlags(
14 : const Instruction* instr) const {
15 196945 : 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 : return (instr->addressing_mode() == kMode_None)
269 : ? kNoOpcodeFlags
270 72871 : : kIsLoadOperation | kHasSideEffect;
271 :
272 : case kX64Idiv:
273 : case kX64Idiv32:
274 : case kX64Udiv:
275 : case kX64Udiv32:
276 : return (instr->addressing_mode() == kMode_None)
277 : ? kMayNeedDeoptOrTrapCheck
278 140 : : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect;
279 :
280 : case kX64Movsxbl:
281 : case kX64Movzxbl:
282 : case kX64Movsxbq:
283 : case kX64Movzxbq:
284 : case kX64Movsxwl:
285 : case kX64Movzxwl:
286 : case kX64Movsxwq:
287 : case kX64Movzxwq:
288 : case kX64Movsxlq:
289 : DCHECK_LE(1, instr->InputCount());
290 15496 : return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
291 15496 : : kIsLoadOperation;
292 :
293 : case kX64Movb:
294 : case kX64Movw:
295 : return kHasSideEffect;
296 :
297 : case kX64Movl:
298 11624 : if (instr->HasOutput()) {
299 : DCHECK_LE(1, instr->InputCount());
300 5980 : return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
301 5980 : : kIsLoadOperation;
302 : } else {
303 : return kHasSideEffect;
304 : }
305 :
306 : case kX64MovqDecompressTaggedSigned:
307 : case kX64MovqDecompressTaggedPointer:
308 : case kX64MovqDecompressAnyTagged:
309 : case kX64Movq:
310 : case kX64Movsd:
311 : case kX64Movss:
312 : case kX64Movdqu:
313 86861 : return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
314 :
315 : case kX64StackCheck:
316 : case kX64Peek:
317 0 : return kIsLoadOperation;
318 :
319 : case kX64Push:
320 : case kX64Poke:
321 : return kHasSideEffect;
322 :
323 : case kLFence:
324 : return kHasSideEffect;
325 :
326 : case kX64Word64AtomicLoadUint8:
327 : case kX64Word64AtomicLoadUint16:
328 : case kX64Word64AtomicLoadUint32:
329 : case kX64Word64AtomicLoadUint64:
330 0 : return kIsLoadOperation;
331 :
332 : case kX64Word64AtomicStoreWord8:
333 : case kX64Word64AtomicStoreWord16:
334 : case kX64Word64AtomicStoreWord32:
335 : case kX64Word64AtomicStoreWord64:
336 : case kX64Word64AtomicAddUint8:
337 : case kX64Word64AtomicAddUint16:
338 : case kX64Word64AtomicAddUint32:
339 : case kX64Word64AtomicAddUint64:
340 : case kX64Word64AtomicSubUint8:
341 : case kX64Word64AtomicSubUint16:
342 : case kX64Word64AtomicSubUint32:
343 : case kX64Word64AtomicSubUint64:
344 : case kX64Word64AtomicAndUint8:
345 : case kX64Word64AtomicAndUint16:
346 : case kX64Word64AtomicAndUint32:
347 : case kX64Word64AtomicAndUint64:
348 : case kX64Word64AtomicOrUint8:
349 : case kX64Word64AtomicOrUint16:
350 : case kX64Word64AtomicOrUint32:
351 : case kX64Word64AtomicOrUint64:
352 : case kX64Word64AtomicXorUint8:
353 : case kX64Word64AtomicXorUint16:
354 : case kX64Word64AtomicXorUint32:
355 : case kX64Word64AtomicXorUint64:
356 : case kX64Word64AtomicExchangeUint8:
357 : case kX64Word64AtomicExchangeUint16:
358 : case kX64Word64AtomicExchangeUint32:
359 : case kX64Word64AtomicExchangeUint64:
360 : case kX64Word64AtomicCompareExchangeUint8:
361 : case kX64Word64AtomicCompareExchangeUint16:
362 : case kX64Word64AtomicCompareExchangeUint32:
363 : case kX64Word64AtomicCompareExchangeUint64:
364 : return kHasSideEffect;
365 :
366 : #define CASE(Name) case k##Name:
367 : COMMON_ARCH_OPCODE_LIST(CASE)
368 : #undef CASE
369 : // Already covered in architecture independent code.
370 0 : UNREACHABLE();
371 : }
372 :
373 0 : UNREACHABLE();
374 : }
375 :
376 322918 : int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
377 : // Basic latency modeling for x64 instructions. They have been determined
378 : // in an empirical way.
379 322918 : switch (instr->arch_opcode()) {
380 : case kSSEFloat64Mul:
381 : return 5;
382 : case kX64Imul:
383 : case kX64Imul32:
384 : case kX64ImulHigh32:
385 : case kX64UmulHigh32:
386 : case kSSEFloat32Cmp:
387 : case kSSEFloat32Add:
388 : case kSSEFloat32Sub:
389 : case kSSEFloat32Abs:
390 : case kSSEFloat32Neg:
391 : case kSSEFloat64Cmp:
392 : case kSSEFloat64Add:
393 : case kSSEFloat64Sub:
394 : case kSSEFloat64Max:
395 : case kSSEFloat64Min:
396 : case kSSEFloat64Abs:
397 : case kSSEFloat64Neg:
398 : return 3;
399 : case kSSEFloat32Mul:
400 : case kSSEFloat32ToFloat64:
401 : case kSSEFloat64ToFloat32:
402 : case kSSEFloat32Round:
403 : case kSSEFloat64Round:
404 : case kSSEFloat32ToInt32:
405 : case kSSEFloat32ToUint32:
406 : case kSSEFloat64ToInt32:
407 : case kSSEFloat64ToUint32:
408 : return 4;
409 : case kX64Idiv:
410 : return 49;
411 : case kX64Idiv32:
412 : return 35;
413 : case kX64Udiv:
414 : return 38;
415 : case kX64Udiv32:
416 : return 26;
417 : case kSSEFloat32Div:
418 : case kSSEFloat64Div:
419 : case kSSEFloat32Sqrt:
420 : case kSSEFloat64Sqrt:
421 : return 13;
422 : case kSSEFloat32ToInt64:
423 : case kSSEFloat64ToInt64:
424 : case kSSEFloat32ToUint64:
425 : case kSSEFloat64ToUint64:
426 : return 10;
427 : case kSSEFloat64Mod:
428 : return 50;
429 : case kArchTruncateDoubleToI:
430 : return 6;
431 : default:
432 : return 1;
433 : }
434 : }
435 :
436 : } // namespace compiler
437 : } // namespace internal
438 183867 : } // namespace v8
|