Commit ff7e60c8 authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Refactor the OSR environment merging to create an explicit environment.

This is useful for my upcoming work on OSR typing, which needs
to create checkpoints (which in turn require environments).

Review-Url: https://codereview.chromium.org/2379643003
Cr-Commit-Position: refs/heads/master@{#39869}
parent 837c91e8
......@@ -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);
}
}
}
......
......@@ -579,6 +579,11 @@ class AstGraphBuilder::Environment : public ZoneObject {
// Copies this environment at a loop header control-flow point.
Environment* CopyForLoop(BitVector* assigned, bool is_osr = false);
// Copies this environment for Osr entry. This only produces environment
// of the right shape, the caller is responsible for filling in the right
// values and dependencies.
Environment* CopyForOsrEntry();
private:
AstGraphBuilder* builder_;
int parameters_count_;
......@@ -608,7 +613,8 @@ class AstGraphBuilder::Environment : public ZoneObject {
bool IsLivenessBlockConsistent();
// Prepare environment to be used as loop header.
void PrepareForLoop(BitVector* assigned, bool is_osr = false);
void PrepareForLoop(BitVector* assigned);
void PrepareForOsrEntry();
};
} // namespace compiler
......
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