Commit 4fd92b25 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[turbofan] Do not consume SignedSmall feedback in TurboFan anymore.

This changes TurboFan to treat SignedSmall feedback similar to Signed32
feedback for binary and compare operations, in order to simplify and
unify the machinery.

This is an experiment. If this turns out to tank performance, we will
need to revisit and ideally revert this change.

Bug: v8:7094
Change-Id: I885769c2fe93d8413e59838fbe844650c848c3f1
Reviewed-on: https://chromium-review.googlesource.com/c/1261442Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56411}
parent 3c8eaa19
...@@ -2828,9 +2828,9 @@ void BytecodeGraphBuilder::VisitForInContinue() { ...@@ -2828,9 +2828,9 @@ void BytecodeGraphBuilder::VisitForInContinue() {
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* cache_length = Node* cache_length =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* exit_cond = NewNode(simplified()->SpeculativeNumberLessThan( Node* exit_cond = NewNode(
NumberOperationHint::kSignedSmall), simplified()->SpeculativeNumberLessThan(NumberOperationHint::kSigned32),
index, cache_length); index, cache_length);
environment()->BindAccumulator(exit_cond); environment()->BindAccumulator(exit_cond);
} }
...@@ -2868,9 +2868,9 @@ void BytecodeGraphBuilder::VisitForInStep() { ...@@ -2868,9 +2868,9 @@ void BytecodeGraphBuilder::VisitForInStep() {
PrepareEagerCheckpoint(); PrepareEagerCheckpoint();
Node* index = Node* index =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
index = NewNode(simplified()->SpeculativeSafeIntegerAdd( index = NewNode(
NumberOperationHint::kSignedSmall), simplified()->SpeculativeSafeIntegerAdd(NumberOperationHint::kSigned32),
index, jsgraph()->OneConstant()); index, jsgraph()->OneConstant());
environment()->BindAccumulator(index, Environment::kAttachFrameState); environment()->BindAccumulator(index, Environment::kAttachFrameState);
} }
......
...@@ -20,14 +20,12 @@ namespace { ...@@ -20,14 +20,12 @@ namespace {
bool BinaryOperationHintToNumberOperationHint( bool BinaryOperationHintToNumberOperationHint(
BinaryOperationHint binop_hint, NumberOperationHint* number_hint) { BinaryOperationHint binop_hint, NumberOperationHint* number_hint) {
switch (binop_hint) { switch (binop_hint) {
case BinaryOperationHint::kSigned32:
case BinaryOperationHint::kSignedSmall: case BinaryOperationHint::kSignedSmall:
*number_hint = NumberOperationHint::kSignedSmall; *number_hint = NumberOperationHint::kSigned32;
return true; return true;
case BinaryOperationHint::kSignedSmallInputs: case BinaryOperationHint::kSignedSmallInputs:
*number_hint = NumberOperationHint::kSignedSmallInputs; *number_hint = NumberOperationHint::kSigned32Inputs;
return true;
case BinaryOperationHint::kSigned32:
*number_hint = NumberOperationHint::kSigned32;
return true; return true;
case BinaryOperationHint::kNumber: case BinaryOperationHint::kNumber:
*number_hint = NumberOperationHint::kNumber; *number_hint = NumberOperationHint::kNumber;
...@@ -77,7 +75,7 @@ class JSSpeculativeBinopBuilder final { ...@@ -77,7 +75,7 @@ class JSSpeculativeBinopBuilder final {
bool GetCompareNumberOperationHint(NumberOperationHint* hint) { bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
switch (GetCompareOperationHint()) { switch (GetCompareOperationHint()) {
case CompareOperationHint::kSignedSmall: case CompareOperationHint::kSignedSmall:
*hint = NumberOperationHint::kSignedSmall; *hint = NumberOperationHint::kSigned32;
return true; return true;
case CompareOperationHint::kNumber: case CompareOperationHint::kNumber:
*hint = NumberOperationHint::kNumber; *hint = NumberOperationHint::kNumber;
...@@ -100,15 +98,13 @@ class JSSpeculativeBinopBuilder final { ...@@ -100,15 +98,13 @@ class JSSpeculativeBinopBuilder final {
const Operator* SpeculativeNumberOp(NumberOperationHint hint) { const Operator* SpeculativeNumberOp(NumberOperationHint hint) {
switch (op_->opcode()) { switch (op_->opcode()) {
case IrOpcode::kJSAdd: case IrOpcode::kJSAdd:
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
return simplified()->SpeculativeSafeIntegerAdd(hint); return simplified()->SpeculativeSafeIntegerAdd(hint);
} else { } else {
return simplified()->SpeculativeNumberAdd(hint); return simplified()->SpeculativeNumberAdd(hint);
} }
case IrOpcode::kJSSubtract: case IrOpcode::kJSSubtract:
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
return simplified()->SpeculativeSafeIntegerSubtract(hint); return simplified()->SpeculativeSafeIntegerSubtract(hint);
} else { } else {
return simplified()->SpeculativeNumberSubtract(hint); return simplified()->SpeculativeNumberSubtract(hint);
......
...@@ -37,7 +37,7 @@ class JSBinopReduction final { ...@@ -37,7 +37,7 @@ class JSBinopReduction final {
DCHECK_EQ(1, node_->op()->EffectOutputCount()); DCHECK_EQ(1, node_->op()->EffectOutputCount());
switch (CompareOperationHintOf(node_->op())) { switch (CompareOperationHintOf(node_->op())) {
case CompareOperationHint::kSignedSmall: case CompareOperationHint::kSignedSmall:
*hint = NumberOperationHint::kSignedSmall; *hint = NumberOperationHint::kSigned32;
return true; return true;
case CompareOperationHint::kNumber: case CompareOperationHint::kNumber:
*hint = NumberOperationHint::kNumber; *hint = NumberOperationHint::kNumber;
......
...@@ -94,10 +94,8 @@ UseInfo CheckedUseInfoAsWord32FromHint( ...@@ -94,10 +94,8 @@ UseInfo CheckedUseInfoAsWord32FromHint(
NumberOperationHint hint, const VectorSlotPair& feedback = VectorSlotPair(), NumberOperationHint hint, const VectorSlotPair& feedback = VectorSlotPair(),
IdentifyZeros identify_zeros = kDistinguishZeros) { IdentifyZeros identify_zeros = kDistinguishZeros) {
switch (hint) { switch (hint) {
case NumberOperationHint::kSignedSmall:
case NumberOperationHint::kSignedSmallInputs:
return UseInfo::CheckedSignedSmallAsWord32(identify_zeros, feedback);
case NumberOperationHint::kSigned32: case NumberOperationHint::kSigned32:
case NumberOperationHint::kSigned32Inputs:
return UseInfo::CheckedSigned32AsWord32(identify_zeros, feedback); return UseInfo::CheckedSigned32AsWord32(identify_zeros, feedback);
case NumberOperationHint::kNumber: case NumberOperationHint::kNumber:
return UseInfo::CheckedNumberAsWord32(feedback); return UseInfo::CheckedNumberAsWord32(feedback);
...@@ -111,9 +109,8 @@ UseInfo CheckedUseInfoAsFloat64FromHint( ...@@ -111,9 +109,8 @@ UseInfo CheckedUseInfoAsFloat64FromHint(
NumberOperationHint hint, const VectorSlotPair& feedback, NumberOperationHint hint, const VectorSlotPair& feedback,
IdentifyZeros identify_zeros = kDistinguishZeros) { IdentifyZeros identify_zeros = kDistinguishZeros) {
switch (hint) { switch (hint) {
case NumberOperationHint::kSignedSmall:
case NumberOperationHint::kSignedSmallInputs:
case NumberOperationHint::kSigned32: case NumberOperationHint::kSigned32:
case NumberOperationHint::kSigned32Inputs:
// Not used currently. // Not used currently.
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -747,11 +744,6 @@ class RepresentationSelector { ...@@ -747,11 +744,6 @@ class RepresentationSelector {
GetUpperBound(node->InputAt(1)).Is(type); GetUpperBound(node->InputAt(1)).Is(type);
} }
bool IsNodeRepresentationTagged(Node* node) {
MachineRepresentation representation = GetInfo(node)->representation();
return IsAnyTagged(representation);
}
bool OneInputCannotBe(Node* node, Type type) { bool OneInputCannotBe(Node* node, Type type) {
DCHECK_EQ(2, node->op()->ValueInputCount()); DCHECK_EQ(2, node->op()->ValueInputCount());
return !GetUpperBound(node->InputAt(0)).Maybe(type) || return !GetUpperBound(node->InputAt(0)).Maybe(type) ||
...@@ -1319,9 +1311,7 @@ class RepresentationSelector { ...@@ -1319,9 +1311,7 @@ class RepresentationSelector {
// Try to use type feedback. // Try to use type feedback.
NumberOperationHint hint = NumberOperationHintOf(node->op()); NumberOperationHint hint = NumberOperationHintOf(node->op());
DCHECK_EQ(NumberOperationHint::kSigned32, hint);
DCHECK(hint == NumberOperationHint::kSignedSmall ||
hint == NumberOperationHint::kSigned32);
Type left_feedback_type = TypeOf(node->InputAt(0)); Type left_feedback_type = TypeOf(node->InputAt(0));
Type right_feedback_type = TypeOf(node->InputAt(1)); Type right_feedback_type = TypeOf(node->InputAt(1));
...@@ -1415,8 +1405,7 @@ class RepresentationSelector { ...@@ -1415,8 +1405,7 @@ class RepresentationSelector {
// Handle the case when no uint32 checks on inputs are necessary // Handle the case when no uint32 checks on inputs are necessary
// (but an overflow check is needed on the output). // (but an overflow check is needed on the output).
if (BothInputsAreUnsigned32(node)) { if (BothInputsAreUnsigned32(node)) {
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
VisitBinop(node, UseInfo::TruncatingWord32(), VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32, Type::Unsigned32()); MachineRepresentation::kWord32, Type::Unsigned32());
if (lower()) ChangeToUint32OverflowOp(node); if (lower()) ChangeToUint32OverflowOp(node);
...@@ -1428,8 +1417,7 @@ class RepresentationSelector { ...@@ -1428,8 +1417,7 @@ class RepresentationSelector {
// (but an overflow check is needed on the output). // (but an overflow check is needed on the output).
if (BothInputsAre(node, Type::Signed32())) { if (BothInputsAre(node, Type::Signed32())) {
// If both the inputs the feedback are int32, use the overflow op. // If both the inputs the feedback are int32, use the overflow op.
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
VisitBinop(node, UseInfo::TruncatingWord32(), VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32, Type::Signed32()); MachineRepresentation::kWord32, Type::Signed32());
if (lower()) ChangeToInt32OverflowOp(node); if (lower()) ChangeToInt32OverflowOp(node);
...@@ -1437,8 +1425,7 @@ class RepresentationSelector { ...@@ -1437,8 +1425,7 @@ class RepresentationSelector {
} }
} }
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
// If the result is truncated, we only need to check the inputs. // If the result is truncated, we only need to check the inputs.
// For the left hand side we just propagate the identify zeros // For the left hand side we just propagate the identify zeros
// mode of the {truncation}; and for modulus the sign of the // mode of the {truncation}; and for modulus the sign of the
...@@ -1759,37 +1746,13 @@ class RepresentationSelector { ...@@ -1759,37 +1746,13 @@ class RepresentationSelector {
NumberOperationHint hint = NumberOperationHintOf(node->op()); NumberOperationHint hint = NumberOperationHintOf(node->op());
switch (hint) { switch (hint) {
case NumberOperationHint::kSigned32: case NumberOperationHint::kSigned32:
case NumberOperationHint::kSignedSmall: VisitBinop(node,
if (propagate()) { CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
VisitBinop(node, kIdentifyZeros),
CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(), MachineRepresentation::kBit);
kIdentifyZeros), if (lower()) ChangeToPureOp(node, Int32Op(node));
MachineRepresentation::kBit);
} else if (retype()) {
SetOutput(node, MachineRepresentation::kBit, Type::Any());
} else {
DCHECK(lower());
Node* lhs = node->InputAt(0);
Node* rhs = node->InputAt(1);
if (IsNodeRepresentationTagged(lhs) &&
IsNodeRepresentationTagged(rhs)) {
VisitBinop(node,
UseInfo::CheckedSignedSmallAsTaggedSigned(
VectorSlotPair(), kIdentifyZeros),
MachineRepresentation::kBit);
ChangeToPureOp(
node, changer_->TaggedSignedOperatorFor(node->opcode()));
} else {
VisitBinop(node,
CheckedUseInfoAsWord32FromHint(
hint, VectorSlotPair(), kIdentifyZeros),
MachineRepresentation::kBit);
ChangeToPureOp(node, Int32Op(node));
}
}
return; return;
case NumberOperationHint::kSignedSmallInputs: case NumberOperationHint::kSigned32Inputs:
// This doesn't make sense for compare operations. // This doesn't make sense for compare operations.
UNREACHABLE(); UNREACHABLE();
case NumberOperationHint::kNumberOrOddball: case NumberOperationHint::kNumberOrOddball:
...@@ -1860,8 +1823,7 @@ class RepresentationSelector { ...@@ -1860,8 +1823,7 @@ class RepresentationSelector {
// (but an overflow check is needed on the output). // (but an overflow check is needed on the output).
if (BothInputsAre(node, Type::Signed32())) { if (BothInputsAre(node, Type::Signed32())) {
// If both inputs and feedback are int32, use the overflow op. // If both inputs and feedback are int32, use the overflow op.
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
VisitBinop(node, UseInfo::TruncatingWord32(), VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32, Type::Signed32()); MachineRepresentation::kWord32, Type::Signed32());
if (lower()) { if (lower()) {
...@@ -1872,8 +1834,7 @@ class RepresentationSelector { ...@@ -1872,8 +1834,7 @@ class RepresentationSelector {
} }
} }
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Signed32()); MachineRepresentation::kWord32, Type::Signed32());
if (lower()) { if (lower()) {
...@@ -1939,8 +1900,7 @@ class RepresentationSelector { ...@@ -1939,8 +1900,7 @@ class RepresentationSelector {
// Handle the case when no uint32 checks on inputs are necessary // Handle the case when no uint32 checks on inputs are necessary
// (but an overflow check is needed on the output). // (but an overflow check is needed on the output).
if (BothInputsAreUnsigned32(node)) { if (BothInputsAreUnsigned32(node)) {
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
VisitBinop(node, UseInfo::TruncatingWord32(), VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32, Type::Unsigned32()); MachineRepresentation::kWord32, Type::Unsigned32());
if (lower()) ChangeToUint32OverflowOp(node); if (lower()) ChangeToUint32OverflowOp(node);
...@@ -1952,8 +1912,7 @@ class RepresentationSelector { ...@@ -1952,8 +1912,7 @@ class RepresentationSelector {
// (but an overflow check is needed on the output). // (but an overflow check is needed on the output).
if (BothInputsAreSigned32(node)) { if (BothInputsAreSigned32(node)) {
// If both the inputs the feedback are int32, use the overflow op. // If both the inputs the feedback are int32, use the overflow op.
if (hint == NumberOperationHint::kSignedSmall || if (hint == NumberOperationHint::kSigned32) {
hint == NumberOperationHint::kSigned32) {
VisitBinop(node, UseInfo::TruncatingWord32(), VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32, Type::Signed32()); MachineRepresentation::kWord32, Type::Signed32());
if (lower()) ChangeToInt32OverflowOp(node); if (lower()) ChangeToInt32OverflowOp(node);
...@@ -1962,15 +1921,14 @@ class RepresentationSelector { ...@@ -1962,15 +1921,14 @@ class RepresentationSelector {
} }
if (hint == NumberOperationHint::kSigned32 || if (hint == NumberOperationHint::kSigned32 ||
hint == NumberOperationHint::kSignedSmall || hint == NumberOperationHint::kSigned32Inputs) {
hint == NumberOperationHint::kSignedSmallInputs) {
// If the result is truncated, we only need to check the inputs. // If the result is truncated, we only need to check the inputs.
if (truncation.IsUsedAsWord32()) { if (truncation.IsUsedAsWord32()) {
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32); MachineRepresentation::kWord32);
if (lower()) DeferReplacement(node, lowering->Int32Div(node)); if (lower()) DeferReplacement(node, lowering->Int32Div(node));
return; return;
} else if (hint != NumberOperationHint::kSignedSmallInputs) { } else if (hint != NumberOperationHint::kSigned32Inputs) {
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Signed32()); MachineRepresentation::kWord32, Type::Signed32());
if (lower()) ChangeToInt32OverflowOp(node); if (lower()) ChangeToInt32OverflowOp(node);
...@@ -2132,8 +2090,7 @@ class RepresentationSelector { ...@@ -2132,8 +2090,7 @@ class RepresentationSelector {
NumberOperationHint hint = NumberOperationHintOf(node->op()); NumberOperationHint hint = NumberOperationHintOf(node->op());
Type rhs_type = GetUpperBound(node->InputAt(1)); Type rhs_type = GetUpperBound(node->InputAt(1));
if (rhs_type.Is(type_cache_.kZeroish) && if (rhs_type.Is(type_cache_.kZeroish) &&
(hint == NumberOperationHint::kSignedSmall || hint == NumberOperationHint::kSigned32 &&
hint == NumberOperationHint::kSigned32) &&
!truncation.IsUsedAsWord32()) { !truncation.IsUsedAsWord32()) {
// The SignedSmall or Signed32 feedback means that the results that we // The SignedSmall or Signed32 feedback means that the results that we
// have seen so far were of type Unsigned31. We speculate that this // have seen so far were of type Unsigned31. We speculate that this
...@@ -2869,8 +2826,7 @@ class RepresentationSelector { ...@@ -2869,8 +2826,7 @@ class RepresentationSelector {
NumberOperationParametersOf(node->op()); NumberOperationParametersOf(node->op());
switch (p.hint()) { switch (p.hint()) {
case NumberOperationHint::kSigned32: case NumberOperationHint::kSigned32:
case NumberOperationHint::kSignedSmall: case NumberOperationHint::kSigned32Inputs:
case NumberOperationHint::kSignedSmallInputs:
VisitUnop(node, VisitUnop(node,
CheckedUseInfoAsWord32FromHint(p.hint(), p.feedback()), CheckedUseInfoAsWord32FromHint(p.hint(), p.feedback()),
MachineRepresentation::kWord32, Type::Signed32()); MachineRepresentation::kWord32, Type::Signed32());
......
...@@ -509,10 +509,8 @@ Handle<Map> FastMapParameterOf(const Operator* op) { ...@@ -509,10 +509,8 @@ Handle<Map> FastMapParameterOf(const Operator* op) {
std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) { std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
switch (hint) { switch (hint) {
case NumberOperationHint::kSignedSmall: case NumberOperationHint::kSigned32Inputs:
return os << "SignedSmall"; return os << "Signed32Inputs";
case NumberOperationHint::kSignedSmallInputs:
return os << "SignedSmallInputs";
case NumberOperationHint::kSigned32: case NumberOperationHint::kSigned32:
return os << "Signed32"; return os << "Signed32";
case NumberOperationHint::kNumber: case NumberOperationHint::kNumber:
...@@ -1084,10 +1082,8 @@ struct SimplifiedOperatorGlobalCache final { ...@@ -1084,10 +1082,8 @@ struct SimplifiedOperatorGlobalCache final {
IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
#Name, 2, 1, 1, 1, 1, 0, kHint) {} \ #Name, 2, 1, 1, 1, 1, 0, kHint) {} \
}; \ }; \
Name##Operator<NumberOperationHint::kSignedSmall> \ Name##Operator<NumberOperationHint::kSigned32Inputs> \
k##Name##SignedSmallOperator; \ k##Name##Signed32InputsOperator; \
Name##Operator<NumberOperationHint::kSignedSmallInputs> \
k##Name##SignedSmallInputsOperator; \
Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \ Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \
Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \ Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \
Name##Operator<NumberOperationHint::kNumberOrOddball> \ Name##Operator<NumberOperationHint::kNumberOrOddball> \
...@@ -1105,8 +1101,6 @@ struct SimplifiedOperatorGlobalCache final { ...@@ -1105,8 +1101,6 @@ struct SimplifiedOperatorGlobalCache final {
1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0,
NumberOperationParameters(kHint, VectorSlotPair())) {} NumberOperationParameters(kHint, VectorSlotPair())) {}
}; };
SpeculativeToNumberOperator<NumberOperationHint::kSignedSmall>
kSpeculativeToNumberSignedSmallOperator;
SpeculativeToNumberOperator<NumberOperationHint::kSigned32> SpeculativeToNumberOperator<NumberOperationHint::kSigned32>
kSpeculativeToNumberSigned32Operator; kSpeculativeToNumberSigned32Operator;
SpeculativeToNumberOperator<NumberOperationHint::kNumber> SpeculativeToNumberOperator<NumberOperationHint::kNumber>
...@@ -1333,12 +1327,10 @@ const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber( ...@@ -1333,12 +1327,10 @@ const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber(
NumberOperationHint hint, const VectorSlotPair& feedback) { NumberOperationHint hint, const VectorSlotPair& feedback) {
if (!feedback.IsValid()) { if (!feedback.IsValid()) {
switch (hint) { switch (hint) {
case NumberOperationHint::kSignedSmall:
return &cache_.kSpeculativeToNumberSignedSmallOperator;
case NumberOperationHint::kSignedSmallInputs:
break;
case NumberOperationHint::kSigned32: case NumberOperationHint::kSigned32:
return &cache_.kSpeculativeToNumberSigned32Operator; return &cache_.kSpeculativeToNumberSigned32Operator;
case NumberOperationHint::kSigned32Inputs:
break;
case NumberOperationHint::kNumber: case NumberOperationHint::kNumber:
return &cache_.kSpeculativeToNumberNumberOperator; return &cache_.kSpeculativeToNumberNumberOperator;
case NumberOperationHint::kNumberOrOddball: case NumberOperationHint::kNumberOrOddball:
...@@ -1538,10 +1530,8 @@ const Operator* SimplifiedOperatorBuilder::StringFromSingleCodePoint( ...@@ -1538,10 +1530,8 @@ const Operator* SimplifiedOperatorBuilder::StringFromSingleCodePoint(
#define SPECULATIVE_NUMBER_BINOP(Name) \ #define SPECULATIVE_NUMBER_BINOP(Name) \
const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \ const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \
switch (hint) { \ switch (hint) { \
case NumberOperationHint::kSignedSmall: \ case NumberOperationHint::kSigned32Inputs: \
return &cache_.k##Name##SignedSmallOperator; \ return &cache_.k##Name##Signed32InputsOperator; \
case NumberOperationHint::kSignedSmallInputs: \
return &cache_.k##Name##SignedSmallInputsOperator; \
case NumberOperationHint::kSigned32: \ case NumberOperationHint::kSigned32: \
return &cache_.k##Name##Signed32Operator; \ return &cache_.k##Name##Signed32Operator; \
case NumberOperationHint::kNumber: \ case NumberOperationHint::kNumber: \
......
...@@ -434,11 +434,10 @@ Type ValueTypeParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT; ...@@ -434,11 +434,10 @@ Type ValueTypeParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
// A hint for speculative number operations. // A hint for speculative number operations.
enum class NumberOperationHint : uint8_t { enum class NumberOperationHint : uint8_t {
kSignedSmall, // Inputs were Smi, output was in Smi. kSigned32, // Inputs were Signed32, output was Number.
kSignedSmallInputs, // Inputs were Smi, output was Number. kSigned32Inputs, // Inputs were Signed32, output was Number.
kSigned32, // Inputs were Signed32, output was Number. kNumber, // Inputs were Number, output was Number.
kNumber, // Inputs were Number, output was Number. kNumberOrOddball, // Inputs were Number or Oddball, output was Number.
kNumberOrOddball, // Inputs were Number or Oddball, output was Number.
}; };
size_t hash_value(NumberOperationHint); size_t hash_value(NumberOperationHint);
......
...@@ -585,7 +585,7 @@ TEST(LogAll) { ...@@ -585,7 +585,7 @@ TEST(LogAll) {
CHECK(logger.ContainsLine({"api,v8::Script::Run"})); CHECK(logger.ContainsLine({"api,v8::Script::Run"}));
CHECK(logger.ContainsLine({"code-creation,LazyCompile,", "testAddFn"})); CHECK(logger.ContainsLine({"code-creation,LazyCompile,", "testAddFn"}));
if (i::FLAG_opt && !i::FLAG_always_opt) { if (i::FLAG_opt && !i::FLAG_always_opt) {
CHECK(logger.ContainsLine({"code-deopt,", "not a Smi"})); CHECK(logger.ContainsLine({"code-deopt,", "not a heap number"}));
if (i::FLAG_enable_one_shot_optimization) if (i::FLAG_enable_one_shot_optimization)
CHECK(logger.ContainsLine({"code-deopt,", "DeoptimizeNow"})); CHECK(logger.ContainsLine({"code-deopt,", "DeoptimizeNow"}));
CHECK(logger.ContainsLine({"timer-event-start", "V8.DeoptimizeCode"})); CHECK(logger.ContainsLine({"timer-event-start", "V8.DeoptimizeCode"}));
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --opt --no-always-opt --deopt-every-n-times=6 // Flags: --allow-natives-syntax --opt --no-always-opt --deopt-every-n-times=3
// Check that stress deopt count resets correctly // Check that stress deopt count resets correctly
...@@ -14,34 +14,34 @@ function f(x) { ...@@ -14,34 +14,34 @@ function f(x) {
f(1); f(1);
%OptimizeFunctionOnNextCall(f); %OptimizeFunctionOnNextCall(f);
// stress_deopt_count == 6 // stress_deopt_count == 3
f(1); f(1);
assertOptimized(f, undefined, undefined, false); assertOptimized(f, undefined, undefined, false);
// stress_deopt_count == 4 // stress_deopt_count == 2
f(1); f(1);
assertOptimized(f, undefined, undefined, false); assertOptimized(f, undefined, undefined, false);
// stress_deopt_count == 2 // stress_deopt_count == 1
f(1); f(1);
// deopt & counter reset // deopt & counter reset
assertUnoptimized(f, undefined, undefined, false); assertUnoptimized(f, undefined, undefined, false);
// stress_deopt_count == 6 // stress_deopt_count == 3
%OptimizeFunctionOnNextCall(f); %OptimizeFunctionOnNextCall(f);
f(1); f(1);
assertOptimized(f, undefined, undefined, false); assertOptimized(f, undefined, undefined, false);
// stress_deopt_count == 4 // stress_deopt_count == 2
f(1); f(1);
assertOptimized(f, undefined, undefined, false); assertOptimized(f, undefined, undefined, false);
// stress_deopt_count == 2 // stress_deopt_count == 1
f(1); f(1);
// deopt & counter reset // deopt & counter reset
......
...@@ -27,41 +27,34 @@ ...@@ -27,41 +27,34 @@
// Flags: --allow-natives-syntax --opt --noalways-opt // Flags: --allow-natives-syntax --opt --noalways-opt
function mul(a, b) { (function() {
return a * b; function mul(a, b) {
} return a * b;
}
mul(-1, 2); mul(-1, 2);
mul(-1, 2); mul(-1, 2);
%OptimizeFunctionOnNextCall(mul); %OptimizeFunctionOnNextCall(mul);
assertEquals(-2, mul(-1, 2)); assertEquals(-2, mul(-1, 2));
assertOptimized(mul); assertOptimized(mul);
// Deopt on minus zero. // Deopt on minus zero.
assertEquals(-0, mul(-1, 0)); assertEquals(-0, mul(-1, 0));
assertUnoptimized(mul); assertUnoptimized(mul);
})();
function mul2(a, b) { (function() {
return a * b; function mul2(a, b) {
} return a * b;
}
mul2(-1, 2);
mul2(-1, 2); mul2(-1, 2);
%OptimizeFunctionOnNextCall(mul2); mul2(-1, 2);
%OptimizeFunctionOnNextCall(mul2);
// 2^30 is a smi boundary on arm and ia32. assertEquals(-2, mul2(-1, 2));
var two_30 = 1 << 30; assertOptimized(mul2);
// 2^31 is a smi boundary on x64.
var two_31 = 2 * two_30; // Deopt on 2^31.
assertEquals(1 << 31, mul2(-(1 << 31), -1));
if (%IsValidSmi(two_31)) {
// Deopt on two_31 on x64.
assertEquals(two_31, mul2(-two_31, -1));
assertUnoptimized(mul2);
} else {
// Deopt on two_30 on ia32.
assertEquals(two_30, mul2(-two_30, -1));
assertUnoptimized(mul2); assertUnoptimized(mul2);
} })();
...@@ -72,12 +72,8 @@ const CheckTaggedInputMode kCheckTaggedInputModes[] = { ...@@ -72,12 +72,8 @@ const CheckTaggedInputMode kCheckTaggedInputModes[] = {
CheckTaggedInputMode::kNumber, CheckTaggedInputMode::kNumberOrOddball}; CheckTaggedInputMode::kNumber, CheckTaggedInputMode::kNumberOrOddball};
const NumberOperationHint kNumberOperationHints[] = { const NumberOperationHint kNumberOperationHints[] = {
NumberOperationHint::kSignedSmall, NumberOperationHint::kSigned32, NumberOperationHint::kSigned32Inputs,
NumberOperationHint::kSignedSmallInputs, NumberOperationHint::kNumber, NumberOperationHint::kNumberOrOddball};
NumberOperationHint::kSigned32,
NumberOperationHint::kNumber,
NumberOperationHint::kNumberOrOddball,
};
} // namespace } // namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment