Index: src/compiler/ast-graph-builder.cc |
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc |
index 68cf58905f87e1f62e0d2186409657ba29861d39..b292a2e49efd8e26020d9ad36a8ea96f1e150cc6 100644 |
--- a/src/compiler/ast-graph-builder.cc |
+++ b/src/compiler/ast-graph-builder.cc |
@@ -787,6 +787,10 @@ AstGraphBuilder::Environment::CopyAsUnreachable() { |
return env; |
} |
+AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForOsrEntry() { |
+ return new (zone()) |
+ Environment(this, builder_->liveness_analyzer()->NewBlock()); |
+} |
AstGraphBuilder::Environment* |
AstGraphBuilder::Environment::CopyAndShareLiveness() { |
@@ -801,8 +805,15 @@ AstGraphBuilder::Environment::CopyAndShareLiveness() { |
AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop( |
BitVector* assigned, bool is_osr) { |
- PrepareForLoop(assigned, is_osr); |
- return CopyAndShareLiveness(); |
+ PrepareForLoop(assigned); |
+ Environment* loop = CopyAndShareLiveness(); |
+ if (is_osr) { |
+ // Create and merge the OSR entry if necessary. |
+ Environment* osr_env = CopyForOsrEntry(); |
+ osr_env->PrepareForOsrEntry(); |
+ loop->Merge(osr_env); |
+ } |
+ return loop; |
} |
@@ -4182,9 +4193,39 @@ void AstGraphBuilder::Environment::Merge(Environment* other) { |
} |
} |
+void AstGraphBuilder::Environment::PrepareForOsrEntry() { |
+ int size = static_cast<int>(values()->size()); |
+ Graph* graph = builder_->graph(); |
+ |
+ // Set the control and effect to the OSR loop entry. |
+ Node* osr_loop_entry = graph->NewNode(builder_->common()->OsrLoopEntry(), |
+ graph->start(), graph->start()); |
+ UpdateControlDependency(osr_loop_entry); |
+ UpdateEffectDependency(osr_loop_entry); |
+ // Set OSR values. |
+ for (int i = 0; i < size; ++i) { |
+ values()->at(i) = |
+ graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry); |
+ } |
+ |
+ // Set the contexts. |
+ // The innermost context is the OSR value, and the outer contexts are |
+ // reconstructed by dynamically walking up the context chain. |
+ Node* osr_context = nullptr; |
+ const Operator* op = |
+ builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); |
+ const Operator* op_inner = |
+ builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex); |
+ int last = static_cast<int>(contexts()->size() - 1); |
+ for (int i = last; i >= 0; i--) { |
+ osr_context = (i == last) ? graph->NewNode(op_inner, osr_loop_entry) |
+ : graph->NewNode(op, osr_context, osr_context, |
+ osr_loop_entry); |
+ contexts()->at(i) = osr_context; |
+ } |
+} |
-void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned, |
- bool is_osr) { |
+void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) { |
int size = static_cast<int>(values()->size()); |
Node* control = builder_->NewLoop(); |
@@ -4219,40 +4260,6 @@ void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned, |
contexts()->at(i) = builder_->NewPhi(1, context, control); |
} |
} |
- |
- if (is_osr) { |
- // Merge OSR values as inputs to the phis of the loop. |
- Graph* graph = builder_->graph(); |
- Node* osr_loop_entry = builder_->graph()->NewNode( |
- builder_->common()->OsrLoopEntry(), graph->start(), graph->start()); |
- |
- builder_->MergeControl(control, osr_loop_entry); |
- builder_->MergeEffect(effect, osr_loop_entry, control); |
- |
- for (int i = 0; i < size; ++i) { |
- Node* value = values()->at(i); |
- Node* osr_value = |
- graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry); |
- values()->at(i) = builder_->MergeValue(value, osr_value, control); |
- } |
- |
- // Rename all the contexts in the environment. |
- // The innermost context is the OSR value, and the outer contexts are |
- // reconstructed by dynamically walking up the context chain. |
- Node* osr_context = nullptr; |
- const Operator* op = |
- builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); |
- const Operator* op_inner = |
- builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex); |
- int last = static_cast<int>(contexts()->size() - 1); |
- for (int i = last; i >= 0; i--) { |
- Node* context = contexts()->at(i); |
- osr_context = (i == last) ? graph->NewNode(op_inner, osr_loop_entry) |
- : graph->NewNode(op, osr_context, osr_context, |
- osr_loop_entry); |
- contexts()->at(i) = builder_->MergeValue(context, osr_context, control); |
- } |
- } |
} |