Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Unified Diff: src/compiler/simplified-lowering.cc

Issue 2074903002: [turbofan] Numeric type feedback for mul, div and mod. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/representation-change.cc ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/simplified-lowering.cc
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index 9ce76688c9ad8df2686d10d6a230b60bac41b272..80ed7a61be8f83793cd33608f090bdbf209f2e73 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -398,6 +398,66 @@ class RepresentationSelector {
break;
}
+ case IrOpcode::kSpeculativeNumberMultiply: {
+ Type* lhs = FeedbackTypeOf(node->InputAt(0));
+ Type* rhs = FeedbackTypeOf(node->InputAt(1));
+ if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false;
+ // TODO(jarin) The ToNumber conversion is too conservative here,
+ // e.g. it will treat true as 1 even though the number check will
+ // fail on a boolean. OperationTyper should have a function that
+ // computes a more precise type.
+ lhs = op_typer_.ToNumber(lhs);
+ rhs = op_typer_.ToNumber(rhs);
+ Type* static_type = op_typer_.NumericMultiply(lhs, rhs);
+ if (info->type_check() == TypeCheckKind::kNone) {
+ new_type = static_type;
+ } else {
+ Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
+ new_type = Type::Intersect(static_type, feedback_type, graph_zone());
+ }
+ break;
+ }
+
+ case IrOpcode::kSpeculativeNumberDivide: {
+ Type* lhs = FeedbackTypeOf(node->InputAt(0));
+ Type* rhs = FeedbackTypeOf(node->InputAt(1));
+ if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false;
+ // TODO(jarin) The ToNumber conversion is too conservative here,
+ // e.g. it will treat true as 1 even though the number check will
+ // fail on a boolean. OperationTyper should have a function that
+ // computes a more precise type.
+ lhs = op_typer_.ToNumber(lhs);
+ rhs = op_typer_.ToNumber(rhs);
+ Type* static_type = op_typer_.NumericDivide(lhs, rhs);
+ if (info->type_check() == TypeCheckKind::kNone) {
+ new_type = static_type;
+ } else {
+ Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
+ new_type = Type::Intersect(static_type, feedback_type, graph_zone());
+ }
+ break;
+ }
+
+ case IrOpcode::kSpeculativeNumberModulus: {
+ Type* lhs = FeedbackTypeOf(node->InputAt(0));
+ Type* rhs = FeedbackTypeOf(node->InputAt(1));
+ if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false;
+ // TODO(jarin) The ToNumber conversion is too conservative here,
+ // e.g. it will treat true as 1 even though the number check will
+ // fail on a boolean. OperationTyper should have a function that
+ // computes a more precise type.
+ lhs = op_typer_.ToNumber(lhs);
+ rhs = op_typer_.ToNumber(rhs);
+ Type* static_type = op_typer_.NumericModulus(lhs, rhs);
+ if (info->type_check() == TypeCheckKind::kNone) {
+ new_type = static_type;
+ } else {
+ Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
+ new_type = Type::Intersect(static_type, feedback_type, graph_zone());
+ }
+ break;
+ }
+
case IrOpcode::kPhi: {
new_type = TypePhi(node);
if (type != nullptr) {
@@ -1003,10 +1063,7 @@ class RepresentationSelector {
return jsgraph_->simplified();
}
- void ChangeToPureOp(Node* node, const Operator* new_op) {
- // Disconnect the node from effect and control chains.
- Node* control = NodeProperties::GetControlInput(node);
- Node* effect = NodeProperties::GetEffectInput(node);
+ void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
for (Edge edge : node->use_edges()) {
if (NodeProperties::IsControlEdge(edge)) {
edge.UpdateTo(control);
@@ -1016,21 +1073,21 @@ class RepresentationSelector {
DCHECK(NodeProperties::IsValueEdge(edge));
}
}
-
- node->TrimInputCount(new_op->ValueInputCount());
- NodeProperties::ChangeOp(node, new_op);
}
- void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
- for (Edge edge : node->use_edges()) {
- if (NodeProperties::IsControlEdge(edge)) {
- edge.UpdateTo(control);
- } else if (NodeProperties::IsEffectEdge(edge)) {
- edge.UpdateTo(effect);
- } else {
- DCHECK(NodeProperties::IsValueEdge(edge));
- }
+ void ChangeToPureOp(Node* node, const Operator* new_op) {
+ if (node->op()->EffectInputCount() > 0) {
+ DCHECK_LT(0, node->op()->ControlInputCount());
+ // Disconnect the node from effect and control chains.
+ Node* control = NodeProperties::GetControlInput(node);
+ Node* effect = NodeProperties::GetEffectInput(node);
+ ReplaceEffectControlUses(node, effect, control);
+ node->TrimInputCount(new_op->ValueInputCount());
+ } else {
+ DCHECK_EQ(0, node->op()->ControlInputCount());
}
+
+ NodeProperties::ChangeOp(node, new_op);
}
void ChangeToInt32OverflowOp(Node* node, const Operator* op) {
@@ -1295,13 +1352,14 @@ class RepresentationSelector {
}
return;
}
+ case IrOpcode::kSpeculativeNumberMultiply:
case IrOpcode::kNumberMultiply: {
if (BothInputsAreSigned32(node)) {
if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
// Multiply reduces to Int32Mul if the inputs and the output
// are integers.
VisitInt32Binop(node);
- if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
+ if (lower()) ChangeToPureOp(node, Int32Op(node));
return;
}
if (truncation.TruncatesToWord32() &&
@@ -1310,15 +1368,24 @@ class RepresentationSelector {
// the uses are truncating and the result is in the safe
// integer range.
VisitWord32TruncatingBinop(node);
- if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
+ if (lower()) ChangeToPureOp(node, Int32Op(node));
return;
}
}
- // => Float64Mul
- VisitFloat64Binop(node);
- if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
+ // Number x Number => Float64Mul
+ if (BothInputsAre(node, Type::NumberOrUndefined())) {
+ VisitFloat64Binop(node);
+ if (lower()) ChangeToPureOp(node, Float64Op(node));
+ return;
+ }
+ // Checked float64 x float64 => float64
+ DCHECK_EQ(IrOpcode::kSpeculativeNumberMultiply, node->opcode());
+ VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
+ MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
+ if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
}
+ case IrOpcode::kSpeculativeNumberDivide:
case IrOpcode::kNumberDivide: {
if (BothInputsAreSigned32(node)) {
if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
@@ -1340,11 +1407,20 @@ class RepresentationSelector {
if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
return;
}
- // => Float64Div
- VisitFloat64Binop(node);
- if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
+ // Number x Number => Float64Div
+ if (BothInputsAre(node, Type::NumberOrUndefined())) {
+ VisitFloat64Binop(node);
+ if (lower()) ChangeToPureOp(node, Float64Op(node));
+ return;
+ }
+ // Checked float64 x float64 => float64
+ DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode());
+ VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
+ MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
+ if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
}
+ case IrOpcode::kSpeculativeNumberModulus:
case IrOpcode::kNumberModulus: {
if (BothInputsAreSigned32(node)) {
if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
@@ -1366,9 +1442,18 @@ class RepresentationSelector {
if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
return;
}
- // => Float64Mod
- VisitFloat64Binop(node);
- if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
+ // Number x Number => Float64Mod
+ if (BothInputsAre(node, Type::NumberOrUndefined())) {
+ // => Float64Mod
+ VisitFloat64Binop(node);
+ if (lower()) ChangeToPureOp(node, Float64Op(node));
+ return;
+ }
+ // Checked float64 x float64 => float64
+ DCHECK_EQ(IrOpcode::kSpeculativeNumberModulus, node->opcode());
+ VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
+ MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
+ if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
}
case IrOpcode::kNumberBitwiseOr:
@@ -1933,6 +2018,17 @@ class RepresentationSelector {
node->op()->mnemonic(), replacement->id(),
replacement->op()->mnemonic());
+ // Disconnect the node from effect and control chains, if necessary.
+ if (node->op()->EffectInputCount() > 0) {
+ DCHECK_LT(0, node->op()->ControlInputCount());
+ // Disconnect the node from effect and control chains.
+ Node* control = NodeProperties::GetControlInput(node);
+ Node* effect = NodeProperties::GetEffectInput(node);
+ ReplaceEffectControlUses(node, effect, control);
+ } else {
+ DCHECK_EQ(0, node->op()->ControlInputCount());
+ }
+
if (replacement->id() < count_ &&
GetUpperBound(node)->Is(GetUpperBound(replacement)) &&
TypeOf(node)->Is(TypeOf(replacement))) {
« no previous file with comments | « src/compiler/representation-change.cc ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698