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