Home | History | Annotate | Download | only in compiler
      1 // Copyright 2012 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/simplified-operator.h"
      6 
      7 #include "src/base/lazy-instance.h"
      8 #include "src/compiler/opcodes.h"
      9 #include "src/compiler/operator.h"
     10 #include "src/types.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 namespace compiler {
     15 
     16 size_t hash_value(BaseTaggedness base_taggedness) {
     17   return static_cast<uint8_t>(base_taggedness);
     18 }
     19 
     20 std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
     21   switch (base_taggedness) {
     22     case kUntaggedBase:
     23       return os << "untagged base";
     24     case kTaggedBase:
     25       return os << "tagged base";
     26   }
     27   UNREACHABLE();
     28   return os;
     29 }
     30 
     31 
     32 MachineType BufferAccess::machine_type() const {
     33   switch (external_array_type_) {
     34     case kExternalUint8Array:
     35     case kExternalUint8ClampedArray:
     36       return MachineType::Uint8();
     37     case kExternalInt8Array:
     38       return MachineType::Int8();
     39     case kExternalUint16Array:
     40       return MachineType::Uint16();
     41     case kExternalInt16Array:
     42       return MachineType::Int16();
     43     case kExternalUint32Array:
     44       return MachineType::Uint32();
     45     case kExternalInt32Array:
     46       return MachineType::Int32();
     47     case kExternalFloat32Array:
     48       return MachineType::Float32();
     49     case kExternalFloat64Array:
     50       return MachineType::Float64();
     51   }
     52   UNREACHABLE();
     53   return MachineType::None();
     54 }
     55 
     56 
     57 bool operator==(BufferAccess lhs, BufferAccess rhs) {
     58   return lhs.external_array_type() == rhs.external_array_type();
     59 }
     60 
     61 
     62 bool operator!=(BufferAccess lhs, BufferAccess rhs) { return !(lhs == rhs); }
     63 
     64 
     65 size_t hash_value(BufferAccess access) {
     66   return base::hash<ExternalArrayType>()(access.external_array_type());
     67 }
     68 
     69 
     70 std::ostream& operator<<(std::ostream& os, BufferAccess access) {
     71   switch (access.external_array_type()) {
     72 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
     73   case kExternal##Type##Array:                          \
     74     return os << #Type;
     75     TYPED_ARRAYS(TYPED_ARRAY_CASE)
     76 #undef TYPED_ARRAY_CASE
     77   }
     78   UNREACHABLE();
     79   return os;
     80 }
     81 
     82 
     83 BufferAccess const BufferAccessOf(const Operator* op) {
     84   DCHECK(op->opcode() == IrOpcode::kLoadBuffer ||
     85          op->opcode() == IrOpcode::kStoreBuffer);
     86   return OpParameter<BufferAccess>(op);
     87 }
     88 
     89 
     90 bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) {
     91   // On purpose we don't include the write barrier kind here, as this method is
     92   // really only relevant for eliminating loads and they don't care about the
     93   // write barrier mode.
     94   return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
     95          lhs.machine_type == rhs.machine_type;
     96 }
     97 
     98 
     99 bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) {
    100   return !(lhs == rhs);
    101 }
    102 
    103 
    104 size_t hash_value(FieldAccess const& access) {
    105   // On purpose we don't include the write barrier kind here, as this method is
    106   // really only relevant for eliminating loads and they don't care about the
    107   // write barrier mode.
    108   return base::hash_combine(access.base_is_tagged, access.offset,
    109                             access.machine_type);
    110 }
    111 
    112 
    113 std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
    114   os << "[" << access.base_is_tagged << ", " << access.offset << ", ";
    115 #ifdef OBJECT_PRINT
    116   Handle<Name> name;
    117   if (access.name.ToHandle(&name)) {
    118     name->Print(os);
    119     os << ", ";
    120   }
    121 #endif
    122   access.type->PrintTo(os);
    123   os << ", " << access.machine_type << ", " << access.write_barrier_kind << "]";
    124   return os;
    125 }
    126 
    127 
    128 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
    129   // On purpose we don't include the write barrier kind here, as this method is
    130   // really only relevant for eliminating loads and they don't care about the
    131   // write barrier mode.
    132   return lhs.base_is_tagged == rhs.base_is_tagged &&
    133          lhs.header_size == rhs.header_size &&
    134          lhs.machine_type == rhs.machine_type;
    135 }
    136 
    137 
    138 bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) {
    139   return !(lhs == rhs);
    140 }
    141 
    142 
    143 size_t hash_value(ElementAccess const& access) {
    144   // On purpose we don't include the write barrier kind here, as this method is
    145   // really only relevant for eliminating loads and they don't care about the
    146   // write barrier mode.
    147   return base::hash_combine(access.base_is_tagged, access.header_size,
    148                             access.machine_type);
    149 }
    150 
    151 
    152 std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
    153   os << access.base_is_tagged << ", " << access.header_size << ", ";
    154   access.type->PrintTo(os);
    155   os << ", " << access.machine_type << ", " << access.write_barrier_kind;
    156   return os;
    157 }
    158 
    159 
    160 const FieldAccess& FieldAccessOf(const Operator* op) {
    161   DCHECK_NOT_NULL(op);
    162   DCHECK(op->opcode() == IrOpcode::kLoadField ||
    163          op->opcode() == IrOpcode::kStoreField);
    164   return OpParameter<FieldAccess>(op);
    165 }
    166 
    167 
    168 const ElementAccess& ElementAccessOf(const Operator* op) {
    169   DCHECK_NOT_NULL(op);
    170   DCHECK(op->opcode() == IrOpcode::kLoadElement ||
    171          op->opcode() == IrOpcode::kStoreElement);
    172   return OpParameter<ElementAccess>(op);
    173 }
    174 
    175 size_t hash_value(CheckFloat64HoleMode mode) {
    176   return static_cast<size_t>(mode);
    177 }
    178 
    179 std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) {
    180   switch (mode) {
    181     case CheckFloat64HoleMode::kAllowReturnHole:
    182       return os << "allow-return-hole";
    183     case CheckFloat64HoleMode::kNeverReturnHole:
    184       return os << "never-return-hole";
    185   }
    186   UNREACHABLE();
    187   return os;
    188 }
    189 
    190 CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator* op) {
    191   DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
    192   return OpParameter<CheckFloat64HoleMode>(op);
    193 }
    194 
    195 size_t hash_value(CheckTaggedHoleMode mode) {
    196   return static_cast<size_t>(mode);
    197 }
    198 
    199 std::ostream& operator<<(std::ostream& os, CheckTaggedHoleMode mode) {
    200   switch (mode) {
    201     case CheckTaggedHoleMode::kConvertHoleToUndefined:
    202       return os << "convert-hole-to-undefined";
    203     case CheckTaggedHoleMode::kNeverReturnHole:
    204       return os << "never-return-hole";
    205   }
    206   UNREACHABLE();
    207   return os;
    208 }
    209 
    210 CheckTaggedHoleMode CheckTaggedHoleModeOf(const Operator* op) {
    211   DCHECK_EQ(IrOpcode::kCheckTaggedHole, op->opcode());
    212   return OpParameter<CheckTaggedHoleMode>(op);
    213 }
    214 
    215 Type* TypeOf(const Operator* op) {
    216   DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode());
    217   return OpParameter<Type*>(op);
    218 }
    219 
    220 BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) {
    221   DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd ||
    222          op->opcode() == IrOpcode::kSpeculativeNumberSubtract ||
    223          op->opcode() == IrOpcode::kSpeculativeNumberMultiply ||
    224          op->opcode() == IrOpcode::kSpeculativeNumberDivide ||
    225          op->opcode() == IrOpcode::kSpeculativeNumberModulus);
    226   return OpParameter<BinaryOperationHints::Hint>(op);
    227 }
    228 
    229 CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) {
    230   DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
    231          op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
    232          op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual);
    233   return OpParameter<CompareOperationHints::Hint>(op);
    234 }
    235 
    236 #define PURE_OP_LIST(V)                                    \
    237   V(BooleanNot, Operator::kNoProperties, 1)                \
    238   V(BooleanToNumber, Operator::kNoProperties, 1)           \
    239   V(NumberEqual, Operator::kCommutative, 2)                \
    240   V(NumberLessThan, Operator::kNoProperties, 2)            \
    241   V(NumberLessThanOrEqual, Operator::kNoProperties, 2)     \
    242   V(NumberAdd, Operator::kCommutative, 2)                  \
    243   V(NumberSubtract, Operator::kNoProperties, 2)            \
    244   V(NumberMultiply, Operator::kCommutative, 2)             \
    245   V(NumberDivide, Operator::kNoProperties, 2)              \
    246   V(NumberModulus, Operator::kNoProperties, 2)             \
    247   V(NumberBitwiseOr, Operator::kCommutative, 2)            \
    248   V(NumberBitwiseXor, Operator::kCommutative, 2)           \
    249   V(NumberBitwiseAnd, Operator::kCommutative, 2)           \
    250   V(NumberShiftLeft, Operator::kNoProperties, 2)           \
    251   V(NumberShiftRight, Operator::kNoProperties, 2)          \
    252   V(NumberShiftRightLogical, Operator::kNoProperties, 2)   \
    253   V(NumberImul, Operator::kCommutative, 2)                 \
    254   V(NumberAbs, Operator::kNoProperties, 1)                 \
    255   V(NumberClz32, Operator::kNoProperties, 1)               \
    256   V(NumberCeil, Operator::kNoProperties, 1)                \
    257   V(NumberFloor, Operator::kNoProperties, 1)               \
    258   V(NumberFround, Operator::kNoProperties, 1)              \
    259   V(NumberAtan, Operator::kNoProperties, 1)                \
    260   V(NumberAtan2, Operator::kNoProperties, 2)               \
    261   V(NumberAtanh, Operator::kNoProperties, 1)               \
    262   V(NumberCbrt, Operator::kNoProperties, 1)                \
    263   V(NumberCos, Operator::kNoProperties, 1)                 \
    264   V(NumberExp, Operator::kNoProperties, 1)                 \
    265   V(NumberExpm1, Operator::kNoProperties, 1)               \
    266   V(NumberLog, Operator::kNoProperties, 1)                 \
    267   V(NumberLog1p, Operator::kNoProperties, 1)               \
    268   V(NumberLog10, Operator::kNoProperties, 1)               \
    269   V(NumberLog2, Operator::kNoProperties, 1)                \
    270   V(NumberRound, Operator::kNoProperties, 1)               \
    271   V(NumberSin, Operator::kNoProperties, 1)                 \
    272   V(NumberSqrt, Operator::kNoProperties, 1)                \
    273   V(NumberTan, Operator::kNoProperties, 1)                 \
    274   V(NumberTrunc, Operator::kNoProperties, 1)               \
    275   V(NumberToInt32, Operator::kNoProperties, 1)             \
    276   V(NumberToUint32, Operator::kNoProperties, 1)            \
    277   V(NumberSilenceNaN, Operator::kNoProperties, 1)          \
    278   V(StringFromCharCode, Operator::kNoProperties, 1)        \
    279   V(StringToNumber, Operator::kNoProperties, 1)            \
    280   V(PlainPrimitiveToNumber, Operator::kNoProperties, 1)    \
    281   V(PlainPrimitiveToWord32, Operator::kNoProperties, 1)    \
    282   V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1)   \
    283   V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1) \
    284   V(ChangeTaggedToInt32, Operator::kNoProperties, 1)       \
    285   V(ChangeTaggedToUint32, Operator::kNoProperties, 1)      \
    286   V(ChangeTaggedToFloat64, Operator::kNoProperties, 1)     \
    287   V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1) \
    288   V(ChangeInt32ToTagged, Operator::kNoProperties, 1)       \
    289   V(ChangeUint32ToTagged, Operator::kNoProperties, 1)      \
    290   V(ChangeFloat64ToTagged, Operator::kNoProperties, 1)     \
    291   V(ChangeTaggedToBit, Operator::kNoProperties, 1)         \
    292   V(ChangeBitToTagged, Operator::kNoProperties, 1)         \
    293   V(TruncateTaggedToWord32, Operator::kNoProperties, 1)    \
    294   V(TruncateTaggedToFloat64, Operator::kNoProperties, 1)   \
    295   V(ObjectIsCallable, Operator::kNoProperties, 1)          \
    296   V(ObjectIsNumber, Operator::kNoProperties, 1)            \
    297   V(ObjectIsReceiver, Operator::kNoProperties, 1)          \
    298   V(ObjectIsSmi, Operator::kNoProperties, 1)               \
    299   V(ObjectIsString, Operator::kNoProperties, 1)            \
    300   V(ObjectIsUndetectable, Operator::kNoProperties, 1)      \
    301   V(StringEqual, Operator::kCommutative, 2)                \
    302   V(StringLessThan, Operator::kNoProperties, 2)            \
    303   V(StringLessThanOrEqual, Operator::kNoProperties, 2)
    304 
    305 #define SPECULATIVE_BINOP_LIST(V) \
    306   V(SpeculativeNumberAdd)         \
    307   V(SpeculativeNumberSubtract)    \
    308   V(SpeculativeNumberDivide)      \
    309   V(SpeculativeNumberMultiply)    \
    310   V(SpeculativeNumberModulus)
    311 
    312 #define CHECKED_OP_LIST(V)    \
    313   V(CheckTaggedPointer, 1)    \
    314   V(CheckTaggedSigned, 1)     \
    315   V(CheckedInt32Add, 2)       \
    316   V(CheckedInt32Sub, 2)       \
    317   V(CheckedUint32ToInt32, 1)  \
    318   V(CheckedFloat64ToInt32, 1) \
    319   V(CheckedTaggedToInt32, 1)  \
    320   V(CheckedTaggedToFloat64, 1)
    321 
    322 struct SimplifiedOperatorGlobalCache final {
    323 #define PURE(Name, properties, input_count)                                \
    324   struct Name##Operator final : public Operator {                          \
    325     Name##Operator()                                                       \
    326         : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
    327                    input_count, 0, 0, 1, 0, 0) {}                          \
    328   };                                                                       \
    329   Name##Operator k##Name;
    330   PURE_OP_LIST(PURE)
    331 #undef PURE
    332 
    333 #define CHECKED(Name, value_input_count)                            \
    334   struct Name##Operator final : public Operator {                   \
    335     Name##Operator()                                                \
    336         : Operator(IrOpcode::k##Name,                               \
    337                    Operator::kFoldable | Operator::kNoThrow, #Name, \
    338                    value_input_count, 1, 1, 1, 1, 0) {}             \
    339   };                                                                \
    340   Name##Operator k##Name;
    341   CHECKED_OP_LIST(CHECKED)
    342 #undef CHECKED
    343 
    344   template <CheckFloat64HoleMode kMode>
    345   struct CheckFloat64HoleNaNOperator final
    346       : public Operator1<CheckFloat64HoleMode> {
    347     CheckFloat64HoleNaNOperator()
    348         : Operator1<CheckFloat64HoleMode>(
    349               IrOpcode::kCheckFloat64Hole,
    350               Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1,
    351               1, 1, 1, 1, 0, kMode) {}
    352   };
    353   CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole>
    354       kCheckFloat64HoleAllowReturnHoleOperator;
    355   CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kNeverReturnHole>
    356       kCheckFloat64HoleNeverReturnHoleOperator;
    357 
    358   template <CheckTaggedHoleMode kMode>
    359   struct CheckTaggedHoleOperator final : public Operator1<CheckTaggedHoleMode> {
    360     CheckTaggedHoleOperator()
    361         : Operator1<CheckTaggedHoleMode>(
    362               IrOpcode::kCheckTaggedHole,
    363               Operator::kFoldable | Operator::kNoThrow, "CheckTaggedHole", 1, 1,
    364               1, 1, 1, 0, kMode) {}
    365   };
    366   CheckTaggedHoleOperator<CheckTaggedHoleMode::kConvertHoleToUndefined>
    367       kCheckTaggedHoleConvertHoleToUndefinedOperator;
    368   CheckTaggedHoleOperator<CheckTaggedHoleMode::kNeverReturnHole>
    369       kCheckTaggedHoleNeverReturnHoleOperator;
    370 
    371   template <PretenureFlag kPretenure>
    372   struct AllocateOperator final : public Operator1<PretenureFlag> {
    373     AllocateOperator()
    374         : Operator1<PretenureFlag>(
    375               IrOpcode::kAllocate,
    376               Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
    377               "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {}
    378   };
    379   AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator;
    380   AllocateOperator<TENURED> kAllocateTenuredOperator;
    381 
    382 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size)                          \
    383   struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> {  \
    384     LoadBuffer##Type##Operator()                                              \
    385         : Operator1<BufferAccess>(                                            \
    386               IrOpcode::kLoadBuffer,                                          \
    387               Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,   \
    388               "LoadBuffer", 3, 1, 1, 1, 1, 0,                                 \
    389               BufferAccess(kExternal##Type##Array)) {}                        \
    390   };                                                                          \
    391   struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \
    392     StoreBuffer##Type##Operator()                                             \
    393         : Operator1<BufferAccess>(                                            \
    394               IrOpcode::kStoreBuffer,                                         \
    395               Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,    \
    396               "StoreBuffer", 4, 1, 1, 0, 1, 0,                                \
    397               BufferAccess(kExternal##Type##Array)) {}                        \
    398   };                                                                          \
    399   LoadBuffer##Type##Operator kLoadBuffer##Type;                               \
    400   StoreBuffer##Type##Operator kStoreBuffer##Type;
    401   TYPED_ARRAYS(BUFFER_ACCESS)
    402 #undef BUFFER_ACCESS
    403 };
    404 
    405 
    406 static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache =
    407     LAZY_INSTANCE_INITIALIZER;
    408 
    409 
    410 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
    411     : cache_(kCache.Get()), zone_(zone) {}
    412 
    413 #define GET_FROM_CACHE(Name, properties, input_count) \
    414   const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
    415 PURE_OP_LIST(GET_FROM_CACHE)
    416 #undef GET_FROM_CACHE
    417 
    418 #define GET_FROM_CACHE(Name, value_input_count) \
    419   const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
    420 CHECKED_OP_LIST(GET_FROM_CACHE)
    421 #undef GET_FROM_CACHE
    422 
    423 const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
    424     CheckFloat64HoleMode mode) {
    425   switch (mode) {
    426     case CheckFloat64HoleMode::kAllowReturnHole:
    427       return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
    428     case CheckFloat64HoleMode::kNeverReturnHole:
    429       return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
    430   }
    431   UNREACHABLE();
    432   return nullptr;
    433 }
    434 
    435 const Operator* SimplifiedOperatorBuilder::CheckTaggedHole(
    436     CheckTaggedHoleMode mode) {
    437   switch (mode) {
    438     case CheckTaggedHoleMode::kConvertHoleToUndefined:
    439       return &cache_.kCheckTaggedHoleConvertHoleToUndefinedOperator;
    440     case CheckTaggedHoleMode::kNeverReturnHole:
    441       return &cache_.kCheckTaggedHoleNeverReturnHoleOperator;
    442   }
    443   UNREACHABLE();
    444   return nullptr;
    445 }
    446 
    447 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) {
    448   return new (zone()) Operator(IrOpcode::kReferenceEqual,
    449                                Operator::kCommutative | Operator::kPure,
    450                                "ReferenceEqual", 2, 0, 0, 1, 0, 0);
    451 }
    452 
    453 const Operator* SimplifiedOperatorBuilder::CheckBounds() {
    454   // TODO(bmeurer): Cache this operator. Make it pure!
    455   return new (zone())
    456       Operator(IrOpcode::kCheckBounds, Operator::kFoldable | Operator::kNoThrow,
    457                "CheckBounds", 2, 1, 1, 1, 1, 0);
    458 }
    459 
    460 const Operator* SimplifiedOperatorBuilder::TypeGuard(Type* type) {
    461   class TypeGuardOperator final : public Operator1<Type*> {
    462    public:
    463     explicit TypeGuardOperator(Type* type)
    464         : Operator1<Type*>(                           // --
    465               IrOpcode::kTypeGuard, Operator::kPure,  // opcode
    466               "TypeGuard",                            // name
    467               1, 0, 1, 1, 0, 0,                       // counts
    468               type) {}                                // parameter
    469 
    470     void PrintParameter(std::ostream& os) const final {
    471       parameter()->PrintTo(os);
    472     }
    473   };
    474   return new (zone()) TypeGuardOperator(type);
    475 }
    476 
    477 const Operator* SimplifiedOperatorBuilder::Allocate(PretenureFlag pretenure) {
    478   switch (pretenure) {
    479     case NOT_TENURED:
    480       return &cache_.kAllocateNotTenuredOperator;
    481     case TENURED:
    482       return &cache_.kAllocateTenuredOperator;
    483   }
    484   UNREACHABLE();
    485   return nullptr;
    486 }
    487 
    488 
    489 const Operator* SimplifiedOperatorBuilder::LoadBuffer(BufferAccess access) {
    490   switch (access.external_array_type()) {
    491 #define LOAD_BUFFER(Type, type, TYPE, ctype, size) \
    492   case kExternal##Type##Array:                     \
    493     return &cache_.kLoadBuffer##Type;
    494     TYPED_ARRAYS(LOAD_BUFFER)
    495 #undef LOAD_BUFFER
    496   }
    497   UNREACHABLE();
    498   return nullptr;
    499 }
    500 
    501 
    502 const Operator* SimplifiedOperatorBuilder::StoreBuffer(BufferAccess access) {
    503   switch (access.external_array_type()) {
    504 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \
    505   case kExternal##Type##Array:                      \
    506     return &cache_.kStoreBuffer##Type;
    507     TYPED_ARRAYS(STORE_BUFFER)
    508 #undef STORE_BUFFER
    509   }
    510   UNREACHABLE();
    511   return nullptr;
    512 }
    513 
    514 #define SPECULATIVE_BINOP_DEF(Name)                                            \
    515   const Operator* SimplifiedOperatorBuilder::Name(                             \
    516       BinaryOperationHints::Hint hint) {                                       \
    517     return new (zone()) Operator1<BinaryOperationHints::Hint>(                 \
    518         IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, 2, \
    519         1, 1, 1, 1, 0, hint);                                                  \
    520   }
    521 SPECULATIVE_BINOP_LIST(SPECULATIVE_BINOP_DEF)
    522 #undef SPECULATIVE_BINOP_DEF
    523 
    524 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberEqual(
    525     CompareOperationHints::Hint hint) {
    526   return new (zone()) Operator1<CompareOperationHints::Hint>(
    527       IrOpcode::kSpeculativeNumberEqual,
    528       Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberEqual", 2, 1,
    529       1, 1, 1, 0, hint);
    530 }
    531 
    532 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThan(
    533     CompareOperationHints::Hint hint) {
    534   return new (zone()) Operator1<CompareOperationHints::Hint>(
    535       IrOpcode::kSpeculativeNumberLessThan,
    536       Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberLessThan", 2,
    537       1, 1, 1, 1, 0, hint);
    538 }
    539 
    540 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThanOrEqual(
    541     CompareOperationHints::Hint hint) {
    542   return new (zone()) Operator1<CompareOperationHints::Hint>(
    543       IrOpcode::kSpeculativeNumberLessThanOrEqual,
    544       Operator::kFoldable | Operator::kNoThrow,
    545       "SpeculativeNumberLessThanOrEqual", 2, 1, 1, 1, 1, 0, hint);
    546 }
    547 
    548 #define ACCESS_OP_LIST(V)                                    \
    549   V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1)     \
    550   V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0)     \
    551   V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
    552   V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0)
    553 
    554 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
    555                output_count)                                                   \
    556   const Operator* SimplifiedOperatorBuilder::Name(const Type& access) {        \
    557     return new (zone())                                                        \
    558         Operator1<Type>(IrOpcode::k##Name,                                     \
    559                         Operator::kNoDeopt | Operator::kNoThrow | properties,  \
    560                         #Name, value_input_count, 1, control_input_count,      \
    561                         output_count, 1, 0, access);                           \
    562   }
    563 ACCESS_OP_LIST(ACCESS)
    564 #undef ACCESS
    565 
    566 }  // namespace compiler
    567 }  // namespace internal
    568 }  // namespace v8
    569