[turbofan] Consume feedback types for NumberMax and NumberMin.

For nodes

  NumberMin(lhs, rhs)
  NumberMax(lhs, rhs)

we might have feedback types for lhs and rhs that would allow us to
generate unsigned32 or signed32 versions of this operator, which is way
more efficient that going to the full Float64Min/Float64Max operator.
However we cannot promise word32 truncations in this case, since we
based this decision on the feedback types.

This allows us to generate better code for Math.min and Math.max when
one of the inputs is a speculative number operator that provides better
typing during representation selection. We've seen such code in the
hottest function on Google Maps for example.

BUG=v8:5267
R=jarin@chromium.org,mvstanton@chromium.org

Review-Url: https://codereview.chromium.org/2734193003
Cr-Commit-Position: refs/heads/master@{#43660}
This commit is contained in:
bmeurer 2017-03-07 22:05:41 -08:00 committed by Commit bot
parent 76224f7e49
commit 99aaa69b29

View File

@ -2061,20 +2061,27 @@ class RepresentationSelector {
return;
}
case IrOpcode::kNumberMax: {
// TODO(turbofan): We should consider feedback types here as well.
if (BothInputsAreUnsigned32(node)) {
// It is safe to use the feedback types for left and right hand side
// here, since we can only narrow those types and thus we can only
// promise a more specific truncation.
Type* const lhs_type = TypeOf(node->InputAt(0));
Type* const rhs_type = TypeOf(node->InputAt(1));
if (lhs_type->Is(Type::Unsigned32()) &&
rhs_type->Is(Type::Unsigned32())) {
VisitWord32TruncatingBinop(node);
if (lower()) {
lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
MachineRepresentation::kWord32);
}
} else if (BothInputsAreSigned32(node)) {
} else if (lhs_type->Is(Type::Signed32()) &&
rhs_type->Is(Type::Signed32())) {
VisitWord32TruncatingBinop(node);
if (lower()) {
lowering->DoMax(node, lowering->machine()->Int32LessThan(),
MachineRepresentation::kWord32);
}
} else if (BothInputsAre(node, Type::PlainNumber())) {
} else if (lhs_type->Is(Type::PlainNumber()) &&
rhs_type->Is(Type::PlainNumber())) {
VisitFloat64Binop(node);
if (lower()) {
lowering->DoMax(node, lowering->machine()->Float64LessThan(),
@ -2087,20 +2094,27 @@ class RepresentationSelector {
return;
}
case IrOpcode::kNumberMin: {
// TODO(turbofan): We should consider feedback types here as well.
if (BothInputsAreUnsigned32(node)) {
// It is safe to use the feedback types for left and right hand side
// here, since we can only narrow those types and thus we can only
// promise a more specific truncation.
Type* const lhs_type = TypeOf(node->InputAt(0));
Type* const rhs_type = TypeOf(node->InputAt(1));
if (lhs_type->Is(Type::Unsigned32()) &&
rhs_type->Is(Type::Unsigned32())) {
VisitWord32TruncatingBinop(node);
if (lower()) {
lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
MachineRepresentation::kWord32);
}
} else if (BothInputsAreSigned32(node)) {
} else if (lhs_type->Is(Type::Signed32()) &&
rhs_type->Is(Type::Signed32())) {
VisitWord32TruncatingBinop(node);
if (lower()) {
lowering->DoMin(node, lowering->machine()->Int32LessThan(),
MachineRepresentation::kWord32);
}
} else if (BothInputsAre(node, Type::PlainNumber())) {
} else if (lhs_type->Is(Type::PlainNumber()) &&
rhs_type->Is(Type::PlainNumber())) {
VisitFloat64Binop(node);
if (lower()) {
lowering->DoMin(node, lowering->machine()->Float64LessThan(),