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

Unified Diff: src/compiler/tail-call-optimization.cc

Issue 1114163005: [turbofan] Fix tail call optimization. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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
Index: src/compiler/tail-call-optimization.cc
diff --git a/src/compiler/tail-call-optimization.cc b/src/compiler/tail-call-optimization.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a88ebe3e63d6f5d220a6958860953ec9b82b869b
--- /dev/null
+++ b/src/compiler/tail-call-optimization.cc
@@ -0,0 +1,83 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/tail-call-optimization.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-properties.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Reduction TailCallOptimization::Reduce(Node* node) {
+ if (node->opcode() != IrOpcode::kReturn) return NoChange();
+ // The value which is returned must be the result of a potential tail call,
+ // there must be no try/catch/finally around the Call, and there must be no
+ // other effect between the Call and the Return nodes.
+ Node* const call = NodeProperties::GetValueInput(node, 0);
+ if (call->opcode() == IrOpcode::kCall &&
+ OpParameter<CallDescriptor const*>(call)->SupportsTailCalls() &&
+ NodeProperties::GetEffectInput(node) == call &&
+ !NodeProperties::IsExceptionalCall(call)) {
+ Node* const control = NodeProperties::GetControlInput(node);
+ if (control->opcode() == IrOpcode::kIfSuccess &&
+ call->OwnedBy(node, control) && control->OwnedBy(node)) {
+ // Furthermore, control has to flow via an IfSuccess from the Call, so
+ // the Return node value and effect depends directly on the Call node,
+ // and indirectly control depends on the Call via an IfSuccess.
+
+ // Value1 ... ValueN Effect Control
+ // ^ ^ ^ ^
+ // | | | |
+ // | +--+ +-+ |
+ // +----------+ | | +------+
+ // \ | | /
+ // Call[Descriptor]
+ // ^ ^ ^
+ // | | |
+ // +-+ | |
+ // | | |
+ // | +-+ |
+ // | | IfSuccess
+ // | | ^
+ // | | |
+ // Return
+ // ^
+ // |
+
+ // The resulting graph looks like this:
+
+ // Value1 ... ValueN Effect Control
+ // ^ ^ ^ ^
+ // | | | |
+ // | +--+ +-+ |
+ // +----------+ | | +------+
+ // \ | | /
+ // TailCall[Descriptor]
+ // ^
+ // |
+
+ DCHECK_EQ(call, NodeProperties::GetControlInput(control, 0));
+ DCHECK_EQ(3, node->InputCount());
+ node->set_op(
+ common()->TailCall(OpParameter<CallDescriptor const*>(call)));
+ node->ReplaceInput(0, NodeProperties::GetEffectInput(call));
+ node->ReplaceInput(1, NodeProperties::GetControlInput(call));
+ node->RemoveInput(2);
+ for (int index = 0; index < call->op()->ValueInputCount(); ++index) {
+ node->InsertInput(graph()->zone(), index,
+ NodeProperties::GetValueInput(call, index));
+ }
+ return Changed(node);
+ }
+ }
+ return NoChange();
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8

Powered by Google App Engine
This is Rietveld 408576698