diff options
author | Michaël Zasso <targos@protonmail.com> | 2016-09-06 22:49:51 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2016-09-22 09:51:19 +0200 |
commit | ec02b811a8a5c999bab4de312be2d732b7d9d50b (patch) | |
tree | ca3068017254f238cf413a451c57a803572983a4 /deps/v8/src/compiler/simplified-operator.cc | |
parent | d2eb7ce0105369a9cad82787cb33a665e9bd00ad (diff) | |
download | node-new-ec02b811a8a5c999bab4de312be2d732b7d9d50b.tar.gz |
deps: update V8 to 5.4.500.27
Pick up latest commit from the 5.4-lkgr branch.
deps: edit V8 gitignore to allow trace event copy
deps: update V8 trace event to 315bf1e2d45be7d53346c31cfcc37424a32c30c8
deps: edit V8 gitignore to allow gtest_prod.h copy
deps: update V8 gtest to 6f8a66431cb592dad629028a50b3dd418a408c87
PR-URL: https://github.com/nodejs/node/pull/8317
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/src/compiler/simplified-operator.cc')
-rw-r--r-- | deps/v8/src/compiler/simplified-operator.cc | 645 |
1 files changed, 563 insertions, 82 deletions
diff --git a/deps/v8/src/compiler/simplified-operator.cc b/deps/v8/src/compiler/simplified-operator.cc index daa9501b8c..cf0c3deb56 100644 --- a/deps/v8/src/compiler/simplified-operator.cc +++ b/deps/v8/src/compiler/simplified-operator.cc @@ -13,6 +13,10 @@ namespace v8 { namespace internal { namespace compiler { +size_t hash_value(BaseTaggedness base_taggedness) { + return static_cast<uint8_t>(base_taggedness); +} + std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) { switch (base_taggedness) { case kUntaggedBase: @@ -84,6 +88,9 @@ BufferAccess const BufferAccessOf(const Operator* op) { bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) { + // On purpose we don't include the write barrier kind here, as this method is + // really only relevant for eliminating loads and they don't care about the + // write barrier mode. return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset && lhs.machine_type == rhs.machine_type; } @@ -95,6 +102,9 @@ bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) { size_t hash_value(FieldAccess const& access) { + // On purpose we don't include the write barrier kind here, as this method is + // really only relevant for eliminating loads and they don't care about the + // write barrier mode. return base::hash_combine(access.base_is_tagged, access.offset, access.machine_type); } @@ -110,12 +120,24 @@ std::ostream& operator<<(std::ostream& os, FieldAccess const& access) { } #endif access.type->PrintTo(os); - os << ", " << access.machine_type << "]"; + os << ", " << access.machine_type << ", " << access.write_barrier_kind << "]"; return os; } +template <> +void Operator1<FieldAccess>::PrintParameter(std::ostream& os, + PrintVerbosity verbose) const { + if (verbose == PrintVerbosity::kVerbose) { + os << parameter(); + } else { + os << "[+" << parameter().offset << "]"; + } +} bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) { + // On purpose we don't include the write barrier kind here, as this method is + // really only relevant for eliminating loads and they don't care about the + // write barrier mode. return lhs.base_is_tagged == rhs.base_is_tagged && lhs.header_size == rhs.header_size && lhs.machine_type == rhs.machine_type; @@ -128,6 +150,9 @@ bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) { size_t hash_value(ElementAccess const& access) { + // On purpose we don't include the write barrier kind here, as this method is + // really only relevant for eliminating loads and they don't care about the + // write barrier mode. return base::hash_combine(access.base_is_tagged, access.header_size, access.machine_type); } @@ -136,7 +161,7 @@ size_t hash_value(ElementAccess const& access) { std::ostream& operator<<(std::ostream& os, ElementAccess const& access) { os << access.base_is_tagged << ", " << access.header_size << ", "; access.type->PrintTo(os); - os << ", " << access.machine_type; + os << ", " << access.machine_type << ", " << access.write_barrier_kind; return os; } @@ -156,87 +181,420 @@ const ElementAccess& ElementAccessOf(const Operator* op) { return OpParameter<ElementAccess>(op); } -#define PURE_OP_LIST(V) \ - V(BooleanNot, Operator::kNoProperties, 1) \ - V(BooleanToNumber, Operator::kNoProperties, 1) \ - V(NumberEqual, Operator::kCommutative, 2) \ - V(NumberLessThan, Operator::kNoProperties, 2) \ - V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ - V(NumberAdd, Operator::kCommutative, 2) \ - V(NumberSubtract, Operator::kNoProperties, 2) \ - V(NumberMultiply, Operator::kCommutative, 2) \ - V(NumberDivide, Operator::kNoProperties, 2) \ - V(NumberModulus, Operator::kNoProperties, 2) \ - V(NumberBitwiseOr, Operator::kCommutative, 2) \ - V(NumberBitwiseXor, Operator::kCommutative, 2) \ - V(NumberBitwiseAnd, Operator::kCommutative, 2) \ - V(NumberShiftLeft, Operator::kNoProperties, 2) \ - V(NumberShiftRight, Operator::kNoProperties, 2) \ - V(NumberShiftRightLogical, Operator::kNoProperties, 2) \ - V(NumberImul, Operator::kNoProperties, 2) \ - V(NumberClz32, Operator::kNoProperties, 1) \ - V(NumberCeil, Operator::kNoProperties, 1) \ - V(NumberFloor, Operator::kNoProperties, 1) \ - V(NumberRound, Operator::kNoProperties, 1) \ - V(NumberTrunc, Operator::kNoProperties, 1) \ - V(NumberToInt32, Operator::kNoProperties, 1) \ - V(NumberToUint32, Operator::kNoProperties, 1) \ - V(NumberIsHoleNaN, Operator::kNoProperties, 1) \ - V(PlainPrimitiveToNumber, Operator::kNoProperties, 1) \ - V(StringToNumber, Operator::kNoProperties, 1) \ - V(ChangeTaggedToInt32, Operator::kNoProperties, 1) \ - V(ChangeTaggedToUint32, Operator::kNoProperties, 1) \ - V(ChangeTaggedToFloat64, Operator::kNoProperties, 1) \ - V(ChangeInt32ToTagged, Operator::kNoProperties, 1) \ - V(ChangeUint32ToTagged, Operator::kNoProperties, 1) \ - V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \ - V(ChangeBoolToBit, Operator::kNoProperties, 1) \ - V(ChangeBitToBool, Operator::kNoProperties, 1) \ - V(ObjectIsNumber, Operator::kNoProperties, 1) \ - V(ObjectIsReceiver, Operator::kNoProperties, 1) \ - V(ObjectIsSmi, Operator::kNoProperties, 1) \ - V(ObjectIsUndetectable, Operator::kNoProperties, 1) - -#define NO_THROW_OP_LIST(V) \ - V(StringEqual, Operator::kCommutative, 2) \ - V(StringLessThan, Operator::kNoThrow, 2) \ - V(StringLessThanOrEqual, Operator::kNoThrow, 2) +ExternalArrayType ExternalArrayTypeOf(const Operator* op) { + DCHECK(op->opcode() == IrOpcode::kLoadTypedElement || + op->opcode() == IrOpcode::kStoreTypedElement); + return OpParameter<ExternalArrayType>(op); +} + +size_t hash_value(CheckFloat64HoleMode mode) { + return static_cast<size_t>(mode); +} + +std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) { + switch (mode) { + case CheckFloat64HoleMode::kAllowReturnHole: + return os << "allow-return-hole"; + case CheckFloat64HoleMode::kNeverReturnHole: + return os << "never-return-hole"; + } + UNREACHABLE(); + return os; +} + +CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator* op) { + DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode()); + return OpParameter<CheckFloat64HoleMode>(op); +} + +CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator* op) { + DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged || + op->opcode() == IrOpcode::kCheckedInt32Mul || + op->opcode() == IrOpcode::kCheckedFloat64ToInt32 || + op->opcode() == IrOpcode::kCheckedTaggedToInt32); + return OpParameter<CheckForMinusZeroMode>(op); +} + +size_t hash_value(CheckForMinusZeroMode mode) { + return static_cast<size_t>(mode); +} + +std::ostream& operator<<(std::ostream& os, CheckForMinusZeroMode mode) { + switch (mode) { + case CheckForMinusZeroMode::kCheckForMinusZero: + return os << "check-for-minus-zero"; + case CheckForMinusZeroMode::kDontCheckForMinusZero: + return os << "dont-check-for-minus-zero"; + } + UNREACHABLE(); + return os; +} + +size_t hash_value(CheckTaggedInputMode mode) { + return static_cast<size_t>(mode); +} + +std::ostream& operator<<(std::ostream& os, CheckTaggedInputMode mode) { + switch (mode) { + case CheckTaggedInputMode::kNumber: + return os << "Number"; + case CheckTaggedInputMode::kNumberOrOddball: + return os << "NumberOrOddball"; + } + UNREACHABLE(); + return os; +} + +CheckTaggedInputMode CheckTaggedInputModeOf(const Operator* op) { + DCHECK_EQ(IrOpcode::kCheckedTaggedToFloat64, op->opcode()); + return OpParameter<CheckTaggedInputMode>(op); +} + +std::ostream& operator<<(std::ostream& os, GrowFastElementsFlags flags) { + bool empty = true; + if (flags & GrowFastElementsFlag::kArrayObject) { + os << "ArrayObject"; + empty = false; + } + if (flags & GrowFastElementsFlag::kDoubleElements) { + if (!empty) os << "|"; + os << "DoubleElements"; + empty = false; + } + if (flags & GrowFastElementsFlag::kHoleyElements) { + if (!empty) os << "|"; + os << "HoleyElements"; + empty = false; + } + if (empty) os << "None"; + return os; +} + +GrowFastElementsFlags GrowFastElementsFlagsOf(const Operator* op) { + DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode()); + return OpParameter<GrowFastElementsFlags>(op); +} + +size_t hash_value(ElementsTransition transition) { + return static_cast<uint8_t>(transition); +} + +std::ostream& operator<<(std::ostream& os, ElementsTransition transition) { + switch (transition) { + case ElementsTransition::kFastTransition: + return os << "fast-transition"; + case ElementsTransition::kSlowTransition: + return os << "slow-transition"; + } + UNREACHABLE(); + return os; +} + +ElementsTransition ElementsTransitionOf(const Operator* op) { + DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode()); + return OpParameter<ElementsTransition>(op); +} + +std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) { + switch (hint) { + case NumberOperationHint::kSignedSmall: + return os << "SignedSmall"; + case NumberOperationHint::kSigned32: + return os << "Signed32"; + case NumberOperationHint::kNumber: + return os << "Number"; + case NumberOperationHint::kNumberOrOddball: + return os << "NumberOrOddball"; + } + UNREACHABLE(); + return os; +} + +size_t hash_value(NumberOperationHint hint) { + return static_cast<uint8_t>(hint); +} + +NumberOperationHint NumberOperationHintOf(const Operator* op) { + DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || + op->opcode() == IrOpcode::kSpeculativeNumberSubtract || + op->opcode() == IrOpcode::kSpeculativeNumberMultiply || + op->opcode() == IrOpcode::kSpeculativeNumberDivide || + op->opcode() == IrOpcode::kSpeculativeNumberModulus || + op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft || + op->opcode() == IrOpcode::kSpeculativeNumberShiftRight || + op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical || + op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd || + op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr || + op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor || + op->opcode() == IrOpcode::kSpeculativeNumberEqual || + op->opcode() == IrOpcode::kSpeculativeNumberLessThan || + op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual); + return OpParameter<NumberOperationHint>(op); +} + +#define PURE_OP_LIST(V) \ + V(BooleanNot, Operator::kNoProperties, 1, 0) \ + V(NumberEqual, Operator::kCommutative, 2, 0) \ + V(NumberLessThan, Operator::kNoProperties, 2, 0) \ + V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \ + V(NumberAdd, Operator::kCommutative, 2, 0) \ + V(NumberSubtract, Operator::kNoProperties, 2, 0) \ + V(NumberMultiply, Operator::kCommutative, 2, 0) \ + V(NumberDivide, Operator::kNoProperties, 2, 0) \ + V(NumberModulus, Operator::kNoProperties, 2, 0) \ + V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \ + V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \ + V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \ + V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \ + V(NumberShiftRight, Operator::kNoProperties, 2, 0) \ + V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \ + V(NumberImul, Operator::kCommutative, 2, 0) \ + V(NumberAbs, Operator::kNoProperties, 1, 0) \ + V(NumberClz32, Operator::kNoProperties, 1, 0) \ + V(NumberCeil, Operator::kNoProperties, 1, 0) \ + V(NumberFloor, Operator::kNoProperties, 1, 0) \ + V(NumberFround, Operator::kNoProperties, 1, 0) \ + V(NumberAcos, Operator::kNoProperties, 1, 0) \ + V(NumberAcosh, Operator::kNoProperties, 1, 0) \ + V(NumberAsin, Operator::kNoProperties, 1, 0) \ + V(NumberAsinh, Operator::kNoProperties, 1, 0) \ + V(NumberAtan, Operator::kNoProperties, 1, 0) \ + V(NumberAtan2, Operator::kNoProperties, 2, 0) \ + V(NumberAtanh, Operator::kNoProperties, 1, 0) \ + V(NumberCbrt, Operator::kNoProperties, 1, 0) \ + V(NumberCos, Operator::kNoProperties, 1, 0) \ + V(NumberCosh, Operator::kNoProperties, 1, 0) \ + V(NumberExp, Operator::kNoProperties, 1, 0) \ + V(NumberExpm1, Operator::kNoProperties, 1, 0) \ + V(NumberLog, Operator::kNoProperties, 1, 0) \ + V(NumberLog1p, Operator::kNoProperties, 1, 0) \ + V(NumberLog10, Operator::kNoProperties, 1, 0) \ + V(NumberLog2, Operator::kNoProperties, 1, 0) \ + V(NumberMax, Operator::kNoProperties, 2, 0) \ + V(NumberMin, Operator::kNoProperties, 2, 0) \ + V(NumberPow, Operator::kNoProperties, 2, 0) \ + V(NumberRound, Operator::kNoProperties, 1, 0) \ + V(NumberSign, Operator::kNoProperties, 1, 0) \ + V(NumberSin, Operator::kNoProperties, 1, 0) \ + V(NumberSinh, Operator::kNoProperties, 1, 0) \ + V(NumberSqrt, Operator::kNoProperties, 1, 0) \ + V(NumberTan, Operator::kNoProperties, 1, 0) \ + V(NumberTanh, Operator::kNoProperties, 1, 0) \ + V(NumberTrunc, Operator::kNoProperties, 1, 0) \ + V(NumberToInt32, Operator::kNoProperties, 1, 0) \ + V(NumberToUint32, Operator::kNoProperties, 1, 0) \ + V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \ + V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \ + V(StringFromCharCode, Operator::kNoProperties, 1, 0) \ + V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \ + V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \ + V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \ + V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \ + V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \ + V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \ + V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \ + V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \ + V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \ + V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \ + V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \ + V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \ + V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \ + V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \ + V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \ + V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \ + V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \ + V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \ + V(ObjectIsString, Operator::kNoProperties, 1, 0) \ + V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \ + V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \ + V(ReferenceEqual, Operator::kCommutative, 2, 0) \ + V(StringEqual, Operator::kCommutative, 2, 0) \ + V(StringLessThan, Operator::kNoProperties, 2, 0) \ + V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) + +#define SPECULATIVE_NUMBER_BINOP_LIST(V) \ + SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \ + V(SpeculativeNumberEqual) \ + V(SpeculativeNumberLessThan) \ + V(SpeculativeNumberLessThanOrEqual) + +#define CHECKED_OP_LIST(V) \ + V(CheckBounds, 2, 1) \ + V(CheckIf, 1, 0) \ + V(CheckNumber, 1, 1) \ + V(CheckString, 1, 1) \ + V(CheckTaggedHole, 1, 1) \ + V(CheckTaggedPointer, 1, 1) \ + V(CheckTaggedSigned, 1, 1) \ + V(CheckedInt32Add, 2, 1) \ + V(CheckedInt32Sub, 2, 1) \ + V(CheckedInt32Div, 2, 1) \ + V(CheckedInt32Mod, 2, 1) \ + V(CheckedUint32Div, 2, 1) \ + V(CheckedUint32Mod, 2, 1) \ + V(CheckedUint32ToInt32, 1, 1) \ + V(CheckedTaggedSignedToInt32, 1, 1) \ + V(CheckedTruncateTaggedToWord32, 1, 1) struct SimplifiedOperatorGlobalCache final { -#define PURE(Name, properties, input_count) \ +#define PURE(Name, properties, value_input_count, control_input_count) \ struct Name##Operator final : public Operator { \ Name##Operator() \ : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ - input_count, 0, 0, 1, 0, 0) {} \ + value_input_count, 0, control_input_count, 1, 0, 0) {} \ }; \ Name##Operator k##Name; PURE_OP_LIST(PURE) #undef PURE -#define NO_THROW(Name, properties, input_count) \ - struct Name##Operator final : public Operator { \ - Name##Operator() \ - : Operator(IrOpcode::k##Name, Operator::kNoThrow | properties, #Name, \ - input_count, 1, 1, 1, 1, 0) {} \ - }; \ +#define CHECKED(Name, value_input_count, value_output_count) \ + struct Name##Operator final : public Operator { \ + Name##Operator() \ + : Operator(IrOpcode::k##Name, \ + Operator::kFoldable | Operator::kNoThrow, #Name, \ + value_input_count, 1, 1, value_output_count, 1, 0) {} \ + }; \ Name##Operator k##Name; - NO_THROW_OP_LIST(NO_THROW) -#undef NO_THROW + CHECKED_OP_LIST(CHECKED) +#undef CHECKED + + template <CheckForMinusZeroMode kMode> + struct ChangeFloat64ToTaggedOperator final + : public Operator1<CheckForMinusZeroMode> { + ChangeFloat64ToTaggedOperator() + : Operator1<CheckForMinusZeroMode>( + IrOpcode::kChangeFloat64ToTagged, Operator::kPure, + "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {} + }; + ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kCheckForMinusZero> + kChangeFloat64ToTaggedCheckForMinusZeroOperator; + ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kDontCheckForMinusZero> + kChangeFloat64ToTaggedDontCheckForMinusZeroOperator; + + template <CheckForMinusZeroMode kMode> + struct CheckedInt32MulOperator final + : public Operator1<CheckForMinusZeroMode> { + CheckedInt32MulOperator() + : Operator1<CheckForMinusZeroMode>( + IrOpcode::kCheckedInt32Mul, + Operator::kFoldable | Operator::kNoThrow, "CheckedInt32Mul", 2, 1, + 1, 1, 1, 0, kMode) {} + }; + CheckedInt32MulOperator<CheckForMinusZeroMode::kCheckForMinusZero> + kCheckedInt32MulCheckForMinusZeroOperator; + CheckedInt32MulOperator<CheckForMinusZeroMode::kDontCheckForMinusZero> + kCheckedInt32MulDontCheckForMinusZeroOperator; + + template <CheckForMinusZeroMode kMode> + struct CheckedFloat64ToInt32Operator final + : public Operator1<CheckForMinusZeroMode> { + CheckedFloat64ToInt32Operator() + : Operator1<CheckForMinusZeroMode>( + IrOpcode::kCheckedFloat64ToInt32, + Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32", + 1, 1, 1, 1, 1, 0, kMode) {} + }; + CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero> + kCheckedFloat64ToInt32CheckForMinusZeroOperator; + CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero> + kCheckedFloat64ToInt32DontCheckForMinusZeroOperator; + + template <CheckForMinusZeroMode kMode> + struct CheckedTaggedToInt32Operator final + : public Operator1<CheckForMinusZeroMode> { + CheckedTaggedToInt32Operator() + : Operator1<CheckForMinusZeroMode>( + IrOpcode::kCheckedTaggedToInt32, + Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt32", + 1, 1, 1, 1, 1, 0, kMode) {} + }; + CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero> + kCheckedTaggedToInt32CheckForMinusZeroOperator; + CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero> + kCheckedTaggedToInt32DontCheckForMinusZeroOperator; + + template <CheckTaggedInputMode kMode> + struct CheckedTaggedToFloat64Operator final + : public Operator1<CheckTaggedInputMode> { + CheckedTaggedToFloat64Operator() + : Operator1<CheckTaggedInputMode>( + IrOpcode::kCheckedTaggedToFloat64, + Operator::kFoldable | Operator::kNoThrow, + "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0, kMode) {} + }; + CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumber> + kCheckedTaggedToFloat64NumberOperator; + CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumberOrOddball> + kCheckedTaggedToFloat64NumberOrOddballOperator; + + template <CheckFloat64HoleMode kMode> + struct CheckFloat64HoleNaNOperator final + : public Operator1<CheckFloat64HoleMode> { + CheckFloat64HoleNaNOperator() + : Operator1<CheckFloat64HoleMode>( + IrOpcode::kCheckFloat64Hole, + Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1, + 1, 1, 1, 1, 0, kMode) {} + }; + CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole> + kCheckFloat64HoleAllowReturnHoleOperator; + CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kNeverReturnHole> + kCheckFloat64HoleNeverReturnHoleOperator; + + template <PretenureFlag kPretenure> + struct AllocateOperator final : public Operator1<PretenureFlag> { + AllocateOperator() + : Operator1<PretenureFlag>( + IrOpcode::kAllocate, + Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, + "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {} + }; + AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator; + AllocateOperator<TENURED> kAllocateTenuredOperator; + + struct EnsureWritableFastElementsOperator final : public Operator { + EnsureWritableFastElementsOperator() + : Operator( // -- + IrOpcode::kEnsureWritableFastElements, // opcode + Operator::kNoDeopt | Operator::kNoThrow, // flags + "EnsureWritableFastElements", // name + 2, 1, 1, 1, 1, 0) {} // counts + }; + EnsureWritableFastElementsOperator kEnsureWritableFastElements; + +#define SPECULATIVE_NUMBER_BINOP(Name) \ + template <NumberOperationHint kHint> \ + struct Name##Operator final : public Operator1<NumberOperationHint> { \ + Name##Operator() \ + : Operator1<NumberOperationHint>( \ + IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ + #Name, 2, 1, 1, 1, 1, 0, kHint) {} \ + }; \ + Name##Operator<NumberOperationHint::kSignedSmall> \ + k##Name##SignedSmallOperator; \ + Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \ + Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \ + Name##Operator<NumberOperationHint::kNumberOrOddball> \ + k##Name##NumberOrOddballOperator; + SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP) +#undef SPECULATIVE_NUMBER_BINOP #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \ LoadBuffer##Type##Operator() \ - : Operator1<BufferAccess>(IrOpcode::kLoadBuffer, \ - Operator::kNoThrow | Operator::kNoWrite, \ - "LoadBuffer", 3, 1, 1, 1, 1, 0, \ - BufferAccess(kExternal##Type##Array)) {} \ + : Operator1<BufferAccess>( \ + IrOpcode::kLoadBuffer, \ + Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \ + "LoadBuffer", 3, 1, 1, 1, 1, 0, \ + BufferAccess(kExternal##Type##Array)) {} \ }; \ struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \ StoreBuffer##Type##Operator() \ - : Operator1<BufferAccess>(IrOpcode::kStoreBuffer, \ - Operator::kNoRead | Operator::kNoThrow, \ - "StoreBuffer", 4, 1, 1, 0, 1, 0, \ - BufferAccess(kExternal##Type##Array)) {} \ + : Operator1<BufferAccess>( \ + IrOpcode::kStoreBuffer, \ + Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ + "StoreBuffer", 4, 1, 1, 0, 1, 0, \ + BufferAccess(kExternal##Type##Array)) {} \ }; \ LoadBuffer##Type##Operator kLoadBuffer##Type; \ StoreBuffer##Type##Operator kStoreBuffer##Type; @@ -252,25 +610,129 @@ static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache = SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) : cache_(kCache.Get()), zone_(zone) {} - -#define GET_FROM_CACHE(Name, properties, input_count) \ +#define GET_FROM_CACHE(Name, ...) \ const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } PURE_OP_LIST(GET_FROM_CACHE) -NO_THROW_OP_LIST(GET_FROM_CACHE) +CHECKED_OP_LIST(GET_FROM_CACHE) #undef GET_FROM_CACHE +const Operator* SimplifiedOperatorBuilder::ChangeFloat64ToTagged( + CheckForMinusZeroMode mode) { + switch (mode) { + case CheckForMinusZeroMode::kCheckForMinusZero: + return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator; + case CheckForMinusZeroMode::kDontCheckForMinusZero: + return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator; + } + UNREACHABLE(); + return nullptr; +} + +const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul( + CheckForMinusZeroMode mode) { + switch (mode) { + case CheckForMinusZeroMode::kCheckForMinusZero: + return &cache_.kCheckedInt32MulCheckForMinusZeroOperator; + case CheckForMinusZeroMode::kDontCheckForMinusZero: + return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator; + } + UNREACHABLE(); + return nullptr; +} + +const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt32( + CheckForMinusZeroMode mode) { + switch (mode) { + case CheckForMinusZeroMode::kCheckForMinusZero: + return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator; + case CheckForMinusZeroMode::kDontCheckForMinusZero: + return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator; + } + UNREACHABLE(); + return nullptr; +} + +const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt32( + CheckForMinusZeroMode mode) { + switch (mode) { + case CheckForMinusZeroMode::kCheckForMinusZero: + return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator; + case CheckForMinusZeroMode::kDontCheckForMinusZero: + return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator; + } + UNREACHABLE(); + return nullptr; +} -const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) { - return new (zone()) Operator(IrOpcode::kReferenceEqual, - Operator::kCommutative | Operator::kPure, - "ReferenceEqual", 2, 0, 0, 1, 0, 0); +const Operator* SimplifiedOperatorBuilder::CheckedTaggedToFloat64( + CheckTaggedInputMode mode) { + switch (mode) { + case CheckTaggedInputMode::kNumber: + return &cache_.kCheckedTaggedToFloat64NumberOperator; + case CheckTaggedInputMode::kNumberOrOddball: + return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator; + } + UNREACHABLE(); + return nullptr; } +const Operator* SimplifiedOperatorBuilder::CheckMaps(int map_input_count) { + // TODO(bmeurer): Cache the most important versions of this operator. + DCHECK_LT(0, map_input_count); + int const value_input_count = 1 + map_input_count; + return new (zone()) Operator1<int>( // -- + IrOpcode::kCheckMaps, // opcode + Operator::kNoThrow | Operator::kNoWrite, // flags + "CheckMaps", // name + value_input_count, 1, 1, 0, 1, 0, // counts + map_input_count); // parameter +} + +const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole( + CheckFloat64HoleMode mode) { + switch (mode) { + case CheckFloat64HoleMode::kAllowReturnHole: + return &cache_.kCheckFloat64HoleAllowReturnHoleOperator; + case CheckFloat64HoleMode::kNeverReturnHole: + return &cache_.kCheckFloat64HoleNeverReturnHoleOperator; + } + UNREACHABLE(); + return nullptr; +} + +const Operator* SimplifiedOperatorBuilder::EnsureWritableFastElements() { + return &cache_.kEnsureWritableFastElements; +} + +const Operator* SimplifiedOperatorBuilder::MaybeGrowFastElements( + GrowFastElementsFlags flags) { + return new (zone()) Operator1<GrowFastElementsFlags>( // -- + IrOpcode::kMaybeGrowFastElements, // opcode + Operator::kNoThrow, // flags + "MaybeGrowFastElements", // name + 4, 1, 1, 1, 1, 0, // counts + flags); // parameter +} + +const Operator* SimplifiedOperatorBuilder::TransitionElementsKind( + ElementsTransition transition) { + return new (zone()) Operator1<ElementsTransition>( // -- + IrOpcode::kTransitionElementsKind, // opcode + Operator::kNoDeopt | Operator::kNoThrow, // flags + "TransitionElementsKind", // name + 3, 1, 1, 0, 1, 0, // counts + transition); // parameter +} const Operator* SimplifiedOperatorBuilder::Allocate(PretenureFlag pretenure) { - return new (zone()) - Operator1<PretenureFlag>(IrOpcode::kAllocate, Operator::kNoThrow, - "Allocate", 1, 1, 1, 1, 1, 0, pretenure); + switch (pretenure) { + case NOT_TENURED: + return &cache_.kAllocateNotTenuredOperator; + case TENURED: + return &cache_.kAllocateTenuredOperator; + } + UNREACHABLE(); + return nullptr; } @@ -299,19 +761,38 @@ const Operator* SimplifiedOperatorBuilder::StoreBuffer(BufferAccess access) { return nullptr; } +#define SPECULATIVE_NUMBER_BINOP(Name) \ + const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \ + switch (hint) { \ + case NumberOperationHint::kSignedSmall: \ + return &cache_.k##Name##SignedSmallOperator; \ + case NumberOperationHint::kSigned32: \ + return &cache_.k##Name##Signed32Operator; \ + case NumberOperationHint::kNumber: \ + return &cache_.k##Name##NumberOperator; \ + case NumberOperationHint::kNumberOrOddball: \ + return &cache_.k##Name##NumberOrOddballOperator; \ + } \ + UNREACHABLE(); \ + return nullptr; \ + } +SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP) +#undef SPECULATIVE_NUMBER_BINOP -#define ACCESS_OP_LIST(V) \ - V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ - V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ - V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ - V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) - +#define ACCESS_OP_LIST(V) \ + V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ + V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ + V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ + V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \ + V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \ + V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ output_count) \ const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ return new (zone()) \ - Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ + Operator1<Type>(IrOpcode::k##Name, \ + Operator::kNoDeopt | Operator::kNoThrow | properties, \ #Name, value_input_count, 1, control_input_count, \ output_count, 1, 0, access); \ } |