From: titzer Date: Thu, 19 Feb 2015 12:38:44 +0000 (-0800) Subject: [turbofan] Transfer types from loop phis to OSR values. X-Git-Tag: upstream/4.7.83~4294 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8e241468ed8183fc4270fd185dde45bafdc9c6f9;p=platform%2Fupstream%2Fv8.git [turbofan] Transfer types from loop phis to OSR values. R=jarin@chromium.org BUG= Review URL: https://codereview.chromium.org/930003003 Cr-Commit-Position: refs/heads/master@{#26746} --- diff --git a/src/compiler/osr.cc b/src/compiler/osr.cc index e96b047..b7cd7ec 100644 --- a/src/compiler/osr.cc +++ b/src/compiler/osr.cc @@ -173,6 +173,40 @@ static void PeelOuterLoopsForOsr(Graph* graph, CommonOperatorBuilder* common, } +static void TransferOsrValueTypesFromLoopPhis(Zone* zone, Node* osr_loop_entry, + Node* osr_loop) { + // Find the index of the osr loop entry into the loop. + int index = 0; + for (index = 0; index < osr_loop->InputCount(); index++) { + if (osr_loop->InputAt(index) == osr_loop_entry) break; + } + if (index == osr_loop->InputCount()) return; + + for (Node* osr_value : osr_loop_entry->uses()) { + if (osr_value->opcode() != IrOpcode::kOsrValue) continue; + bool unknown = true; + for (Node* phi : osr_value->uses()) { + if (phi->opcode() != IrOpcode::kPhi) continue; + if (NodeProperties::GetControlInput(phi) != osr_loop) continue; + if (phi->InputAt(index) != osr_value) continue; + if (NodeProperties::IsTyped(phi)) { + // Transfer the type from the phi to the OSR value itself. + Bounds phi_bounds = NodeProperties::GetBounds(phi); + if (unknown) { + NodeProperties::SetBounds(osr_value, phi_bounds); + } else { + Bounds osr_bounds = NodeProperties::GetBounds(osr_value); + NodeProperties::SetBounds(osr_value, + Bounds::Both(phi_bounds, osr_bounds, zone)); + } + unknown = false; + } + } + if (unknown) NodeProperties::SetBounds(osr_value, Bounds::Unbounded(zone)); + } +} + + bool OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common, Zone* tmp_zone) { Graph* graph = jsgraph->graph(); @@ -203,6 +237,9 @@ bool OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common, CHECK(osr_loop); // Should have found the OSR loop. + // Transfer the types from loop phis to the OSR values which flow into them. + TransferOsrValueTypesFromLoopPhis(graph->zone(), osr_loop_entry, osr_loop); + // Analyze the graph to determine how deeply nested the OSR loop is. LoopTree* loop_tree = LoopFinder::BuildLoopTree(graph, tmp_zone); diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index f646d19..9af6559 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -623,11 +623,16 @@ Bounds Typer::Visitor::TypeParameter(Node* node) { Bounds Typer::Visitor::TypeOsrValue(Node* node) { - // OSR values explicitly have type {None} before OSR form is deconstructed. if (node->InputAt(0)->opcode() == IrOpcode::kOsrLoopEntry) { + // Before deconstruction, OSR values have type {None} to avoid polluting + // the types of phis and other nodes in the graph. return Bounds(Type::None(), Type::None()); } - // TODO(turbofan): preserve the type of OSR values after deconstruction. + if (NodeProperties::IsTyped(node)) { + // After deconstruction, OSR values may have had a type explicitly set. + return NodeProperties::GetBounds(node); + } + // Otherwise, be conservative. return Bounds::Unbounded(zone()); } diff --git a/test/cctest/compiler/test-osr.cc b/test/cctest/compiler/test-osr.cc index c23fde6..e396390 100644 --- a/test/cctest/compiler/test-osr.cc +++ b/test/cctest/compiler/test-osr.cc @@ -158,6 +158,30 @@ TEST(Deconstruct_osr1) { } +TEST(Deconstruct_osr1_type) { + OsrDeconstructorTester T(1); + + Node* loop = T.NewOsrLoop(1); + Node* osr_phi = + T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant()); + Type* type = Type::Signed32(); + NodeProperties::SetBounds(osr_phi, Bounds(type, type)); + + Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop); + T.graph.SetEnd(ret); + + OsrHelper helper(0, 0); + helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone()); + + CHECK_EQ(type, NodeProperties::GetBounds(T.osr_values[0]).lower); + CHECK_EQ(type, NodeProperties::GetBounds(T.osr_values[0]).upper); + + CheckInputs(loop, T.start, loop); + CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop); + CheckInputs(ret, osr_phi, T.start, loop); +} + + TEST(Deconstruct_osr_remove_prologue) { OsrDeconstructorTester T(1); Diamond d(&T.graph, &T.common, T.p0);