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

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: Fix Typer life cycle. 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 e7c76aabc3934d7212c714197bd75ba34470b87a..b1e9156a4aaa5eb4b39b415f703dc95323c059c8 100644
--- a/src/compiler/pipeline.cc
+++ b/src/compiler/pipeline.cc
@@ -56,19 +56,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),
@@ -77,16 +91,17 @@ class PipelineData {
javascript_(nullptr),
jsgraph_(nullptr),
js_type_feedback_(nullptr),
- typer_(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(
@@ -96,20 +111,17 @@ class PipelineData {
javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_);
jsgraph_ = new (graph_zone_)
JSGraph(isolate_, graph_, common_, javascript_, machine_);
- typer_.Reset(new Typer(isolate_, graph_, info_->context()));
}
// 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_)),
@@ -119,27 +131,26 @@ class PipelineData {
javascript_(nullptr),
jsgraph_(nullptr),
js_type_feedback_(nullptr),
- typer_(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,13 +159,14 @@ class PipelineData {
javascript_(nullptr),
jsgraph_(nullptr),
js_type_feedback_(nullptr),
- typer_(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) {}
@@ -166,8 +178,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_; }
@@ -192,7 +206,6 @@ class PipelineData {
void set_js_type_feedback(JSTypeFeedbackTable* js_type_feedback) {
js_type_feedback_ = js_type_feedback;
}
- Typer* typer() const { return typer_.get(); }
LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; }
void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) {
@@ -210,6 +223,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_;
@@ -218,7 +236,6 @@ class PipelineData {
void DeleteGraphZone() {
// Destroy objects with destructors first.
source_positions_.Reset(nullptr);
- typer_.Reset(nullptr);
if (graph_zone_ == nullptr) return;
// Destroy zone and clear pointers.
graph_zone_scope_.Destroy();
@@ -250,6 +267,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());
@@ -267,12 +288,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_;
@@ -290,8 +315,10 @@ class PipelineData {
JSGraph* jsgraph_;
JSTypeFeedbackTable* js_type_feedback_;
// TODO(dcarney): make this into a ZoneObject.
- SmartPointer<Typer> typer_;
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
@@ -450,19 +477,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);
}
@@ -522,7 +558,7 @@ struct InliningPhase {
struct TyperPhase {
static const char* phase_name() { return "typer"; }
- void Run(PipelineData* data, Zone* temp_zone) { data->typer()->Run(); }
+ void Run(PipelineData* data, Zone* temp_zone, Typer* typer) { typer->Run(); }
};
@@ -702,10 +738,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);
@@ -862,8 +898,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());
}
@@ -931,7 +967,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.
@@ -939,21 +975,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) {
@@ -982,12 +1010,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");
@@ -1001,14 +1026,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>();
@@ -1025,15 +1050,17 @@ 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.
- Run<TyperPhase>();
+ typer.Reset(new Typer(isolate(), data()->graph(), info()->context()));
+ Run<TyperPhase>(typer.get());
RunPrintAndVerify("Typed");
}
@@ -1079,7 +1106,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");
}
}
@@ -1091,10 +1118,21 @@ Handle<Code> Pipeline::GenerateCode() {
BeginPhaseKind("block building");
- data.source_positions()->RemoveDecorator();
+ data()->source_positions()->RemoveDecorator();
+ return true;
+}
+
+
+bool Pipeline::OptimizeGraph() {
+ return ScheduleAndAllocateRegisters(
+ Linkage::ComputeIncoming(data()->instruction_zone(), info()));
+}
+
+Handle<Code> Pipeline::GenerateCode() {
+ if (!CreateGraph()) return Handle<Code>::null();
return ScheduleAndGenerateCode(
- Linkage::ComputeIncoming(data.instruction_zone(), info()));
+ Linkage::ComputeIncoming(data()->instruction_zone(), info()));
}
@@ -1122,17 +1160,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);
}
@@ -1146,18 +1182,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());
@@ -1165,17 +1198,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());
@@ -1183,10 +1210,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();
@@ -1198,7 +1224,7 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier);
if (data->compilation_failed()) {
info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
- return Handle<Code>();
+ return false;
}
BeginPhaseKind("code generation");
@@ -1208,15 +1234,22 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
Run<JumpThreadingPhase>();
}
+ return true;
+}
+
+
+Handle<Code> Pipeline::DoGenerateCode() {
+ PipelineData* data = this->data_;
+
// 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
}
@@ -1239,7 +1272,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);
}
@@ -1253,9 +1286,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;
« src/compiler.cc ('K') | « src/compiler/pipeline.h ('k') | src/compiler/scheduler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698