Home | History | Annotate | Download | only in x64
      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/instruction-scheduler.h"
      6 
      7 namespace v8 {
      8 namespace internal {
      9 namespace compiler {
     10 
     11 bool InstructionScheduler::SchedulerSupported() { return true; }
     12 
     13 
     14 int InstructionScheduler::GetTargetInstructionFlags(
     15     const Instruction* instr) const {
     16   switch (instr->arch_opcode()) {
     17     case kX64Add:
     18     case kX64Add32:
     19     case kX64And:
     20     case kX64And32:
     21     case kX64Cmp:
     22     case kX64Cmp32:
     23     case kX64Cmp16:
     24     case kX64Cmp8:
     25     case kX64Test:
     26     case kX64Test32:
     27     case kX64Test16:
     28     case kX64Test8:
     29     case kX64Or:
     30     case kX64Or32:
     31     case kX64Xor:
     32     case kX64Xor32:
     33     case kX64Sub:
     34     case kX64Sub32:
     35     case kX64Imul:
     36     case kX64Imul32:
     37     case kX64ImulHigh32:
     38     case kX64UmulHigh32:
     39     case kX64Not:
     40     case kX64Not32:
     41     case kX64Neg:
     42     case kX64Neg32:
     43     case kX64Shl:
     44     case kX64Shl32:
     45     case kX64Shr:
     46     case kX64Shr32:
     47     case kX64Sar:
     48     case kX64Sar32:
     49     case kX64Ror:
     50     case kX64Ror32:
     51     case kX64Lzcnt:
     52     case kX64Lzcnt32:
     53     case kX64Tzcnt:
     54     case kX64Tzcnt32:
     55     case kX64Popcnt:
     56     case kX64Popcnt32:
     57     case kX64Bswap:
     58     case kX64Bswap32:
     59     case kSSEFloat32Cmp:
     60     case kSSEFloat32Add:
     61     case kSSEFloat32Sub:
     62     case kSSEFloat32Mul:
     63     case kSSEFloat32Div:
     64     case kSSEFloat32Abs:
     65     case kSSEFloat32Neg:
     66     case kSSEFloat32Sqrt:
     67     case kSSEFloat32Round:
     68     case kSSEFloat32ToFloat64:
     69     case kSSEFloat64Cmp:
     70     case kSSEFloat64Add:
     71     case kSSEFloat64Sub:
     72     case kSSEFloat64Mul:
     73     case kSSEFloat64Div:
     74     case kSSEFloat64Mod:
     75     case kSSEFloat64Abs:
     76     case kSSEFloat64Neg:
     77     case kSSEFloat64Sqrt:
     78     case kSSEFloat64Round:
     79     case kSSEFloat32Max:
     80     case kSSEFloat64Max:
     81     case kSSEFloat32Min:
     82     case kSSEFloat64Min:
     83     case kSSEFloat64ToFloat32:
     84     case kSSEFloat32ToInt32:
     85     case kSSEFloat32ToUint32:
     86     case kSSEFloat64ToInt32:
     87     case kSSEFloat64ToUint32:
     88     case kSSEFloat64ToInt64:
     89     case kSSEFloat32ToInt64:
     90     case kSSEFloat64ToUint64:
     91     case kSSEFloat32ToUint64:
     92     case kSSEInt32ToFloat64:
     93     case kSSEInt32ToFloat32:
     94     case kSSEInt64ToFloat32:
     95     case kSSEInt64ToFloat64:
     96     case kSSEUint64ToFloat32:
     97     case kSSEUint64ToFloat64:
     98     case kSSEUint32ToFloat64:
     99     case kSSEUint32ToFloat32:
    100     case kSSEFloat64ExtractLowWord32:
    101     case kSSEFloat64ExtractHighWord32:
    102     case kSSEFloat64InsertLowWord32:
    103     case kSSEFloat64InsertHighWord32:
    104     case kSSEFloat64LoadLowWord32:
    105     case kSSEFloat64SilenceNaN:
    106     case kAVXFloat32Cmp:
    107     case kAVXFloat32Add:
    108     case kAVXFloat32Sub:
    109     case kAVXFloat32Mul:
    110     case kAVXFloat32Div:
    111     case kAVXFloat64Cmp:
    112     case kAVXFloat64Add:
    113     case kAVXFloat64Sub:
    114     case kAVXFloat64Mul:
    115     case kAVXFloat64Div:
    116     case kAVXFloat64Abs:
    117     case kAVXFloat64Neg:
    118     case kAVXFloat32Abs:
    119     case kAVXFloat32Neg:
    120     case kX64BitcastFI:
    121     case kX64BitcastDL:
    122     case kX64BitcastIF:
    123     case kX64BitcastLD:
    124     case kX64Lea32:
    125     case kX64Lea:
    126     case kX64Dec32:
    127     case kX64Inc32:
    128     case kX64F32x4Splat:
    129     case kX64F32x4ExtractLane:
    130     case kX64F32x4ReplaceLane:
    131     case kX64F32x4RecipApprox:
    132     case kX64F32x4RecipSqrtApprox:
    133     case kX64F32x4Abs:
    134     case kX64F32x4Neg:
    135     case kX64F32x4Add:
    136     case kX64F32x4AddHoriz:
    137     case kX64F32x4Sub:
    138     case kX64F32x4Mul:
    139     case kX64F32x4Min:
    140     case kX64F32x4Max:
    141     case kX64F32x4Eq:
    142     case kX64F32x4Ne:
    143     case kX64F32x4Lt:
    144     case kX64F32x4Le:
    145     case kX64I32x4Splat:
    146     case kX64I32x4ExtractLane:
    147     case kX64I32x4ReplaceLane:
    148     case kX64I32x4Neg:
    149     case kX64I32x4Shl:
    150     case kX64I32x4ShrS:
    151     case kX64I32x4Add:
    152     case kX64I32x4AddHoriz:
    153     case kX64I32x4Sub:
    154     case kX64I32x4Mul:
    155     case kX64I32x4MinS:
    156     case kX64I32x4MaxS:
    157     case kX64I32x4Eq:
    158     case kX64I32x4Ne:
    159     case kX64I32x4GtS:
    160     case kX64I32x4GeS:
    161     case kX64I32x4ShrU:
    162     case kX64I32x4MinU:
    163     case kX64I32x4MaxU:
    164     case kX64I32x4GtU:
    165     case kX64I32x4GeU:
    166     case kX64I16x8Splat:
    167     case kX64I16x8ExtractLane:
    168     case kX64I16x8ReplaceLane:
    169     case kX64I16x8Neg:
    170     case kX64I16x8Shl:
    171     case kX64I16x8ShrS:
    172     case kX64I16x8Add:
    173     case kX64I16x8AddSaturateS:
    174     case kX64I16x8AddHoriz:
    175     case kX64I16x8Sub:
    176     case kX64I16x8SubSaturateS:
    177     case kX64I16x8Mul:
    178     case kX64I16x8MinS:
    179     case kX64I16x8MaxS:
    180     case kX64I16x8Eq:
    181     case kX64I16x8Ne:
    182     case kX64I16x8GtS:
    183     case kX64I16x8GeS:
    184     case kX64I16x8ShrU:
    185     case kX64I16x8AddSaturateU:
    186     case kX64I16x8SubSaturateU:
    187     case kX64I16x8MinU:
    188     case kX64I16x8MaxU:
    189     case kX64I16x8GtU:
    190     case kX64I16x8GeU:
    191     case kX64I8x16Splat:
    192     case kX64I8x16ExtractLane:
    193     case kX64I8x16ReplaceLane:
    194     case kX64I8x16Neg:
    195     case kX64I8x16Add:
    196     case kX64I8x16AddSaturateS:
    197     case kX64I8x16Sub:
    198     case kX64I8x16SubSaturateS:
    199     case kX64I8x16MinS:
    200     case kX64I8x16MaxS:
    201     case kX64I8x16Eq:
    202     case kX64I8x16Ne:
    203     case kX64I8x16GtS:
    204     case kX64I8x16GeS:
    205     case kX64I8x16AddSaturateU:
    206     case kX64I8x16SubSaturateU:
    207     case kX64I8x16MinU:
    208     case kX64I8x16MaxU:
    209     case kX64I8x16GtU:
    210     case kX64I8x16GeU:
    211     case kX64S128And:
    212     case kX64S128Or:
    213     case kX64S128Xor:
    214     case kX64S128Not:
    215     case kX64S128Select:
    216     case kX64S128Zero:
    217       return (instr->addressing_mode() == kMode_None)
    218           ? kNoOpcodeFlags
    219           : kIsLoadOperation | kHasSideEffect;
    220 
    221     case kX64Idiv:
    222     case kX64Idiv32:
    223     case kX64Udiv:
    224     case kX64Udiv32:
    225       return (instr->addressing_mode() == kMode_None)
    226                  ? kMayNeedDeoptOrTrapCheck
    227                  : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect;
    228 
    229     case kX64Movsxbl:
    230     case kX64Movzxbl:
    231     case kX64Movsxbq:
    232     case kX64Movzxbq:
    233     case kX64Movsxwl:
    234     case kX64Movzxwl:
    235     case kX64Movsxwq:
    236     case kX64Movzxwq:
    237     case kX64Movsxlq:
    238       DCHECK_LE(1, instr->InputCount());
    239       return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
    240                                              : kIsLoadOperation;
    241 
    242     case kX64Movb:
    243     case kX64Movw:
    244       return kHasSideEffect;
    245 
    246     case kX64Movl:
    247       if (instr->HasOutput()) {
    248         DCHECK_LE(1, instr->InputCount());
    249         return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
    250                                                : kIsLoadOperation;
    251       } else {
    252         return kHasSideEffect;
    253       }
    254 
    255     case kX64Movq:
    256     case kX64Movsd:
    257     case kX64Movss:
    258     case kX64Movdqu:
    259       return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
    260 
    261     case kX64StackCheck:
    262     case kX64Peek:
    263       return kIsLoadOperation;
    264 
    265     case kX64Push:
    266     case kX64Poke:
    267       return kHasSideEffect;
    268 
    269     case kLFence:
    270       return kHasSideEffect;
    271 
    272     case kX64Word64AtomicLoadUint8:
    273     case kX64Word64AtomicLoadUint16:
    274     case kX64Word64AtomicLoadUint32:
    275     case kX64Word64AtomicLoadUint64:
    276       return kIsLoadOperation;
    277 
    278     case kX64Word64AtomicStoreWord8:
    279     case kX64Word64AtomicStoreWord16:
    280     case kX64Word64AtomicStoreWord32:
    281     case kX64Word64AtomicStoreWord64:
    282     case kX64Word64AtomicAddUint8:
    283     case kX64Word64AtomicAddUint16:
    284     case kX64Word64AtomicAddUint32:
    285     case kX64Word64AtomicAddUint64:
    286     case kX64Word64AtomicSubUint8:
    287     case kX64Word64AtomicSubUint16:
    288     case kX64Word64AtomicSubUint32:
    289     case kX64Word64AtomicSubUint64:
    290     case kX64Word64AtomicAndUint8:
    291     case kX64Word64AtomicAndUint16:
    292     case kX64Word64AtomicAndUint32:
    293     case kX64Word64AtomicAndUint64:
    294     case kX64Word64AtomicOrUint8:
    295     case kX64Word64AtomicOrUint16:
    296     case kX64Word64AtomicOrUint32:
    297     case kX64Word64AtomicOrUint64:
    298     case kX64Word64AtomicXorUint8:
    299     case kX64Word64AtomicXorUint16:
    300     case kX64Word64AtomicXorUint32:
    301     case kX64Word64AtomicXorUint64:
    302     case kX64Word64AtomicExchangeUint8:
    303     case kX64Word64AtomicExchangeUint16:
    304     case kX64Word64AtomicExchangeUint32:
    305     case kX64Word64AtomicExchangeUint64:
    306     case kX64Word64AtomicCompareExchangeUint8:
    307     case kX64Word64AtomicCompareExchangeUint16:
    308     case kX64Word64AtomicCompareExchangeUint32:
    309     case kX64Word64AtomicCompareExchangeUint64:
    310       return kHasSideEffect;
    311 
    312 #define CASE(Name) case k##Name:
    313     COMMON_ARCH_OPCODE_LIST(CASE)
    314 #undef CASE
    315       // Already covered in architecture independent code.
    316       UNREACHABLE();
    317   }
    318 
    319   UNREACHABLE();
    320 }
    321 
    322 
    323 int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
    324   // Basic latency modeling for x64 instructions. They have been determined
    325   // in an empirical way.
    326   switch (instr->arch_opcode()) {
    327     case kSSEFloat64Mul:
    328       return 5;
    329     case kX64Imul:
    330     case kX64Imul32:
    331     case kX64ImulHigh32:
    332     case kX64UmulHigh32:
    333     case kSSEFloat32Cmp:
    334     case kSSEFloat32Add:
    335     case kSSEFloat32Sub:
    336     case kSSEFloat32Abs:
    337     case kSSEFloat32Neg:
    338     case kSSEFloat64Cmp:
    339     case kSSEFloat64Add:
    340     case kSSEFloat64Sub:
    341     case kSSEFloat64Max:
    342     case kSSEFloat64Min:
    343     case kSSEFloat64Abs:
    344     case kSSEFloat64Neg:
    345       return 3;
    346     case kSSEFloat32Mul:
    347     case kSSEFloat32ToFloat64:
    348     case kSSEFloat64ToFloat32:
    349     case kSSEFloat32Round:
    350     case kSSEFloat64Round:
    351     case kSSEFloat32ToInt32:
    352     case kSSEFloat32ToUint32:
    353     case kSSEFloat64ToInt32:
    354     case kSSEFloat64ToUint32:
    355       return 4;
    356     case kX64Idiv:
    357       return 49;
    358     case kX64Idiv32:
    359       return 35;
    360     case kX64Udiv:
    361       return 38;
    362     case kX64Udiv32:
    363       return 26;
    364     case kSSEFloat32Div:
    365     case kSSEFloat64Div:
    366     case kSSEFloat32Sqrt:
    367     case kSSEFloat64Sqrt:
    368       return 13;
    369     case kSSEFloat32ToInt64:
    370     case kSSEFloat64ToInt64:
    371     case kSSEFloat32ToUint64:
    372     case kSSEFloat64ToUint64:
    373       return 10;
    374     case kSSEFloat64Mod:
    375       return 50;
    376     case kArchTruncateDoubleToI:
    377       return 6;
    378     default:
    379       return 1;
    380   }
    381 }
    382 
    383 }  // namespace compiler
    384 }  // namespace internal
    385 }  // namespace v8
    386