[turbofan] Remove dead tail call optimization support.
R=bmeurer@chromium.org BUG=v8:4698 Change-Id: I8917315d913f908b1631e82357a94f2f6cf0026f Reviewed-on: https://chromium-review.googlesource.com/571781 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#46672}
This commit is contained in:
parent
065c47dedd
commit
3876999572
2
BUILD.gn
2
BUILD.gn
@ -1443,8 +1443,6 @@ v8_source_set("v8_base") {
|
||||
"src/compiler/state-values-utils.h",
|
||||
"src/compiler/store-store-elimination.cc",
|
||||
"src/compiler/store-store-elimination.h",
|
||||
"src/compiler/tail-call-optimization.cc",
|
||||
"src/compiler/tail-call-optimization.h",
|
||||
"src/compiler/type-cache.cc",
|
||||
"src/compiler/type-cache.h",
|
||||
"src/compiler/typed-optimization.cc",
|
||||
|
@ -64,7 +64,6 @@
|
||||
#include "src/compiler/simplified-operator-reducer.h"
|
||||
#include "src/compiler/simplified-operator.h"
|
||||
#include "src/compiler/store-store-elimination.h"
|
||||
#include "src/compiler/tail-call-optimization.h"
|
||||
#include "src/compiler/typed-optimization.h"
|
||||
#include "src/compiler/typer.h"
|
||||
#include "src/compiler/value-numbering-reducer.h"
|
||||
@ -1346,13 +1345,11 @@ struct LateOptimizationPhase {
|
||||
data->common(), data->machine());
|
||||
SelectLowering select_lowering(data->jsgraph()->graph(),
|
||||
data->jsgraph()->common());
|
||||
TailCallOptimization tco(data->common(), data->graph());
|
||||
AddReducer(data, &graph_reducer, &branch_condition_elimination);
|
||||
AddReducer(data, &graph_reducer, &dead_code_elimination);
|
||||
AddReducer(data, &graph_reducer, &machine_reducer);
|
||||
AddReducer(data, &graph_reducer, &common_reducer);
|
||||
AddReducer(data, &graph_reducer, &select_lowering);
|
||||
AddReducer(data, &graph_reducer, &tco);
|
||||
AddReducer(data, &graph_reducer, &value_numbering);
|
||||
graph_reducer.ReduceGraph();
|
||||
}
|
||||
|
@ -1,80 +0,0 @@
|
||||
// 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-matchers.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 or control between the Call and the Return nodes.
|
||||
Node* const call = NodeProperties::GetValueInput(node, 1);
|
||||
if (call->opcode() == IrOpcode::kCall &&
|
||||
CallDescriptorOf(call->op())->SupportsTailCalls() &&
|
||||
NodeProperties::GetEffectInput(node) == call &&
|
||||
NodeProperties::GetControlInput(node) == call &&
|
||||
!NodeProperties::IsExceptionalCall(call) && call->UseCount() == 3) {
|
||||
// Ensure that no additional arguments are being popped other than those in
|
||||
// the CallDescriptor, otherwise the tail call transformation is invalid.
|
||||
DCHECK_EQ(0, Int32Matcher(NodeProperties::GetValueInput(node, 0)).Value());
|
||||
// Furthermore, the Return node value, effect, and control depends
|
||||
// directly on the Call, no other uses of the Call node exist.
|
||||
//
|
||||
// The input graph looks as follows:
|
||||
|
||||
// Value1 ... ValueN Effect Control
|
||||
// ^ ^ ^ ^
|
||||
// | | | |
|
||||
// | +--+ +-+ |
|
||||
// +----------+ | | +------+
|
||||
// \ | | /
|
||||
// Call[Descriptor]
|
||||
// ^ ^ ^
|
||||
// Int32(0) <-+ | | |
|
||||
// \ | | |
|
||||
// Return
|
||||
// ^
|
||||
// |
|
||||
|
||||
// The resulting graph looks like this:
|
||||
|
||||
// Value1 ... ValueN Effect Control
|
||||
// ^ ^ ^ ^
|
||||
// | | | |
|
||||
// | +--+ +-+ |
|
||||
// +----------+ | | +------+
|
||||
// \ | | /
|
||||
// TailCall[Descriptor]
|
||||
// ^
|
||||
// |
|
||||
|
||||
DCHECK_EQ(4, node->InputCount());
|
||||
node->ReplaceInput(0, NodeProperties::GetEffectInput(call));
|
||||
node->ReplaceInput(1, NodeProperties::GetControlInput(call));
|
||||
node->RemoveInput(3);
|
||||
node->RemoveInput(2);
|
||||
for (int index = 0; index < call->op()->ValueInputCount(); ++index) {
|
||||
node->InsertInput(graph()->zone(), index,
|
||||
NodeProperties::GetValueInput(call, index));
|
||||
}
|
||||
NodeProperties::ChangeOp(node,
|
||||
common()->TailCall(CallDescriptorOf(call->op())));
|
||||
return Changed(node);
|
||||
}
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -1,43 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef V8_COMPILER_TAIL_CALL_OPTIMIZATION_H_
|
||||
#define V8_COMPILER_TAIL_CALL_OPTIMIZATION_H_
|
||||
|
||||
#include "src/compiler/graph-reducer.h"
|
||||
#include "src/globals.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
// Forward declarations.
|
||||
class CommonOperatorBuilder;
|
||||
class Graph;
|
||||
|
||||
|
||||
// Performs tail call optimization by replacing certain combinations of Return
|
||||
// and Call nodes with a single TailCall.
|
||||
class V8_EXPORT_PRIVATE TailCallOptimization final : public Reducer {
|
||||
public:
|
||||
TailCallOptimization(CommonOperatorBuilder* common, Graph* graph)
|
||||
: common_(common), graph_(graph) {}
|
||||
|
||||
const char* reducer_name() const override { return "TailCallOptimization"; }
|
||||
|
||||
Reduction Reduce(Node* node) final;
|
||||
|
||||
private:
|
||||
CommonOperatorBuilder* common() const { return common_; }
|
||||
Graph* graph() const { return graph_; }
|
||||
|
||||
CommonOperatorBuilder* const common_;
|
||||
Graph* const graph_;
|
||||
};
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_COMPILER_TAIL_CALL_OPTIMIZATION_H_
|
@ -874,8 +874,6 @@
|
||||
'compiler/state-values-utils.h',
|
||||
'compiler/store-store-elimination.cc',
|
||||
'compiler/store-store-elimination.h',
|
||||
'compiler/tail-call-optimization.cc',
|
||||
'compiler/tail-call-optimization.h',
|
||||
'compiler/types.cc',
|
||||
'compiler/types.h',
|
||||
'compiler/type-cache.cc',
|
||||
|
@ -92,7 +92,6 @@ v8_executable("unittests") {
|
||||
"compiler/simplified-operator-reducer-unittest.cc",
|
||||
"compiler/simplified-operator-unittest.cc",
|
||||
"compiler/state-values-utils-unittest.cc",
|
||||
"compiler/tail-call-optimization-unittest.cc",
|
||||
"compiler/typed-optimization-unittest.cc",
|
||||
"compiler/typer-unittest.cc",
|
||||
"compiler/value-numbering-reducer-unittest.cc",
|
||||
|
@ -1,163 +0,0 @@
|
||||
// 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/linkage.h"
|
||||
#include "src/compiler/tail-call-optimization.h"
|
||||
#include "test/unittests/compiler/graph-unittest.h"
|
||||
#include "test/unittests/compiler/node-test-utils.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
class TailCallOptimizationTest : public GraphTest {
|
||||
public:
|
||||
explicit TailCallOptimizationTest(int num_parameters = 1)
|
||||
: GraphTest(num_parameters) {}
|
||||
~TailCallOptimizationTest() override {}
|
||||
|
||||
protected:
|
||||
Reduction Reduce(Node* node) {
|
||||
TailCallOptimization tco(common(), graph());
|
||||
return tco.Reduce(node);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallCodeObject0) {
|
||||
LinkageLocation kLocationSignature[] = {
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
LinkageLocation::ForRegister(1, MachineType::Pointer())};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallCodeObject, MachineType::AnyTagged(),
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
|
||||
Node* p0 = Parameter(0);
|
||||
Node* p1 = Parameter(1);
|
||||
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
|
||||
graph()->start(), graph()->start());
|
||||
Node* zero = graph()->NewNode(common()->Int32Constant(0));
|
||||
Node* ret = graph()->NewNode(common()->Return(), zero, call, call, call);
|
||||
Reduction r = Reduce(ret);
|
||||
ASSERT_FALSE(r.Changed());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallCodeObject1) {
|
||||
LinkageLocation kLocationSignature[] = {
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
LinkageLocation::ForRegister(1, MachineType::Pointer())};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallCodeObject, MachineType::AnyTagged(),
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
|
||||
Node* p0 = Parameter(0);
|
||||
Node* p1 = Parameter(1);
|
||||
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
|
||||
graph()->start(), graph()->start());
|
||||
Node* if_success = graph()->NewNode(common()->IfSuccess(), call);
|
||||
Node* if_exception = graph()->NewNode(common()->IfException(), call, call);
|
||||
Node* zero = graph()->NewNode(common()->Int32Constant(0));
|
||||
Node* ret =
|
||||
graph()->NewNode(common()->Return(), zero, call, call, if_success);
|
||||
Node* end = graph()->NewNode(common()->End(1), if_exception);
|
||||
graph()->SetEnd(end);
|
||||
Reduction r = Reduce(ret);
|
||||
ASSERT_FALSE(r.Changed());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallCodeObject2) {
|
||||
LinkageLocation kLocationSignature[] = {
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
LinkageLocation::ForRegister(1, MachineType::Pointer())};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallCodeObject, MachineType::AnyTagged(),
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
|
||||
Node* p0 = Parameter(0);
|
||||
Node* p1 = Parameter(1);
|
||||
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
|
||||
graph()->start(), graph()->start());
|
||||
Node* zero = graph()->NewNode(common()->Int32Constant(0));
|
||||
Node* ret = graph()->NewNode(common()->Return(), zero, call, call, call);
|
||||
Reduction r = Reduce(ret);
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsTailCall(kCallDescriptor, p0, p1,
|
||||
graph()->start(), graph()->start()));
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallJSFunction0) {
|
||||
LinkageLocation kLocationSignature[] = {
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
LinkageLocation::ForRegister(1, MachineType::Pointer())};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallJSFunction, MachineType::AnyTagged(),
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
|
||||
Node* p0 = Parameter(0);
|
||||
Node* p1 = Parameter(1);
|
||||
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
|
||||
graph()->start(), graph()->start());
|
||||
Node* zero = graph()->NewNode(common()->Int32Constant(0));
|
||||
Node* ret = graph()->NewNode(common()->Return(), zero, call, call, call);
|
||||
Reduction r = Reduce(ret);
|
||||
ASSERT_FALSE(r.Changed());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallJSFunction1) {
|
||||
LinkageLocation kLocationSignature[] = {
|
||||
LinkageLocation::ForRegister(0, MachineType::Pointer()),
|
||||
LinkageLocation::ForRegister(1, MachineType::Pointer())};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallJSFunction, MachineType::AnyTagged(),
|
||||
LinkageLocation::ForRegister(0),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
|
||||
Node* p0 = Parameter(0);
|
||||
Node* p1 = Parameter(1);
|
||||
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
|
||||
graph()->start(), graph()->start());
|
||||
Node* if_success = graph()->NewNode(common()->IfSuccess(), call);
|
||||
Node* if_exception = graph()->NewNode(common()->IfException(), call, call);
|
||||
Node* zero = graph()->NewNode(common()->Int32Constant(0));
|
||||
Node* ret =
|
||||
graph()->NewNode(common()->Return(), zero, call, call, if_success);
|
||||
Node* end = graph()->NewNode(common()->End(1), if_exception);
|
||||
graph()->SetEnd(end);
|
||||
Reduction r = Reduce(ret);
|
||||
ASSERT_FALSE(r.Changed());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallJSFunction2) {
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0),
|
||||
LinkageLocation::ForRegister(1)};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallJSFunction, MachineType::AnyTagged(),
|
||||
LinkageLocation::ForRegister(0),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
|
||||
Node* p0 = Parameter(0);
|
||||
Node* p1 = Parameter(1);
|
||||
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
|
||||
graph()->start(), graph()->start());
|
||||
Node* zero = graph()->NewNode(common()->Int32Constant(0));
|
||||
Node* ret = graph()->NewNode(common()->Return(), zero, call, call, call);
|
||||
Reduction r = Reduce(ret);
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsTailCall(kCallDescriptor, p0, p1,
|
||||
graph()->start(), graph()->start()));
|
||||
}
|
||||
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -85,7 +85,6 @@
|
||||
'compiler/simplified-operator-reducer-unittest.cc',
|
||||
'compiler/simplified-operator-unittest.cc',
|
||||
'compiler/state-values-utils-unittest.cc',
|
||||
'compiler/tail-call-optimization-unittest.cc',
|
||||
'compiler/typed-optimization-unittest.cc',
|
||||
'compiler/typer-unittest.cc',
|
||||
'compiler/value-numbering-reducer-unittest.cc',
|
||||
|
Loading…
Reference in New Issue
Block a user