Commit 318e5230 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[turbofan] Handle LoadField with type mismatch in LoadElimination.

This allows to replace redundant LoadField's whose type doesn't match
the type of the replacement, by just turning those LoadField's into
TypeGuard's.

Bug: v8:8070
Change-Id: Ia329bb536f8829be27e070e90e9eaae0618dac7a
Reviewed-on: https://chromium-review.googlesource.com/1188131Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55407}
parent a839bd42
......@@ -912,8 +912,9 @@ Reduction LoadElimination::ReduceTransitionAndStoreElement(Node* node) {
Reduction LoadElimination::ReduceLoadField(Node* node) {
FieldAccess const& access = FieldAccessOf(node->op());
Node* const object = NodeProperties::GetValueInput(node, 0);
Node* const effect = NodeProperties::GetEffectInput(node);
Node* object = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
AbstractState const* state = node_states_.Get(effect);
if (state == nullptr) return NoChange();
if (access.offset == HeapObject::kMapOffset &&
......@@ -931,12 +932,19 @@ Reduction LoadElimination::ReduceLoadField(Node* node) {
if (field_index >= 0) {
if (Node* replacement = state->LookupField(object, field_index)) {
// Make sure we don't resurrect dead {replacement} nodes.
// Skip lowering if the type of the {replacement} node is not a subtype
// of the original {node}'s type.
// TODO(tebbi): We should insert a {TypeGuard} for the intersection of
// these two types here once we properly handle {Type::None} everywhere.
if (!replacement->IsDead() && NodeProperties::GetType(replacement)
.Is(NodeProperties::GetType(node))) {
if (!replacement->IsDead()) {
// Introduce a TypeGuard if the type of the {replacement} node is not
// a subtype of the original {node}'s type.
if (!NodeProperties::GetType(replacement)
.Is(NodeProperties::GetType(node))) {
Type replacement_type = Type::Intersect(
NodeProperties::GetType(node),
NodeProperties::GetType(replacement), graph()->zone());
replacement = effect =
graph()->NewNode(common()->TypeGuard(replacement_type),
replacement, effect, control);
NodeProperties::SetType(replacement, replacement_type);
}
ReplaceWithValue(node, replacement, effect);
return Replace(replacement);
}
......
......@@ -410,9 +410,10 @@ TEST_F(LoadEliminationTest, LoadFieldWithTypeMismatch) {
Node* load = graph()->NewNode(simplified()->LoadField(access), object, effect,
control);
EXPECT_CALL(editor, ReplaceWithValue(load, IsTypeGuard(value, _), _, _));
Reduction r = load_elimination.Reduce(load);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(load, r.replacement());
EXPECT_THAT(r.replacement(), IsTypeGuard(value, _));
}
TEST_F(LoadEliminationTest, LoadElementWithTypeMismatch) {
......
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