Commit 969fe7a3 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[turbofan] Refactor the pipeline to separate scheduling from instruction selection.

This moves the funky conditional code in ScheduleAndSelectInstructions to
the caller (the caller mostly knows statically what it wants).

My hidden agenda is to prepare the pipeline for post-scheduling passes.

Change-Id: Ia6009a6b2472d7211ef213eb4eb551957ae9709c
Bug: v8:5267
Reviewed-on: https://chromium-review.googlesource.com/863663
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50562}
parent bb7138f6
......@@ -430,21 +430,26 @@ class PipelineImpl final {
template <typename Phase, typename Arg0, typename Arg1>
void Run(Arg0 arg_0, Arg1 arg_1);
// Run the graph creation and initial optimization passes.
// Step A. Run the graph creation and initial optimization passes.
bool CreateGraph();
// Run the concurrent optimization passes.
// B. Run the concurrent optimization passes.
bool OptimizeGraph(Linkage* linkage);
// Run the code assembly pass.
// Substep B.1. Produce a scheduled graph.
void ComputeScheduledGraph();
// Substep B.2. Select instructions from a scheduled graph.
bool SelectInstructions(Linkage* linkage);
// Step C. Run the code assembly pass.
void AssembleCode(Linkage* linkage);
// Run the code finalization pass.
// Step D. Run the code finalization pass.
Handle<Code> FinalizeCode();
bool ScheduleAndSelectInstructions(Linkage* linkage, bool trim_graph);
void RunPrintAndVerify(const char* phase, bool untyped = false);
Handle<Code> ScheduleAndGenerateCode(CallDescriptor* call_descriptor);
Handle<Code> GenerateCode(CallDescriptor* call_descriptor);
void AllocateRegisters(const RegisterConfiguration* config,
CallDescriptor* descriptor, bool run_verifier);
......@@ -959,7 +964,8 @@ PipelineWasmCompilationJob::ExecuteJobImpl() {
pipeline_.RunPrintAndVerify("Optimized Machine", true);
}
if (!pipeline_.ScheduleAndSelectInstructions(&linkage_, true)) return FAILED;
pipeline_.ComputeScheduledGraph();
if (!pipeline_.SelectInstructions(&linkage_)) return FAILED;
pipeline_.AssembleCode(&linkage_);
return SUCCEEDED;
}
......@@ -1937,7 +1943,9 @@ bool PipelineImpl::OptimizeGraph(Linkage* linkage) {
data->source_positions()->RemoveDecorator();
return ScheduleAndSelectInstructions(linkage, true);
ComputeScheduledGraph();
return SelectInstructions(linkage);
}
Handle<Code> Pipeline::GenerateCodeForCodeStub(
......@@ -1978,7 +1986,7 @@ Handle<Code> Pipeline::GenerateCodeForCodeStub(
}
pipeline.Run<VerifyGraphPhase>(false, true);
return pipeline.ScheduleAndGenerateCode(call_descriptor);
return pipeline.GenerateCode(call_descriptor);
}
// static
......@@ -2039,7 +2047,12 @@ Handle<Code> Pipeline::GenerateCodeForTesting(
// TODO(rossberg): Should this really be untyped?
pipeline.RunPrintAndVerify("Machine", true);
return pipeline.ScheduleAndGenerateCode(call_descriptor);
// Ensure we have a schedule.
if (data.schedule() == nullptr) {
pipeline.ComputeScheduledGraph();
}
return pipeline.GenerateCode(call_descriptor);
}
// static
......@@ -2078,19 +2091,26 @@ bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
return !data.compilation_failed();
}
bool PipelineImpl::ScheduleAndSelectInstructions(Linkage* linkage,
bool trim_graph) {
CallDescriptor* call_descriptor = linkage->GetIncomingDescriptor();
void PipelineImpl::ComputeScheduledGraph() {
PipelineData* data = this->data_;
DCHECK_NOT_NULL(data->graph());
// We should only schedule the graph if it is not scheduled yet.
DCHECK_NULL(data->schedule());
if (trim_graph) {
Run<LateGraphTrimmingPhase>();
RunPrintAndVerify("Late trimmed", true);
}
if (data->schedule() == nullptr) Run<ComputeSchedulePhase>();
Run<LateGraphTrimmingPhase>();
RunPrintAndVerify("Late trimmed", true);
Run<ComputeSchedulePhase>();
TraceSchedule(data->info(), data->isolate(), data->schedule());
}
bool PipelineImpl::SelectInstructions(Linkage* linkage) {
CallDescriptor* call_descriptor = linkage->GetIncomingDescriptor();
PipelineData* data = this->data_;
// We should have a scheduled graph.
DCHECK_NOT_NULL(data->graph());
DCHECK_NOT_NULL(data->schedule());
if (FLAG_turbo_profiling) {
data->set_profiler_data(BasicBlockInstrumentor::Instrument(
......@@ -2244,12 +2264,11 @@ Handle<Code> PipelineImpl::FinalizeCode() {
return code;
}
Handle<Code> PipelineImpl::ScheduleAndGenerateCode(
CallDescriptor* call_descriptor) {
Handle<Code> PipelineImpl::GenerateCode(CallDescriptor* call_descriptor) {
Linkage linkage(call_descriptor);
// Schedule the graph, perform instruction selection and register allocation.
if (!ScheduleAndSelectInstructions(&linkage, false)) return Handle<Code>();
// Perform instruction selection and register allocation.
if (!SelectInstructions(&linkage)) return Handle<Code>();
// Generate the final machine code.
AssembleCode(&linkage);
......
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