Reviewers: Michael Starzinger,

Description:
[turbofan] Use Start as sentinel for frame states.

This simplifies inlining, in that we only need to update uses of Start
and inputs of End instead of walking the whole inlinee to update all
outer frame states.

[email protected]

Please review this at https://codereview.chromium.org/1146403008/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+26, -21 lines):
  M src/compiler/ast-graph-builder.cc
  M src/compiler/js-graph.cc
  M src/compiler/js-inlining.h
  M src/compiler/js-inlining.cc
  M src/compiler/verifier.cc
  M test/cctest/compiler/test-run-inlining.cc


Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 9778c79b1e714473d0d974001f70422b3ab0b545..bc96c4c91ad602499dd33ccd49a92c27d1ecdef8 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -856,7 +856,7 @@ Node* AstGraphBuilder::Environment::Checkpoint(
   Node* result = graph()->NewNode(op, parameters_node_, locals_node_,
stack_node_, builder()->current_context(),
                                   builder()->GetFunctionClosure(),
- builder()->jsgraph()->UndefinedConstant());
+                                  builder()->graph()->start());

   DCHECK(IsLivenessBlockConsistent());
   if (liveness_block() != nullptr) {
Index: src/compiler/js-graph.cc
diff --git a/src/compiler/js-graph.cc b/src/compiler/js-graph.cc
index 44d5c52772ed971b2129e3516463792028ce5b56..4d83c86eebc39e8e96569defe8b447057ccc1e0a 100644
--- a/src/compiler/js-graph.cc
+++ b/src/compiler/js-graph.cc
@@ -191,7 +191,7 @@ Node* JSGraph::EmptyFrameState() {
         common()->FrameState(JS_FRAME, BailoutId::None(),
                              OutputFrameStateCombine::Ignore()),
         state_values, state_values, state_values, NoContextConstant(),
-        UndefinedConstant(), UndefinedConstant());
+        UndefinedConstant(), graph()->start());
     cached_nodes_[kEmptyFrameState] = empty_frame_state;
   }
   return empty_frame_state;
Index: src/compiler/js-inlining.cc
diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc
index 72f12fc7e0144993d0055e621f9f3b1badfe26d2..6964e5eb4d8390338e4ef7f23e9a6728853676ec 100644
--- a/src/compiler/js-inlining.cc
+++ b/src/compiler/js-inlining.cc
@@ -116,7 +116,8 @@ class CopyVisitor {
 };


-Reduction JSInliner::InlineCall(Node* call, Node* start, Node* end) {
+Reduction JSInliner::InlineCall(Node* call, Node* frame_state, Node* start,
+                                Node* end) {
// The scheduler is smart enough to place our code; we just ensure {control} // becomes the control input of the start of the inlinee, and {effect} becomes
   // the effect input of the start of the inlinee.
@@ -158,6 +159,8 @@ Reduction JSInliner::InlineCall(Node* call, Node* start, Node* end) {
           edge.UpdateTo(effect);
         } else if (NodeProperties::IsControlEdge(edge)) {
           edge.UpdateTo(control);
+        } else if (NodeProperties::IsFrameStateEdge(edge)) {
+          edge.UpdateTo(frame_state);
         } else {
           UNREACHABLE();
         }
@@ -284,7 +287,7 @@ Reduction JSInliner::Reduce(Node* node) {
   Node* start = visitor.GetCopy(graph.start());
   Node* end = visitor.GetCopy(graph.end());

-  Node* outer_frame_state = call.frame_state();
+  Node* frame_state = call.frame_state();
size_t const inlinee_formal_parameters = start->op()->ValueOutputCount() - 3;
   // Insert argument adaptor frame if required.
   if (call.formal_arguments() != inlinee_formal_parameters) {
@@ -294,22 +297,10 @@ Reduction JSInliner::Reduce(Node* node) {
         call.formal_arguments() < inlinee_formal_parameters) {
       return NoChange();
     }
- outer_frame_state = CreateArgumentsAdaptorFrameState(&call, info.zone());
+    frame_state = CreateArgumentsAdaptorFrameState(&call, info.zone());
   }

-  // Fix up all outer frame states from the inlinee.
-  for (Node* const node : visitor.copies()) {
-    if (node->opcode() == IrOpcode::kFrameState) {
- DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); - // Don't touch this frame state, if it already has an "outer frame state".
-      if (NodeProperties::GetFrameStateInput(node, 0)->opcode() !=
-          IrOpcode::kFrameState) {
-        NodeProperties::ReplaceFrameStateInput(node, 0, outer_frame_state);
-      }
-    }
-  }
-
-  return InlineCall(node, start, end);
+  return InlineCall(node, frame_state, start, end);
 }

 }  // namespace compiler
Index: src/compiler/js-inlining.h
diff --git a/src/compiler/js-inlining.h b/src/compiler/js-inlining.h
index f7a0ba3a97c75e6bba86697247a23c5027479dbd..af82ed6638f479d77a9e66920945637faa61df47 100644
--- a/src/compiler/js-inlining.h
+++ b/src/compiler/js-inlining.h
@@ -37,7 +37,7 @@ class JSInliner final : public AdvancedReducer {
   Node* CreateArgumentsAdaptorFrameState(JSCallFunctionAccessor* call,
                                          Zone* temp_zone);

-  Reduction InlineCall(Node* call, Node* start, Node* end);
+ Reduction InlineCall(Node* call, Node* frame_state, Node* start, Node* end);
 };

 }  // namespace compiler
Index: src/compiler/verifier.cc
diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc
index da94390879e11c758b6138dd9c1f657f84c11e37..d2582038ad22e1a09a49005549e2dc70921e34e4 100644
--- a/src/compiler/verifier.cc
+++ b/src/compiler/verifier.cc
@@ -118,9 +118,9 @@ void Verifier::Visitor::Check(Node* node) {
   for (int i = 0; i < frame_state_count; i++) {
     Node* frame_state = NodeProperties::GetFrameStateInput(node, i);
     CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
-          // kFrameState uses undefined as a sentinel.
+          // kFrameState uses Start as a sentinel.
           (node->opcode() == IrOpcode::kFrameState &&
-           frame_state->opcode() == IrOpcode::kHeapConstant));
+           frame_state->opcode() == IrOpcode::kStart));
     CHECK(IsDefUseChainLinkPresent(frame_state, node));
     CHECK(IsUseDefChainLinkPresent(frame_state, node));
   }
Index: test/cctest/compiler/test-run-inlining.cc
diff --git a/test/cctest/compiler/test-run-inlining.cc b/test/cctest/compiler/test-run-inlining.cc index 2ab72172278f034d957e3901f401720dc314067c..3de929cbc81ee03a7dffc112ec3063c7c245dd47 100644
--- a/test/cctest/compiler/test-run-inlining.cc
+++ b/test/cctest/compiler/test-run-inlining.cc
@@ -78,6 +78,20 @@ TEST(SimpleInliningDeopt) {
 }


+TEST(SimpleInliningDeoptSelf) {
+  FunctionTester T(
+      "(function(){"
+      "  function foo(s) { %_DeoptimizeNow(); return s; };"
+      "  function bar(s, t) { return foo(s); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
+}
+
+
 TEST(SimpleInliningContext) {
   FunctionTester T(
       "(function () {"


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to