diff options
Diffstat (limited to 'deps/v8/src/compiler/pipeline.cc')
-rw-r--r-- | deps/v8/src/compiler/pipeline.cc | 204 |
1 files changed, 122 insertions, 82 deletions
diff --git a/deps/v8/src/compiler/pipeline.cc b/deps/v8/src/compiler/pipeline.cc index ceff8d660b..4d6aacd78a 100644 --- a/deps/v8/src/compiler/pipeline.cc +++ b/deps/v8/src/compiler/pipeline.cc @@ -12,7 +12,6 @@ #include "src/compiler/ast-graph-builder.h" #include "src/compiler/ast-loop-assignment-analyzer.h" #include "src/compiler/basic-block-instrumentor.h" -#include "src/compiler/binary-operator-reducer.h" #include "src/compiler/branch-elimination.h" #include "src/compiler/bytecode-graph-builder.h" #include "src/compiler/change-lowering.h" @@ -20,6 +19,8 @@ #include "src/compiler/common-operator-reducer.h" #include "src/compiler/control-flow-optimizer.h" #include "src/compiler/dead-code-elimination.h" +#include "src/compiler/escape-analysis.h" +#include "src/compiler/escape-analysis-reducer.h" #include "src/compiler/frame-elider.h" #include "src/compiler/graph-replay.h" #include "src/compiler/graph-trimmer.h" @@ -28,6 +29,7 @@ #include "src/compiler/instruction.h" #include "src/compiler/instruction-selector.h" #include "src/compiler/js-builtin-reducer.h" +#include "src/compiler/js-call-reducer.h" #include "src/compiler/js-context-relaxation.h" #include "src/compiler/js-context-specialization.h" #include "src/compiler/js-frame-specialization.h" @@ -55,6 +57,7 @@ #include "src/compiler/simplified-operator.h" #include "src/compiler/simplified-operator-reducer.h" #include "src/compiler/tail-call-optimization.h" +#include "src/compiler/type-hint-analyzer.h" #include "src/compiler/typer.h" #include "src/compiler/value-numbering-reducer.h" #include "src/compiler/verifier.h" @@ -102,7 +105,7 @@ class PipelineData { source_positions_.Reset(new SourcePositionTable(graph_)); simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_); machine_ = new (graph_zone_) MachineOperatorBuilder( - graph_zone_, kMachPtr, + graph_zone_, MachineType::PointerRepresentation(), InstructionSelector::SupportedMachineOperatorFlags()); common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); @@ -197,6 +200,12 @@ class PipelineData { CommonOperatorBuilder* common() const { return common_; } JSOperatorBuilder* javascript() const { return javascript_; } JSGraph* jsgraph() const { return jsgraph_; } + MaybeHandle<Context> native_context() const { + if (info()->is_native_context_specializing()) { + return handle(info()->native_context(), isolate()); + } + return MaybeHandle<Context>(); + } LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; } void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) { @@ -204,6 +213,12 @@ class PipelineData { loop_assignment_ = loop_assignment; } + TypeHintAnalysis* type_hint_analysis() const { return type_hint_analysis_; } + void set_type_hint_analysis(TypeHintAnalysis* type_hint_analysis) { + DCHECK_NULL(type_hint_analysis_); + type_hint_analysis_ = type_hint_analysis; + } + Schedule* schedule() const { return schedule_; } void set_schedule(Schedule* schedule) { DCHECK(!schedule_); @@ -228,6 +243,7 @@ class PipelineData { graph_zone_ = nullptr; graph_ = nullptr; loop_assignment_ = nullptr; + type_hint_analysis_ = nullptr; simplified_ = nullptr; machine_ = nullptr; common_ = nullptr; @@ -267,12 +283,12 @@ class PipelineData { DCHECK(register_allocation_data_ == nullptr); int fixed_frame_size = 0; if (descriptor != nullptr) { - fixed_frame_size = (descriptor->kind() == CallDescriptor::kCallAddress) + fixed_frame_size = (descriptor->IsCFunctionCall()) ? StandardFrameConstants::kFixedSlotCountAboveFp + StandardFrameConstants::kCPSlotCount : StandardFrameConstants::kFixedSlotCount; } - frame_ = new (instruction_zone()) Frame(fixed_frame_size); + frame_ = new (instruction_zone()) Frame(fixed_frame_size, descriptor); register_allocation_data_ = new (register_allocation_zone()) RegisterAllocationData(config, register_allocation_zone(), frame(), sequence(), debug_name); @@ -288,13 +304,14 @@ class PipelineData { Handle<Code> code_; // All objects in the following group of fields are allocated in graph_zone_. - // They are all set to NULL when the graph_zone_ is destroyed. + // They are all set to nullptr when the graph_zone_ is destroyed. ZonePool::Scope graph_zone_scope_; Zone* graph_zone_; Graph* graph_; // TODO(dcarney): make this into a ZoneObject. base::SmartPointer<SourcePositionTable> source_positions_; LoopAssignmentAnalysis* loop_assignment_; + TypeHintAnalysis* type_hint_analysis_ = nullptr; SimplifiedOperatorBuilder* simplified_; MachineOperatorBuilder* machine_; CommonOperatorBuilder* common_; @@ -303,7 +320,8 @@ class PipelineData { Schedule* schedule_; // All objects in the following group of fields are allocated in - // instruction_zone_. They are all set to NULL when the instruction_zone_ is + // instruction_zone_. They are all set to nullptr when the instruction_zone_ + // is // destroyed. ZonePool::Scope instruction_zone_scope_; Zone* instruction_zone_; @@ -311,7 +329,7 @@ class PipelineData { Frame* frame_; // All objects in the following group of fields are allocated in - // register_allocation_zone_. They are all set to NULL when the zone is + // register_allocation_zone_. They are all set to nullptr when the zone is // destroyed. ZonePool::Scope register_allocation_zone_scope_; Zone* register_allocation_zone_; @@ -332,7 +350,7 @@ struct TurboCfgFile : public std::ofstream { void TraceSchedule(CompilationInfo* info, Schedule* schedule) { if (FLAG_trace_turbo) { - FILE* json_file = OpenVisualizerLogFile(info, NULL, "json", "a+"); + FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+"); if (json_file != nullptr) { OFStream json_of(json_file); json_of << "{\"name\":\"Schedule\",\"type\":\"schedule\",\"data\":\""; @@ -357,8 +375,10 @@ class AstGraphBuilderWithPositions final : public AstGraphBuilder { AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, LoopAssignmentAnalysis* loop_assignment, + TypeHintAnalysis* type_hint_analysis, SourcePositionTable* source_positions) - : AstGraphBuilder(local_zone, info, jsgraph, loop_assignment), + : AstGraphBuilder(local_zone, info, jsgraph, loop_assignment, + type_hint_analysis), source_positions_(source_positions), start_position_(info->shared_info()->start_position()) {} @@ -470,6 +490,18 @@ struct LoopAssignmentAnalysisPhase { }; +struct TypeHintAnalysisPhase { + static const char* phase_name() { return "type hint analysis"; } + + void Run(PipelineData* data, Zone* temp_zone) { + TypeHintAnalyzer analyzer(data->graph_zone()); + Handle<Code> code(data->info()->shared_info()->code(), data->isolate()); + TypeHintAnalysis* type_hint_analysis = analyzer.Analyze(code); + data->set_type_hint_analysis(type_hint_analysis); + } +}; + + struct GraphBuilderPhase { static const char* phase_name() { return "graph builder"; } @@ -484,7 +516,7 @@ struct GraphBuilderPhase { } else { AstGraphBuilderWithPositions graph_builder( temp_zone, data->info(), data->jsgraph(), data->loop_assignment(), - data->source_positions()); + data->type_hint_analysis(), data->source_positions()); succeeded = graph_builder.CreateGraph(stack_check); } @@ -495,8 +527,8 @@ struct GraphBuilderPhase { }; -struct NativeContextSpecializationPhase { - static const char* phase_name() { return "native context specialization"; } +struct InliningPhase { + static const char* phase_name() { return "inlining"; } void Run(PipelineData* data, Zone* temp_zone) { JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); @@ -504,46 +536,30 @@ struct NativeContextSpecializationPhase { data->common()); CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), data->common(), data->machine()); + JSCallReducer call_reducer(data->jsgraph(), + data->info()->is_deoptimization_enabled() + ? JSCallReducer::kDeoptimizationEnabled + : JSCallReducer::kNoFlags, + data->native_context()); + JSContextSpecialization context_specialization( + &graph_reducer, data->jsgraph(), + data->info()->is_function_context_specializing() + ? data->info()->context() + : MaybeHandle<Context>()); + JSFrameSpecialization frame_specialization(data->info()->osr_frame(), + data->jsgraph()); JSGlobalObjectSpecialization global_object_specialization( &graph_reducer, data->jsgraph(), data->info()->is_deoptimization_enabled() ? JSGlobalObjectSpecialization::kDeoptimizationEnabled : JSGlobalObjectSpecialization::kNoFlags, - handle(data->info()->global_object(), data->isolate()), - data->info()->dependencies()); + data->native_context(), data->info()->dependencies()); JSNativeContextSpecialization native_context_specialization( &graph_reducer, data->jsgraph(), data->info()->is_deoptimization_enabled() ? JSNativeContextSpecialization::kDeoptimizationEnabled : JSNativeContextSpecialization::kNoFlags, - handle(data->info()->global_object()->native_context(), - data->isolate()), - data->info()->dependencies(), temp_zone); - AddReducer(data, &graph_reducer, &dead_code_elimination); - AddReducer(data, &graph_reducer, &common_reducer); - AddReducer(data, &graph_reducer, &global_object_specialization); - AddReducer(data, &graph_reducer, &native_context_specialization); - graph_reducer.ReduceGraph(); - } -}; - - -struct InliningPhase { - static const char* phase_name() { return "inlining"; } - - void Run(PipelineData* data, Zone* temp_zone) { - JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); - DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(), - data->common()); - CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), - data->common(), data->machine()); - JSContextSpecialization context_specialization( - &graph_reducer, data->jsgraph(), - data->info()->is_function_context_specializing() - ? data->info()->context() - : MaybeHandle<Context>()); - JSFrameSpecialization frame_specialization(data->info()->osr_frame(), - data->jsgraph()); + data->native_context(), data->info()->dependencies(), temp_zone); JSInliningHeuristic inlining(&graph_reducer, data->info()->is_inlining_enabled() ? JSInliningHeuristic::kGeneralInlining @@ -554,7 +570,10 @@ struct InliningPhase { if (data->info()->is_frame_specializing()) { AddReducer(data, &graph_reducer, &frame_specialization); } + AddReducer(data, &graph_reducer, &global_object_specialization); + AddReducer(data, &graph_reducer, &native_context_specialization); AddReducer(data, &graph_reducer, &context_specialization); + AddReducer(data, &graph_reducer, &call_reducer); AddReducer(data, &graph_reducer, &inlining); graph_reducer.ReduceGraph(); } @@ -591,11 +610,16 @@ struct TypedLoweringPhase { data->common()); LoadElimination load_elimination(&graph_reducer); JSBuiltinReducer builtin_reducer(&graph_reducer, data->jsgraph()); + JSTypedLowering::Flags typed_lowering_flags = JSTypedLowering::kNoFlags; + if (data->info()->is_deoptimization_enabled()) { + typed_lowering_flags |= JSTypedLowering::kDeoptimizationEnabled; + } + if (data->info()->shared_info()->HasBytecodeArray()) { + typed_lowering_flags |= JSTypedLowering::kDisableBinaryOpReduction; + } JSTypedLowering typed_lowering(&graph_reducer, data->info()->dependencies(), - data->info()->is_deoptimization_enabled() - ? JSTypedLowering::kDeoptimizationEnabled - : JSTypedLowering::kNoFlags, - data->jsgraph(), temp_zone); + typed_lowering_flags, data->jsgraph(), + temp_zone); JSIntrinsicLowering intrinsic_lowering( &graph_reducer, data->jsgraph(), data->info()->is_deoptimization_enabled() @@ -630,6 +654,22 @@ struct BranchEliminationPhase { }; +struct EscapeAnalysisPhase { + static const char* phase_name() { return "escape analysis"; } + + void Run(PipelineData* data, Zone* temp_zone) { + EscapeAnalysis escape_analysis(data->graph(), data->jsgraph()->common(), + temp_zone); + escape_analysis.Run(); + JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); + EscapeAnalysisReducer escape_reducer(&graph_reducer, data->jsgraph(), + &escape_analysis, temp_zone); + AddReducer(data, &graph_reducer, &escape_reducer); + graph_reducer.ReduceGraph(); + } +}; + + struct SimplifiedLoweringPhase { static const char* phase_name() { return "simplified lowering"; } @@ -645,14 +685,11 @@ struct SimplifiedLoweringPhase { MachineOperatorReducer machine_reducer(data->jsgraph()); CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), data->common(), data->machine()); - BinaryOperatorReducer binary_reducer(&graph_reducer, data->graph(), - data->common(), data->machine()); AddReducer(data, &graph_reducer, &dead_code_elimination); AddReducer(data, &graph_reducer, &simple_reducer); AddReducer(data, &graph_reducer, &value_numbering); AddReducer(data, &graph_reducer, &machine_reducer); AddReducer(data, &graph_reducer, &common_reducer); - AddReducer(data, &graph_reducer, &binary_reducer); graph_reducer.ReduceGraph(); } }; @@ -722,7 +759,7 @@ struct StressLoopPeelingPhase { // Peel the first outer loop for testing. // TODO(titzer): peel all loops? the N'th loop? Innermost loops? LoopTree* loop_tree = LoopFinder::BuildLoopTree(data->graph(), temp_zone); - if (loop_tree != NULL && loop_tree->outer_loops().size() > 0) { + if (loop_tree != nullptr && loop_tree->outer_loops().size() > 0) { LoopPeeler::Peel(data->graph(), data->common(), loop_tree, loop_tree->outer_loops()[0], temp_zone); } @@ -969,16 +1006,8 @@ struct PrintGraphPhase { CompilationInfo* info = data->info(); Graph* graph = data->graph(); - { // Print dot. - FILE* dot_file = OpenVisualizerLogFile(info, phase, "dot", "w+"); - if (dot_file == nullptr) return; - OFStream dot_of(dot_file); - dot_of << AsDOT(*graph); - fclose(dot_file); - } - { // Print JSON. - FILE* json_file = OpenVisualizerLogFile(info, NULL, "json", "a+"); + FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+"); if (json_file == nullptr) return; OFStream json_of(json_file); json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":" @@ -1007,7 +1036,7 @@ struct VerifyGraphPhase { void Pipeline::BeginPhaseKind(const char* phase_kind_name) { - if (data_->pipeline_statistics() != NULL) { + if (data_->pipeline_statistics() != nullptr) { data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); } } @@ -1040,7 +1069,7 @@ Handle<Code> Pipeline::GenerateCode() { } if (FLAG_trace_turbo) { - FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "w+"); + FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "w+"); if (json_file != nullptr) { OFStream json_of(json_file); Handle<Script> script = info()->script(); @@ -1084,6 +1113,10 @@ Handle<Code> Pipeline::GenerateCode() { Run<LoopAssignmentAnalysisPhase>(); } + if (info()->is_typing_enabled()) { + Run<TypeHintAnalysisPhase>(); + } + Run<GraphBuilderPhase>(); if (data.compilation_failed()) return Handle<Code>::null(); RunPrintAndVerify("Initial untyped", true); @@ -1094,12 +1127,6 @@ Handle<Code> Pipeline::GenerateCode() { RunPrintAndVerify("OSR deconstruction", true); } - // Perform native context specialization (if enabled). - if (info()->is_native_context_specializing()) { - Run<NativeContextSpecializationPhase>(); - RunPrintAndVerify("Native context specialized", true); - } - // Perform function context specialization and inlining (if enabled). Run<InliningPhase>(); RunPrintAndVerify("Inlined", true); @@ -1120,7 +1147,7 @@ Handle<Code> Pipeline::GenerateCode() { info()->is_deoptimization_enabled() ? Typer::kDeoptimizationEnabled : Typer::kNoFlags, - info()->dependencies(), info()->function_type())); + info()->dependencies())); Run<TyperPhase>(typer.get()); RunPrintAndVerify("Typed"); } @@ -1137,6 +1164,11 @@ Handle<Code> Pipeline::GenerateCode() { RunPrintAndVerify("Loop peeled"); } + if (FLAG_turbo_escape) { + Run<EscapeAnalysisPhase>(); + RunPrintAndVerify("Escape Analysed"); + } + // Lower simplified operators and insert changes. Run<SimplifiedLoweringPhase>(); RunPrintAndVerify("Lowered simplified"); @@ -1177,10 +1209,13 @@ Handle<Code> Pipeline::GenerateCode() { } -Handle<Code> Pipeline::GenerateCodeForInterpreter( - Isolate* isolate, CallDescriptor* call_descriptor, Graph* graph, - Schedule* schedule, const char* bytecode_name) { - CompilationInfo info(bytecode_name, isolate, graph->zone()); +Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, + CallDescriptor* call_descriptor, + Graph* graph, Schedule* schedule, + Code::Kind kind, + const char* debug_name) { + CompilationInfo info(debug_name, isolate, graph->zone()); + info.set_output_code_kind(kind); // Construct a pipeline for scheduling and code generation. ZonePool zone_pool; @@ -1188,21 +1223,24 @@ Handle<Code> Pipeline::GenerateCodeForInterpreter( base::SmartPointer<PipelineStatistics> pipeline_statistics; if (FLAG_turbo_stats) { pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool)); - pipeline_statistics->BeginPhaseKind("interpreter handler codegen"); + pipeline_statistics->BeginPhaseKind("stub codegen"); } + + Pipeline pipeline(&info); + pipeline.data_ = &data; + DCHECK_NOT_NULL(data.schedule()); + if (FLAG_trace_turbo) { - FILE* json_file = OpenVisualizerLogFile(&info, NULL, "json", "w+"); + FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+"); if (json_file != nullptr) { OFStream json_of(json_file); json_of << "{\"function\":\"" << info.GetDebugName().get() << "\", \"source\":\"\",\n\"phases\":["; fclose(json_file); } + pipeline.Run<PrintGraphPhase>("Machine"); } - Pipeline pipeline(&info); - pipeline.data_ = &data; - pipeline.RunPrintAndVerify("Machine", true); return pipeline.ScheduleAndGenerateCode(call_descriptor); } @@ -1262,7 +1300,7 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode( if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); TraceSchedule(data->info(), data->schedule()); - BasicBlockProfiler::Data* profiler_data = NULL; + BasicBlockProfiler::Data* profiler_data = nullptr; if (FLAG_turbo_profiling) { profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), data->schedule()); @@ -1311,10 +1349,10 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode( Run<GenerateCodePhase>(&linkage); Handle<Code> code = data->code(); - if (profiler_data != NULL) { + if (profiler_data != nullptr) { #if ENABLE_DISASSEMBLER std::ostringstream os; - code->Disassemble(NULL, os); + code->Disassemble(nullptr, os); profiler_data->SetCode(&os); #endif } @@ -1323,14 +1361,14 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode( v8::internal::CodeGenerator::PrintCode(code, info()); if (FLAG_trace_turbo) { - FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "a+"); + FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+"); if (json_file != nullptr) { OFStream json_of(json_file); json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; #if ENABLE_DISASSEMBLER std::stringstream disassembly_stream; - code->Disassemble(NULL, disassembly_stream); + code->Disassemble(nullptr, disassembly_stream); std::string disassembly_string(disassembly_stream.str()); for (const auto& c : disassembly_string) { json_of << AsEscapedUC16ForJSON(c); @@ -1388,6 +1426,8 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config, } if (verifier != nullptr) { CHECK(!data->register_allocation_data()->ExistsUseWithoutDefinition()); + CHECK(data->register_allocation_data() + ->RangesDefinedInDeferredStayInDeferred()); } if (FLAG_turbo_preprocess_ranges) { |