Commit 4b2c6d03 authored by Michael Starzinger's avatar Michael Starzinger

[turbofan] Add proper type guards to escape analysis.

This makes sure the {EscapeAnalysisReducer} inserts proper {TypeGuard}
nodes if the replacement node is not a subtype of the original node.
This happens predominantly for code that has been made unreachable by
type checks.

R=jarin@chromium.org
TEST=mjsunit/regress/regress-crbug-640497
BUG=chromium:640497

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

Cr-Commit-Position: refs/heads/master@{#39656}
parent 6a939714
......@@ -97,6 +97,22 @@ Reduction EscapeAnalysisReducer::Reduce(Node* node) {
return NoChange();
}
namespace {
Node* MaybeGuard(JSGraph* jsgraph, Node* original, Node* replacement) {
// We might need to guard the replacement if the type of the {replacement}
// node is not in a sub-type relation to the type of the the {original} node.
Type* const replacement_type = NodeProperties::GetType(replacement);
Type* const original_type = NodeProperties::GetType(original);
if (!replacement_type->Is(original_type)) {
Node* const control = NodeProperties::GetControlInput(original);
replacement = jsgraph->graph()->NewNode(
jsgraph->common()->TypeGuard(original_type), replacement, control);
}
return replacement;
}
} // namespace
Reduction EscapeAnalysisReducer::ReduceLoad(Node* node) {
DCHECK(node->opcode() == IrOpcode::kLoadField ||
......@@ -108,6 +124,7 @@ Reduction EscapeAnalysisReducer::ReduceLoad(Node* node) {
isolate()->counters()->turbo_escape_loads_replaced()->Increment();
TRACE("Replaced #%d (%s) with #%d (%s)\n", node->id(),
node->op()->mnemonic(), rep->id(), rep->op()->mnemonic());
rep = MaybeGuard(jsgraph(), node, rep);
ReplaceWithValue(node, rep);
return Replace(rep);
}
......
// Copyright 2016 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.
// Flags: --allow-natives-syntax --turbo --turbo-escape
// Warm up {g} with arrays and strings.
function g(v) { return v.length; }
assertEquals(1, g("x"));
assertEquals(2, g("xy"));
assertEquals(1, g([1]));
assertEquals(2, g([1,2]));
// Inline into {f}, where we see only an array.
function f() { assertEquals(0, g([])); }
f();
f();
%OptimizeFunctionOnNextCall(f);
f();
......@@ -17,7 +17,7 @@ namespace v8 {
namespace internal {
namespace compiler {
class EscapeAnalysisTest : public GraphTest {
class EscapeAnalysisTest : public TypedGraphTest {
public:
EscapeAnalysisTest()
: simplified_(zone()),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment