instruction-scheduler-ia32.cc 11.5 KB
Newer Older
1 2 3 4
// 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.

5
#include "src/compiler/backend/instruction-scheduler.h"
6 7 8 9 10 11 12 13 14 15 16 17 18

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:
19 20
    case kIA32Cmp16:
    case kIA32Cmp8:
21
    case kIA32Test:
22 23
    case kIA32Test16:
    case kIA32Test8:
24 25 26 27 28 29 30 31 32 33 34
    case kIA32Or:
    case kIA32Xor:
    case kIA32Sub:
    case kIA32Imul:
    case kIA32ImulHigh:
    case kIA32UmulHigh:
    case kIA32Not:
    case kIA32Neg:
    case kIA32Shl:
    case kIA32Shr:
    case kIA32Sar:
35
    case kIA32AddPair:
36
    case kIA32SubPair:
37
    case kIA32MulPair:
38 39 40
    case kIA32ShlPair:
    case kIA32ShrPair:
    case kIA32SarPair:
41 42 43 44
    case kIA32Ror:
    case kIA32Lzcnt:
    case kIA32Tzcnt:
    case kIA32Popcnt:
45
    case kIA32Bswap:
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
    case kIA32Lea:
    case kSSEFloat32Cmp:
    case kSSEFloat32Add:
    case kSSEFloat32Sub:
    case kSSEFloat32Mul:
    case kSSEFloat32Div:
    case kSSEFloat32Abs:
    case kSSEFloat32Neg:
    case kSSEFloat32Sqrt:
    case kSSEFloat32Round:
    case kSSEFloat64Cmp:
    case kSSEFloat64Add:
    case kSSEFloat64Sub:
    case kSSEFloat64Mul:
    case kSSEFloat64Div:
    case kSSEFloat64Mod:
62
    case kSSEFloat32Max:
63
    case kSSEFloat64Max:
64
    case kSSEFloat32Min:
65 66 67 68 69 70 71
    case kSSEFloat64Min:
    case kSSEFloat64Abs:
    case kSSEFloat64Neg:
    case kSSEFloat64Sqrt:
    case kSSEFloat64Round:
    case kSSEFloat32ToFloat64:
    case kSSEFloat64ToFloat32:
72
    case kSSEFloat32ToInt32:
73
    case kSSEFloat32ToUint32:
74 75
    case kSSEFloat64ToInt32:
    case kSSEFloat64ToUint32:
76
    case kSSEInt32ToFloat32:
77
    case kSSEUint32ToFloat32:
78 79 80 81 82 83 84
    case kSSEInt32ToFloat64:
    case kSSEUint32ToFloat64:
    case kSSEFloat64ExtractLowWord32:
    case kSSEFloat64ExtractHighWord32:
    case kSSEFloat64InsertLowWord32:
    case kSSEFloat64InsertHighWord32:
    case kSSEFloat64LoadLowWord32:
85
    case kSSEFloat64SilenceNaN:
86 87 88 89 90 91 92 93 94 95 96 97 98 99
    case kAVXFloat32Add:
    case kAVXFloat32Sub:
    case kAVXFloat32Mul:
    case kAVXFloat32Div:
    case kAVXFloat64Add:
    case kAVXFloat64Sub:
    case kAVXFloat64Mul:
    case kAVXFloat64Div:
    case kAVXFloat64Abs:
    case kAVXFloat64Neg:
    case kAVXFloat32Abs:
    case kAVXFloat32Neg:
    case kIA32BitcastFI:
    case kIA32BitcastIF:
100 101 102 103 104 105
    case kSSEF32x4Splat:
    case kAVXF32x4Splat:
    case kSSEF32x4ExtractLane:
    case kAVXF32x4ExtractLane:
    case kSSEF32x4ReplaceLane:
    case kAVXF32x4ReplaceLane:
106 107 108
    case kIA32F32x4SConvertI32x4:
    case kSSEF32x4UConvertI32x4:
    case kAVXF32x4UConvertI32x4:
109 110 111 112
    case kSSEF32x4Abs:
    case kAVXF32x4Abs:
    case kSSEF32x4Neg:
    case kAVXF32x4Neg:
113 114
    case kIA32F32x4RecipApprox:
    case kIA32F32x4RecipSqrtApprox:
115 116
    case kSSEF32x4Add:
    case kAVXF32x4Add:
117 118
    case kSSEF32x4AddHoriz:
    case kAVXF32x4AddHoriz:
119 120 121 122 123 124 125 126
    case kSSEF32x4Sub:
    case kAVXF32x4Sub:
    case kSSEF32x4Mul:
    case kAVXF32x4Mul:
    case kSSEF32x4Min:
    case kAVXF32x4Min:
    case kSSEF32x4Max:
    case kAVXF32x4Max:
127 128 129 130 131 132 133 134
    case kSSEF32x4Eq:
    case kAVXF32x4Eq:
    case kSSEF32x4Ne:
    case kAVXF32x4Ne:
    case kSSEF32x4Lt:
    case kAVXF32x4Lt:
    case kSSEF32x4Le:
    case kAVXF32x4Le:
135 136
    case kIA32I32x4Splat:
    case kIA32I32x4ExtractLane:
137 138
    case kSSEI32x4ReplaceLane:
    case kAVXI32x4ReplaceLane:
139 140
    case kSSEI32x4SConvertF32x4:
    case kAVXI32x4SConvertF32x4:
141 142
    case kIA32I32x4SConvertI16x8Low:
    case kIA32I32x4SConvertI16x8High:
143
    case kIA32I32x4Neg:
144 145 146 147
    case kSSEI32x4Shl:
    case kAVXI32x4Shl:
    case kSSEI32x4ShrS:
    case kAVXI32x4ShrS:
148
    case kSSEI32x4Add:
149
    case kAVXI32x4Add:
150 151
    case kSSEI32x4AddHoriz:
    case kAVXI32x4AddHoriz:
152
    case kSSEI32x4Sub:
153
    case kAVXI32x4Sub:
154 155 156 157 158 159
    case kSSEI32x4Mul:
    case kAVXI32x4Mul:
    case kSSEI32x4MinS:
    case kAVXI32x4MinS:
    case kSSEI32x4MaxS:
    case kAVXI32x4MaxS:
160 161 162 163 164 165 166 167
    case kSSEI32x4Eq:
    case kAVXI32x4Eq:
    case kSSEI32x4Ne:
    case kAVXI32x4Ne:
    case kSSEI32x4GtS:
    case kAVXI32x4GtS:
    case kSSEI32x4GeS:
    case kAVXI32x4GeS:
168 169
    case kSSEI32x4UConvertF32x4:
    case kAVXI32x4UConvertF32x4:
170 171
    case kIA32I32x4UConvertI16x8Low:
    case kIA32I32x4UConvertI16x8High:
172 173 174 175 176 177
    case kSSEI32x4ShrU:
    case kAVXI32x4ShrU:
    case kSSEI32x4MinU:
    case kAVXI32x4MinU:
    case kSSEI32x4MaxU:
    case kAVXI32x4MaxU:
178 179 180 181
    case kSSEI32x4GtU:
    case kAVXI32x4GtU:
    case kSSEI32x4GeU:
    case kAVXI32x4GeU:
182 183 184 185
    case kIA32I16x8Splat:
    case kIA32I16x8ExtractLane:
    case kSSEI16x8ReplaceLane:
    case kAVXI16x8ReplaceLane:
186 187
    case kIA32I16x8SConvertI8x16Low:
    case kIA32I16x8SConvertI8x16High:
188
    case kIA32I16x8Neg:
189 190 191 192
    case kSSEI16x8Shl:
    case kAVXI16x8Shl:
    case kSSEI16x8ShrS:
    case kAVXI16x8ShrS:
193 194
    case kSSEI16x8SConvertI32x4:
    case kAVXI16x8SConvertI32x4:
195 196 197 198
    case kSSEI16x8Add:
    case kAVXI16x8Add:
    case kSSEI16x8AddSaturateS:
    case kAVXI16x8AddSaturateS:
199 200
    case kSSEI16x8AddHoriz:
    case kAVXI16x8AddHoriz:
201 202 203 204
    case kSSEI16x8Sub:
    case kAVXI16x8Sub:
    case kSSEI16x8SubSaturateS:
    case kAVXI16x8SubSaturateS:
205 206 207 208 209 210 211 212 213 214
    case kSSEI16x8Mul:
    case kAVXI16x8Mul:
    case kSSEI16x8MinS:
    case kAVXI16x8MinS:
    case kSSEI16x8MaxS:
    case kAVXI16x8MaxS:
    case kSSEI16x8Eq:
    case kAVXI16x8Eq:
    case kSSEI16x8Ne:
    case kAVXI16x8Ne:
215 216 217 218
    case kSSEI16x8GtS:
    case kAVXI16x8GtS:
    case kSSEI16x8GeS:
    case kAVXI16x8GeS:
219 220
    case kIA32I16x8UConvertI8x16Low:
    case kIA32I16x8UConvertI8x16High:
221 222
    case kSSEI16x8ShrU:
    case kAVXI16x8ShrU:
223 224
    case kSSEI16x8UConvertI32x4:
    case kAVXI16x8UConvertI32x4:
225 226 227 228 229 230 231 232
    case kSSEI16x8AddSaturateU:
    case kAVXI16x8AddSaturateU:
    case kSSEI16x8SubSaturateU:
    case kAVXI16x8SubSaturateU:
    case kSSEI16x8MinU:
    case kAVXI16x8MinU:
    case kSSEI16x8MaxU:
    case kAVXI16x8MaxU:
233 234 235 236
    case kSSEI16x8GtU:
    case kAVXI16x8GtU:
    case kSSEI16x8GeU:
    case kAVXI16x8GeU:
237 238 239 240
    case kIA32I8x16Splat:
    case kIA32I8x16ExtractLane:
    case kSSEI8x16ReplaceLane:
    case kAVXI8x16ReplaceLane:
241 242
    case kSSEI8x16SConvertI16x8:
    case kAVXI8x16SConvertI16x8:
243
    case kIA32I8x16Neg:
244 245
    case kSSEI8x16Shl:
    case kAVXI8x16Shl:
246
    case kIA32I8x16ShrS:
247 248 249 250 251 252 253 254
    case kSSEI8x16Add:
    case kAVXI8x16Add:
    case kSSEI8x16AddSaturateS:
    case kAVXI8x16AddSaturateS:
    case kSSEI8x16Sub:
    case kAVXI8x16Sub:
    case kSSEI8x16SubSaturateS:
    case kAVXI8x16SubSaturateS:
255 256
    case kSSEI8x16Mul:
    case kAVXI8x16Mul:
257 258 259 260 261 262 263 264 265 266 267 268
    case kSSEI8x16MinS:
    case kAVXI8x16MinS:
    case kSSEI8x16MaxS:
    case kAVXI8x16MaxS:
    case kSSEI8x16Eq:
    case kAVXI8x16Eq:
    case kSSEI8x16Ne:
    case kAVXI8x16Ne:
    case kSSEI8x16GtS:
    case kAVXI8x16GtS:
    case kSSEI8x16GeS:
    case kAVXI8x16GeS:
269 270
    case kSSEI8x16UConvertI16x8:
    case kAVXI8x16UConvertI16x8:
271 272 273 274
    case kSSEI8x16AddSaturateU:
    case kAVXI8x16AddSaturateU:
    case kSSEI8x16SubSaturateU:
    case kAVXI8x16SubSaturateU:
275
    case kIA32I8x16ShrU:
276 277 278 279 280 281 282 283
    case kSSEI8x16MinU:
    case kAVXI8x16MinU:
    case kSSEI8x16MaxU:
    case kAVXI8x16MaxU:
    case kSSEI8x16GtU:
    case kAVXI8x16GtU:
    case kSSEI8x16GeU:
    case kAVXI8x16GeU:
284 285 286 287 288 289 290 291 292
    case kIA32S128Zero:
    case kSSES128Not:
    case kAVXS128Not:
    case kSSES128And:
    case kAVXS128And:
    case kSSES128Or:
    case kAVXS128Or:
    case kSSES128Xor:
    case kAVXS128Xor:
jing.bao's avatar
jing.bao committed
293 294
    case kSSES128Select:
    case kAVXS128Select:
295 296
    case kIA32S8x16Shuffle:
    case kIA32S32x4Swizzle:
297
    case kIA32S32x4Shuffle:
298
    case kIA32S16x8Blend:
299 300
    case kIA32S16x8HalfShuffle1:
    case kIA32S16x8HalfShuffle2:
301
    case kIA32S8x16Alignr:
302 303
    case kIA32S16x8Dup:
    case kIA32S8x16Dup:
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
    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:
324 325 326 327 328 329
    case kSSES8x8Reverse:
    case kAVXS8x8Reverse:
    case kSSES8x4Reverse:
    case kAVXS8x4Reverse:
    case kSSES8x2Reverse:
    case kAVXS8x2Reverse:
330 331 332 333 334 335
    case kIA32S1x4AnyTrue:
    case kIA32S1x4AllTrue:
    case kIA32S1x8AnyTrue:
    case kIA32S1x8AllTrue:
    case kIA32S1x16AnyTrue:
    case kIA32S1x16AllTrue:
336
      return (instr->addressing_mode() == kMode_None)
337 338
                 ? kNoOpcodeFlags
                 : kIsLoadOperation | kHasSideEffect;
339

340 341 342
    case kIA32Idiv:
    case kIA32Udiv:
      return (instr->addressing_mode() == kMode_None)
343 344
                 ? kMayNeedDeoptOrTrapCheck
                 : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect;
345

346 347 348 349 350 351 352 353 354
    case kIA32Movsxbl:
    case kIA32Movzxbl:
    case kIA32Movb:
    case kIA32Movsxwl:
    case kIA32Movzxwl:
    case kIA32Movw:
    case kIA32Movl:
    case kIA32Movss:
    case kIA32Movsd:
355
    case kIA32Movdqu:
356 357 358 359
      // Moves are used for memory load/store operations.
      return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;

    case kIA32StackCheck:
360
    case kIA32Peek:
361 362 363
      return kIsLoadOperation;

    case kIA32Push:
364 365
    case kIA32PushFloat32:
    case kIA32PushFloat64:
366
    case kIA32PushSimd128:
367
    case kIA32Poke:
368
    case kLFence:
369 370
      return kHasSideEffect;

371 372 373 374
    case kIA32Word32AtomicPairLoad:
      return kIsLoadOperation;

    case kIA32Word32AtomicPairStore:
375 376 377 378 379 380 381
    case kIA32Word32AtomicPairAdd:
    case kIA32Word32AtomicPairSub:
    case kIA32Word32AtomicPairAnd:
    case kIA32Word32AtomicPairOr:
    case kIA32Word32AtomicPairXor:
    case kIA32Word32AtomicPairExchange:
    case kIA32Word32AtomicPairCompareExchange:
382 383
      return kHasSideEffect;

384
#define CASE(Name) case k##Name:
385
      COMMON_ARCH_OPCODE_LIST(CASE)
386 387 388 389 390 391 392 393 394
#undef CASE
      // Already covered in architecture independent code.
      UNREACHABLE();
  }

  UNREACHABLE();
}

int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
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
  // Basic latency modeling for ia32 instructions. They have been determined
  // in an empirical way.
  switch (instr->arch_opcode()) {
    case kSSEFloat64Mul:
      return 5;
    case kIA32Imul:
    case kIA32ImulHigh:
      return 5;
    case kSSEFloat32Cmp:
    case kSSEFloat64Cmp:
      return 9;
    case kSSEFloat32Add:
    case kSSEFloat32Sub:
    case kSSEFloat32Abs:
    case kSSEFloat32Neg:
    case kSSEFloat64Add:
    case kSSEFloat64Sub:
    case kSSEFloat64Max:
    case kSSEFloat64Min:
    case kSSEFloat64Abs:
    case kSSEFloat64Neg:
      return 5;
    case kSSEFloat32Mul:
      return 4;
    case kSSEFloat32ToFloat64:
    case kSSEFloat64ToFloat32:
      return 6;
    case kSSEFloat32Round:
    case kSSEFloat64Round:
    case kSSEFloat32ToInt32:
    case kSSEFloat64ToInt32:
      return 8;
    case kSSEFloat32ToUint32:
      return 21;
    case kSSEFloat64ToUint32:
      return 15;
    case kIA32Idiv:
      return 33;
    case kIA32Udiv:
      return 26;
    case kSSEFloat32Div:
      return 35;
    case kSSEFloat64Div:
      return 63;
    case kSSEFloat32Sqrt:
    case kSSEFloat64Sqrt:
      return 25;
    case kSSEFloat64Mod:
      return 50;
    case kArchTruncateDoubleToI:
      return 9;
    default:
      return 1;
  }
449 450 451 452 453
}

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