summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/simplified-operator.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2016-09-06 22:49:51 +0200
committerMichaël Zasso <targos@protonmail.com>2016-09-22 09:51:19 +0200
commitec02b811a8a5c999bab4de312be2d732b7d9d50b (patch)
treeca3068017254f238cf413a451c57a803572983a4 /deps/v8/src/compiler/simplified-operator.cc
parentd2eb7ce0105369a9cad82787cb33a665e9bd00ad (diff)
downloadnode-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.cc645
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); \
}