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

Unified Diff: src/compiler/pipeline.cc

Issue 727733002: [turbofan] refactor pipeline to use hydrogen like Run calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 6 years, 1 month 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
« no previous file with comments | « src/compiler/pipeline.h ('k') | test/cctest/compiler/test-codegen-deopt.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/pipeline.cc
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
index a05e2b3e382657ebbe83e1e1ed0bdd7e333ad48a..e940198ac3bf5ed724b7ab9320021fc8a5e89c5d 100644
--- a/src/compiler/pipeline.cc
+++ b/src/compiler/pipeline.cc
@@ -43,12 +43,15 @@ namespace compiler {
class PipelineData {
public:
- explicit PipelineData(CompilationInfo* info, ZonePool* zone_pool,
- PipelineStatistics* pipeline_statistics)
+ PipelineData(CompilationInfo* info, ZonePool* zone_pool,
+ PipelineStatistics* pipeline_statistics)
: isolate_(info->zone()->isolate()),
+ info_(info),
outer_zone_(info->zone()),
zone_pool_(zone_pool),
pipeline_statistics_(pipeline_statistics),
+ compilation_failed_(false),
+ code_(Handle<Code>::null()),
graph_zone_scope_(zone_pool_),
graph_zone_(graph_zone_scope_.zone()),
graph_(new (graph_zone()) Graph(graph_zone())),
@@ -61,28 +64,38 @@ class PipelineData {
jsgraph_(new (graph_zone())
JSGraph(graph(), common(), javascript(), machine())),
typer_(new Typer(graph(), info->context())),
- schedule_(NULL),
+ context_node_(nullptr),
+ schedule_(nullptr),
instruction_zone_scope_(zone_pool_),
- instruction_zone_(instruction_zone_scope_.zone()) {}
+ instruction_zone_(instruction_zone_scope_.zone()),
+ sequence_(nullptr),
+ frame_(nullptr) {}
+
// For machine graph testing only.
PipelineData(Graph* graph, Schedule* schedule, ZonePool* zone_pool)
: isolate_(graph->zone()->isolate()),
- outer_zone_(NULL),
+ info_(nullptr),
+ outer_zone_(nullptr),
zone_pool_(zone_pool),
- pipeline_statistics_(NULL),
+ pipeline_statistics_(nullptr),
+ compilation_failed_(false),
+ code_(Handle<Code>::null()),
graph_zone_scope_(zone_pool_),
- graph_zone_(NULL),
+ graph_zone_(nullptr),
graph_(graph),
source_positions_(new SourcePositionTable(graph)),
- machine_(NULL),
- common_(NULL),
- javascript_(NULL),
- jsgraph_(NULL),
- typer_(NULL),
+ machine_(nullptr),
+ common_(nullptr),
+ javascript_(nullptr),
+ jsgraph_(nullptr),
+ typer_(nullptr),
+ context_node_(nullptr),
schedule_(schedule),
instruction_zone_scope_(zone_pool_),
- instruction_zone_(instruction_zone_scope_.zone()) {}
+ instruction_zone_(instruction_zone_scope_.zone()),
+ sequence_(nullptr),
+ frame_(nullptr) {}
~PipelineData() {
DeleteInstructionZone();
@@ -90,8 +103,19 @@ 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_; }
+ bool compilation_failed() const { return compilation_failed_; }
+ void set_compilation_failed() { compilation_failed_ = true; }
+ Handle<Code> code() { return code_; }
+ void set_code(Handle<Code> code) {
+ DCHECK(code_.is_null());
+ code_ = code;
+ }
+
+ // RawMachineAssembler generally produces graphs which cannot be verified.
+ bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
Zone* graph_zone() const { return graph_zone_; }
Graph* graph() const { return graph_; }
@@ -103,43 +127,64 @@ class PipelineData {
JSOperatorBuilder* javascript() const { return javascript_; }
JSGraph* jsgraph() const { return jsgraph_; }
Typer* typer() const { return typer_.get(); }
+
+ Node* context_node() const { return context_node_; }
+ void set_context_node(Node* context_node) {
+ DCHECK_EQ(nullptr, context_node_);
+ context_node_ = context_node;
+ }
+
Schedule* schedule() const { return schedule_; }
void set_schedule(Schedule* schedule) {
- DCHECK_EQ(NULL, schedule_);
+ DCHECK_EQ(nullptr, schedule_);
schedule_ = schedule;
}
Zone* instruction_zone() const { return instruction_zone_; }
- // RawMachineAssembler generally produces graphs which cannot be verified.
- bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
+ InstructionSequence* sequence() const { return sequence_; }
+ void set_sequence(InstructionSequence* sequence) {
+ DCHECK_EQ(nullptr, sequence_);
+ sequence_ = sequence;
+ }
+ Frame* frame() const { return frame_; }
+ void set_frame(Frame* frame) {
+ DCHECK_EQ(nullptr, frame_);
+ frame_ = frame;
+ }
void DeleteGraphZone() {
// Destroy objects with destructors first.
- source_positions_.Reset(NULL);
- typer_.Reset(NULL);
- if (graph_zone_ == NULL) return;
+ source_positions_.Reset(nullptr);
+ typer_.Reset(nullptr);
+ if (graph_zone_ == nullptr) return;
// Destroy zone and clear pointers.
graph_zone_scope_.Destroy();
- graph_zone_ = NULL;
- graph_ = NULL;
- machine_ = NULL;
- common_ = NULL;
- javascript_ = NULL;
- jsgraph_ = NULL;
- schedule_ = NULL;
+ graph_zone_ = nullptr;
+ graph_ = nullptr;
+ machine_ = nullptr;
+ common_ = nullptr;
+ javascript_ = nullptr;
+ jsgraph_ = nullptr;
+ context_node_ = nullptr;
+ schedule_ = nullptr;
}
void DeleteInstructionZone() {
- if (instruction_zone_ == NULL) return;
+ if (instruction_zone_ == nullptr) return;
instruction_zone_scope_.Destroy();
- instruction_zone_ = NULL;
+ instruction_zone_ = nullptr;
+ sequence_ = nullptr;
+ frame_ = nullptr;
}
private:
Isolate* isolate_;
+ CompilationInfo* info_;
Zone* outer_zone_;
ZonePool* zone_pool_;
PipelineStatistics* pipeline_statistics_;
+ bool compilation_failed_;
+ Handle<Code> code_;
ZonePool::Scope graph_zone_scope_;
Zone* graph_zone_;
@@ -154,6 +199,7 @@ class PipelineData {
JSGraph* jsgraph_;
// TODO(dcarney): make this into a ZoneObject.
SmartPointer<Typer> typer_;
+ Node* context_node_;
Schedule* schedule_;
// All objects in the following group of fields are allocated in
@@ -161,6 +207,8 @@ class PipelineData {
// destroyed.
ZonePool::Scope instruction_zone_scope_;
Zone* instruction_zone_;
+ InstructionSequence* sequence_;
+ Frame* frame_;
DISALLOW_COPY_AND_ASSIGN(PipelineData);
};
@@ -182,18 +230,335 @@ struct TurboCfgFile : public std::ofstream {
};
-void Pipeline::VerifyAndPrintGraph(
- Graph* graph, const char* phase, bool untyped) {
- if (FLAG_trace_turbo) {
+static void TraceSchedule(Schedule* schedule) {
+ if (!FLAG_trace_turbo) return;
+ OFStream os(stdout);
+ os << "-- Schedule --------------------------------------\n" << *schedule;
+}
+
+
+static SmartArrayPointer<char> GetDebugName(CompilationInfo* info) {
+ SmartArrayPointer<char> name;
+ if (info->IsStub()) {
+ if (info->code_stub() != NULL) {
+ CodeStub::Major major_key = info->code_stub()->MajorKey();
+ const char* major_name = CodeStub::MajorName(major_key, false);
+ size_t len = strlen(major_name);
+ name.Reset(new char[len]);
+ memcpy(name.get(), major_name, len);
+ }
+ } else {
+ AllowHandleDereference allow_deref;
+ name = info->function()->debug_name()->ToCString();
+ }
+ return name;
+}
+
+
+class AstGraphBuilderWithPositions : public AstGraphBuilder {
+ public:
+ explicit AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
+ JSGraph* jsgraph,
+ SourcePositionTable* source_positions)
+ : AstGraphBuilder(local_zone, info, jsgraph),
+ source_positions_(source_positions) {}
+
+ bool CreateGraph() {
+ SourcePositionTable::Scope pos(source_positions_,
+ SourcePosition::Unknown());
+ return AstGraphBuilder::CreateGraph();
+ }
+
+#define DEF_VISIT(type) \
+ virtual void Visit##type(type* node) OVERRIDE { \
+ SourcePositionTable::Scope pos(source_positions_, \
+ SourcePosition(node->position())); \
+ AstGraphBuilder::Visit##type(node); \
+ }
+ AST_NODE_LIST(DEF_VISIT)
+#undef DEF_VISIT
+
+ Node* GetFunctionContext() { return AstGraphBuilder::GetFunctionContext(); }
+
+ private:
+ SourcePositionTable* source_positions_;
+};
+
+
+class PipelineRunScope {
+ public:
+ PipelineRunScope(PipelineData* data, const char* phase_name)
+ : phase_scope_(
+ phase_name == nullptr ? nullptr : data->pipeline_statistics(),
+ phase_name),
+ zone_scope_(data->zone_pool()) {}
+
+ Zone* zone() { return zone_scope_.zone(); }
+
+ private:
+ PhaseScope phase_scope_;
+ ZonePool::Scope zone_scope_;
+};
+
+
+template <typename Phase>
+void Pipeline::Run() {
+ PipelineRunScope scope(this->data_, Phase::phase_name());
+ Phase phase;
+ phase.Run(this->data_, scope.zone());
+}
+
+
+template <typename Phase, typename Arg0>
+void Pipeline::Run(Arg0 arg_0) {
+ PipelineRunScope scope(this->data_, Phase::phase_name());
+ Phase phase;
+ phase.Run(this->data_, scope.zone(), arg_0);
+}
+
+
+// TODO(dcarney): this one should be unecessary.
+template <typename Phase, typename Arg0, typename Arg1>
+void Pipeline::Run(Arg0 arg_0, Arg1 arg_1) {
+ PipelineRunScope scope(this->data_, Phase::phase_name());
+ Phase phase;
+ phase.Run(this->data_, scope.zone(), arg_0, arg_1);
+}
+
+
+struct GraphBuilderPhase {
+ static const char* phase_name() { return "graph builder"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ AstGraphBuilderWithPositions graph_builder(
+ temp_zone, data->info(), data->jsgraph(), data->source_positions());
+ if (graph_builder.CreateGraph()) {
+ data->set_context_node(graph_builder.GetFunctionContext());
+ } else {
+ data->set_compilation_failed();
+ }
+ }
+};
+
+
+struct ContextSpecializerPhase {
+ static const char* phase_name() { return nullptr; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ SourcePositionTable::Scope pos(data->source_positions(),
+ SourcePosition::Unknown());
+ JSContextSpecializer spec(data->info(), data->jsgraph(),
+ data->context_node());
+ spec.SpecializeToContext();
+ }
+};
+
+
+struct InliningPhase {
+ static const char* phase_name() { return "inlining"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ SourcePositionTable::Scope pos(data->source_positions(),
+ SourcePosition::Unknown());
+ JSInliner inliner(temp_zone, data->info(), data->jsgraph());
+ inliner.Inline();
+ }
+};
+
+
+struct TyperPhase {
+ static const char* phase_name() { return "typer"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) { data->typer()->Run(); }
+};
+
+
+struct TypedLoweringPhase {
+ static const char* phase_name() { return "typed lowering"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ SourcePositionTable::Scope pos(data->source_positions(),
+ SourcePosition::Unknown());
+ ValueNumberingReducer vn_reducer(data->graph_zone());
+ JSTypedLowering lowering(data->jsgraph());
+ SimplifiedOperatorReducer simple_reducer(data->jsgraph());
+ GraphReducer graph_reducer(data->graph());
+ graph_reducer.AddReducer(&vn_reducer);
+ graph_reducer.AddReducer(&lowering);
+ graph_reducer.AddReducer(&simple_reducer);
+ graph_reducer.ReduceGraph();
+ }
+};
+
+
+struct SimplifiedLoweringPhase {
+ static const char* phase_name() { return "simplified lowering"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ SourcePositionTable::Scope pos(data->source_positions(),
+ SourcePosition::Unknown());
+ SimplifiedLowering lowering(data->jsgraph());
+ lowering.LowerAllNodes();
+ ValueNumberingReducer vn_reducer(data->graph_zone());
+ SimplifiedOperatorReducer simple_reducer(data->jsgraph());
+ GraphReducer graph_reducer(data->graph());
+ graph_reducer.AddReducer(&vn_reducer);
+ graph_reducer.AddReducer(&simple_reducer);
+ graph_reducer.ReduceGraph();
+ }
+};
+
+
+struct ChangeLoweringPhase {
+ static const char* phase_name() { return "change lowering"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ SourcePositionTable::Scope pos(data->source_positions(),
+ SourcePosition::Unknown());
+ Linkage linkage(data->graph_zone(), data->info());
+ ValueNumberingReducer vn_reducer(data->graph_zone());
+ SimplifiedOperatorReducer simple_reducer(data->jsgraph());
+ ChangeLowering lowering(data->jsgraph(), &linkage);
+ MachineOperatorReducer mach_reducer(data->jsgraph());
+ GraphReducer graph_reducer(data->graph());
+ // TODO(titzer): Figure out if we should run all reducers at once here.
+ graph_reducer.AddReducer(&vn_reducer);
+ graph_reducer.AddReducer(&simple_reducer);
+ graph_reducer.AddReducer(&lowering);
+ graph_reducer.AddReducer(&mach_reducer);
+ graph_reducer.ReduceGraph();
+ }
+};
+
+
+struct ControlReductionPhase {
+ void Run(PipelineData* data, Zone* temp_zone) {
+ SourcePositionTable::Scope pos(data->source_positions(),
+ SourcePosition::Unknown());
+ ControlReducer::ReduceGraph(temp_zone, data->jsgraph(), data->common());
+ }
+};
+
+
+struct EarlyControlReductionPhase : ControlReductionPhase {
+ static const char* phase_name() { return "early control reduction"; }
+};
+
+
+struct LateControlReductionPhase : ControlReductionPhase {
+ static const char* phase_name() { return "late control reduction"; }
+};
+
+
+struct GenericLoweringPhase {
+ static const char* phase_name() { return "generic lowering"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ SourcePositionTable::Scope pos(data->source_positions(),
+ SourcePosition::Unknown());
+ JSGenericLowering generic(data->info(), data->jsgraph());
+ SelectLowering select(data->jsgraph()->graph(), data->jsgraph()->common());
+ GraphReducer graph_reducer(data->graph());
+ graph_reducer.AddReducer(&generic);
+ graph_reducer.AddReducer(&select);
+ graph_reducer.ReduceGraph();
+ }
+};
+
+
+struct ComputeSchedulePhase {
+ static const char* phase_name() { return "scheduling"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ Schedule* schedule = Scheduler::ComputeSchedule(temp_zone, data->graph());
+ TraceSchedule(schedule);
+ if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
+ data->set_schedule(schedule);
+ }
+};
+
+
+struct InstructionSelectionPhase {
+ static const char* phase_name() { return "select instructions"; }
+
+ void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
+ InstructionSelector selector(temp_zone, data->graph(), linkage,
+ data->sequence(), data->schedule(),
+ data->source_positions());
+ selector.SelectInstructions();
+ }
+};
+
+
+// TODO(dcarney): break this up.
+struct RegisterAllocationPhase {
+ static const char* phase_name() { return nullptr; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ int node_count = data->sequence()->VirtualRegisterCount();
+ if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
+ data->set_compilation_failed();
+ return;
+ }
+
+ SmartArrayPointer<char> debug_name;
+#ifdef DEBUG
+ if (data->info() != nullptr) {
+ debug_name = GetDebugName(data->info());
+ }
+#endif
+
+ RegisterAllocator allocator(RegisterConfiguration::ArchDefault(), temp_zone,
+ data->frame(), data->sequence(),
+ debug_name.get());
+
+ if (!allocator.Allocate(data->pipeline_statistics())) {
+ data->set_compilation_failed();
+ return;
+ }
+
+ if (FLAG_trace_turbo) {
+ OFStream os(stdout);
+ PrintableInstructionSequence printable = {
+ RegisterConfiguration::ArchDefault(), data->sequence()};
+ os << "----- Instruction sequence after register allocation -----\n"
+ << printable;
+ }
+
+ if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
+ TurboCfgFile tcf(data->isolate());
+ tcf << AsC1VAllocator("CodeGen", &allocator);
+ }
+ }
+};
+
+
+struct GenerateCodePhase {
+ static const char* phase_name() { return "generate code"; }
+
+ void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage,
+ CompilationInfo* info) {
+ CodeGenerator generator(data->frame(), linkage, data->sequence(), info);
+ data->set_code(generator.GenerateCode());
+ }
+};
+
+
+struct PrintGraphPhase {
+ static const char* phase_name() { return nullptr; }
+
+ void Run(PipelineData* data, Zone* temp_zone, const char* phase) {
+ CompilationInfo* info = data->info();
+ Graph* graph = data->graph();
char buffer[256];
Vector<char> filename(buffer, sizeof(buffer));
SmartArrayPointer<char> functionname;
- if (!info_->shared_info().is_null()) {
- functionname = info_->shared_info()->DebugName()->ToCString();
+ if (!info->shared_info().is_null()) {
+ functionname = info->shared_info()->DebugName()->ToCString();
if (strlen(functionname.get()) > 0) {
SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase);
} else {
- SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info_), phase);
+ SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info), phase);
}
} else {
SNPrintF(filename, "turbo-none-%s", phase);
@@ -221,63 +586,27 @@ void Pipeline::VerifyAndPrintGraph(
os << "-- " << phase << " graph printed to file " << filename.start()
<< "\n";
}
- if (VerifyGraphs()) {
- Verifier::Run(graph,
- FLAG_turbo_types && !untyped ? Verifier::TYPED : Verifier::UNTYPED);
- }
-}
+};
-class AstGraphBuilderWithPositions : public AstGraphBuilder {
- public:
- explicit AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
- JSGraph* jsgraph,
- SourcePositionTable* source_positions)
- : AstGraphBuilder(local_zone, info, jsgraph),
- source_positions_(source_positions) {}
+struct VerifyGraphPhase {
+ static const char* phase_name() { return nullptr; }
- bool CreateGraph() {
- SourcePositionTable::Scope pos(source_positions_,
- SourcePosition::Unknown());
- return AstGraphBuilder::CreateGraph();
- }
-
-#define DEF_VISIT(type) \
- virtual void Visit##type(type* node) OVERRIDE { \
- SourcePositionTable::Scope pos(source_positions_, \
- SourcePosition(node->position())); \
- AstGraphBuilder::Visit##type(node); \
+ void Run(PipelineData* data, Zone* temp_zone, const bool untyped) {
+ Verifier::Run(data->graph(), FLAG_turbo_types && !untyped
+ ? Verifier::TYPED
+ : Verifier::UNTYPED);
}
- AST_NODE_LIST(DEF_VISIT)
-#undef DEF_VISIT
-
- private:
- SourcePositionTable* source_positions_;
};
-static void TraceSchedule(Schedule* schedule) {
- if (!FLAG_trace_turbo) return;
- OFStream os(stdout);
- os << "-- Schedule --------------------------------------\n" << *schedule;
-}
-
-
-static SmartArrayPointer<char> GetDebugName(CompilationInfo* info) {
- SmartArrayPointer<char> name;
- if (info->IsStub()) {
- if (info->code_stub() != NULL) {
- CodeStub::Major major_key = info->code_stub()->MajorKey();
- const char* major_name = CodeStub::MajorName(major_key, false);
- size_t len = strlen(major_name);
- name.Reset(new char[len]);
- memcpy(name.get(), major_name, len);
- }
- } else {
- AllowHandleDereference allow_deref;
- name = info->function()->debug_name()->ToCString();
+void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
+ if (FLAG_trace_turbo) {
+ Run<PrintGraphPhase>(phase);
+ }
+ if (VerifyGraphs()) {
+ Run<VerifyGraphPhase>(untyped);
}
- return name;
}
@@ -297,13 +626,16 @@ Handle<Code> Pipeline::GenerateCode() {
}
ZonePool zone_pool(isolate());
-
SmartPointer<PipelineStatistics> pipeline_statistics;
+
if (FLAG_turbo_stats) {
pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
pipeline_statistics->BeginPhaseKind("graph creation");
}
+ PipelineData data(info(), &zone_pool, pipeline_statistics.get());
+ this->data_ = &data;
+
if (FLAG_trace_turbo) {
OFStream os(stdout);
os << "---------------------------------------------------\n"
@@ -313,56 +645,28 @@ Handle<Code> Pipeline::GenerateCode() {
tcf << AsC1VCompilation(info());
}
- // Initialize the graph and builders.
- PipelineData data(info(), &zone_pool, pipeline_statistics.get());
-
data.source_positions()->AddDecorator();
- Node* context_node;
- {
- PhaseScope phase_scope(pipeline_statistics.get(), "graph builder");
- ZonePool::Scope zone_scope(data.zone_pool());
- AstGraphBuilderWithPositions graph_builder(
- zone_scope.zone(), info(), data.jsgraph(), data.source_positions());
- if (!graph_builder.CreateGraph()) return Handle<Code>::null();
- context_node = graph_builder.GetFunctionContext();
- }
-
- VerifyAndPrintGraph(data.graph(), "Initial untyped", true);
+ Run<GraphBuilderPhase>();
+ if (data.compilation_failed()) return Handle<Code>::null();
+ RunPrintAndVerify("Initial untyped", true);
- {
- PhaseScope phase_scope(pipeline_statistics.get(),
- "early control reduction");
- SourcePositionTable::Scope pos(data.source_positions(),
- SourcePosition::Unknown());
- ZonePool::Scope zone_scope(data.zone_pool());
- ControlReducer::ReduceGraph(zone_scope.zone(), data.jsgraph(),
- data.common());
-
- VerifyAndPrintGraph(data.graph(), "Early Control reduced", true);
- }
+ Run<EarlyControlReductionPhase>();
+ RunPrintAndVerify("Early Control reduced", true);
if (info()->is_context_specializing()) {
- SourcePositionTable::Scope pos(data.source_positions(),
- SourcePosition::Unknown());
// Specialize the code to the context as aggressively as possible.
- JSContextSpecializer spec(info(), data.jsgraph(), context_node);
- spec.SpecializeToContext();
- VerifyAndPrintGraph(data.graph(), "Context specialized", true);
+ Run<ContextSpecializerPhase>();
+ RunPrintAndVerify("Context specialized", true);
}
if (info()->is_inlining_enabled()) {
- PhaseScope phase_scope(pipeline_statistics.get(), "inlining");
- SourcePositionTable::Scope pos(data.source_positions(),
- SourcePosition::Unknown());
- ZonePool::Scope zone_scope(data.zone_pool());
- JSInliner inliner(zone_scope.zone(), info(), data.jsgraph());
- inliner.Inline();
- VerifyAndPrintGraph(data.graph(), "Inlined", true);
+ Run<InliningPhase>();
+ RunPrintAndVerify("Inlined", true);
}
- // Print a replay of the initial graph.
if (FLAG_print_turbo_replay) {
+ // Print a replay of the initial graph.
GraphReplayPrinter::PrintReplay(data.graph());
}
@@ -370,118 +674,54 @@ Handle<Code> Pipeline::GenerateCode() {
if (!SupportedTarget()) return Handle<Code>::null();
if (info()->is_typing_enabled()) {
- {
- // Type the graph.
- PhaseScope phase_scope(pipeline_statistics.get(), "typer");
- data.typer()->Run();
- VerifyAndPrintGraph(data.graph(), "Typed");
- }
+ // Type the graph.
+ Run<TyperPhase>();
+ RunPrintAndVerify("Typed");
}
if (!pipeline_statistics.is_empty()) {
- pipeline_statistics->BeginPhaseKind("lowering");
+ data.pipeline_statistics()->BeginPhaseKind("lowering");
}
if (info()->is_typing_enabled()) {
- {
- // Lower JSOperators where we can determine types.
- PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering");
- SourcePositionTable::Scope pos(data.source_positions(),
- SourcePosition::Unknown());
- ValueNumberingReducer vn_reducer(data.graph_zone());
- JSTypedLowering lowering(data.jsgraph());
- SimplifiedOperatorReducer simple_reducer(data.jsgraph());
- GraphReducer graph_reducer(data.graph());
- graph_reducer.AddReducer(&vn_reducer);
- graph_reducer.AddReducer(&lowering);
- graph_reducer.AddReducer(&simple_reducer);
- graph_reducer.ReduceGraph();
-
- VerifyAndPrintGraph(data.graph(), "Lowered typed");
- }
- {
- // Lower simplified operators and insert changes.
- PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering");
- SourcePositionTable::Scope pos(data.source_positions(),
- SourcePosition::Unknown());
- SimplifiedLowering lowering(data.jsgraph());
- lowering.LowerAllNodes();
- ValueNumberingReducer vn_reducer(data.graph_zone());
- SimplifiedOperatorReducer simple_reducer(data.jsgraph());
- GraphReducer graph_reducer(data.graph());
- graph_reducer.AddReducer(&vn_reducer);
- graph_reducer.AddReducer(&simple_reducer);
- graph_reducer.ReduceGraph();
-
- VerifyAndPrintGraph(data.graph(), "Lowered simplified");
- }
- {
- // Lower changes that have been inserted before.
- PhaseScope phase_scope(pipeline_statistics.get(), "change lowering");
- SourcePositionTable::Scope pos(data.source_positions(),
- SourcePosition::Unknown());
- Linkage linkage(data.graph_zone(), info());
- ValueNumberingReducer vn_reducer(data.graph_zone());
- SimplifiedOperatorReducer simple_reducer(data.jsgraph());
- ChangeLowering lowering(data.jsgraph(), &linkage);
- MachineOperatorReducer mach_reducer(data.jsgraph());
- GraphReducer graph_reducer(data.graph());
- // TODO(titzer): Figure out if we should run all reducers at once here.
- graph_reducer.AddReducer(&vn_reducer);
- graph_reducer.AddReducer(&simple_reducer);
- graph_reducer.AddReducer(&lowering);
- graph_reducer.AddReducer(&mach_reducer);
- graph_reducer.ReduceGraph();
-
- // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
- VerifyAndPrintGraph(data.graph(), "Lowered changes", true);
- }
+ // Lower JSOperators where we can determine types.
+ Run<TypedLoweringPhase>();
+ RunPrintAndVerify("Lowered typed");
- {
- PhaseScope phase_scope(pipeline_statistics.get(),
- "late control reduction");
- SourcePositionTable::Scope pos(data.source_positions(),
- SourcePosition::Unknown());
- ZonePool::Scope zone_scope(data.zone_pool());
- ControlReducer::ReduceGraph(zone_scope.zone(), data.jsgraph(),
- data.common());
-
- VerifyAndPrintGraph(data.graph(), "Late Control reduced");
- }
- }
+ // Lower simplified operators and insert changes.
+ Run<SimplifiedLoweringPhase>();
+ RunPrintAndVerify("Lowered simplified");
- {
- // Lower any remaining generic JSOperators.
- PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering");
- SourcePositionTable::Scope pos(data.source_positions(),
- SourcePosition::Unknown());
- JSGenericLowering generic(info(), data.jsgraph());
- SelectLowering select(data.jsgraph()->graph(), data.jsgraph()->common());
- GraphReducer graph_reducer(data.graph());
- graph_reducer.AddReducer(&generic);
- graph_reducer.AddReducer(&select);
- graph_reducer.ReduceGraph();
+ // Lower changes that have been inserted before.
+ Run<ChangeLoweringPhase>();
+ // // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
+ RunPrintAndVerify("Lowered changes", true);
- // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
- VerifyAndPrintGraph(data.graph(), "Lowered generic", true);
+ Run<LateControlReductionPhase>();
+ RunPrintAndVerify("Late Control reduced");
}
+ // Lower any remaining generic JSOperators.
+ Run<GenericLoweringPhase>();
+ // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
+ RunPrintAndVerify("Lowered generic", true);
+
if (!pipeline_statistics.is_empty()) {
- pipeline_statistics->BeginPhaseKind("block building");
+ data.pipeline_statistics()->BeginPhaseKind("block building");
}
data.source_positions()->RemoveDecorator();
// Compute a schedule.
- ComputeSchedule(&data);
+ Run<ComputeSchedulePhase>();
- Handle<Code> code = Handle<Code>::null();
{
// Generate optimized code.
Linkage linkage(data.instruction_zone(), info());
- code = GenerateCode(&linkage, &data);
- info()->SetCode(code);
+ GenerateCode(&linkage);
}
+ Handle<Code> code = data.code();
+ info()->SetCode(code);
// Print optimized code.
v8::internal::CodeGenerator::PrintCode(code, info());
@@ -497,32 +737,24 @@ Handle<Code> Pipeline::GenerateCode() {
}
-void Pipeline::ComputeSchedule(PipelineData* data) {
- PhaseScope phase_scope(data->pipeline_statistics(), "scheduling");
- ZonePool::Scope zone_scope(data->zone_pool());
- Schedule* schedule =
- Scheduler::ComputeSchedule(zone_scope.zone(), data->graph());
- TraceSchedule(schedule);
- if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
- data->set_schedule(schedule);
-}
-
-
Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
Graph* graph,
Schedule* schedule) {
ZonePool zone_pool(isolate());
CHECK(SupportedBackend());
PipelineData data(graph, schedule, &zone_pool);
+ this->data_ = &data;
if (schedule == NULL) {
// TODO(rossberg): Should this really be untyped?
- VerifyAndPrintGraph(graph, "Machine", true);
- ComputeSchedule(&data);
+ RunPrintAndVerify("Machine", true);
+ Run<ComputeSchedulePhase>();
} else {
TraceSchedule(schedule);
}
- Handle<Code> code = GenerateCode(linkage, &data);
+ GenerateCode(linkage);
+ Handle<Code> code = data.code();
+
#if ENABLE_DISASSEMBLER
if (!code.is_null() && FLAG_print_opt_code) {
CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
@@ -534,7 +766,9 @@ Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
}
-Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) {
+void Pipeline::GenerateCode(Linkage* linkage) {
+ PipelineData* data = this->data_;
+
DCHECK_NOT_NULL(linkage);
DCHECK_NOT_NULL(data->graph());
DCHECK_NOT_NULL(data->schedule());
@@ -549,22 +783,16 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) {
InstructionBlocks* instruction_blocks =
InstructionSequence::InstructionBlocksFor(data->instruction_zone(),
data->schedule());
- InstructionSequence sequence(data->instruction_zone(), instruction_blocks);
+ data->set_sequence(new (data->instruction_zone()) InstructionSequence(
+ data->instruction_zone(), instruction_blocks));
// Select and schedule instructions covering the scheduled graph.
- {
- PhaseScope phase_scope(data->pipeline_statistics(), "select instructions");
- ZonePool::Scope zone_scope(data->zone_pool());
- InstructionSelector selector(zone_scope.zone(), data->graph(), linkage,
- &sequence, data->schedule(),
- data->source_positions());
- selector.SelectInstructions();
- }
+ Run<InstructionSelectionPhase>(linkage);
if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
TurboCfgFile tcf(isolate());
tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(),
- &sequence);
+ data->sequence());
}
data->DeleteGraphZone();
@@ -577,43 +805,15 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) {
// Don't track usage for this zone in compiler stats.
Zone verifier_zone(info()->isolate());
RegisterAllocatorVerifier verifier(
- &verifier_zone, RegisterConfiguration::ArchDefault(), &sequence);
+ &verifier_zone, RegisterConfiguration::ArchDefault(), data->sequence());
#endif
// Allocate registers.
- Frame frame;
- {
- int node_count = sequence.VirtualRegisterCount();
- if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
- info()->AbortOptimization(kNotEnoughVirtualRegistersForValues);
- return Handle<Code>::null();
- }
- ZonePool::Scope zone_scope(data->zone_pool());
-
- SmartArrayPointer<char> debug_name;
-#ifdef DEBUG
- debug_name = GetDebugName(info());
-#endif
-
- RegisterAllocator allocator(RegisterConfiguration::ArchDefault(),
- zone_scope.zone(), &frame, &sequence,
- debug_name.get());
- if (!allocator.Allocate(data->pipeline_statistics())) {
- info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
- return Handle<Code>::null();
- }
- if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
- TurboCfgFile tcf(isolate());
- tcf << AsC1VAllocator("CodeGen", &allocator);
- }
- }
-
- if (FLAG_trace_turbo) {
- OFStream os(stdout);
- PrintableInstructionSequence printable = {
- RegisterConfiguration::ArchDefault(), &sequence};
- os << "----- Instruction sequence after register allocation -----\n"
- << printable;
+ data->set_frame(new (data->instruction_zone()) Frame);
+ Run<RegisterAllocationPhase>();
+ if (data->compilation_failed()) {
+ info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
+ return;
}
#ifdef DEBUG
@@ -626,20 +826,15 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) {
}
// Generate native sequence.
- Handle<Code> code;
- {
- PhaseScope phase_scope(data->pipeline_statistics(), "generate code");
- CodeGenerator generator(&frame, linkage, &sequence, info());
- code = generator.GenerateCode();
- }
+ Run<GenerateCodePhase>(linkage, info());
+
if (profiler_data != NULL) {
#if ENABLE_DISASSEMBLER
std::ostringstream os;
- code->Disassemble(NULL, os);
+ data->code()->Disassemble(NULL, os);
profiler_data->SetCode(&os);
#endif
}
- return code;
}
« no previous file with comments | « src/compiler/pipeline.h ('k') | test/cctest/compiler/test-codegen-deopt.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698