diff options
Diffstat (limited to 'deps/v8/src/compiler/pipeline.cc')
-rw-r--r-- | deps/v8/src/compiler/pipeline.cc | 192 |
1 files changed, 151 insertions, 41 deletions
diff --git a/deps/v8/src/compiler/pipeline.cc b/deps/v8/src/compiler/pipeline.cc index b0b3eb76ef..333382aaf3 100644 --- a/deps/v8/src/compiler/pipeline.cc +++ b/deps/v8/src/compiler/pipeline.cc @@ -6,6 +6,8 @@ #include "src/base/platform/elapsed-timer.h" #include "src/compiler/ast-graph-builder.h" +#include "src/compiler/basic-block-instrumentor.h" +#include "src/compiler/change-lowering.h" #include "src/compiler/code-generator.h" #include "src/compiler/graph-replay.h" #include "src/compiler/graph-visualizer.h" @@ -13,13 +15,17 @@ #include "src/compiler/instruction-selector.h" #include "src/compiler/js-context-specialization.h" #include "src/compiler/js-generic-lowering.h" +#include "src/compiler/js-inlining.h" #include "src/compiler/js-typed-lowering.h" +#include "src/compiler/machine-operator-reducer.h" #include "src/compiler/phi-reducer.h" #include "src/compiler/register-allocator.h" #include "src/compiler/schedule.h" #include "src/compiler/scheduler.h" #include "src/compiler/simplified-lowering.h" +#include "src/compiler/simplified-operator-reducer.h" #include "src/compiler/typer.h" +#include "src/compiler/value-numbering-reducer.h" #include "src/compiler/verifier.h" #include "src/hydrogen.h" #include "src/ostreams.h" @@ -73,23 +79,48 @@ class PhaseStats { }; +static inline bool VerifyGraphs() { +#ifdef DEBUG + return true; +#else + return FLAG_turbo_verify; +#endif +} + + void Pipeline::VerifyAndPrintGraph(Graph* graph, const char* phase) { if (FLAG_trace_turbo) { char buffer[256]; Vector<char> filename(buffer, sizeof(buffer)); - SmartArrayPointer<char> functionname = - info_->shared_info()->DebugName()->ToCString(); - if (strlen(functionname.get()) > 0) { - SNPrintF(filename, "turbo-%s-%s.dot", functionname.get(), phase); + if (!info_->shared_info().is_null()) { + SmartArrayPointer<char> 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); + } } else { - SNPrintF(filename, "turbo-%p-%s.dot", static_cast<void*>(info_), phase); + SNPrintF(filename, "turbo-none-%s", phase); } std::replace(filename.start(), filename.start() + filename.length(), ' ', '_'); - FILE* file = base::OS::FOpen(filename.start(), "w+"); - OFStream of(file); - of << AsDOT(*graph); - fclose(file); + + char dot_buffer[256]; + Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer)); + SNPrintF(dot_filename, "%s.dot", filename.start()); + FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+"); + OFStream dot_of(dot_file); + dot_of << AsDOT(*graph); + fclose(dot_file); + + char json_buffer[256]; + Vector<char> json_filename(json_buffer, sizeof(json_buffer)); + SNPrintF(json_filename, "%s.json", filename.start()); + FILE* json_file = base::OS::FOpen(json_filename.start(), "w+"); + OFStream json_of(json_file); + json_of << AsJSON(*graph); + fclose(json_file); OFStream os(stdout); os << "-- " << phase << " graph printed to file " << filename.start() @@ -112,7 +143,7 @@ class AstGraphBuilderWithPositions : public AstGraphBuilder { } #define DEF_VISIT(type) \ - virtual void Visit##type(type* node) V8_OVERRIDE { \ + virtual void Visit##type(type* node) OVERRIDE { \ SourcePositionTable::Scope pos(source_positions_, \ SourcePosition(node->position())); \ AstGraphBuilder::Visit##type(node); \ @@ -133,6 +164,17 @@ static void TraceSchedule(Schedule* schedule) { Handle<Code> Pipeline::GenerateCode() { + if (info()->function()->dont_optimize_reason() == kTryCatchStatement || + info()->function()->dont_optimize_reason() == kTryFinallyStatement || + // TODO(turbofan): Make ES6 for-of work and remove this bailout. + info()->function()->dont_optimize_reason() == kForOfStatement || + // TODO(turbofan): Make super work and remove this bailout. + info()->function()->dont_optimize_reason() == kSuperReference || + // TODO(turbofan): Make OSR work and remove this bailout. + info()->is_osr()) { + return Handle<Code>::null(); + } + if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_); if (FLAG_trace_turbo) { @@ -151,8 +193,10 @@ Handle<Code> Pipeline::GenerateCode() { // construction. This is currently only needed for the node cache, which the // typer could sweep over later. Typer typer(zone()); + MachineOperatorBuilder machine; CommonOperatorBuilder common(zone()); - JSGraph jsgraph(&graph, &common, &typer); + JSOperatorBuilder javascript(zone()); + JSGraph jsgraph(&graph, &common, &javascript, &typer, &machine); Node* context_node; { PhaseStats graph_builder_stats(info(), PhaseStats::CREATE_GRAPH, @@ -176,25 +220,37 @@ Handle<Code> Pipeline::GenerateCode() { VerifyAndPrintGraph(&graph, "Initial untyped"); - if (FLAG_context_specialization) { - SourcePositionTable::Scope pos_(&source_positions, - SourcePosition::Unknown()); + if (info()->is_context_specializing()) { + SourcePositionTable::Scope pos(&source_positions, + SourcePosition::Unknown()); // Specialize the code to the context as aggressively as possible. JSContextSpecializer spec(info(), &jsgraph, context_node); spec.SpecializeToContext(); VerifyAndPrintGraph(&graph, "Context specialized"); } + if (info()->is_inlining_enabled()) { + SourcePositionTable::Scope pos(&source_positions, + SourcePosition::Unknown()); + JSInliner inliner(info(), &jsgraph); + inliner.Inline(); + VerifyAndPrintGraph(&graph, "Inlined"); + } + // Print a replay of the initial graph. if (FLAG_print_turbo_replay) { GraphReplayPrinter::PrintReplay(&graph); } - if (FLAG_turbo_types) { + // Bailout here in case target architecture is not supported. + if (!SupportedTarget()) return Handle<Code>::null(); + + if (info()->is_typing_enabled()) { { // Type the graph. PhaseStats typer_stats(info(), PhaseStats::CREATE_GRAPH, "typer"); typer.Run(&graph, info()->context()); + VerifyAndPrintGraph(&graph, "Typed"); } // All new nodes must be typed. typer.DecorateGraph(&graph); @@ -202,42 +258,80 @@ Handle<Code> Pipeline::GenerateCode() { // Lower JSOperators where we can determine types. PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH, "typed lowering"); - JSTypedLowering lowering(&jsgraph, &source_positions); - lowering.LowerAllNodes(); + SourcePositionTable::Scope pos(&source_positions, + SourcePosition::Unknown()); + JSTypedLowering lowering(&jsgraph); + GraphReducer graph_reducer(&graph); + graph_reducer.AddReducer(&lowering); + graph_reducer.ReduceGraph(); VerifyAndPrintGraph(&graph, "Lowered typed"); } - } - - Handle<Code> code = Handle<Code>::null(); - if (SupportedTarget()) { { - // Lower any remaining generic JSOperators. + // Lower simplified operators and insert changes. PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH, - "generic lowering"); - MachineOperatorBuilder machine(zone()); - JSGenericLowering lowering(info(), &jsgraph, &machine, &source_positions); + "simplified lowering"); + SourcePositionTable::Scope pos(&source_positions, + SourcePosition::Unknown()); + SimplifiedLowering lowering(&jsgraph); lowering.LowerAllNodes(); - VerifyAndPrintGraph(&graph, "Lowered generic"); + VerifyAndPrintGraph(&graph, "Lowered simplified"); } - - // Compute a schedule. - Schedule* schedule = ComputeSchedule(&graph); - TraceSchedule(schedule); - { - // Generate optimized code. - PhaseStats codegen_stats(info(), PhaseStats::CODEGEN, "codegen"); + // Lower changes that have been inserted before. + PhaseStats lowering_stats(info(), PhaseStats::OPTIMIZATION, + "change lowering"); + SourcePositionTable::Scope pos(&source_positions, + SourcePosition::Unknown()); Linkage linkage(info()); - code = GenerateCode(&linkage, &graph, schedule, &source_positions); - info()->SetCode(code); + // TODO(turbofan): Value numbering disabled for now. + // ValueNumberingReducer vn_reducer(zone()); + SimplifiedOperatorReducer simple_reducer(&jsgraph); + ChangeLowering lowering(&jsgraph, &linkage); + MachineOperatorReducer mach_reducer(&jsgraph); + GraphReducer graph_reducer(&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(); + + VerifyAndPrintGraph(&graph, "Lowered changes"); } + } + + { + // Lower any remaining generic JSOperators. + PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH, + "generic lowering"); + SourcePositionTable::Scope pos(&source_positions, + SourcePosition::Unknown()); + JSGenericLowering lowering(info(), &jsgraph); + GraphReducer graph_reducer(&graph); + graph_reducer.AddReducer(&lowering); + graph_reducer.ReduceGraph(); - // Print optimized code. - v8::internal::CodeGenerator::PrintCode(code, info()); + VerifyAndPrintGraph(&graph, "Lowered generic"); } + source_positions.RemoveDecorator(); + + Handle<Code> code = Handle<Code>::null(); + { + // Compute a schedule. + Schedule* schedule = ComputeSchedule(&graph); + // Generate optimized code. + PhaseStats codegen_stats(info(), PhaseStats::CODEGEN, "codegen"); + Linkage linkage(info()); + code = GenerateCode(&linkage, &graph, schedule, &source_positions); + info()->SetCode(code); + } + + // Print optimized code. + v8::internal::CodeGenerator::PrintCode(code, info()); + if (FLAG_trace_turbo) { OFStream os(stdout); os << "--------------------------------------------------\n" @@ -252,7 +346,10 @@ Handle<Code> Pipeline::GenerateCode() { Schedule* Pipeline::ComputeSchedule(Graph* graph) { PhaseStats schedule_stats(info(), PhaseStats::CODEGEN, "scheduling"); - return Scheduler::ComputeSchedule(graph); + Schedule* schedule = Scheduler::ComputeSchedule(graph); + TraceSchedule(schedule); + if (VerifyGraphs()) ScheduleVerifier::Run(schedule); + return schedule; } @@ -287,6 +384,11 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, Graph* graph, DCHECK_NOT_NULL(schedule); CHECK(SupportedBackend()); + BasicBlockProfiler::Data* profiler_data = NULL; + if (FLAG_turbo_profiling) { + profiler_data = BasicBlockInstrumentor::Instrument(info_, graph, schedule); + } + InstructionSequence sequence(linkage, graph, schedule); // Select and schedule instructions covering the scheduled graph. @@ -305,12 +407,12 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, Graph* graph, { int node_count = graph->NodeCount(); if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { - linkage->info()->set_bailout_reason(kNotEnoughVirtualRegistersForValues); + linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); return Handle<Code>::null(); } RegisterAllocator allocator(&sequence); if (!allocator.Allocate()) { - linkage->info()->set_bailout_reason(kNotEnoughVirtualRegistersRegalloc); + linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); return Handle<Code>::null(); } } @@ -323,7 +425,15 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, Graph* graph, // Generate native sequence. CodeGenerator generator(&sequence); - return generator.GenerateCode(); + Handle<Code> code = generator.GenerateCode(); + if (profiler_data != NULL) { +#if ENABLE_DISASSEMBLER + OStringStream os; + code->Disassemble(NULL, os); + profiler_data->SetCode(&os); +#endif + } + return code; } |