Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 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/common-operator.h"
      6 
      7 #include "src/assembler.h"
      8 #include "src/base/lazy-instance.h"
      9 #include "src/compiler/linkage.h"
     10 #include "src/compiler/opcodes.h"
     11 #include "src/compiler/operator.h"
     12 #include "src/handles-inl.h"
     13 #include "src/zone.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 namespace compiler {
     18 
     19 std::ostream& operator<<(std::ostream& os, BranchHint hint) {
     20   switch (hint) {
     21     case BranchHint::kNone:
     22       return os << "None";
     23     case BranchHint::kTrue:
     24       return os << "True";
     25     case BranchHint::kFalse:
     26       return os << "False";
     27   }
     28   UNREACHABLE();
     29   return os;
     30 }
     31 
     32 
     33 BranchHint BranchHintOf(const Operator* const op) {
     34   DCHECK_EQ(IrOpcode::kBranch, op->opcode());
     35   return OpParameter<BranchHint>(op);
     36 }
     37 
     38 
     39 size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); }
     40 
     41 
     42 std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
     43   switch (kind) {
     44     case DeoptimizeKind::kEager:
     45       return os << "Eager";
     46     case DeoptimizeKind::kSoft:
     47       return os << "Soft";
     48   }
     49   UNREACHABLE();
     50   return os;
     51 }
     52 
     53 
     54 DeoptimizeKind DeoptimizeKindOf(const Operator* const op) {
     55   DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode());
     56   return OpParameter<DeoptimizeKind>(op);
     57 }
     58 
     59 
     60 size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); }
     61 
     62 
     63 std::ostream& operator<<(std::ostream& os, IfExceptionHint hint) {
     64   switch (hint) {
     65     case IfExceptionHint::kLocallyCaught:
     66       return os << "Caught";
     67     case IfExceptionHint::kLocallyUncaught:
     68       return os << "Uncaught";
     69   }
     70   UNREACHABLE();
     71   return os;
     72 }
     73 
     74 
     75 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
     76   return lhs.representation() == rhs.representation() &&
     77          lhs.hint() == rhs.hint();
     78 }
     79 
     80 
     81 bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
     82   return !(lhs == rhs);
     83 }
     84 
     85 
     86 size_t hash_value(SelectParameters const& p) {
     87   return base::hash_combine(p.representation(), p.hint());
     88 }
     89 
     90 
     91 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
     92   return os << p.representation() << "|" << p.hint();
     93 }
     94 
     95 
     96 SelectParameters const& SelectParametersOf(const Operator* const op) {
     97   DCHECK_EQ(IrOpcode::kSelect, op->opcode());
     98   return OpParameter<SelectParameters>(op);
     99 }
    100 
    101 
    102 size_t ProjectionIndexOf(const Operator* const op) {
    103   DCHECK_EQ(IrOpcode::kProjection, op->opcode());
    104   return OpParameter<size_t>(op);
    105 }
    106 
    107 
    108 MachineRepresentation PhiRepresentationOf(const Operator* const op) {
    109   DCHECK_EQ(IrOpcode::kPhi, op->opcode());
    110   return OpParameter<MachineRepresentation>(op);
    111 }
    112 
    113 
    114 int ParameterIndexOf(const Operator* const op) {
    115   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
    116   return OpParameter<ParameterInfo>(op).index();
    117 }
    118 
    119 
    120 const ParameterInfo& ParameterInfoOf(const Operator* const op) {
    121   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
    122   return OpParameter<ParameterInfo>(op);
    123 }
    124 
    125 
    126 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
    127   return lhs.index() == rhs.index();
    128 }
    129 
    130 
    131 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
    132   return !(lhs == rhs);
    133 }
    134 
    135 
    136 size_t hash_value(ParameterInfo const& p) { return p.index(); }
    137 
    138 
    139 std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
    140   if (i.debug_name()) os << i.debug_name() << '#';
    141   os << i.index();
    142   return os;
    143 }
    144 
    145 
    146 #define CACHED_OP_LIST(V)                                  \
    147   V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1)           \
    148   V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1)          \
    149   V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1)         \
    150   V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1)       \
    151   V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1)       \
    152   V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1)           \
    153   V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1)       \
    154   V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
    155   V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1)   \
    156   V(BeginRegion, Operator::kNoThrow, 0, 1, 0, 0, 1, 0)     \
    157   V(FinishRegion, Operator::kNoThrow, 1, 1, 0, 1, 1, 0)
    158 
    159 
    160 #define CACHED_RETURN_LIST(V) \
    161   V(1)                        \
    162   V(2)                        \
    163   V(3)
    164 
    165 
    166 #define CACHED_END_LIST(V) \
    167   V(1)                     \
    168   V(2)                     \
    169   V(3)                     \
    170   V(4)                     \
    171   V(5)                     \
    172   V(6)                     \
    173   V(7)                     \
    174   V(8)
    175 
    176 
    177 #define CACHED_EFFECT_PHI_LIST(V) \
    178   V(1)                            \
    179   V(2)                            \
    180   V(3)                            \
    181   V(4)                            \
    182   V(5)                            \
    183   V(6)
    184 
    185 
    186 #define CACHED_LOOP_LIST(V) \
    187   V(1)                      \
    188   V(2)
    189 
    190 
    191 #define CACHED_MERGE_LIST(V) \
    192   V(1)                       \
    193   V(2)                       \
    194   V(3)                       \
    195   V(4)                       \
    196   V(5)                       \
    197   V(6)                       \
    198   V(7)                       \
    199   V(8)
    200 
    201 
    202 #define CACHED_PARAMETER_LIST(V) \
    203   V(0)                           \
    204   V(1)                           \
    205   V(2)                           \
    206   V(3)                           \
    207   V(4)                           \
    208   V(5)                           \
    209   V(6)
    210 
    211 
    212 #define CACHED_PHI_LIST(V) \
    213   V(kTagged, 1)            \
    214   V(kTagged, 2)            \
    215   V(kTagged, 3)            \
    216   V(kTagged, 4)            \
    217   V(kTagged, 5)            \
    218   V(kTagged, 6)            \
    219   V(kBit, 2)               \
    220   V(kFloat64, 2)           \
    221   V(kWord32, 2)
    222 
    223 
    224 #define CACHED_PROJECTION_LIST(V) \
    225   V(0)                            \
    226   V(1)
    227 
    228 
    229 #define CACHED_STATE_VALUES_LIST(V) \
    230   V(0)                              \
    231   V(1)                              \
    232   V(2)                              \
    233   V(3)                              \
    234   V(4)                              \
    235   V(5)                              \
    236   V(6)                              \
    237   V(7)                              \
    238   V(8)                              \
    239   V(10)                             \
    240   V(11)                             \
    241   V(12)                             \
    242   V(13)                             \
    243   V(14)
    244 
    245 
    246 struct CommonOperatorGlobalCache final {
    247 #define CACHED(Name, properties, value_input_count, effect_input_count,      \
    248                control_input_count, value_output_count, effect_output_count, \
    249                control_output_count)                                         \
    250   struct Name##Operator final : public Operator {                            \
    251     Name##Operator()                                                         \
    252         : Operator(IrOpcode::k##Name, properties, #Name, value_input_count,  \
    253                    effect_input_count, control_input_count,                  \
    254                    value_output_count, effect_output_count,                  \
    255                    control_output_count) {}                                  \
    256   };                                                                         \
    257   Name##Operator k##Name##Operator;
    258   CACHED_OP_LIST(CACHED)
    259 #undef CACHED
    260 
    261   template <DeoptimizeKind kKind>
    262   struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> {
    263     DeoptimizeOperator()
    264         : Operator1<DeoptimizeKind>(                      // --
    265               IrOpcode::kDeoptimize, Operator::kNoThrow,  // opcode
    266               "Deoptimize",                               // name
    267               1, 1, 1, 0, 0, 1,                           // counts
    268               kKind) {}                                   // parameter
    269   };
    270   DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator;
    271   DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator;
    272 
    273   template <IfExceptionHint kCaughtLocally>
    274   struct IfExceptionOperator final : public Operator1<IfExceptionHint> {
    275     IfExceptionOperator()
    276         : Operator1<IfExceptionHint>(                      // --
    277               IrOpcode::kIfException, Operator::kKontrol,  // opcode
    278               "IfException",                               // name
    279               0, 1, 1, 1, 1, 1,                            // counts
    280               kCaughtLocally) {}                           // parameter
    281   };
    282   IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator;
    283   IfExceptionOperator<IfExceptionHint::kLocallyUncaught> kIfExceptionUOperator;
    284 
    285   template <size_t kInputCount>
    286   struct EndOperator final : public Operator {
    287     EndOperator()
    288         : Operator(                                // --
    289               IrOpcode::kEnd, Operator::kKontrol,  // opcode
    290               "End",                               // name
    291               0, 0, kInputCount, 0, 0, 0) {}       // counts
    292   };
    293 #define CACHED_END(input_count) \
    294   EndOperator<input_count> kEnd##input_count##Operator;
    295   CACHED_END_LIST(CACHED_END)
    296 #undef CACHED_END
    297 
    298   template <size_t kInputCount>
    299   struct ReturnOperator final : public Operator {
    300     ReturnOperator()
    301         : Operator(                                   // --
    302               IrOpcode::kReturn, Operator::kNoThrow,  // opcode
    303               "Return",                               // name
    304               kInputCount, 1, 1, 0, 0, 1) {}          // counts
    305   };
    306 #define CACHED_RETURN(input_count) \
    307   ReturnOperator<input_count> kReturn##input_count##Operator;
    308   CACHED_RETURN_LIST(CACHED_RETURN)
    309 #undef CACHED_RETURN
    310 
    311   template <BranchHint kBranchHint>
    312   struct BranchOperator final : public Operator1<BranchHint> {
    313     BranchOperator()
    314         : Operator1<BranchHint>(                      // --
    315               IrOpcode::kBranch, Operator::kKontrol,  // opcode
    316               "Branch",                               // name
    317               1, 0, 1, 0, 0, 2,                       // counts
    318               kBranchHint) {}                         // parameter
    319   };
    320   BranchOperator<BranchHint::kNone> kBranchNoneOperator;
    321   BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
    322   BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
    323 
    324   template <int kEffectInputCount>
    325   struct EffectPhiOperator final : public Operator {
    326     EffectPhiOperator()
    327         : Operator(                                   // --
    328               IrOpcode::kEffectPhi, Operator::kPure,  // opcode
    329               "EffectPhi",                            // name
    330               0, kEffectInputCount, 1, 0, 1, 0) {}    // counts
    331   };
    332 #define CACHED_EFFECT_PHI(input_count) \
    333   EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
    334   CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
    335 #undef CACHED_EFFECT_PHI
    336 
    337   template <size_t kInputCount>
    338   struct LoopOperator final : public Operator {
    339     LoopOperator()
    340         : Operator(                                 // --
    341               IrOpcode::kLoop, Operator::kKontrol,  // opcode
    342               "Loop",                               // name
    343               0, 0, kInputCount, 0, 0, 1) {}        // counts
    344   };
    345 #define CACHED_LOOP(input_count) \
    346   LoopOperator<input_count> kLoop##input_count##Operator;
    347   CACHED_LOOP_LIST(CACHED_LOOP)
    348 #undef CACHED_LOOP
    349 
    350   template <size_t kInputCount>
    351   struct MergeOperator final : public Operator {
    352     MergeOperator()
    353         : Operator(                                  // --
    354               IrOpcode::kMerge, Operator::kKontrol,  // opcode
    355               "Merge",                               // name
    356               0, 0, kInputCount, 0, 0, 1) {}         // counts
    357   };
    358 #define CACHED_MERGE(input_count) \
    359   MergeOperator<input_count> kMerge##input_count##Operator;
    360   CACHED_MERGE_LIST(CACHED_MERGE)
    361 #undef CACHED_MERGE
    362 
    363   template <MachineRepresentation kRep, int kInputCount>
    364   struct PhiOperator final : public Operator1<MachineRepresentation> {
    365     PhiOperator()
    366         : Operator1<MachineRepresentation>(     //--
    367               IrOpcode::kPhi, Operator::kPure,  // opcode
    368               "Phi",                            // name
    369               kInputCount, 0, 1, 1, 0, 0,       // counts
    370               kRep) {}                          // parameter
    371   };
    372 #define CACHED_PHI(rep, input_count)                   \
    373   PhiOperator<MachineRepresentation::rep, input_count> \
    374       kPhi##rep##input_count##Operator;
    375   CACHED_PHI_LIST(CACHED_PHI)
    376 #undef CACHED_PHI
    377 
    378   template <int kIndex>
    379   struct ParameterOperator final : public Operator1<ParameterInfo> {
    380     ParameterOperator()
    381         : Operator1<ParameterInfo>(                   // --
    382               IrOpcode::kParameter, Operator::kPure,  // opcode
    383               "Parameter",                            // name
    384               1, 0, 0, 1, 0, 0,                       // counts,
    385               ParameterInfo(kIndex, nullptr)) {}      // parameter and name
    386   };
    387 #define CACHED_PARAMETER(index) \
    388   ParameterOperator<index> kParameter##index##Operator;
    389   CACHED_PARAMETER_LIST(CACHED_PARAMETER)
    390 #undef CACHED_PARAMETER
    391 
    392   template <size_t kIndex>
    393   struct ProjectionOperator final : public Operator1<size_t> {
    394     ProjectionOperator()
    395         : Operator1<size_t>(          // --
    396               IrOpcode::kProjection,  // opcode
    397               Operator::kPure,        // flags
    398               "Projection",           // name
    399               1, 0, 0, 1, 0, 0,       // counts,
    400               kIndex) {}              // parameter
    401   };
    402 #define CACHED_PROJECTION(index) \
    403   ProjectionOperator<index> kProjection##index##Operator;
    404   CACHED_PROJECTION_LIST(CACHED_PROJECTION)
    405 #undef CACHED_PROJECTION
    406 
    407   template <int kInputCount>
    408   struct StateValuesOperator final : public Operator {
    409     StateValuesOperator()
    410         : Operator(                           // --
    411               IrOpcode::kStateValues,         // opcode
    412               Operator::kPure,                // flags
    413               "StateValues",                  // name
    414               kInputCount, 0, 0, 1, 0, 0) {}  // counts
    415   };
    416 #define CACHED_STATE_VALUES(input_count) \
    417   StateValuesOperator<input_count> kStateValues##input_count##Operator;
    418   CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
    419 #undef CACHED_STATE_VALUES
    420 };
    421 
    422 
    423 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
    424     LAZY_INSTANCE_INITIALIZER;
    425 
    426 
    427 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
    428     : cache_(kCache.Get()), zone_(zone) {}
    429 
    430 
    431 #define CACHED(Name, properties, value_input_count, effect_input_count,      \
    432                control_input_count, value_output_count, effect_output_count, \
    433                control_output_count)                                         \
    434   const Operator* CommonOperatorBuilder::Name() {                            \
    435     return &cache_.k##Name##Operator;                                        \
    436   }
    437 CACHED_OP_LIST(CACHED)
    438 #undef CACHED
    439 
    440 
    441 const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
    442   switch (control_input_count) {
    443 #define CACHED_END(input_count) \
    444   case input_count:             \
    445     return &cache_.kEnd##input_count##Operator;
    446     CACHED_END_LIST(CACHED_END)
    447 #undef CACHED_END
    448     default:
    449       break;
    450   }
    451   // Uncached.
    452   return new (zone()) Operator(             //--
    453       IrOpcode::kEnd, Operator::kKontrol,   // opcode
    454       "End",                                // name
    455       0, 0, control_input_count, 0, 0, 0);  // counts
    456 }
    457 
    458 
    459 const Operator* CommonOperatorBuilder::Return(int value_input_count) {
    460   switch (value_input_count) {
    461 #define CACHED_RETURN(input_count) \
    462   case input_count:                \
    463     return &cache_.kReturn##input_count##Operator;
    464     CACHED_RETURN_LIST(CACHED_RETURN)
    465 #undef CACHED_RETURN
    466     default:
    467       break;
    468   }
    469   // Uncached.
    470   return new (zone()) Operator(               //--
    471       IrOpcode::kReturn, Operator::kNoThrow,  // opcode
    472       "Return",                               // name
    473       value_input_count, 1, 1, 0, 0, 1);      // counts
    474 }
    475 
    476 
    477 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
    478   switch (hint) {
    479     case BranchHint::kNone:
    480       return &cache_.kBranchNoneOperator;
    481     case BranchHint::kTrue:
    482       return &cache_.kBranchTrueOperator;
    483     case BranchHint::kFalse:
    484       return &cache_.kBranchFalseOperator;
    485   }
    486   UNREACHABLE();
    487   return nullptr;
    488 }
    489 
    490 
    491 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) {
    492   switch (kind) {
    493     case DeoptimizeKind::kEager:
    494       return &cache_.kDeoptimizeEagerOperator;
    495     case DeoptimizeKind::kSoft:
    496       return &cache_.kDeoptimizeSoftOperator;
    497   }
    498   UNREACHABLE();
    499   return nullptr;
    500 }
    501 
    502 
    503 const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) {
    504   switch (hint) {
    505     case IfExceptionHint::kLocallyCaught:
    506       return &cache_.kIfExceptionCOperator;
    507     case IfExceptionHint::kLocallyUncaught:
    508       return &cache_.kIfExceptionUOperator;
    509   }
    510   UNREACHABLE();
    511   return nullptr;
    512 }
    513 
    514 
    515 const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
    516   return new (zone()) Operator(               // --
    517       IrOpcode::kSwitch, Operator::kKontrol,  // opcode
    518       "Switch",                               // name
    519       1, 0, 1, 0, 0, control_output_count);   // counts
    520 }
    521 
    522 
    523 const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
    524   return new (zone()) Operator1<int32_t>(      // --
    525       IrOpcode::kIfValue, Operator::kKontrol,  // opcode
    526       "IfValue",                               // name
    527       0, 0, 1, 0, 0, 1,                        // counts
    528       index);                                  // parameter
    529 }
    530 
    531 
    532 const Operator* CommonOperatorBuilder::Start(int value_output_count) {
    533   return new (zone()) Operator(               // --
    534       IrOpcode::kStart, Operator::kFoldable,  // opcode
    535       "Start",                                // name
    536       0, 0, 0, value_output_count, 1, 1);     // counts
    537 }
    538 
    539 
    540 const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
    541   switch (control_input_count) {
    542 #define CACHED_LOOP(input_count) \
    543   case input_count:              \
    544     return &cache_.kLoop##input_count##Operator;
    545     CACHED_LOOP_LIST(CACHED_LOOP)
    546 #undef CACHED_LOOP
    547     default:
    548       break;
    549   }
    550   // Uncached.
    551   return new (zone()) Operator(             // --
    552       IrOpcode::kLoop, Operator::kKontrol,  // opcode
    553       "Loop",                               // name
    554       0, 0, control_input_count, 0, 0, 1);  // counts
    555 }
    556 
    557 
    558 const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
    559   switch (control_input_count) {
    560 #define CACHED_MERGE(input_count) \
    561   case input_count:               \
    562     return &cache_.kMerge##input_count##Operator;
    563     CACHED_MERGE_LIST(CACHED_MERGE)
    564 #undef CACHED_MERGE
    565     default:
    566       break;
    567   }
    568   // Uncached.
    569   return new (zone()) Operator(              // --
    570       IrOpcode::kMerge, Operator::kKontrol,  // opcode
    571       "Merge",                               // name
    572       0, 0, control_input_count, 0, 0, 1);   // counts
    573 }
    574 
    575 
    576 const Operator* CommonOperatorBuilder::Parameter(int index,
    577                                                  const char* debug_name) {
    578   if (!debug_name) {
    579     switch (index) {
    580 #define CACHED_PARAMETER(index) \
    581   case index:                   \
    582     return &cache_.kParameter##index##Operator;
    583       CACHED_PARAMETER_LIST(CACHED_PARAMETER)
    584 #undef CACHED_PARAMETER
    585       default:
    586         break;
    587     }
    588   }
    589   // Uncached.
    590   return new (zone()) Operator1<ParameterInfo>(  // --
    591       IrOpcode::kParameter, Operator::kPure,     // opcode
    592       "Parameter",                               // name
    593       1, 0, 0, 1, 0, 0,                          // counts
    594       ParameterInfo(index, debug_name));         // parameter info
    595 }
    596 
    597 
    598 const Operator* CommonOperatorBuilder::OsrValue(int index) {
    599   return new (zone()) Operator1<int>(                // --
    600       IrOpcode::kOsrValue, Operator::kNoProperties,  // opcode
    601       "OsrValue",                                    // name
    602       0, 0, 1, 1, 0, 0,                              // counts
    603       index);                                        // parameter
    604 }
    605 
    606 
    607 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
    608   return new (zone()) Operator1<int32_t>(         // --
    609       IrOpcode::kInt32Constant, Operator::kPure,  // opcode
    610       "Int32Constant",                            // name
    611       0, 0, 0, 1, 0, 0,                           // counts
    612       value);                                     // parameter
    613 }
    614 
    615 
    616 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
    617   return new (zone()) Operator1<int64_t>(         // --
    618       IrOpcode::kInt64Constant, Operator::kPure,  // opcode
    619       "Int64Constant",                            // name
    620       0, 0, 0, 1, 0, 0,                           // counts
    621       value);                                     // parameter
    622 }
    623 
    624 
    625 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
    626   return new (zone()) Operator1<float>(             // --
    627       IrOpcode::kFloat32Constant, Operator::kPure,  // opcode
    628       "Float32Constant",                            // name
    629       0, 0, 0, 1, 0, 0,                             // counts
    630       value);                                       // parameter
    631 }
    632 
    633 
    634 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
    635   return new (zone()) Operator1<double>(            // --
    636       IrOpcode::kFloat64Constant, Operator::kPure,  // opcode
    637       "Float64Constant",                            // name
    638       0, 0, 0, 1, 0, 0,                             // counts
    639       value);                                       // parameter
    640 }
    641 
    642 
    643 const Operator* CommonOperatorBuilder::ExternalConstant(
    644     const ExternalReference& value) {
    645   return new (zone()) Operator1<ExternalReference>(  // --
    646       IrOpcode::kExternalConstant, Operator::kPure,  // opcode
    647       "ExternalConstant",                            // name
    648       0, 0, 0, 1, 0, 0,                              // counts
    649       value);                                        // parameter
    650 }
    651 
    652 
    653 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
    654   return new (zone()) Operator1<double>(           // --
    655       IrOpcode::kNumberConstant, Operator::kPure,  // opcode
    656       "NumberConstant",                            // name
    657       0, 0, 0, 1, 0, 0,                            // counts
    658       value);                                      // parameter
    659 }
    660 
    661 
    662 const Operator* CommonOperatorBuilder::HeapConstant(
    663     const Handle<HeapObject>& value) {
    664   return new (zone()) Operator1<Handle<HeapObject>>(  // --
    665       IrOpcode::kHeapConstant, Operator::kPure,       // opcode
    666       "HeapConstant",                                 // name
    667       0, 0, 0, 1, 0, 0,                               // counts
    668       value);                                         // parameter
    669 }
    670 
    671 
    672 const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
    673                                               BranchHint hint) {
    674   return new (zone()) Operator1<SelectParameters>(  // --
    675       IrOpcode::kSelect, Operator::kPure,           // opcode
    676       "Select",                                     // name
    677       3, 0, 0, 1, 0, 0,                             // counts
    678       SelectParameters(rep, hint));                 // parameter
    679 }
    680 
    681 
    682 const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
    683                                            int value_input_count) {
    684   DCHECK(value_input_count > 0);  // Disallow empty phis.
    685 #define CACHED_PHI(kRep, kValueInputCount)                 \
    686   if (MachineRepresentation::kRep == rep &&                \
    687       kValueInputCount == value_input_count) {             \
    688     return &cache_.kPhi##kRep##kValueInputCount##Operator; \
    689   }
    690   CACHED_PHI_LIST(CACHED_PHI)
    691 #undef CACHED_PHI
    692   // Uncached.
    693   return new (zone()) Operator1<MachineRepresentation>(  // --
    694       IrOpcode::kPhi, Operator::kPure,                   // opcode
    695       "Phi",                                             // name
    696       value_input_count, 0, 1, 1, 0, 0,                  // counts
    697       rep);                                              // parameter
    698 }
    699 
    700 
    701 const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
    702   DCHECK(effect_input_count > 0);  // Disallow empty effect phis.
    703   switch (effect_input_count) {
    704 #define CACHED_EFFECT_PHI(input_count) \
    705   case input_count:                    \
    706     return &cache_.kEffectPhi##input_count##Operator;
    707     CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
    708 #undef CACHED_EFFECT_PHI
    709     default:
    710       break;
    711   }
    712   // Uncached.
    713   return new (zone()) Operator(               // --
    714       IrOpcode::kEffectPhi, Operator::kPure,  // opcode
    715       "EffectPhi",                            // name
    716       0, effect_input_count, 1, 0, 1, 0);     // counts
    717 }
    718 
    719 
    720 const Operator* CommonOperatorBuilder::Guard(Type* type) {
    721   return new (zone()) Operator1<Type*>(      // --
    722       IrOpcode::kGuard, Operator::kKontrol,  // opcode
    723       "Guard",                               // name
    724       1, 0, 1, 1, 0, 0,                      // counts
    725       type);                                 // parameter
    726 }
    727 
    728 
    729 const Operator* CommonOperatorBuilder::EffectSet(int arguments) {
    730   DCHECK(arguments > 1);                      // Disallow empty/singleton sets.
    731   return new (zone()) Operator(               // --
    732       IrOpcode::kEffectSet, Operator::kPure,  // opcode
    733       "EffectSet",                            // name
    734       0, arguments, 0, 0, 1, 0);              // counts
    735 }
    736 
    737 
    738 const Operator* CommonOperatorBuilder::StateValues(int arguments) {
    739   switch (arguments) {
    740 #define CACHED_STATE_VALUES(arguments) \
    741   case arguments:                      \
    742     return &cache_.kStateValues##arguments##Operator;
    743     CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
    744 #undef CACHED_STATE_VALUES
    745     default:
    746       break;
    747   }
    748   // Uncached.
    749   return new (zone()) Operator(                 // --
    750       IrOpcode::kStateValues, Operator::kPure,  // opcode
    751       "StateValues",                            // name
    752       arguments, 0, 0, 1, 0, 0);                // counts
    753 }
    754 
    755 
    756 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots, int id) {
    757   return new (zone()) Operator1<int>(           // --
    758       IrOpcode::kObjectState, Operator::kPure,  // opcode
    759       "ObjectState",                            // name
    760       pointer_slots, 0, 0, 1, 0, 0, id);        // counts
    761 }
    762 
    763 
    764 const Operator* CommonOperatorBuilder::TypedStateValues(
    765     const ZoneVector<MachineType>* types) {
    766   return new (zone()) Operator1<const ZoneVector<MachineType>*>(  // --
    767       IrOpcode::kTypedStateValues, Operator::kPure,               // opcode
    768       "TypedStateValues",                                         // name
    769       static_cast<int>(types->size()), 0, 0, 1, 0, 0, types);     // counts
    770 }
    771 
    772 
    773 const Operator* CommonOperatorBuilder::FrameState(
    774     BailoutId bailout_id, OutputFrameStateCombine state_combine,
    775     const FrameStateFunctionInfo* function_info) {
    776   FrameStateInfo state_info(bailout_id, state_combine, function_info);
    777   return new (zone()) Operator1<FrameStateInfo>(  // --
    778       IrOpcode::kFrameState, Operator::kPure,     // opcode
    779       "FrameState",                               // name
    780       5, 0, 0, 1, 0, 0,                           // counts
    781       state_info);                                // parameter
    782 }
    783 
    784 
    785 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
    786   class CallOperator final : public Operator1<const CallDescriptor*> {
    787    public:
    788     explicit CallOperator(const CallDescriptor* descriptor)
    789         : Operator1<const CallDescriptor*>(
    790               IrOpcode::kCall, descriptor->properties(), "Call",
    791               descriptor->InputCount() + descriptor->FrameStateCount(),
    792               Operator::ZeroIfPure(descriptor->properties()),
    793               Operator::ZeroIfEliminatable(descriptor->properties()),
    794               descriptor->ReturnCount(),
    795               Operator::ZeroIfPure(descriptor->properties()),
    796               Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
    797 
    798     void PrintParameter(std::ostream& os) const override {
    799       os << "[" << *parameter() << "]";
    800     }
    801   };
    802   return new (zone()) CallOperator(descriptor);
    803 }
    804 
    805 
    806 const Operator* CommonOperatorBuilder::LazyBailout() {
    807   return Call(Linkage::GetLazyBailoutDescriptor(zone()));
    808 }
    809 
    810 
    811 const Operator* CommonOperatorBuilder::TailCall(
    812     const CallDescriptor* descriptor) {
    813   class TailCallOperator final : public Operator1<const CallDescriptor*> {
    814    public:
    815     explicit TailCallOperator(const CallDescriptor* descriptor)
    816         : Operator1<const CallDescriptor*>(
    817               IrOpcode::kTailCall, descriptor->properties(), "TailCall",
    818               descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
    819               0, 1, descriptor) {}
    820 
    821     void PrintParameter(std::ostream& os) const override {
    822       os << "[" << *parameter() << "]";
    823     }
    824   };
    825   return new (zone()) TailCallOperator(descriptor);
    826 }
    827 
    828 
    829 const Operator* CommonOperatorBuilder::Projection(size_t index) {
    830   switch (index) {
    831 #define CACHED_PROJECTION(index) \
    832   case index:                    \
    833     return &cache_.kProjection##index##Operator;
    834     CACHED_PROJECTION_LIST(CACHED_PROJECTION)
    835 #undef CACHED_PROJECTION
    836     default:
    837       break;
    838   }
    839   // Uncached.
    840   return new (zone()) Operator1<size_t>(         // --
    841       IrOpcode::kProjection,                     // opcode
    842       Operator::kFoldable | Operator::kNoThrow,  // flags
    843       "Projection",                              // name
    844       1, 0, 0, 1, 0, 0,                          // counts
    845       index);                                    // parameter
    846 }
    847 
    848 
    849 const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
    850                                                         int size) {
    851   if (op->opcode() == IrOpcode::kPhi) {
    852     return Phi(PhiRepresentationOf(op), size);
    853   } else if (op->opcode() == IrOpcode::kEffectPhi) {
    854     return EffectPhi(size);
    855   } else if (op->opcode() == IrOpcode::kMerge) {
    856     return Merge(size);
    857   } else if (op->opcode() == IrOpcode::kLoop) {
    858     return Loop(size);
    859   } else {
    860     UNREACHABLE();
    861     return nullptr;
    862   }
    863 }
    864 
    865 
    866 const FrameStateFunctionInfo*
    867 CommonOperatorBuilder::CreateFrameStateFunctionInfo(
    868     FrameStateType type, int parameter_count, int local_count,
    869     Handle<SharedFunctionInfo> shared_info,
    870     ContextCallingMode context_calling_mode) {
    871   return new (zone()->New(sizeof(FrameStateFunctionInfo)))
    872       FrameStateFunctionInfo(type, parameter_count, local_count, shared_info,
    873                              context_calling_mode);
    874 }
    875 
    876 }  // namespace compiler
    877 }  // namespace internal
    878 }  // namespace v8
    879