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