Commit 8e241468 authored by titzer's avatar titzer Committed by Commit bot

[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}
parent d050c331
......@@ -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);
......
......@@ -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());
}
......
......@@ -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);
......
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