| Index: src/compiler/simplified-lowering.cc
|
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
|
| index 8a7513d101781d6883185f9e384669552ecb9119..f50ba3ccfc64d3186edae9ea6455db36adbca59d 100644
|
| --- a/src/compiler/simplified-lowering.cc
|
| +++ b/src/compiler/simplified-lowering.cc
|
| @@ -241,12 +241,6 @@ class RepresentationSelector {
|
| bool weakened() const { return weakened_; }
|
| void set_restriction_type(Type* type) { restriction_type_ = type; }
|
| Type* restriction_type() const { return restriction_type_; }
|
| - void set_unrestricted_feedback_type(Type* type) {
|
| - unrestricted_feedback_type_ = type;
|
| - }
|
| - Type* unrestricted_feedback_type() const {
|
| - return unrestricted_feedback_type_;
|
| - }
|
|
|
| private:
|
| enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
|
| @@ -257,7 +251,6 @@ class RepresentationSelector {
|
|
|
| Type* restriction_type_ = Type::Any();
|
| Type* feedback_type_ = nullptr;
|
| - Type* unrestricted_feedback_type_ = nullptr;
|
| bool weakened_ = false;
|
| };
|
|
|
| @@ -371,11 +364,6 @@ class RepresentationSelector {
|
| return type == nullptr ? Type::None() : type;
|
| }
|
|
|
| - Type* UnrestrictedFeedbackTypeOf(Node* node) {
|
| - Type* type = GetInfo(node)->unrestricted_feedback_type();
|
| - return type == nullptr ? NodeProperties::GetType(node) : type;
|
| - }
|
| -
|
| Type* TypePhi(Node* node) {
|
| int arity = node->op()->ValueInputCount();
|
| Type* type = FeedbackTypeOf(node->InputAt(0));
|
| @@ -418,11 +406,13 @@ class RepresentationSelector {
|
| SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
|
| #undef DECLARE_CASE
|
|
|
| -#define DECLARE_CASE(Name) \
|
| - case IrOpcode::k##Name: { \
|
| - new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0)), \
|
| - FeedbackTypeOf(node->InputAt(1))); \
|
| - break; \
|
| +#define DECLARE_CASE(Name) \
|
| + case IrOpcode::k##Name: { \
|
| + new_type = \
|
| + Type::Intersect(op_typer_.Name(FeedbackTypeOf(node->InputAt(0)), \
|
| + FeedbackTypeOf(node->InputAt(1))), \
|
| + info->restriction_type(), graph_zone()); \
|
| + break; \
|
| }
|
| SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
|
| #undef DECLARE_CASE
|
| @@ -461,17 +451,11 @@ class RepresentationSelector {
|
| default:
|
| // Shortcut for operations that we do not handle.
|
| if (type == nullptr) {
|
| - type = GetUpperBound(node);
|
| - info->set_unrestricted_feedback_type(type);
|
| - info->set_feedback_type(
|
| - Type::Intersect(type, info->restriction_type(), graph_zone()));
|
| + GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
|
| return true;
|
| }
|
| return false;
|
| }
|
| - Type* unrestricted_feedback_type = new_type;
|
| - new_type =
|
| - Type::Intersect(new_type, info->restriction_type(), graph_zone());
|
| // We need to guarantee that the feedback type is a subtype of the upper
|
| // bound. Naively that should hold, but weakening can actually produce
|
| // a bigger type if we are unlucky with ordering of phi typing. To be
|
| @@ -479,8 +463,7 @@ class RepresentationSelector {
|
| new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
|
|
|
| if (type != nullptr && new_type->Is(type)) return false;
|
| - info->set_unrestricted_feedback_type(unrestricted_feedback_type);
|
| - info->set_feedback_type(new_type);
|
| + GetInfo(node)->set_feedback_type(new_type);
|
| if (FLAG_trace_representation) {
|
| PrintNodeFeedbackType(node);
|
| }
|
| @@ -1117,6 +1100,22 @@ class RepresentationSelector {
|
| return jsgraph_->simplified();
|
| }
|
|
|
| + void LowerToCheckedInt32Mul(Node* node, Truncation truncation,
|
| + Type* input0_type, Type* input1_type) {
|
| + // If one of the inputs is positive and/or truncation is being applied,
|
| + // there is no need to return -0.
|
| + CheckForMinusZeroMode mz_mode =
|
| + truncation.IsUsedAsWord32() ||
|
| + (input0_type->Is(Type::OrderedNumber()) &&
|
| + input0_type->Min() > 0) ||
|
| + (input1_type->Is(Type::OrderedNumber()) &&
|
| + input1_type->Min() > 0)
|
| + ? CheckForMinusZeroMode::kDontCheckForMinusZero
|
| + : CheckForMinusZeroMode::kCheckForMinusZero;
|
| +
|
| + NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
|
| + }
|
| +
|
| void ChangeToInt32OverflowOp(Node* node) {
|
| NodeProperties::ChangeOp(node, Int32OverflowOp(node));
|
| }
|
| @@ -1144,32 +1143,29 @@ class RepresentationSelector {
|
| return;
|
| }
|
|
|
| - // We always take SignedSmall/Signed32 feedback otherwise.
|
| - NumberOperationHint const hint = NumberOperationHintOf(node->op());
|
| - if (hint == NumberOperationHint::kSignedSmall ||
|
| - hint == NumberOperationHint::kSigned32) {
|
| - // Check if we can guarantee truncations for the inputs.
|
| - if (BothInputsAre(node, Type::Signed32()) ||
|
| - (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
|
| - NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) {
|
| + // Try to use type feedback.
|
| + NumberOperationHint hint = NumberOperationHintOf(node->op());
|
| +
|
| + // Handle the case when no int32 checks on inputs are necessary
|
| + // (but an overflow check is needed on the output).
|
| + if (BothInputsAre(node, Type::Signed32()) ||
|
| + (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
|
| + NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) {
|
| + // If both the inputs the feedback are int32, use the overflow op.
|
| + if (hint == NumberOperationHint::kSignedSmall ||
|
| + hint == NumberOperationHint::kSigned32) {
|
| VisitBinop(node, UseInfo::TruncatingWord32(),
|
| MachineRepresentation::kWord32, Type::Signed32());
|
| - } else {
|
| - VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
|
| - MachineRepresentation::kWord32, Type::Signed32());
|
| - }
|
| - if (lower()) {
|
| - // Avoid overflow checks if the unrestricted feedback type of {node}
|
| - // suggests that the result will fit into Signed32/Unsigned32 range.
|
| - Type* const type = UnrestrictedFeedbackTypeOf(node);
|
| - if (type->Is(Type::Unsigned32())) {
|
| - ChangeToPureOp(node, Uint32Op(node));
|
| - } else if (type->Is(Type::Signed32())) {
|
| - ChangeToPureOp(node, Int32Op(node));
|
| - } else {
|
| - ChangeToInt32OverflowOp(node);
|
| - }
|
| + if (lower()) ChangeToInt32OverflowOp(node);
|
| + return;
|
| }
|
| + }
|
| +
|
| + if (hint == NumberOperationHint::kSignedSmall ||
|
| + hint == NumberOperationHint::kSigned32) {
|
| + VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
|
| + MachineRepresentation::kWord32, Type::Signed32());
|
| + if (lower()) ChangeToInt32OverflowOp(node);
|
| return;
|
| }
|
|
|
| @@ -1179,6 +1175,7 @@ class RepresentationSelector {
|
| if (lower()) {
|
| ChangeToPureOp(node, Float64Op(node));
|
| }
|
| + return;
|
| }
|
|
|
| void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
|
| @@ -1520,39 +1517,33 @@ class RepresentationSelector {
|
| if (lower()) ChangeToPureOp(node, Int32Op(node));
|
| return;
|
| }
|
| + // Try to use type feedback.
|
| + NumberOperationHint hint = NumberOperationHintOf(node->op());
|
| + Type* input0_type = TypeOf(node->InputAt(0));
|
| + Type* input1_type = TypeOf(node->InputAt(1));
|
|
|
| - // We always take SignedSmall/Signed32 feedback otherwise.
|
| - NumberOperationHint const hint = NumberOperationHintOf(node->op());
|
| - if (hint == NumberOperationHint::kSignedSmall ||
|
| - hint == NumberOperationHint::kSigned32) {
|
| - // Handle the case when no int32 checks on inputs are necessary
|
| - // (but an overflow check is needed on the output).
|
| - if (BothInputsAre(node, Type::Signed32())) {
|
| - // If both the inputs the feedback are int32, use the overflow op.
|
| + // Handle the case when no int32 checks on inputs are necessary
|
| + // (but an overflow check is needed on the output).
|
| + if (BothInputsAre(node, Type::Signed32())) {
|
| + // If both the inputs the feedback are int32, use the overflow op.
|
| + if (hint == NumberOperationHint::kSignedSmall ||
|
| + hint == NumberOperationHint::kSigned32) {
|
| VisitBinop(node, UseInfo::TruncatingWord32(),
|
| MachineRepresentation::kWord32, Type::Signed32());
|
| - } else {
|
| - VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
|
| - MachineRepresentation::kWord32, Type::Signed32());
|
| + if (lower()) {
|
| + LowerToCheckedInt32Mul(node, truncation, input0_type,
|
| + input1_type);
|
| + }
|
| + return;
|
| }
|
| + }
|
| +
|
| + if (hint == NumberOperationHint::kSignedSmall ||
|
| + hint == NumberOperationHint::kSigned32) {
|
| + VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
|
| + MachineRepresentation::kWord32, Type::Signed32());
|
| if (lower()) {
|
| - // Avoid overflow checks if the unrestricted feedback type of {node}
|
| - // suggests that the result will fit into Signed32/Unsigned32 range,
|
| - // or at least try to avoid the expensive minus zero checks.
|
| - Type* const type = UnrestrictedFeedbackTypeOf(node);
|
| - if (type->Is(Type::Unsigned32())) {
|
| - ChangeToPureOp(node, Uint32Op(node));
|
| - } else if (type->Is(Type::Signed32())) {
|
| - ChangeToPureOp(node, Int32Op(node));
|
| - } else {
|
| - CheckForMinusZeroMode const mode =
|
| - (truncation.IdentifiesMinusZeroAndZero() ||
|
| - !type->Maybe(Type::MinusZero()))
|
| - ? CheckForMinusZeroMode::kDontCheckForMinusZero
|
| - : CheckForMinusZeroMode::kCheckForMinusZero;
|
| - NodeProperties::ChangeOp(node,
|
| - simplified()->CheckedInt32Mul(mode));
|
| - }
|
| + LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type);
|
| }
|
| return;
|
| }
|
|
|