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/node.h"
     11 #include "src/compiler/opcodes.h"
     12 #include "src/compiler/operator.h"
     13 #include "src/handles-inl.h"
     14 #include "src/objects-inl.h"
     15 #include "src/zone/zone.h"
     16 
     17 namespace v8 {
     18 namespace internal {
     19 namespace compiler {
     20 
     21 std::ostream& operator<<(std::ostream& os, BranchHint hint) {
     22   switch (hint) {
     23     case BranchHint::kNone:
     24       return os << "None";
     25     case BranchHint::kTrue:
     26       return os << "True";
     27     case BranchHint::kFalse:
     28       return os << "False";
     29   }
     30   UNREACHABLE();
     31   return os;
     32 }
     33 
     34 
     35 BranchHint BranchHintOf(const Operator* const op) {
     36   DCHECK_EQ(IrOpcode::kBranch, op->opcode());
     37   return OpParameter<BranchHint>(op);
     38 }
     39 
     40 int ValueInputCountOfReturn(Operator const* const op) {
     41   DCHECK(op->opcode() == IrOpcode::kReturn);
     42   // Return nodes have a hidden input at index 0 which we ignore in the value
     43   // input count.
     44   return op->ValueInputCount() - 1;
     45 }
     46 
     47 bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
     48   return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason();
     49 }
     50 
     51 bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
     52   return !(lhs == rhs);
     53 }
     54 
     55 size_t hash_value(DeoptimizeParameters p) {
     56   return base::hash_combine(p.kind(), p.reason());
     57 }
     58 
     59 std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) {
     60   return os << p.kind() << ":" << p.reason();
     61 }
     62 
     63 DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) {
     64   DCHECK(op->opcode() == IrOpcode::kDeoptimize ||
     65          op->opcode() == IrOpcode::kDeoptimizeIf ||
     66          op->opcode() == IrOpcode::kDeoptimizeUnless);
     67   return OpParameter<DeoptimizeParameters>(op);
     68 }
     69 
     70 
     71 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
     72   return lhs.representation() == rhs.representation() &&
     73          lhs.hint() == rhs.hint();
     74 }
     75 
     76 
     77 bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
     78   return !(lhs == rhs);
     79 }
     80 
     81 
     82 size_t hash_value(SelectParameters const& p) {
     83   return base::hash_combine(p.representation(), p.hint());
     84 }
     85 
     86 
     87 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
     88   return os << p.representation() << "|" << p.hint();
     89 }
     90 
     91 
     92 SelectParameters const& SelectParametersOf(const Operator* const op) {
     93   DCHECK_EQ(IrOpcode::kSelect, op->opcode());
     94   return OpParameter<SelectParameters>(op);
     95 }
     96 
     97 CallDescriptor const* CallDescriptorOf(const Operator* const op) {
     98   DCHECK(op->opcode() == IrOpcode::kCall ||
     99          op->opcode() == IrOpcode::kTailCall);
    100   return OpParameter<CallDescriptor const*>(op);
    101 }
    102 
    103 size_t ProjectionIndexOf(const Operator* const op) {
    104   DCHECK_EQ(IrOpcode::kProjection, op->opcode());
    105   return OpParameter<size_t>(op);
    106 }
    107 
    108 
    109 MachineRepresentation PhiRepresentationOf(const Operator* const op) {
    110   DCHECK_EQ(IrOpcode::kPhi, op->opcode());
    111   return OpParameter<MachineRepresentation>(op);
    112 }
    113 
    114 
    115 int ParameterIndexOf(const Operator* const op) {
    116   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
    117   return OpParameter<ParameterInfo>(op).index();
    118 }
    119 
    120 
    121 const ParameterInfo& ParameterInfoOf(const Operator* const op) {
    122   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
    123   return OpParameter<ParameterInfo>(op);
    124 }
    125 
    126 
    127 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
    128   return lhs.index() == rhs.index();
    129 }
    130 
    131 
    132 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
    133   return !(lhs == rhs);
    134 }
    135 
    136 
    137 size_t hash_value(ParameterInfo const& p) { return p.index(); }
    138 
    139 
    140 std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
    141   if (i.debug_name()) os << i.debug_name() << '#';
    142   os << i.index();
    143   return os;
    144 }
    145 
    146 bool operator==(RelocatablePtrConstantInfo const& lhs,
    147                 RelocatablePtrConstantInfo const& rhs) {
    148   return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value() &&
    149          lhs.type() == rhs.type();
    150 }
    151 
    152 bool operator!=(RelocatablePtrConstantInfo const& lhs,
    153                 RelocatablePtrConstantInfo const& rhs) {
    154   return !(lhs == rhs);
    155 }
    156 
    157 size_t hash_value(RelocatablePtrConstantInfo const& p) {
    158   return base::hash_combine(p.value(), p.rmode(), p.type());
    159 }
    160 
    161 std::ostream& operator<<(std::ostream& os,
    162                          RelocatablePtrConstantInfo const& p) {
    163   return os << p.value() << "|" << p.rmode() << "|" << p.type();
    164 }
    165 
    166 SparseInputMask::InputIterator::InputIterator(
    167     SparseInputMask::BitMaskType bit_mask, Node* parent)
    168     : bit_mask_(bit_mask), parent_(parent), real_index_(0) {
    169 #if DEBUG
    170   if (bit_mask_ != SparseInputMask::kDenseBitMask) {
    171     DCHECK_EQ(base::bits::CountPopulation(bit_mask_) -
    172                   base::bits::CountPopulation(kEndMarker),
    173               parent->InputCount());
    174   }
    175 #endif
    176 }
    177 
    178 void SparseInputMask::InputIterator::Advance() {
    179   DCHECK(!IsEnd());
    180 
    181   if (IsReal()) {
    182     ++real_index_;
    183   }
    184   bit_mask_ >>= 1;
    185 }
    186 
    187 Node* SparseInputMask::InputIterator::GetReal() const {
    188   DCHECK(IsReal());
    189   return parent_->InputAt(real_index_);
    190 }
    191 
    192 bool SparseInputMask::InputIterator::IsReal() const {
    193   return bit_mask_ == SparseInputMask::kDenseBitMask ||
    194          (bit_mask_ & kEntryMask);
    195 }
    196 
    197 bool SparseInputMask::InputIterator::IsEnd() const {
    198   return (bit_mask_ == kEndMarker) ||
    199          (bit_mask_ == SparseInputMask::kDenseBitMask &&
    200           real_index_ >= parent_->InputCount());
    201 }
    202 
    203 int SparseInputMask::CountReal() const {
    204   DCHECK(!IsDense());
    205   return base::bits::CountPopulation(bit_mask_) -
    206          base::bits::CountPopulation(kEndMarker);
    207 }
    208 
    209 SparseInputMask::InputIterator SparseInputMask::IterateOverInputs(Node* node) {
    210   DCHECK(IsDense() || CountReal() == node->InputCount());
    211   return InputIterator(bit_mask_, node);
    212 }
    213 
    214 bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs) {
    215   return lhs.mask() == rhs.mask();
    216 }
    217 
    218 bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs) {
    219   return !(lhs == rhs);
    220 }
    221 
    222 size_t hash_value(SparseInputMask const& p) {
    223   return base::hash_value(p.mask());
    224 }
    225 
    226 std::ostream& operator<<(std::ostream& os, SparseInputMask const& p) {
    227   if (p.IsDense()) {
    228     return os << "dense";
    229   } else {
    230     SparseInputMask::BitMaskType mask = p.mask();
    231     DCHECK_NE(mask, SparseInputMask::kDenseBitMask);
    232 
    233     os << "sparse:";
    234 
    235     while (mask != SparseInputMask::kEndMarker) {
    236       if (mask & SparseInputMask::kEntryMask) {
    237         os << "^";
    238       } else {
    239         os << ".";
    240       }
    241       mask >>= 1;
    242     }
    243     return os;
    244   }
    245 }
    246 
    247 bool operator==(TypedStateValueInfo const& lhs,
    248                 TypedStateValueInfo const& rhs) {
    249   return lhs.machine_types() == rhs.machine_types() &&
    250          lhs.sparse_input_mask() == rhs.sparse_input_mask();
    251 }
    252 
    253 bool operator!=(TypedStateValueInfo const& lhs,
    254                 TypedStateValueInfo const& rhs) {
    255   return !(lhs == rhs);
    256 }
    257 
    258 size_t hash_value(TypedStateValueInfo const& p) {
    259   return base::hash_combine(p.machine_types(), p.sparse_input_mask());
    260 }
    261 
    262 std::ostream& operator<<(std::ostream& os, TypedStateValueInfo const& p) {
    263   return os << p.machine_types() << "|" << p.sparse_input_mask();
    264 }
    265 
    266 size_t hash_value(RegionObservability observability) {
    267   return static_cast<size_t>(observability);
    268 }
    269 
    270 std::ostream& operator<<(std::ostream& os, RegionObservability observability) {
    271   switch (observability) {
    272     case RegionObservability::kObservable:
    273       return os << "observable";
    274     case RegionObservability::kNotObservable:
    275       return os << "not-observable";
    276   }
    277   UNREACHABLE();
    278   return os;
    279 }
    280 
    281 RegionObservability RegionObservabilityOf(Operator const* op) {
    282   DCHECK_EQ(IrOpcode::kBeginRegion, op->opcode());
    283   return OpParameter<RegionObservability>(op);
    284 }
    285 
    286 Type* TypeGuardTypeOf(Operator const* op) {
    287   DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode());
    288   return OpParameter<Type*>(op);
    289 }
    290 
    291 std::ostream& operator<<(std::ostream& os,
    292                          const ZoneVector<MachineType>* types) {
    293   // Print all the MachineTypes, separated by commas.
    294   bool first = true;
    295   for (MachineType elem : *types) {
    296     if (!first) {
    297       os << ", ";
    298     }
    299     first = false;
    300     os << elem;
    301   }
    302   return os;
    303 }
    304 
    305 int OsrValueIndexOf(Operator const* op) {
    306   DCHECK_EQ(IrOpcode::kOsrValue, op->opcode());
    307   return OpParameter<int>(op);
    308 }
    309 
    310 size_t hash_value(OsrGuardType type) { return static_cast<size_t>(type); }
    311 
    312 std::ostream& operator<<(std::ostream& os, OsrGuardType type) {
    313   switch (type) {
    314     case OsrGuardType::kUninitialized:
    315       return os << "Uninitialized";
    316     case OsrGuardType::kSignedSmall:
    317       return os << "SignedSmall";
    318     case OsrGuardType::kAny:
    319       return os << "Any";
    320   }
    321   UNREACHABLE();
    322   return os;
    323 }
    324 
    325 OsrGuardType OsrGuardTypeOf(Operator const* op) {
    326   DCHECK_EQ(IrOpcode::kOsrGuard, op->opcode());
    327   return OpParameter<OsrGuardType>(op);
    328 }
    329 
    330 SparseInputMask SparseInputMaskOf(Operator const* op) {
    331   DCHECK(op->opcode() == IrOpcode::kStateValues ||
    332          op->opcode() == IrOpcode::kTypedStateValues);
    333 
    334   if (op->opcode() == IrOpcode::kTypedStateValues) {
    335     return OpParameter<TypedStateValueInfo>(op).sparse_input_mask();
    336   }
    337   return OpParameter<SparseInputMask>(op);
    338 }
    339 
    340 ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) {
    341   DCHECK(op->opcode() == IrOpcode::kTypedObjectState ||
    342          op->opcode() == IrOpcode::kTypedStateValues);
    343 
    344   if (op->opcode() == IrOpcode::kTypedStateValues) {
    345     return OpParameter<TypedStateValueInfo>(op).machine_types();
    346   }
    347   return OpParameter<const ZoneVector<MachineType>*>(op);
    348 }
    349 
    350 #define CACHED_OP_LIST(V)                                                     \
    351   V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1)                              \
    352   V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1)                             \
    353   V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1)                            \
    354   V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1)                          \
    355   V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1)                        \
    356   V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1)                          \
    357   V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1)                              \
    358   V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1)                          \
    359   V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1)                    \
    360   V(OsrLoopEntry, Operator::kFoldable | Operator::kNoThrow, 0, 1, 1, 0, 1, 1) \
    361   V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1)                           \
    362   V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0)                         \
    363   V(LoopExitEffect, Operator::kNoThrow, 0, 1, 1, 0, 1, 0)                     \
    364   V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0)                         \
    365   V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0)                       \
    366   V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0)
    367 
    368 #define CACHED_RETURN_LIST(V) \
    369   V(1)                        \
    370   V(2)                        \
    371   V(3)                        \
    372   V(4)
    373 
    374 #define CACHED_END_LIST(V) \
    375   V(1)                     \
    376   V(2)                     \
    377   V(3)                     \
    378   V(4)                     \
    379   V(5)                     \
    380   V(6)                     \
    381   V(7)                     \
    382   V(8)
    383 
    384 
    385 #define CACHED_EFFECT_PHI_LIST(V) \
    386   V(1)                            \
    387   V(2)                            \
    388   V(3)                            \
    389   V(4)                            \
    390   V(5)                            \
    391   V(6)
    392 
    393 #define CACHED_INDUCTION_VARIABLE_PHI_LIST(V) \
    394   V(4)                                        \
    395   V(5)                                        \
    396   V(6)                                        \
    397   V(7)
    398 
    399 #define CACHED_LOOP_LIST(V) \
    400   V(1)                      \
    401   V(2)
    402 
    403 
    404 #define CACHED_MERGE_LIST(V) \
    405   V(1)                       \
    406   V(2)                       \
    407   V(3)                       \
    408   V(4)                       \
    409   V(5)                       \
    410   V(6)                       \
    411   V(7)                       \
    412   V(8)
    413 
    414 #define CACHED_DEOPTIMIZE_LIST(V)                        \
    415   V(Eager, MinusZero)                                    \
    416   V(Eager, NoReason)                                     \
    417   V(Eager, WrongMap)                                     \
    418   V(Soft, InsufficientTypeFeedbackForGenericKeyedAccess) \
    419   V(Soft, InsufficientTypeFeedbackForGenericNamedAccess)
    420 
    421 #define CACHED_DEOPTIMIZE_IF_LIST(V) \
    422   V(Eager, DivisionByZero)           \
    423   V(Eager, Hole)                     \
    424   V(Eager, MinusZero)                \
    425   V(Eager, Overflow)                 \
    426   V(Eager, Smi)
    427 
    428 #define CACHED_DEOPTIMIZE_UNLESS_LIST(V) \
    429   V(Eager, LostPrecision)                \
    430   V(Eager, LostPrecisionOrNaN)           \
    431   V(Eager, NoReason)                     \
    432   V(Eager, NotAHeapNumber)               \
    433   V(Eager, NotANumberOrOddball)          \
    434   V(Eager, NotASmi)                      \
    435   V(Eager, OutOfBounds)                  \
    436   V(Eager, WrongInstanceType)            \
    437   V(Eager, WrongMap)
    438 
    439 #define CACHED_TRAP_IF_LIST(V) \
    440   V(TrapDivUnrepresentable)    \
    441   V(TrapFloatUnrepresentable)
    442 
    443 // The reason for a trap.
    444 #define CACHED_TRAP_UNLESS_LIST(V) \
    445   V(TrapUnreachable)               \
    446   V(TrapMemOutOfBounds)            \
    447   V(TrapDivByZero)                 \
    448   V(TrapDivUnrepresentable)        \
    449   V(TrapRemByZero)                 \
    450   V(TrapFloatUnrepresentable)      \
    451   V(TrapFuncInvalid)               \
    452   V(TrapFuncSigMismatch)
    453 
    454 #define CACHED_PARAMETER_LIST(V) \
    455   V(0)                           \
    456   V(1)                           \
    457   V(2)                           \
    458   V(3)                           \
    459   V(4)                           \
    460   V(5)                           \
    461   V(6)
    462 
    463 
    464 #define CACHED_PHI_LIST(V) \
    465   V(kTagged, 1)            \
    466   V(kTagged, 2)            \
    467   V(kTagged, 3)            \
    468   V(kTagged, 4)            \
    469   V(kTagged, 5)            \
    470   V(kTagged, 6)            \
    471   V(kBit, 2)               \
    472   V(kFloat64, 2)           \
    473   V(kWord32, 2)
    474 
    475 
    476 #define CACHED_PROJECTION_LIST(V) \
    477   V(0)                            \
    478   V(1)
    479 
    480 
    481 #define CACHED_STATE_VALUES_LIST(V) \
    482   V(0)                              \
    483   V(1)                              \
    484   V(2)                              \
    485   V(3)                              \
    486   V(4)                              \
    487   V(5)                              \
    488   V(6)                              \
    489   V(7)                              \
    490   V(8)                              \
    491   V(10)                             \
    492   V(11)                             \
    493   V(12)                             \
    494   V(13)                             \
    495   V(14)
    496 
    497 
    498 struct CommonOperatorGlobalCache final {
    499 #define CACHED(Name, properties, value_input_count, effect_input_count,      \
    500                control_input_count, value_output_count, effect_output_count, \
    501                control_output_count)                                         \
    502   struct Name##Operator final : public Operator {                            \
    503     Name##Operator()                                                         \
    504         : Operator(IrOpcode::k##Name, properties, #Name, value_input_count,  \
    505                    effect_input_count, control_input_count,                  \
    506                    value_output_count, effect_output_count,                  \
    507                    control_output_count) {}                                  \
    508   };                                                                         \
    509   Name##Operator k##Name##Operator;
    510   CACHED_OP_LIST(CACHED)
    511 #undef CACHED
    512 
    513   template <size_t kInputCount>
    514   struct EndOperator final : public Operator {
    515     EndOperator()
    516         : Operator(                                // --
    517               IrOpcode::kEnd, Operator::kKontrol,  // opcode
    518               "End",                               // name
    519               0, 0, kInputCount, 0, 0, 0) {}       // counts
    520   };
    521 #define CACHED_END(input_count) \
    522   EndOperator<input_count> kEnd##input_count##Operator;
    523   CACHED_END_LIST(CACHED_END)
    524 #undef CACHED_END
    525 
    526   template <size_t kValueInputCount>
    527   struct ReturnOperator final : public Operator {
    528     ReturnOperator()
    529         : Operator(                                    // --
    530               IrOpcode::kReturn, Operator::kNoThrow,   // opcode
    531               "Return",                                // name
    532               kValueInputCount + 1, 1, 1, 0, 0, 1) {}  // counts
    533   };
    534 #define CACHED_RETURN(value_input_count) \
    535   ReturnOperator<value_input_count> kReturn##value_input_count##Operator;
    536   CACHED_RETURN_LIST(CACHED_RETURN)
    537 #undef CACHED_RETURN
    538 
    539   template <BranchHint kBranchHint>
    540   struct BranchOperator final : public Operator1<BranchHint> {
    541     BranchOperator()
    542         : Operator1<BranchHint>(                      // --
    543               IrOpcode::kBranch, Operator::kKontrol,  // opcode
    544               "Branch",                               // name
    545               1, 0, 1, 0, 0, 2,                       // counts
    546               kBranchHint) {}                         // parameter
    547   };
    548   BranchOperator<BranchHint::kNone> kBranchNoneOperator;
    549   BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
    550   BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
    551 
    552   template <int kEffectInputCount>
    553   struct EffectPhiOperator final : public Operator {
    554     EffectPhiOperator()
    555         : Operator(                                      // --
    556               IrOpcode::kEffectPhi, Operator::kKontrol,  // opcode
    557               "EffectPhi",                               // name
    558               0, kEffectInputCount, 1, 0, 1, 0) {}       // counts
    559   };
    560 #define CACHED_EFFECT_PHI(input_count) \
    561   EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
    562   CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
    563 #undef CACHED_EFFECT_PHI
    564 
    565   template <RegionObservability kRegionObservability>
    566   struct BeginRegionOperator final : public Operator1<RegionObservability> {
    567     BeginRegionOperator()
    568         : Operator1<RegionObservability>(                  // --
    569               IrOpcode::kBeginRegion, Operator::kKontrol,  // opcode
    570               "BeginRegion",                               // name
    571               0, 1, 0, 0, 1, 0,                            // counts
    572               kRegionObservability) {}                     // parameter
    573   };
    574   BeginRegionOperator<RegionObservability::kObservable>
    575       kBeginRegionObservableOperator;
    576   BeginRegionOperator<RegionObservability::kNotObservable>
    577       kBeginRegionNotObservableOperator;
    578 
    579   template <size_t kInputCount>
    580   struct LoopOperator final : public Operator {
    581     LoopOperator()
    582         : Operator(                                 // --
    583               IrOpcode::kLoop, Operator::kKontrol,  // opcode
    584               "Loop",                               // name
    585               0, 0, kInputCount, 0, 0, 1) {}        // counts
    586   };
    587 #define CACHED_LOOP(input_count) \
    588   LoopOperator<input_count> kLoop##input_count##Operator;
    589   CACHED_LOOP_LIST(CACHED_LOOP)
    590 #undef CACHED_LOOP
    591 
    592   template <size_t kInputCount>
    593   struct MergeOperator final : public Operator {
    594     MergeOperator()
    595         : Operator(                                  // --
    596               IrOpcode::kMerge, Operator::kKontrol,  // opcode
    597               "Merge",                               // name
    598               0, 0, kInputCount, 0, 0, 1) {}         // counts
    599   };
    600 #define CACHED_MERGE(input_count) \
    601   MergeOperator<input_count> kMerge##input_count##Operator;
    602   CACHED_MERGE_LIST(CACHED_MERGE)
    603 #undef CACHED_MERGE
    604 
    605   template <DeoptimizeKind kKind, DeoptimizeReason kReason>
    606   struct DeoptimizeOperator final : public Operator1<DeoptimizeParameters> {
    607     DeoptimizeOperator()
    608         : Operator1<DeoptimizeParameters>(               // --
    609               IrOpcode::kDeoptimize,                     // opcode
    610               Operator::kFoldable | Operator::kNoThrow,  // properties
    611               "Deoptimize",                              // name
    612               1, 1, 1, 0, 0, 1,                          // counts
    613               DeoptimizeParameters(kKind, kReason)) {}   // parameter
    614   };
    615 #define CACHED_DEOPTIMIZE(Kind, Reason)                                    \
    616   DeoptimizeOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \
    617       kDeoptimize##Kind##Reason##Operator;
    618   CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
    619 #undef CACHED_DEOPTIMIZE
    620 
    621   template <DeoptimizeKind kKind, DeoptimizeReason kReason>
    622   struct DeoptimizeIfOperator final : public Operator1<DeoptimizeParameters> {
    623     DeoptimizeIfOperator()
    624         : Operator1<DeoptimizeParameters>(               // --
    625               IrOpcode::kDeoptimizeIf,                   // opcode
    626               Operator::kFoldable | Operator::kNoThrow,  // properties
    627               "DeoptimizeIf",                            // name
    628               2, 1, 1, 0, 1, 1,                          // counts
    629               DeoptimizeParameters(kKind, kReason)) {}   // parameter
    630   };
    631 #define CACHED_DEOPTIMIZE_IF(Kind, Reason)                                   \
    632   DeoptimizeIfOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \
    633       kDeoptimizeIf##Kind##Reason##Operator;
    634   CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
    635 #undef CACHED_DEOPTIMIZE_IF
    636 
    637   template <DeoptimizeKind kKind, DeoptimizeReason kReason>
    638   struct DeoptimizeUnlessOperator final
    639       : public Operator1<DeoptimizeParameters> {
    640     DeoptimizeUnlessOperator()
    641         : Operator1<DeoptimizeParameters>(               // --
    642               IrOpcode::kDeoptimizeUnless,               // opcode
    643               Operator::kFoldable | Operator::kNoThrow,  // properties
    644               "DeoptimizeUnless",                        // name
    645               2, 1, 1, 0, 1, 1,                          // counts
    646               DeoptimizeParameters(kKind, kReason)) {}   // parameter
    647   };
    648 #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason)          \
    649   DeoptimizeUnlessOperator<DeoptimizeKind::k##Kind,     \
    650                            DeoptimizeReason::k##Reason> \
    651       kDeoptimizeUnless##Kind##Reason##Operator;
    652   CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
    653 #undef CACHED_DEOPTIMIZE_UNLESS
    654 
    655   template <int32_t trap_id>
    656   struct TrapIfOperator final : public Operator1<int32_t> {
    657     TrapIfOperator()
    658         : Operator1<int32_t>(                            // --
    659               IrOpcode::kTrapIf,                         // opcode
    660               Operator::kFoldable | Operator::kNoThrow,  // properties
    661               "TrapIf",                                  // name
    662               1, 1, 1, 0, 0, 1,                          // counts
    663               trap_id) {}                                // parameter
    664   };
    665 #define CACHED_TRAP_IF(Trap)                                       \
    666   TrapIfOperator<static_cast<int32_t>(Builtins::kThrowWasm##Trap)> \
    667       kTrapIf##Trap##Operator;
    668   CACHED_TRAP_IF_LIST(CACHED_TRAP_IF)
    669 #undef CACHED_TRAP_IF
    670 
    671   template <int32_t trap_id>
    672   struct TrapUnlessOperator final : public Operator1<int32_t> {
    673     TrapUnlessOperator()
    674         : Operator1<int32_t>(                            // --
    675               IrOpcode::kTrapUnless,                     // opcode
    676               Operator::kFoldable | Operator::kNoThrow,  // properties
    677               "TrapUnless",                              // name
    678               1, 1, 1, 0, 0, 1,                          // counts
    679               trap_id) {}                                // parameter
    680   };
    681 #define CACHED_TRAP_UNLESS(Trap)                                       \
    682   TrapUnlessOperator<static_cast<int32_t>(Builtins::kThrowWasm##Trap)> \
    683       kTrapUnless##Trap##Operator;
    684   CACHED_TRAP_UNLESS_LIST(CACHED_TRAP_UNLESS)
    685 #undef CACHED_TRAP_UNLESS
    686 
    687   template <MachineRepresentation kRep, int kInputCount>
    688   struct PhiOperator final : public Operator1<MachineRepresentation> {
    689     PhiOperator()
    690         : Operator1<MachineRepresentation>(     //--
    691               IrOpcode::kPhi, Operator::kPure,  // opcode
    692               "Phi",                            // name
    693               kInputCount, 0, 1, 1, 0, 0,       // counts
    694               kRep) {}                          // parameter
    695   };
    696 #define CACHED_PHI(rep, input_count)                   \
    697   PhiOperator<MachineRepresentation::rep, input_count> \
    698       kPhi##rep##input_count##Operator;
    699   CACHED_PHI_LIST(CACHED_PHI)
    700 #undef CACHED_PHI
    701 
    702   template <int kInputCount>
    703   struct InductionVariablePhiOperator final : public Operator {
    704     InductionVariablePhiOperator()
    705         : Operator(                                              //--
    706               IrOpcode::kInductionVariablePhi, Operator::kPure,  // opcode
    707               "InductionVariablePhi",                            // name
    708               kInputCount, 0, 1, 1, 0, 0) {}                     // counts
    709   };
    710 #define CACHED_INDUCTION_VARIABLE_PHI(input_count) \
    711   InductionVariablePhiOperator<input_count>        \
    712       kInductionVariablePhi##input_count##Operator;
    713   CACHED_INDUCTION_VARIABLE_PHI_LIST(CACHED_INDUCTION_VARIABLE_PHI)
    714 #undef CACHED_INDUCTION_VARIABLE_PHI
    715 
    716   template <int kIndex>
    717   struct ParameterOperator final : public Operator1<ParameterInfo> {
    718     ParameterOperator()
    719         : Operator1<ParameterInfo>(                   // --
    720               IrOpcode::kParameter, Operator::kPure,  // opcode
    721               "Parameter",                            // name
    722               1, 0, 0, 1, 0, 0,                       // counts,
    723               ParameterInfo(kIndex, nullptr)) {}      // parameter and name
    724   };
    725 #define CACHED_PARAMETER(index) \
    726   ParameterOperator<index> kParameter##index##Operator;
    727   CACHED_PARAMETER_LIST(CACHED_PARAMETER)
    728 #undef CACHED_PARAMETER
    729 
    730   template <size_t kIndex>
    731   struct ProjectionOperator final : public Operator1<size_t> {
    732     ProjectionOperator()
    733         : Operator1<size_t>(          // --
    734               IrOpcode::kProjection,  // opcode
    735               Operator::kPure,        // flags
    736               "Projection",           // name
    737               1, 0, 1, 1, 0, 0,       // counts,
    738               kIndex) {}              // parameter
    739   };
    740 #define CACHED_PROJECTION(index) \
    741   ProjectionOperator<index> kProjection##index##Operator;
    742   CACHED_PROJECTION_LIST(CACHED_PROJECTION)
    743 #undef CACHED_PROJECTION
    744 
    745   template <int kInputCount>
    746   struct StateValuesOperator final : public Operator1<SparseInputMask> {
    747     StateValuesOperator()
    748         : Operator1<SparseInputMask>(       // --
    749               IrOpcode::kStateValues,       // opcode
    750               Operator::kPure,              // flags
    751               "StateValues",                // name
    752               kInputCount, 0, 0, 1, 0, 0,   // counts
    753               SparseInputMask::Dense()) {}  // parameter
    754   };
    755 #define CACHED_STATE_VALUES(input_count) \
    756   StateValuesOperator<input_count> kStateValues##input_count##Operator;
    757   CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
    758 #undef CACHED_STATE_VALUES
    759 };
    760 
    761 
    762 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
    763     LAZY_INSTANCE_INITIALIZER;
    764 
    765 
    766 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
    767     : cache_(kCache.Get()), zone_(zone) {}
    768 
    769 
    770 #define CACHED(Name, properties, value_input_count, effect_input_count,      \
    771                control_input_count, value_output_count, effect_output_count, \
    772                control_output_count)                                         \
    773   const Operator* CommonOperatorBuilder::Name() {                            \
    774     return &cache_.k##Name##Operator;                                        \
    775   }
    776 CACHED_OP_LIST(CACHED)
    777 #undef CACHED
    778 
    779 
    780 const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
    781   switch (control_input_count) {
    782 #define CACHED_END(input_count) \
    783   case input_count:             \
    784     return &cache_.kEnd##input_count##Operator;
    785     CACHED_END_LIST(CACHED_END)
    786 #undef CACHED_END
    787     default:
    788       break;
    789   }
    790   // Uncached.
    791   return new (zone()) Operator(             //--
    792       IrOpcode::kEnd, Operator::kKontrol,   // opcode
    793       "End",                                // name
    794       0, 0, control_input_count, 0, 0, 0);  // counts
    795 }
    796 
    797 const Operator* CommonOperatorBuilder::Return(int value_input_count) {
    798   switch (value_input_count) {
    799 #define CACHED_RETURN(input_count) \
    800   case input_count:                \
    801     return &cache_.kReturn##input_count##Operator;
    802     CACHED_RETURN_LIST(CACHED_RETURN)
    803 #undef CACHED_RETURN
    804     default:
    805       break;
    806   }
    807   // Uncached.
    808   return new (zone()) Operator(               //--
    809       IrOpcode::kReturn, Operator::kNoThrow,  // opcode
    810       "Return",                               // name
    811       value_input_count + 1, 1, 1, 0, 0, 1);  // counts
    812 }
    813 
    814 
    815 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
    816   switch (hint) {
    817     case BranchHint::kNone:
    818       return &cache_.kBranchNoneOperator;
    819     case BranchHint::kTrue:
    820       return &cache_.kBranchTrueOperator;
    821     case BranchHint::kFalse:
    822       return &cache_.kBranchFalseOperator;
    823   }
    824   UNREACHABLE();
    825   return nullptr;
    826 }
    827 
    828 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind,
    829                                                   DeoptimizeReason reason) {
    830 #define CACHED_DEOPTIMIZE(Kind, Reason)                 \
    831   if (kind == DeoptimizeKind::k##Kind &&                \
    832       reason == DeoptimizeReason::k##Reason) {          \
    833     return &cache_.kDeoptimize##Kind##Reason##Operator; \
    834   }
    835   CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
    836 #undef CACHED_DEOPTIMIZE
    837   // Uncached
    838   DeoptimizeParameters parameter(kind, reason);
    839   return new (zone()) Operator1<DeoptimizeParameters>(  // --
    840       IrOpcode::kDeoptimize,                            // opcodes
    841       Operator::kFoldable | Operator::kNoThrow,         // properties
    842       "Deoptimize",                                     // name
    843       1, 1, 1, 0, 0, 1,                                 // counts
    844       parameter);                                       // parameter
    845 }
    846 
    847 const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind,
    848                                                     DeoptimizeReason reason) {
    849 #define CACHED_DEOPTIMIZE_IF(Kind, Reason)                \
    850   if (kind == DeoptimizeKind::k##Kind &&                  \
    851       reason == DeoptimizeReason::k##Reason) {            \
    852     return &cache_.kDeoptimizeIf##Kind##Reason##Operator; \
    853   }
    854   CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
    855 #undef CACHED_DEOPTIMIZE_IF
    856   // Uncached
    857   DeoptimizeParameters parameter(kind, reason);
    858   return new (zone()) Operator1<DeoptimizeParameters>(  // --
    859       IrOpcode::kDeoptimizeIf,                          // opcode
    860       Operator::kFoldable | Operator::kNoThrow,         // properties
    861       "DeoptimizeIf",                                   // name
    862       2, 1, 1, 0, 1, 1,                                 // counts
    863       parameter);                                       // parameter
    864 }
    865 
    866 const Operator* CommonOperatorBuilder::DeoptimizeUnless(
    867     DeoptimizeKind kind, DeoptimizeReason reason) {
    868 #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason)                \
    869   if (kind == DeoptimizeKind::k##Kind &&                      \
    870       reason == DeoptimizeReason::k##Reason) {                \
    871     return &cache_.kDeoptimizeUnless##Kind##Reason##Operator; \
    872   }
    873   CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
    874 #undef CACHED_DEOPTIMIZE_UNLESS
    875   // Uncached
    876   DeoptimizeParameters parameter(kind, reason);
    877   return new (zone()) Operator1<DeoptimizeParameters>(  // --
    878       IrOpcode::kDeoptimizeUnless,                      // opcode
    879       Operator::kFoldable | Operator::kNoThrow,         // properties
    880       "DeoptimizeUnless",                               // name
    881       2, 1, 1, 0, 1, 1,                                 // counts
    882       parameter);                                       // parameter
    883 }
    884 
    885 const Operator* CommonOperatorBuilder::TrapIf(int32_t trap_id) {
    886   switch (trap_id) {
    887 #define CACHED_TRAP_IF(Trap)       \
    888   case Builtins::kThrowWasm##Trap: \
    889     return &cache_.kTrapIf##Trap##Operator;
    890     CACHED_TRAP_IF_LIST(CACHED_TRAP_IF)
    891 #undef CACHED_TRAP_IF
    892     default:
    893       break;
    894   }
    895   // Uncached
    896   return new (zone()) Operator1<int>(            // --
    897       IrOpcode::kTrapIf,                         // opcode
    898       Operator::kFoldable | Operator::kNoThrow,  // properties
    899       "TrapIf",                                  // name
    900       1, 1, 1, 0, 0, 1,                          // counts
    901       trap_id);                                  // parameter
    902 }
    903 
    904 const Operator* CommonOperatorBuilder::TrapUnless(int32_t trap_id) {
    905   switch (trap_id) {
    906 #define CACHED_TRAP_UNLESS(Trap)   \
    907   case Builtins::kThrowWasm##Trap: \
    908     return &cache_.kTrapUnless##Trap##Operator;
    909     CACHED_TRAP_UNLESS_LIST(CACHED_TRAP_UNLESS)
    910 #undef CACHED_TRAP_UNLESS
    911     default:
    912       break;
    913   }
    914   // Uncached
    915   return new (zone()) Operator1<int>(            // --
    916       IrOpcode::kTrapUnless,                     // opcode
    917       Operator::kFoldable | Operator::kNoThrow,  // properties
    918       "TrapUnless",                              // name
    919       1, 1, 1, 0, 0, 1,                          // counts
    920       trap_id);                                  // parameter
    921 }
    922 
    923 const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
    924   return new (zone()) Operator(               // --
    925       IrOpcode::kSwitch, Operator::kKontrol,  // opcode
    926       "Switch",                               // name
    927       1, 0, 1, 0, 0, control_output_count);   // counts
    928 }
    929 
    930 
    931 const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
    932   return new (zone()) Operator1<int32_t>(      // --
    933       IrOpcode::kIfValue, Operator::kKontrol,  // opcode
    934       "IfValue",                               // name
    935       0, 0, 1, 0, 0, 1,                        // counts
    936       index);                                  // parameter
    937 }
    938 
    939 
    940 const Operator* CommonOperatorBuilder::Start(int value_output_count) {
    941   return new (zone()) Operator(                                    // --
    942       IrOpcode::kStart, Operator::kFoldable | Operator::kNoThrow,  // opcode
    943       "Start",                                                     // name
    944       0, 0, 0, value_output_count, 1, 1);                          // counts
    945 }
    946 
    947 
    948 const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
    949   switch (control_input_count) {
    950 #define CACHED_LOOP(input_count) \
    951   case input_count:              \
    952     return &cache_.kLoop##input_count##Operator;
    953     CACHED_LOOP_LIST(CACHED_LOOP)
    954 #undef CACHED_LOOP
    955     default:
    956       break;
    957   }
    958   // Uncached.
    959   return new (zone()) Operator(             // --
    960       IrOpcode::kLoop, Operator::kKontrol,  // opcode
    961       "Loop",                               // name
    962       0, 0, control_input_count, 0, 0, 1);  // counts
    963 }
    964 
    965 
    966 const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
    967   switch (control_input_count) {
    968 #define CACHED_MERGE(input_count) \
    969   case input_count:               \
    970     return &cache_.kMerge##input_count##Operator;
    971     CACHED_MERGE_LIST(CACHED_MERGE)
    972 #undef CACHED_MERGE
    973     default:
    974       break;
    975   }
    976   // Uncached.
    977   return new (zone()) Operator(              // --
    978       IrOpcode::kMerge, Operator::kKontrol,  // opcode
    979       "Merge",                               // name
    980       0, 0, control_input_count, 0, 0, 1);   // counts
    981 }
    982 
    983 
    984 const Operator* CommonOperatorBuilder::Parameter(int index,
    985                                                  const char* debug_name) {
    986   if (!debug_name) {
    987     switch (index) {
    988 #define CACHED_PARAMETER(index) \
    989   case index:                   \
    990     return &cache_.kParameter##index##Operator;
    991       CACHED_PARAMETER_LIST(CACHED_PARAMETER)
    992 #undef CACHED_PARAMETER
    993       default:
    994         break;
    995     }
    996   }
    997   // Uncached.
    998   return new (zone()) Operator1<ParameterInfo>(  // --
    999       IrOpcode::kParameter, Operator::kPure,     // opcode
   1000       "Parameter",                               // name
   1001       1, 0, 0, 1, 0, 0,                          // counts
   1002       ParameterInfo(index, debug_name));         // parameter info
   1003 }
   1004 
   1005 const Operator* CommonOperatorBuilder::OsrValue(int index) {
   1006   return new (zone()) Operator1<int>(                // --
   1007       IrOpcode::kOsrValue, Operator::kNoProperties,  // opcode
   1008       "OsrValue",                                    // name
   1009       0, 0, 1, 1, 0, 0,                              // counts
   1010       index);                                        // parameter
   1011 }
   1012 
   1013 const Operator* CommonOperatorBuilder::OsrGuard(OsrGuardType type) {
   1014   return new (zone()) Operator1<OsrGuardType>(  // --
   1015       IrOpcode::kOsrGuard, Operator::kNoThrow,  // opcode
   1016       "OsrGuard",                               // name
   1017       1, 1, 1, 1, 1, 0,                         // counts
   1018       type);                                    // parameter
   1019 }
   1020 
   1021 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
   1022   return new (zone()) Operator1<int32_t>(         // --
   1023       IrOpcode::kInt32Constant, Operator::kPure,  // opcode
   1024       "Int32Constant",                            // name
   1025       0, 0, 0, 1, 0, 0,                           // counts
   1026       value);                                     // parameter
   1027 }
   1028 
   1029 
   1030 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
   1031   return new (zone()) Operator1<int64_t>(         // --
   1032       IrOpcode::kInt64Constant, Operator::kPure,  // opcode
   1033       "Int64Constant",                            // name
   1034       0, 0, 0, 1, 0, 0,                           // counts
   1035       value);                                     // parameter
   1036 }
   1037 
   1038 
   1039 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
   1040   return new (zone()) Operator1<float>(             // --
   1041       IrOpcode::kFloat32Constant, Operator::kPure,  // opcode
   1042       "Float32Constant",                            // name
   1043       0, 0, 0, 1, 0, 0,                             // counts
   1044       value);                                       // parameter
   1045 }
   1046 
   1047 
   1048 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
   1049   return new (zone()) Operator1<double>(            // --
   1050       IrOpcode::kFloat64Constant, Operator::kPure,  // opcode
   1051       "Float64Constant",                            // name
   1052       0, 0, 0, 1, 0, 0,                             // counts
   1053       value);                                       // parameter
   1054 }
   1055 
   1056 
   1057 const Operator* CommonOperatorBuilder::ExternalConstant(
   1058     const ExternalReference& value) {
   1059   return new (zone()) Operator1<ExternalReference>(  // --
   1060       IrOpcode::kExternalConstant, Operator::kPure,  // opcode
   1061       "ExternalConstant",                            // name
   1062       0, 0, 0, 1, 0, 0,                              // counts
   1063       value);                                        // parameter
   1064 }
   1065 
   1066 
   1067 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
   1068   return new (zone()) Operator1<double>(           // --
   1069       IrOpcode::kNumberConstant, Operator::kPure,  // opcode
   1070       "NumberConstant",                            // name
   1071       0, 0, 0, 1, 0, 0,                            // counts
   1072       value);                                      // parameter
   1073 }
   1074 
   1075 const Operator* CommonOperatorBuilder::PointerConstant(intptr_t value) {
   1076   return new (zone()) Operator1<intptr_t>(          // --
   1077       IrOpcode::kPointerConstant, Operator::kPure,  // opcode
   1078       "PointerConstant",                            // name
   1079       0, 0, 0, 1, 0, 0,                             // counts
   1080       value);                                       // parameter
   1081 }
   1082 
   1083 const Operator* CommonOperatorBuilder::HeapConstant(
   1084     const Handle<HeapObject>& value) {
   1085   return new (zone()) Operator1<Handle<HeapObject>>(  // --
   1086       IrOpcode::kHeapConstant, Operator::kPure,       // opcode
   1087       "HeapConstant",                                 // name
   1088       0, 0, 0, 1, 0, 0,                               // counts
   1089       value);                                         // parameter
   1090 }
   1091 
   1092 const Operator* CommonOperatorBuilder::RelocatableInt32Constant(
   1093     int32_t value, RelocInfo::Mode rmode) {
   1094   return new (zone()) Operator1<RelocatablePtrConstantInfo>(  // --
   1095       IrOpcode::kRelocatableInt32Constant, Operator::kPure,   // opcode
   1096       "RelocatableInt32Constant",                             // name
   1097       0, 0, 0, 1, 0, 0,                                       // counts
   1098       RelocatablePtrConstantInfo(value, rmode));              // parameter
   1099 }
   1100 
   1101 const Operator* CommonOperatorBuilder::RelocatableInt64Constant(
   1102     int64_t value, RelocInfo::Mode rmode) {
   1103   return new (zone()) Operator1<RelocatablePtrConstantInfo>(  // --
   1104       IrOpcode::kRelocatableInt64Constant, Operator::kPure,   // opcode
   1105       "RelocatableInt64Constant",                             // name
   1106       0, 0, 0, 1, 0, 0,                                       // counts
   1107       RelocatablePtrConstantInfo(value, rmode));              // parameter
   1108 }
   1109 
   1110 const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
   1111                                               BranchHint hint) {
   1112   return new (zone()) Operator1<SelectParameters>(  // --
   1113       IrOpcode::kSelect, Operator::kPure,           // opcode
   1114       "Select",                                     // name
   1115       3, 0, 0, 1, 0, 0,                             // counts
   1116       SelectParameters(rep, hint));                 // parameter
   1117 }
   1118 
   1119 
   1120 const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
   1121                                            int value_input_count) {
   1122   DCHECK(value_input_count > 0);  // Disallow empty phis.
   1123 #define CACHED_PHI(kRep, kValueInputCount)                 \
   1124   if (MachineRepresentation::kRep == rep &&                \
   1125       kValueInputCount == value_input_count) {             \
   1126     return &cache_.kPhi##kRep##kValueInputCount##Operator; \
   1127   }
   1128   CACHED_PHI_LIST(CACHED_PHI)
   1129 #undef CACHED_PHI
   1130   // Uncached.
   1131   return new (zone()) Operator1<MachineRepresentation>(  // --
   1132       IrOpcode::kPhi, Operator::kPure,                   // opcode
   1133       "Phi",                                             // name
   1134       value_input_count, 0, 1, 1, 0, 0,                  // counts
   1135       rep);                                              // parameter
   1136 }
   1137 
   1138 const Operator* CommonOperatorBuilder::TypeGuard(Type* type) {
   1139   return new (zone()) Operator1<Type*>(       // --
   1140       IrOpcode::kTypeGuard, Operator::kPure,  // opcode
   1141       "TypeGuard",                            // name
   1142       1, 0, 1, 1, 0, 0,                       // counts
   1143       type);                                  // parameter
   1144 }
   1145 
   1146 const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
   1147   DCHECK(effect_input_count > 0);  // Disallow empty effect phis.
   1148   switch (effect_input_count) {
   1149 #define CACHED_EFFECT_PHI(input_count) \
   1150   case input_count:                    \
   1151     return &cache_.kEffectPhi##input_count##Operator;
   1152     CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
   1153 #undef CACHED_EFFECT_PHI
   1154     default:
   1155       break;
   1156   }
   1157   // Uncached.
   1158   return new (zone()) Operator(                  // --
   1159       IrOpcode::kEffectPhi, Operator::kKontrol,  // opcode
   1160       "EffectPhi",                               // name
   1161       0, effect_input_count, 1, 0, 1, 0);        // counts
   1162 }
   1163 
   1164 const Operator* CommonOperatorBuilder::InductionVariablePhi(int input_count) {
   1165   DCHECK(input_count >= 4);  // There must be always the entry, backedge,
   1166                              // increment and at least one bound.
   1167   switch (input_count) {
   1168 #define CACHED_INDUCTION_VARIABLE_PHI(input_count) \
   1169   case input_count:                                \
   1170     return &cache_.kInductionVariablePhi##input_count##Operator;
   1171     CACHED_INDUCTION_VARIABLE_PHI_LIST(CACHED_INDUCTION_VARIABLE_PHI)
   1172 #undef CACHED_INDUCTION_VARIABLE_PHI
   1173     default:
   1174       break;
   1175   }
   1176   // Uncached.
   1177   return new (zone()) Operator(                          // --
   1178       IrOpcode::kInductionVariablePhi, Operator::kPure,  // opcode
   1179       "InductionVariablePhi",                            // name
   1180       input_count, 0, 1, 1, 0, 0);                       // counts
   1181 }
   1182 
   1183 const Operator* CommonOperatorBuilder::BeginRegion(
   1184     RegionObservability region_observability) {
   1185   switch (region_observability) {
   1186     case RegionObservability::kObservable:
   1187       return &cache_.kBeginRegionObservableOperator;
   1188     case RegionObservability::kNotObservable:
   1189       return &cache_.kBeginRegionNotObservableOperator;
   1190   }
   1191   UNREACHABLE();
   1192   return nullptr;
   1193 }
   1194 
   1195 const Operator* CommonOperatorBuilder::StateValues(int arguments,
   1196                                                    SparseInputMask bitmask) {
   1197   if (bitmask.IsDense()) {
   1198     switch (arguments) {
   1199 #define CACHED_STATE_VALUES(arguments) \
   1200   case arguments:                      \
   1201     return &cache_.kStateValues##arguments##Operator;
   1202       CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
   1203 #undef CACHED_STATE_VALUES
   1204       default:
   1205         break;
   1206     }
   1207   }
   1208 
   1209 #if DEBUG
   1210   DCHECK(bitmask.IsDense() || bitmask.CountReal() == arguments);
   1211 #endif
   1212 
   1213   // Uncached.
   1214   return new (zone()) Operator1<SparseInputMask>(  // --
   1215       IrOpcode::kStateValues, Operator::kPure,     // opcode
   1216       "StateValues",                               // name
   1217       arguments, 0, 0, 1, 0, 0,                    // counts
   1218       bitmask);                                    // parameter
   1219 }
   1220 
   1221 const Operator* CommonOperatorBuilder::TypedStateValues(
   1222     const ZoneVector<MachineType>* types, SparseInputMask bitmask) {
   1223 #if DEBUG
   1224   DCHECK(bitmask.IsDense() ||
   1225          bitmask.CountReal() == static_cast<int>(types->size()));
   1226 #endif
   1227 
   1228   return new (zone()) Operator1<TypedStateValueInfo>(  // --
   1229       IrOpcode::kTypedStateValues, Operator::kPure,    // opcode
   1230       "TypedStateValues",                              // name
   1231       static_cast<int>(types->size()), 0, 0, 1, 0, 0,  // counts
   1232       TypedStateValueInfo(types, bitmask));            // parameters
   1233 }
   1234 
   1235 const Operator* CommonOperatorBuilder::ArgumentsObjectState() {
   1236   return new (zone()) Operator(                          // --
   1237       IrOpcode::kArgumentsObjectState, Operator::kPure,  // opcode
   1238       "ArgumentsObjectState",                            // name
   1239       0, 0, 0, 1, 0, 0);                                 // counts
   1240 }
   1241 
   1242 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots) {
   1243   return new (zone()) Operator1<int>(           // --
   1244       IrOpcode::kObjectState, Operator::kPure,  // opcode
   1245       "ObjectState",                            // name
   1246       pointer_slots, 0, 0, 1, 0, 0,             // counts
   1247       pointer_slots);                           // parameter
   1248 }
   1249 
   1250 const Operator* CommonOperatorBuilder::TypedObjectState(
   1251     const ZoneVector<MachineType>* types) {
   1252   return new (zone()) Operator1<const ZoneVector<MachineType>*>(  // --
   1253       IrOpcode::kTypedObjectState, Operator::kPure,               // opcode
   1254       "TypedObjectState",                                         // name
   1255       static_cast<int>(types->size()), 0, 0, 1, 0, 0,             // counts
   1256       types);                                                     // parameter
   1257 }
   1258 
   1259 const Operator* CommonOperatorBuilder::FrameState(
   1260     BailoutId bailout_id, OutputFrameStateCombine state_combine,
   1261     const FrameStateFunctionInfo* function_info) {
   1262   FrameStateInfo state_info(bailout_id, state_combine, function_info);
   1263   return new (zone()) Operator1<FrameStateInfo>(  // --
   1264       IrOpcode::kFrameState, Operator::kPure,     // opcode
   1265       "FrameState",                               // name
   1266       5, 0, 0, 1, 0, 0,                           // counts
   1267       state_info);                                // parameter
   1268 }
   1269 
   1270 
   1271 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
   1272   class CallOperator final : public Operator1<const CallDescriptor*> {
   1273    public:
   1274     explicit CallOperator(const CallDescriptor* descriptor)
   1275         : Operator1<const CallDescriptor*>(
   1276               IrOpcode::kCall, descriptor->properties(), "Call",
   1277               descriptor->InputCount() + descriptor->FrameStateCount(),
   1278               Operator::ZeroIfPure(descriptor->properties()),
   1279               Operator::ZeroIfEliminatable(descriptor->properties()),
   1280               descriptor->ReturnCount(),
   1281               Operator::ZeroIfPure(descriptor->properties()),
   1282               Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
   1283 
   1284     void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
   1285       os << "[" << *parameter() << "]";
   1286     }
   1287   };
   1288   return new (zone()) CallOperator(descriptor);
   1289 }
   1290 
   1291 
   1292 const Operator* CommonOperatorBuilder::TailCall(
   1293     const CallDescriptor* descriptor) {
   1294   class TailCallOperator final : public Operator1<const CallDescriptor*> {
   1295    public:
   1296     explicit TailCallOperator(const CallDescriptor* descriptor)
   1297         : Operator1<const CallDescriptor*>(
   1298               IrOpcode::kTailCall,
   1299               descriptor->properties() | Operator::kNoThrow, "TailCall",
   1300               descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
   1301               0, 1, descriptor) {}
   1302 
   1303     void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
   1304       os << "[" << *parameter() << "]";
   1305     }
   1306   };
   1307   return new (zone()) TailCallOperator(descriptor);
   1308 }
   1309 
   1310 
   1311 const Operator* CommonOperatorBuilder::Projection(size_t index) {
   1312   switch (index) {
   1313 #define CACHED_PROJECTION(index) \
   1314   case index:                    \
   1315     return &cache_.kProjection##index##Operator;
   1316     CACHED_PROJECTION_LIST(CACHED_PROJECTION)
   1317 #undef CACHED_PROJECTION
   1318     default:
   1319       break;
   1320   }
   1321   // Uncached.
   1322   return new (zone()) Operator1<size_t>(  // --
   1323       IrOpcode::kProjection,              // opcode
   1324       Operator::kPure,                    // flags
   1325       "Projection",                       // name
   1326       1, 0, 1, 1, 0, 0,                   // counts
   1327       index);                             // parameter
   1328 }
   1329 
   1330 
   1331 const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
   1332                                                         int size) {
   1333   if (op->opcode() == IrOpcode::kPhi) {
   1334     return Phi(PhiRepresentationOf(op), size);
   1335   } else if (op->opcode() == IrOpcode::kEffectPhi) {
   1336     return EffectPhi(size);
   1337   } else if (op->opcode() == IrOpcode::kMerge) {
   1338     return Merge(size);
   1339   } else if (op->opcode() == IrOpcode::kLoop) {
   1340     return Loop(size);
   1341   } else {
   1342     UNREACHABLE();
   1343     return nullptr;
   1344   }
   1345 }
   1346 
   1347 const FrameStateFunctionInfo*
   1348 CommonOperatorBuilder::CreateFrameStateFunctionInfo(
   1349     FrameStateType type, int parameter_count, int local_count,
   1350     Handle<SharedFunctionInfo> shared_info) {
   1351   return new (zone()->New(sizeof(FrameStateFunctionInfo)))
   1352       FrameStateFunctionInfo(type, parameter_count, local_count, shared_info);
   1353 }
   1354 
   1355 }  // namespace compiler
   1356 }  // namespace internal
   1357 }  // namespace v8
   1358