[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.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/1146403008

Cr-Commit-Position: refs/heads/master@{#28649}
This commit is contained in:
bmeurer 2015-05-27 04:01:51 -07:00 committed by Commit bot
parent cc2d376f11
commit 7483dbd5fc
6 changed files with 26 additions and 21 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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));
}

View File

@ -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 () {"