summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/simplified-lowering.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/simplified-lowering.cc')
-rw-r--r--deps/v8/src/compiler/simplified-lowering.cc227
1 files changed, 159 insertions, 68 deletions
diff --git a/deps/v8/src/compiler/simplified-lowering.cc b/deps/v8/src/compiler/simplified-lowering.cc
index 28634b8c9f..9bdb7cfbaf 100644
--- a/deps/v8/src/compiler/simplified-lowering.cc
+++ b/deps/v8/src/compiler/simplified-lowering.cc
@@ -209,11 +209,11 @@ class InputUseInfos {
bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
Zone* type_zone) {
// We assume the inputs are checked Signed32 (or known statically
- // to be Signed32). Technically, theinputs could also be minus zero, but
+ // to be Signed32). Technically, the inputs could also be minus zero, but
// that cannot cause overflow.
left = Type::Intersect(left, Type::Signed32(), type_zone);
right = Type::Intersect(right, Type::Signed32(), type_zone);
- if (!left->IsInhabited() || !right->IsInhabited()) return false;
+ if (left->IsNone() || right->IsNone()) return false;
switch (op->opcode()) {
case IrOpcode::kSpeculativeSafeIntegerAdd:
return (left->Max() + right->Max() > kMaxInt) ||
@@ -229,6 +229,10 @@ bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
return true;
}
+bool IsSomePositiveOrderedNumber(Type* type) {
+ return type->Is(Type::OrderedNumber()) && !type->IsNone() && type->Min() > 0;
+}
+
} // namespace
class RepresentationSelector {
@@ -426,6 +430,7 @@ class RepresentationSelector {
break; \
}
SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
+ DECLARE_CASE(SameValue)
#undef DECLARE_CASE
#define DECLARE_CASE(Name) \
@@ -457,6 +462,10 @@ class RepresentationSelector {
SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE
+ case IrOpcode::kConvertReceiver:
+ new_type = op_typer_.ConvertReceiver(FeedbackTypeOf(node->InputAt(0)));
+ break;
+
case IrOpcode::kPlainPrimitiveToNumber:
new_type = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
break;
@@ -552,8 +561,10 @@ class RepresentationSelector {
Type* current_integer =
Type::Intersect(current_type, integer, graph_zone());
+ DCHECK(!current_integer->IsNone());
Type* previous_integer =
Type::Intersect(previous_type, integer, graph_zone());
+ DCHECK(!previous_integer->IsNone());
// Once we start weakening a node, we should always weaken.
if (!GetInfo(node)->weakened()) {
@@ -1047,7 +1058,7 @@ class RepresentationSelector {
}
static MachineType DeoptMachineTypeOf(MachineRepresentation rep, Type* type) {
- if (!type->IsInhabited()) {
+ if (type->IsNone()) {
return MachineType::None();
}
// TODO(turbofan): Special treatment for ExternalPointer here,
@@ -1242,10 +1253,8 @@ class RepresentationSelector {
// there is no need to return -0.
CheckForMinusZeroMode mz_mode =
truncation.IdentifiesZeroAndMinusZero() ||
- (input0_type->Is(Type::OrderedNumber()) &&
- input0_type->Min() > 0) ||
- (input1_type->Is(Type::OrderedNumber()) &&
- input1_type->Min() > 0)
+ IsSomePositiveOrderedNumber(input0_type) ||
+ IsSomePositiveOrderedNumber(input1_type)
? CheckForMinusZeroMode::kDontCheckForMinusZero
: CheckForMinusZeroMode::kCheckForMinusZero;
@@ -1264,16 +1273,13 @@ class RepresentationSelector {
SimplifiedLowering* lowering) {
Type* left_upper = GetUpperBound(node->InputAt(0));
Type* right_upper = GetUpperBound(node->InputAt(1));
- // Only eliminate eliminate the node if the ToNumber conversion cannot
- // cause any observable side-effect and if we know for sure that it
- // is a number addition (we must exclude strings).
- if (left_upper->Is(Type::NumberOrOddball()) &&
- right_upper->Is(Type::NumberOrOddball())) {
- if (truncation.IsUnused()) return VisitUnused(node);
- }
if (left_upper->Is(type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
right_upper->Is(type_cache_.kAdditiveSafeIntegerOrMinusZero)) {
+ // Only eliminate the node if its typing rule can be satisfied, namely
+ // that a safe integer is produced.
+ if (truncation.IsUnused()) return VisitUnused(node);
+
// If we know how to interpret the result or if the users only care
// about the low 32-bits, we can truncate to Word32 do a wrapping
// addition.
@@ -1541,10 +1547,9 @@ class RepresentationSelector {
//------------------------------------------------------------------
// JavaScript operators.
//------------------------------------------------------------------
- case IrOpcode::kJSToBoolean: {
+ case IrOpcode::kToBoolean: {
if (truncation.IsUsedAsBool()) {
ProcessInput(node, 0, UseInfo::Bool());
- ProcessInput(node, 1, UseInfo::None());
SetOutput(node, MachineRepresentation::kBit);
if (lower()) DeferReplacement(node, node->InputAt(0));
} else {
@@ -1553,15 +1558,18 @@ class RepresentationSelector {
}
return;
}
- case IrOpcode::kJSToNumber: {
+ case IrOpcode::kJSToNumber:
+ case IrOpcode::kJSToNumeric: {
VisitInputs(node);
// TODO(bmeurer): Optimize somewhat based on input type?
if (truncation.IsUsedAsWord32()) {
SetOutput(node, MachineRepresentation::kWord32);
- if (lower()) lowering->DoJSToNumberTruncatesToWord32(node, this);
+ if (lower())
+ lowering->DoJSToNumberOrNumericTruncatesToWord32(node, this);
} else if (truncation.IsUsedAsFloat64()) {
SetOutput(node, MachineRepresentation::kFloat64);
- if (lower()) lowering->DoJSToNumberTruncatesToFloat64(node, this);
+ if (lower())
+ lowering->DoJSToNumberOrNumericTruncatesToFloat64(node, this);
} else {
SetOutput(node, MachineRepresentation::kTagged);
}
@@ -1583,7 +1591,7 @@ class RepresentationSelector {
node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
} else {
- DCHECK(!TypeOf(node->InputAt(0))->IsInhabited());
+ DCHECK(TypeOf(node->InputAt(0))->IsNone());
DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
}
} else {
@@ -2080,8 +2088,8 @@ class RepresentationSelector {
case IrOpcode::kSpeculativeNumberShiftRightLogical: {
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
// can only eliminate an unused speculative number operation if we know
- // that the inputs are PlainPrimitive, which excludes everything that's
- // might have side effects or throws during a ToNumber conversion.
+ // that the inputs are PlainPrimitive, which excludes everything that
+ // might have side effects or throw during a ToNumber conversion.
if (BothInputsAre(node, Type::PlainPrimitive())) {
if (truncation.IsUnused()) return VisitUnused(node);
}
@@ -2346,6 +2354,17 @@ class RepresentationSelector {
}
return;
}
+ case IrOpcode::kSameValue: {
+ if (truncation.IsUnused()) return VisitUnused(node);
+ VisitBinop(node, UseInfo::AnyTagged(),
+ MachineRepresentation::kTaggedPointer);
+ return;
+ }
+ case IrOpcode::kClassOf:
+ case IrOpcode::kTypeOf: {
+ return VisitUnop(node, UseInfo::AnyTagged(),
+ MachineRepresentation::kTaggedPointer);
+ }
case IrOpcode::kStringEqual:
case IrOpcode::kStringLessThan:
case IrOpcode::kStringLessThanOrEqual: {
@@ -2405,8 +2424,9 @@ class RepresentationSelector {
VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) {
- if (index_type->Min() >= 0.0 &&
- index_type->Max() < length_type->Min()) {
+ if (index_type->IsNone() || length_type->IsNone() ||
+ (index_type->Min() >= 0.0 &&
+ index_type->Max() < length_type->Min())) {
// The bounds check is redundant if we already know that
// the index is within the bounds of [0.0, length[.
DeferReplacement(node, node->InputAt(0));
@@ -2419,6 +2439,11 @@ class RepresentationSelector {
}
return;
}
+ case IrOpcode::kMaskIndexWithBound: {
+ VisitBinop(node, UseInfo::TruncatingWord32(),
+ MachineRepresentation::kWord32);
+ return;
+ }
case IrOpcode::kCheckHeapObject: {
if (InputCannotBe(node, Type::SignedSmall())) {
VisitUnop(node, UseInfo::AnyTagged(),
@@ -2512,12 +2537,6 @@ class RepresentationSelector {
MachineRepresentation field_representation =
access.machine_type.representation();
- // Make sure we convert to Smi if possible. This should help write
- // barrier elimination.
- if (field_representation == MachineRepresentation::kTagged &&
- TypeOf(value_node)->Is(Type::SignedSmall())) {
- field_representation = MachineRepresentation::kTaggedSigned;
- }
WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
access.base_is_tagged, field_representation, access.offset,
access.type, input_info->representation(), value_node);
@@ -2551,12 +2570,6 @@ class RepresentationSelector {
MachineRepresentation element_representation =
access.machine_type.representation();
- // Make sure we convert to Smi if possible. This should help write
- // barrier elimination.
- if (element_representation == MachineRepresentation::kTagged &&
- TypeOf(value_node)->Is(Type::SignedSmall())) {
- element_representation = MachineRepresentation::kTaggedSigned;
- }
WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
access.base_is_tagged, element_representation, access.type,
input_info->representation(), value_node);
@@ -2581,13 +2594,31 @@ class RepresentationSelector {
ProcessInput(node, 0, UseInfo::AnyTagged()); // array
ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index
- ProcessInput(node, 2, UseInfo::AnyTagged()); // value
if (value_type->Is(Type::SignedSmall())) {
+ ProcessInput(node, 2, UseInfo::TruncatingWord32()); // value
if (lower()) {
NodeProperties::ChangeOp(node,
simplified()->StoreSignedSmallElement());
}
+ } else if (value_type->Is(Type::Number())) {
+ ProcessInput(node, 2, UseInfo::TruncatingFloat64()); // value
+ if (lower()) {
+ Handle<Map> double_map = DoubleMapParameterOf(node->op());
+ NodeProperties::ChangeOp(
+ node,
+ simplified()->TransitionAndStoreNumberElement(double_map));
+ }
+ } else if (value_type->Is(Type::NonNumber())) {
+ ProcessInput(node, 2, UseInfo::AnyTagged()); // value
+ if (lower()) {
+ Handle<Map> fast_map = FastMapParameterOf(node->op());
+ NodeProperties::ChangeOp(
+ node, simplified()->TransitionAndStoreNonNumberElement(
+ fast_map, value_type));
+ }
+ } else {
+ ProcessInput(node, 2, UseInfo::AnyTagged()); // value
}
ProcessRemainingInputs(node, 3);
@@ -2618,13 +2649,33 @@ class RepresentationSelector {
SetOutput(node, MachineRepresentation::kNone);
return;
}
+ case IrOpcode::kConvertReceiver: {
+ Type* input_type = TypeOf(node->InputAt(0));
+ VisitBinop(node, UseInfo::AnyTagged(),
+ MachineRepresentation::kTaggedPointer);
+ if (lower()) {
+ // Try to optimize the {node} based on the input type.
+ if (input_type->Is(Type::Receiver())) {
+ DeferReplacement(node, node->InputAt(0));
+ } else if (input_type->Is(Type::NullOrUndefined())) {
+ DeferReplacement(node, node->InputAt(1));
+ } else if (!input_type->Maybe(Type::NullOrUndefined())) {
+ NodeProperties::ChangeOp(
+ node, lowering->simplified()->ConvertReceiver(
+ ConvertReceiverMode::kNotNullOrUndefined));
+ }
+ }
+ return;
+ }
case IrOpcode::kPlainPrimitiveToNumber: {
if (InputIs(node, Type::Boolean())) {
VisitUnop(node, UseInfo::Bool(), MachineRepresentation::kWord32);
if (lower()) DeferReplacement(node, node->InputAt(0));
} else if (InputIs(node, Type::String())) {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
- if (lower()) lowering->DoStringToNumber(node);
+ if (lower()) {
+ NodeProperties::ChangeOp(node, simplified()->StringToNumber());
+ }
} else if (truncation.IsUsedAsWord32()) {
if (InputIs(node, Type::NumberOrOddball())) {
VisitUnop(node, UseInfo::TruncatingWord32(),
@@ -2679,6 +2730,10 @@ class RepresentationSelector {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
return;
}
+ case IrOpcode::kObjectIsBigInt: {
+ VisitObjectIs(node, Type::BigInt(), lowering);
+ return;
+ }
case IrOpcode::kObjectIsCallable: {
VisitObjectIs(node, Type::Callable(), lowering);
return;
@@ -2864,6 +2919,10 @@ class RepresentationSelector {
}
return;
}
+ case IrOpcode::kCheckEqualsSymbol:
+ case IrOpcode::kCheckEqualsInternalizedString:
+ return VisitBinop(node, UseInfo::AnyTagged(),
+ MachineRepresentation::kNone);
case IrOpcode::kMapGuard:
// Eliminate MapGuard nodes here.
return VisitUnused(node);
@@ -2933,8 +2992,19 @@ class RepresentationSelector {
return SetOutput(node, MachineRepresentation::kTagged);
case IrOpcode::kFindOrderedHashMapEntry: {
- VisitBinop(node, UseInfo::AnyTagged(),
- MachineRepresentation::kTaggedSigned);
+ Type* const key_type = TypeOf(node->InputAt(1));
+ if (key_type->Is(Type::Signed32OrMinusZero())) {
+ VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
+ MachineRepresentation::kWord32);
+ if (lower()) {
+ NodeProperties::ChangeOp(
+ node,
+ lowering->simplified()->FindOrderedHashMapEntryForInt32Key());
+ }
+ } else {
+ VisitBinop(node, UseInfo::AnyTagged(),
+ MachineRepresentation::kTaggedSigned);
+ }
return;
}
@@ -2959,15 +3029,19 @@ class RepresentationSelector {
case IrOpcode::kOsrValue:
case IrOpcode::kArgumentsElementsState:
case IrOpcode::kArgumentsLengthState:
+ case IrOpcode::kUnreachable:
case IrOpcode::kRuntimeAbort:
// All JavaScript operators except JSToNumber have uniform handling.
#define OPCODE_CASE(name) case IrOpcode::k##name:
JS_SIMPLE_BINOP_LIST(OPCODE_CASE)
- JS_OTHER_UNOP_LIST(OPCODE_CASE)
JS_OBJECT_OP_LIST(OPCODE_CASE)
JS_CONTEXT_OP_LIST(OPCODE_CASE)
JS_OTHER_OP_LIST(OPCODE_CASE)
#undef OPCODE_CASE
+ case IrOpcode::kJSBitwiseNot:
+ case IrOpcode::kJSDecrement:
+ case IrOpcode::kJSIncrement:
+ case IrOpcode::kJSNegate:
case IrOpcode::kJSToInteger:
case IrOpcode::kJSToLength:
case IrOpcode::kJSToName:
@@ -2976,7 +3050,8 @@ class RepresentationSelector {
VisitInputs(node);
// Assume the output is tagged.
return SetOutput(node, MachineRepresentation::kTagged);
-
+ case IrOpcode::kDeadValue:
+ return SetOutput(node, MachineRepresentation::kNone);
default:
V8_Fatal(
__FILE__, __LINE__,
@@ -3106,9 +3181,10 @@ void SimplifiedLowering::LowerAllNodes() {
selector.Run(this);
}
-void SimplifiedLowering::DoJSToNumberTruncatesToFloat64(
+void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToFloat64(
Node* node, RepresentationSelector* selector) {
- DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
+ DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
+ node->opcode() == IrOpcode::kJSToNumeric);
Node* value = node->InputAt(0);
Node* context = node->InputAt(1);
Node* frame_state = node->InputAt(2);
@@ -3131,12 +3207,16 @@ void SimplifiedLowering::DoJSToNumberTruncatesToFloat64(
Node* efalse0 = effect;
Node* vfalse0;
{
- vfalse0 = efalse0 = if_false0 =
- graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
- frame_state, efalse0, if_false0);
+ Operator const* op = node->opcode() == IrOpcode::kJSToNumber
+ ? ToNumberOperator()
+ : ToNumericOperator();
+ Node* code = node->opcode() == IrOpcode::kJSToNumber ? ToNumberCode()
+ : ToNumericCode();
+ vfalse0 = efalse0 = if_false0 = graph()->NewNode(
+ op, code, value, context, frame_state, efalse0, if_false0);
// Update potential {IfException} uses of {node} to point to the above
- // {ToNumber} stub call node instead.
+ // stub call node instead.
Node* on_exception = nullptr;
if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
NodeProperties::ReplaceControlInput(on_exception, vfalse0);
@@ -3196,9 +3276,10 @@ void SimplifiedLowering::DoJSToNumberTruncatesToFloat64(
selector->DeferReplacement(node, value);
}
-void SimplifiedLowering::DoJSToNumberTruncatesToWord32(
+void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToWord32(
Node* node, RepresentationSelector* selector) {
- DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
+ DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
+ node->opcode() == IrOpcode::kJSToNumeric);
Node* value = node->InputAt(0);
Node* context = node->InputAt(1);
Node* frame_state = node->InputAt(2);
@@ -3218,12 +3299,16 @@ void SimplifiedLowering::DoJSToNumberTruncatesToWord32(
Node* efalse0 = effect;
Node* vfalse0;
{
- vfalse0 = efalse0 = if_false0 =
- graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
- frame_state, efalse0, if_false0);
+ Operator const* op = node->opcode() == IrOpcode::kJSToNumber
+ ? ToNumberOperator()
+ : ToNumericOperator();
+ Node* code = node->opcode() == IrOpcode::kJSToNumber ? ToNumberCode()
+ : ToNumericCode();
+ vfalse0 = efalse0 = if_false0 = graph()->NewNode(
+ op, code, value, context, frame_state, efalse0, if_false0);
// Update potential {IfException} uses of {node} to point to the above
- // {ToNumber} stub call node instead.
+ // stub call node instead.
Node* on_exception = nullptr;
if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
NodeProperties::ReplaceControlInput(on_exception, vfalse0);
@@ -3622,20 +3707,6 @@ void SimplifiedLowering::DoShift(Node* node, Operator const* op,
ChangeToPureOp(node, op);
}
-void SimplifiedLowering::DoStringToNumber(Node* node) {
- Operator::Properties properties = Operator::kEliminatable;
- Callable callable =
- Builtins::CallableFor(isolate(), Builtins::kStringToNumber);
- CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
- CallDescriptor* desc = Linkage::GetStubCallDescriptor(
- isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
- node->InsertInput(graph()->zone(), 0,
- jsgraph()->HeapConstant(callable.code()));
- node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant());
- node->AppendInput(graph()->zone(), graph()->start());
- NodeProperties::ChangeOp(node, common()->Call(desc));
-}
-
void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
Node* const input = node->InputAt(0);
Node* const zero = jsgraph()->Int32Constant(0);
@@ -3737,6 +3808,14 @@ Node* SimplifiedLowering::ToNumberCode() {
return to_number_code_.get();
}
+Node* SimplifiedLowering::ToNumericCode() {
+ if (!to_numeric_code_.is_set()) {
+ Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
+ to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
+ }
+ return to_numeric_code_.get();
+}
+
Operator const* SimplifiedLowering::ToNumberOperator() {
if (!to_number_operator_.is_set()) {
Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
@@ -3749,6 +3828,18 @@ Operator const* SimplifiedLowering::ToNumberOperator() {
return to_number_operator_.get();
}
+Operator const* SimplifiedLowering::ToNumericOperator() {
+ if (!to_numeric_operator_.is_set()) {
+ Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
+ CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ isolate(), graph()->zone(), callable.descriptor(), 0, flags,
+ Operator::kNoProperties);
+ to_numeric_operator_.set(common()->Call(desc));
+ }
+ return to_numeric_operator_.get();
+}
+
#undef TRACE
} // namespace compiler