Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: src/compiler/pipeline.cc

Issue 1179393008: [turbofan] Enable concurrent (re)compilation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Also run late graph trimming concurrently. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/compiler/pipeline.cc
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
index 3e46d6f5194bd6abc0356231c627d67d0d97691e..c8569f28189aa34095d3c604379278a2a8781550 100644
--- a/src/compiler/pipeline.cc
+++ b/src/compiler/pipeline.cc
@@ -58,19 +58,33 @@ namespace v8 {
namespace internal {
namespace compiler {
-class PipelineData {
+namespace {
+
+PipelineStatistics* NewPipelineStatistics(CompilationInfo* const info,
+ ZonePool* const zone_pool) {
+ if (FLAG_turbo_stats) {
+ PipelineStatistics* pipeline_statistics =
+ new PipelineStatistics(info, zone_pool);
+ pipeline_statistics->BeginPhaseKind("initializing");
+ return pipeline_statistics;
+ }
+ return nullptr;
+}
+
+} // namespace
+
+
+class PipelineData final {
public:
// For main entry point.
- PipelineData(ZonePool* zone_pool, CompilationInfo* info,
- PipelineStatistics* pipeline_statistics)
+ explicit PipelineData(CompilationInfo* info)
: isolate_(info->isolate()),
info_(info),
outer_zone_(info_->zone()),
- zone_pool_(zone_pool),
- pipeline_statistics_(pipeline_statistics),
+ pipeline_statistics_(NewPipelineStatistics(info, zone_pool())),
compilation_failed_(false),
code_(Handle<Code>::null()),
- graph_zone_scope_(zone_pool_),
+ graph_zone_scope_(&zone_pool_),
graph_zone_(graph_zone_scope_.zone()),
graph_(nullptr),
loop_assignment_(nullptr),
@@ -80,14 +94,16 @@ class PipelineData {
jsgraph_(nullptr),
js_type_feedback_(nullptr),
schedule_(nullptr),
- instruction_zone_scope_(zone_pool_),
+ linkage_(nullptr),
+ profiler_data_(nullptr),
+ instruction_zone_scope_(&zone_pool_),
instruction_zone_(instruction_zone_scope_.zone()),
sequence_(nullptr),
frame_(nullptr),
- register_allocation_zone_scope_(zone_pool_),
+ register_allocation_zone_scope_(&zone_pool_),
register_allocation_zone_(register_allocation_zone_scope_.zone()),
register_allocation_data_(nullptr) {
- PhaseScope scope(pipeline_statistics, "init pipeline data");
+ PhaseScope scope(pipeline_statistics(), "init pipeline data");
graph_ = new (graph_zone_) Graph(graph_zone_);
source_positions_.Reset(new SourcePositionTable(graph_));
machine_ = new (graph_zone_) MachineOperatorBuilder(
@@ -100,16 +116,14 @@ class PipelineData {
}
// For machine graph testing entry point.
- PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph,
- Schedule* schedule)
+ PipelineData(CompilationInfo* info, Graph* graph, Schedule* schedule)
: isolate_(info->isolate()),
info_(info),
outer_zone_(nullptr),
- zone_pool_(zone_pool),
pipeline_statistics_(nullptr),
compilation_failed_(false),
code_(Handle<Code>::null()),
- graph_zone_scope_(zone_pool_),
+ graph_zone_scope_(&zone_pool_),
graph_zone_(nullptr),
graph_(graph),
source_positions_(new SourcePositionTable(graph_)),
@@ -120,25 +134,25 @@ class PipelineData {
jsgraph_(nullptr),
js_type_feedback_(nullptr),
schedule_(schedule),
- instruction_zone_scope_(zone_pool_),
+ linkage_(nullptr),
+ profiler_data_(nullptr),
+ instruction_zone_scope_(&zone_pool_),
instruction_zone_(instruction_zone_scope_.zone()),
sequence_(nullptr),
frame_(nullptr),
- register_allocation_zone_scope_(zone_pool_),
+ register_allocation_zone_scope_(&zone_pool_),
register_allocation_zone_(register_allocation_zone_scope_.zone()),
register_allocation_data_(nullptr) {}
// For register allocation testing entry point.
- PipelineData(ZonePool* zone_pool, CompilationInfo* info,
- InstructionSequence* sequence)
+ PipelineData(CompilationInfo* info, InstructionSequence* sequence)
: isolate_(info->isolate()),
info_(info),
outer_zone_(nullptr),
- zone_pool_(zone_pool),
pipeline_statistics_(nullptr),
compilation_failed_(false),
code_(Handle<Code>::null()),
- graph_zone_scope_(zone_pool_),
+ graph_zone_scope_(&zone_pool_),
graph_zone_(nullptr),
graph_(nullptr),
loop_assignment_(nullptr),
@@ -148,11 +162,13 @@ class PipelineData {
jsgraph_(nullptr),
js_type_feedback_(nullptr),
schedule_(nullptr),
- instruction_zone_scope_(zone_pool_),
+ linkage_(nullptr),
+ profiler_data_(nullptr),
+ instruction_zone_scope_(&zone_pool_),
instruction_zone_(sequence->zone()),
sequence_(sequence),
frame_(nullptr),
- register_allocation_zone_scope_(zone_pool_),
+ register_allocation_zone_scope_(&zone_pool_),
register_allocation_zone_(register_allocation_zone_scope_.zone()),
register_allocation_data_(nullptr) {}
@@ -164,8 +180,10 @@ class PipelineData {
Isolate* isolate() const { return isolate_; }
CompilationInfo* info() const { return info_; }
- ZonePool* zone_pool() const { return zone_pool_; }
- PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; }
+ ZonePool* zone_pool() { return &zone_pool_; }
+ PipelineStatistics* pipeline_statistics() const {
+ return pipeline_statistics_.get();
+ }
bool compilation_failed() const { return compilation_failed_; }
void set_compilation_failed() { compilation_failed_ = true; }
Handle<Code> code() { return code_; }
@@ -207,6 +225,11 @@ class PipelineData {
InstructionSequence* sequence() const { return sequence_; }
Frame* frame() const { return frame_; }
+ Linkage* linkage() const { return linkage_; }
+ void set_linkage(Linkage* linkage) { linkage_ = linkage; }
+
+ BasicBlockProfiler::Data* profiler_data() const { return profiler_data_; }
+
Zone* register_allocation_zone() const { return register_allocation_zone_; }
RegisterAllocationData* register_allocation_data() const {
return register_allocation_data_;
@@ -246,6 +269,10 @@ class PipelineData {
void InitializeInstructionSequence() {
DCHECK(sequence_ == nullptr);
+ if (FLAG_turbo_profiling) {
+ profiler_data_ =
+ BasicBlockInstrumentor::Instrument(info(), graph(), schedule());
+ }
InstructionBlocks* instruction_blocks =
InstructionSequence::InstructionBlocksFor(instruction_zone(),
schedule());
@@ -263,12 +290,16 @@ class PipelineData {
sequence(), debug_name);
}
+ std::ostringstream& source_position_output() {
+ return source_position_output_;
+ }
+
private:
Isolate* isolate_;
CompilationInfo* info_;
Zone* outer_zone_;
- ZonePool* const zone_pool_;
- PipelineStatistics* pipeline_statistics_;
+ ZonePool zone_pool_;
+ SmartPointer<PipelineStatistics> pipeline_statistics_;
bool compilation_failed_;
Handle<Code> code_;
@@ -286,6 +317,9 @@ class PipelineData {
JSGraph* jsgraph_;
JSTypeFeedbackTable* js_type_feedback_;
Schedule* schedule_;
+ Linkage* linkage_;
+ BasicBlockProfiler::Data* profiler_data_;
+ std::ostringstream source_position_output_;
// All objects in the following group of fields are allocated in
// instruction_zone_. They are all set to NULL when the instruction_zone_ is
@@ -444,19 +478,28 @@ class PipelineRunScope {
} // namespace
+Pipeline::Pipeline(CompilationInfo* info) : Pipeline(new PipelineData(info)) {}
+
+
+Pipeline::~Pipeline() { delete data_; }
+
+
+CompilationInfo* Pipeline::info() const { return data()->info(); }
+
+
template <typename Phase>
void Pipeline::Run() {
- PipelineRunScope scope(this->data_, Phase::phase_name());
+ PipelineRunScope scope(data(), Phase::phase_name());
Phase phase;
- phase.Run(this->data_, scope.zone());
+ phase.Run(data(), scope.zone());
}
template <typename Phase, typename Arg0>
void Pipeline::Run(Arg0 arg_0) {
- PipelineRunScope scope(this->data_, Phase::phase_name());
+ PipelineRunScope scope(data(), Phase::phase_name());
Phase phase;
- phase.Run(this->data_, scope.zone(), arg_0);
+ phase.Run(data(), scope.zone(), arg_0);
}
@@ -737,10 +780,10 @@ struct ComputeSchedulePhase {
struct InstructionSelectionPhase {
static const char* phase_name() { return "select instructions"; }
- void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
+ void Run(PipelineData* data, Zone* temp_zone) {
InstructionSelector selector(
- temp_zone, data->graph()->NodeCount(), linkage, data->sequence(),
- data->schedule(), data->source_positions(),
+ temp_zone, data->graph()->NodeCount(), data->linkage(),
+ data->sequence(), data->schedule(), data->source_positions(),
data->info()->is_source_positions_enabled()
? InstructionSelector::kAllSourcePositions
: InstructionSelector::kCallSourcePositions);
@@ -897,8 +940,8 @@ struct JumpThreadingPhase {
struct GenerateCodePhase {
static const char* phase_name() { return "generate code"; }
- void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
- CodeGenerator generator(data->frame(), linkage, data->sequence(),
+ void Run(PipelineData* data, Zone* temp_zone) {
+ CodeGenerator generator(data->frame(), data->linkage(), data->sequence(),
data->info());
data->set_code(generator.GenerateCode());
}
@@ -956,6 +999,13 @@ void Pipeline::BeginPhaseKind(const char* phase_kind_name) {
}
+void Pipeline::EndPhaseKind() {
+ if (data_->pipeline_statistics() != NULL) {
+ data_->pipeline_statistics()->EndPhaseKind();
+ }
+}
+
+
void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
if (FLAG_trace_turbo) {
Run<PrintGraphPhase>(phase);
@@ -966,7 +1016,7 @@ void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
}
-Handle<Code> Pipeline::GenerateCode() {
+bool Pipeline::CreateGraph() {
// TODO(mstarzinger): This is just a temporary hack to make TurboFan work,
// the correct solution is to restore the context register after invoking
// builtins from full-codegen.
@@ -974,21 +1024,13 @@ Handle<Code> Pipeline::GenerateCode() {
for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id);
- if (*info()->closure() == builtin) return Handle<Code>::null();
+ if (*info()->closure() == builtin) return false;
}
// TODO(dslomov): support turbo optimization of subclass constructors.
if (IsSubclassConstructor(shared->kind())) {
shared->DisableOptimization(kSuperReference);
- return Handle<Code>::null();
- }
-
- ZonePool zone_pool;
- SmartPointer<PipelineStatistics> pipeline_statistics;
-
- if (FLAG_turbo_stats) {
- pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
- pipeline_statistics->BeginPhaseKind("initializing");
+ return false;
}
if (FLAG_trace_turbo) {
@@ -1017,12 +1059,9 @@ Handle<Code> Pipeline::GenerateCode() {
}
}
- PipelineData data(&zone_pool, info(), pipeline_statistics.get());
- this->data_ = &data;
-
if (info()->is_type_feedback_enabled()) {
- data.set_js_type_feedback(new (data.graph_zone())
- JSTypeFeedbackTable(data.graph_zone()));
+ data()->set_js_type_feedback(new (data()->graph_zone())
+ JSTypeFeedbackTable(data()->graph_zone()));
}
BeginPhaseKind("graph creation");
@@ -1036,14 +1075,14 @@ Handle<Code> Pipeline::GenerateCode() {
tcf << AsC1VCompilation(info());
}
- data.source_positions()->AddDecorator();
+ data()->source_positions()->AddDecorator();
if (FLAG_loop_assignment_analysis) {
Run<LoopAssignmentAnalysisPhase>();
}
Run<GraphBuilderPhase>(info()->is_context_specializing());
- if (data.compilation_failed()) return Handle<Code>::null();
+ if (data()->compilation_failed()) return false;
RunPrintAndVerify("Initial untyped", true);
Run<EarlyControlReductionPhase>();
@@ -1063,16 +1102,16 @@ Handle<Code> Pipeline::GenerateCode() {
if (FLAG_print_turbo_replay) {
// Print a replay of the initial graph.
- GraphReplayPrinter::PrintReplay(data.graph());
+ GraphReplayPrinter::PrintReplay(data()->graph());
}
// Bailout here in case target architecture is not supported.
- if (!SupportedTarget()) return Handle<Code>::null();
+ if (!SupportedTarget()) return false;
SmartPointer<Typer> typer;
if (info()->is_typing_enabled()) {
// Type the graph.
- typer.Reset(new Typer(isolate(), data.graph(), info()->context()));
+ typer.Reset(new Typer(isolate(), data()->graph(), info()->context()));
Run<TyperPhase>(typer.get());
RunPrintAndVerify("Typed");
}
@@ -1119,7 +1158,7 @@ Handle<Code> Pipeline::GenerateCode() {
} else {
if (info()->is_osr()) {
Run<OsrDeconstructionPhase>();
- if (info()->bailout_reason() != kNoReason) return Handle<Code>::null();
+ if (info()->bailout_reason() != kNoReason) return false;
RunPrintAndVerify("OSR deconstruction", true);
}
}
@@ -1129,19 +1168,28 @@ Handle<Code> Pipeline::GenerateCode() {
// TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
RunPrintAndVerify("Lowered generic", true);
+ EndPhaseKind();
+
+ data()->source_positions()->RemoveDecorator();
+ return true;
+}
+
+
+bool Pipeline::OptimizeGraph() {
+ BeginPhaseKind("block building");
+
Run<LateGraphTrimmingPhase>();
// TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
RunPrintAndVerify("Late trimmed", true);
- BeginPhaseKind("block building");
-
- data.source_positions()->RemoveDecorator();
+ return ScheduleAndAllocateRegisters(
+ Linkage::ComputeIncoming(data()->instruction_zone(), info()));
+}
- // Kill the Typer and thereby uninstall the decorator (if any).
- typer.Reset(nullptr);
- return ScheduleAndGenerateCode(
- Linkage::ComputeIncoming(data.instruction_zone(), info()));
+Handle<Code> Pipeline::GenerateCode() {
+ if (!CreateGraph() || !OptimizeGraph()) return Handle<Code>::null();
+ return DoGenerateCode();
}
@@ -1169,17 +1217,15 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
Graph* graph,
Schedule* schedule) {
// Construct a pipeline for scheduling and code generation.
- ZonePool zone_pool;
- PipelineData data(&zone_pool, info, graph, schedule);
+ PipelineData* data = new PipelineData(info, graph, schedule);
SmartPointer<PipelineStatistics> pipeline_statistics;
if (FLAG_turbo_stats) {
- pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool));
+ pipeline_statistics.Reset(new PipelineStatistics(info, data->zone_pool()));
pipeline_statistics->BeginPhaseKind("test codegen");
}
- Pipeline pipeline(info);
- pipeline.data_ = &data;
- if (data.schedule() == nullptr) {
+ Pipeline pipeline(data);
+ if (data->schedule() == nullptr) {
// TODO(rossberg): Should this really be untyped?
pipeline.RunPrintAndVerify("Machine", true);
}
@@ -1193,18 +1239,15 @@ bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
bool run_verifier) {
FakeStubForTesting stub(sequence->isolate());
CompilationInfo info(&stub, sequence->isolate(), sequence->zone());
- ZonePool zone_pool;
- PipelineData data(&zone_pool, &info, sequence);
- Pipeline pipeline(&info);
- pipeline.data_ = &data;
+ PipelineData* data = new PipelineData(&info, sequence);
+ Pipeline pipeline(data);
pipeline.AllocateRegisters(config, run_verifier);
- return !data.compilation_failed();
+ return !data->compilation_failed();
}
-Handle<Code> Pipeline::ScheduleAndGenerateCode(
- CallDescriptor* call_descriptor) {
- PipelineData* data = this->data_;
+bool Pipeline::ScheduleAndAllocateRegisters(CallDescriptor* call_descriptor) {
+ PipelineData* data = this->data();
DCHECK_NOT_NULL(data->graph());
CHECK(SupportedBackend());
@@ -1212,17 +1255,11 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
if (data->schedule() == nullptr) Run<ComputeSchedulePhase>();
TraceSchedule(data->info(), data->schedule());
- BasicBlockProfiler::Data* profiler_data = NULL;
- if (FLAG_turbo_profiling) {
- profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(),
- data->schedule());
- }
-
data->InitializeInstructionSequence();
// Select and schedule instructions covering the scheduled graph.
- Linkage linkage(call_descriptor);
- Run<InstructionSelectionPhase>(&linkage);
+ data->set_linkage(new (data->info()->zone()) Linkage(call_descriptor));
+ Run<InstructionSelectionPhase>();
if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
TurboCfgFile tcf(isolate());
@@ -1230,10 +1267,9 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
data->sequence());
}
- std::ostringstream source_position_output;
if (FLAG_trace_turbo) {
// Output source position information before the graph is deleted.
- data_->source_positions()->Print(source_position_output);
+ data->source_positions()->Print(data->source_position_output());
}
data->DeleteGraphZone();
@@ -1245,25 +1281,34 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier);
if (data->compilation_failed()) {
info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
- return Handle<Code>();
+ return false;
}
- BeginPhaseKind("code generation");
-
// Optimimize jumps.
if (FLAG_turbo_jt) {
Run<JumpThreadingPhase>();
}
+ EndPhaseKind();
+
+ return true;
+}
+
+
+Handle<Code> Pipeline::DoGenerateCode() {
+ PipelineData* data = this->data_;
+
+ BeginPhaseKind("code generation");
+
// Generate final machine code.
- Run<GenerateCodePhase>(&linkage);
+ Run<GenerateCodePhase>();
Handle<Code> code = data->code();
- if (profiler_data != NULL) {
+ if (data->profiler_data()) {
#if ENABLE_DISASSEMBLER
std::ostringstream os;
code->Disassemble(NULL, os);
- profiler_data->SetCode(&os);
+ data->profiler_data()->SetCode(&os);
#endif
}
@@ -1286,7 +1331,7 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
#endif // ENABLE_DISASSEMBLER
json_of << "\"}\n],\n";
json_of << "\"nodePositions\":";
- json_of << source_position_output.str();
+ json_of << data->source_position_output().str();
json_of << "}";
fclose(json_file);
}
@@ -1300,9 +1345,18 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
}
+Handle<Code> Pipeline::ScheduleAndGenerateCode(
+ CallDescriptor* call_descriptor) {
+ if (!ScheduleAndAllocateRegisters(call_descriptor)) {
+ return Handle<Code>::null();
+ }
+ return DoGenerateCode();
+}
+
+
void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
bool run_verifier) {
- PipelineData* data = this->data_;
+ PipelineData* data = this->data();
// Don't track usage for this zone in compiler stats.
SmartPointer<Zone> verifier_zone;

Powered by Google App Engine
This is Rietveld 408576698