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

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

Issue 1901803002: [turbofan] Remove phase ordering problem in JSToNumber lowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comment Created 4 years, 8 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/simplified-lowering.h ('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 a5cf0be302bc6367b858622d49b037416b0c4c3f..931f87340fdc687b74c13657bf0ab432d9564a81 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -8,6 +8,7 @@
#include "src/base/bits.h"
#include "src/code-factory.h"
+#include "src/compiler/access-builder.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/diamond.h"
#include "src/compiler/linkage.h"
@@ -761,19 +762,23 @@ class RepresentationSelector {
case IrOpcode::kCall:
return VisitCall(node, lowering);
-//------------------------------------------------------------------
-// JavaScript operators.
-//------------------------------------------------------------------
-// For now, we assume that all JS operators were too complex to lower
-// to Simplified and that they will always require tagged value inputs
-// and produce tagged value outputs.
-// TODO(turbofan): it might be possible to lower some JSOperators here,
-// but that responsibility really lies in the typed lowering phase.
-#define DEFINE_JS_CASE(x) case IrOpcode::k##x:
- JS_OP_LIST(DEFINE_JS_CASE)
-#undef DEFINE_JS_CASE
+ //------------------------------------------------------------------
+ // JavaScript operators.
+ //------------------------------------------------------------------
+ case IrOpcode::kJSToNumber: {
VisitInputs(node);
- return SetOutput(node, MachineRepresentation::kTagged);
+ // TODO(bmeurer): Optimize somewhat based on input type?
+ if (truncation.TruncatesToWord32()) {
+ SetOutput(node, MachineRepresentation::kWord32);
+ if (lower()) lowering->DoJSToNumberTruncatesToWord32(node, this);
+ } else if (truncation.TruncatesToFloat64()) {
+ SetOutput(node, MachineRepresentation::kFloat64);
+ if (lower()) lowering->DoJSToNumberTruncatesToFloat64(node, this);
+ } else {
+ SetOutput(node, MachineRepresentation::kTagged);
+ }
+ break;
+ }
//------------------------------------------------------------------
// Simplified operators.
@@ -1463,6 +1468,165 @@ void SimplifiedLowering::LowerAllNodes() {
selector.Run(this);
}
+void SimplifiedLowering::DoJSToNumberTruncatesToFloat64(
+ Node* node, RepresentationSelector* selector) {
+ DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
+ Node* value = node->InputAt(0);
+ Node* context = node->InputAt(1);
+ Node* frame_state = node->InputAt(2);
+ Node* effect = node->InputAt(3);
+ Node* control = node->InputAt(4);
+ Node* throwing;
+
+ Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+ Node* branch0 =
+ graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
+
+ Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+ Node* etrue0 = effect;
+ Node* vtrue0;
+ {
+ vtrue0 = graph()->NewNode(simplified()->ChangeSmiToInt32(), value);
+ vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
+ }
+
+ Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+ Node* efalse0 = effect;
+ Node* vfalse0;
+ {
+ throwing = vfalse0 = efalse0 =
+ graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
+ frame_state, efalse0, if_false0);
+ if_false0 = graph()->NewNode(common()->IfSuccess(), throwing);
+
+ Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
+ Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
+
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+ Node* etrue1 = efalse0;
+ Node* vtrue1;
+ {
+ vtrue1 = graph()->NewNode(simplified()->ChangeSmiToInt32(), vfalse0);
+ vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
+ }
+
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+ Node* efalse1 = efalse0;
+ Node* vfalse1;
+ {
+ vfalse1 = efalse1 = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
+ efalse1, if_false1);
+ }
+
+ if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
+ efalse0 =
+ graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
+ vfalse0 =
+ graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
+ vtrue1, vfalse1, if_false0);
+ }
+
+ control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
+ effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
+ value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
+ vtrue0, vfalse0, control);
+
+ // Replace effect and control uses appropriately.
+ for (Edge edge : node->use_edges()) {
+ if (NodeProperties::IsControlEdge(edge)) {
+ if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
+ edge.from()->ReplaceUses(control);
+ edge.from()->Kill();
+ } else if (edge.from()->opcode() == IrOpcode::kIfException) {
+ edge.UpdateTo(throwing);
+ } else {
+ UNREACHABLE();
+ }
+ } else if (NodeProperties::IsEffectEdge(edge)) {
+ edge.UpdateTo(effect);
+ }
+ }
+
+ selector->DeferReplacement(node, value);
+}
+
+void SimplifiedLowering::DoJSToNumberTruncatesToWord32(
+ Node* node, RepresentationSelector* selector) {
+ DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
+ Node* value = node->InputAt(0);
+ Node* context = node->InputAt(1);
+ Node* frame_state = node->InputAt(2);
+ Node* effect = node->InputAt(3);
+ Node* control = node->InputAt(4);
+ Node* throwing;
+
+ Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+ Node* branch0 =
+ graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
+
+ Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+ Node* etrue0 = effect;
+ Node* vtrue0 = graph()->NewNode(simplified()->ChangeSmiToInt32(), value);
+
+ Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+ Node* efalse0 = effect;
+ Node* vfalse0;
+ {
+ throwing = vfalse0 = efalse0 =
+ graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
+ frame_state, efalse0, if_false0);
+ if_false0 = graph()->NewNode(common()->IfSuccess(), throwing);
+
+ Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
+ Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
+
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+ Node* etrue1 = efalse0;
+ Node* vtrue1 = graph()->NewNode(simplified()->ChangeSmiToInt32(), vfalse0);
+
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+ Node* efalse1 = efalse0;
+ Node* vfalse1;
+ {
+ vfalse1 = efalse1 = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
+ efalse1, if_false1);
+ vfalse1 = graph()->NewNode(
+ machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript),
+ vfalse1);
+ }
+
+ if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
+ efalse0 =
+ graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
+ vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
+ vtrue1, vfalse1, if_false0);
+ }
+
+ control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
+ effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
+ value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
+ vtrue0, vfalse0, control);
+
+ // Replace effect and control uses appropriately.
+ for (Edge edge : node->use_edges()) {
+ if (NodeProperties::IsControlEdge(edge)) {
+ if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
+ edge.from()->ReplaceUses(control);
+ edge.from()->Kill();
+ } else if (edge.from()->opcode() == IrOpcode::kIfException) {
+ edge.UpdateTo(throwing);
+ } else {
+ UNREACHABLE();
+ }
+ } else if (NodeProperties::IsEffectEdge(edge)) {
+ edge.UpdateTo(effect);
+ }
+ }
+
+ selector->DeferReplacement(node, value);
+}
void SimplifiedLowering::DoLoadBuffer(Node* node,
MachineRepresentation output_rep,
@@ -2183,6 +2347,26 @@ void SimplifiedLowering::DoShift(Node* node, Operator const* op,
NodeProperties::ChangeOp(node, op);
}
+Node* SimplifiedLowering::ToNumberCode() {
+ if (!to_number_code_.is_set()) {
+ Callable callable = CodeFactory::ToNumber(isolate());
+ to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
+ }
+ return to_number_code_.get();
+}
+
+Operator const* SimplifiedLowering::ToNumberOperator() {
+ if (!to_number_operator_.is_set()) {
+ Callable callable = CodeFactory::ToNumber(isolate());
+ CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ isolate(), graph()->zone(), callable.descriptor(), 0, flags,
+ Operator::kNoProperties);
+ to_number_operator_.set(common()->Call(desc));
+ }
+ return to_number_operator_.get();
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698