| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/pipeline.h" | 5 #include "src/compiler/pipeline.h" |
| 6 | 6 |
| 7 #include <fstream> // NOLINT(readability/streams) | 7 #include <fstream> // NOLINT(readability/streams) |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 source_positions_ = new (graph_zone_) SourcePositionTable(graph_); | 104 source_positions_ = new (graph_zone_) SourcePositionTable(graph_); |
| 105 simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_); | 105 simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_); |
| 106 machine_ = new (graph_zone_) MachineOperatorBuilder( | 106 machine_ = new (graph_zone_) MachineOperatorBuilder( |
| 107 graph_zone_, MachineType::PointerRepresentation(), | 107 graph_zone_, MachineType::PointerRepresentation(), |
| 108 InstructionSelector::SupportedMachineOperatorFlags(), | 108 InstructionSelector::SupportedMachineOperatorFlags(), |
| 109 InstructionSelector::AlignmentRequirements()); | 109 InstructionSelector::AlignmentRequirements()); |
| 110 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); | 110 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); |
| 111 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); | 111 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); |
| 112 jsgraph_ = new (graph_zone_) | 112 jsgraph_ = new (graph_zone_) |
| 113 JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_); | 113 JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_); |
| 114 is_asm_ = info->shared_info()->asm_function(); |
| 114 } | 115 } |
| 115 | 116 |
| 116 // For WASM compile entry point. | 117 // For WASM compile entry point. |
| 117 PipelineData(ZoneStats* zone_stats, CompilationInfo* info, JSGraph* jsgraph, | 118 PipelineData(ZoneStats* zone_stats, CompilationInfo* info, JSGraph* jsgraph, |
| 118 SourcePositionTable* source_positions, | 119 SourcePositionTable* source_positions, |
| 119 ZoneVector<trap_handler::ProtectedInstructionData>* | 120 ZoneVector<trap_handler::ProtectedInstructionData>* |
| 120 protected_instructions) | 121 protected_instructions) |
| 121 : isolate_(info->isolate()), | 122 : isolate_(info->isolate()), |
| 122 info_(info), | 123 info_(info), |
| 123 debug_name_(info_->GetDebugName()), | 124 debug_name_(info_->GetDebugName()), |
| 124 zone_stats_(zone_stats), | 125 zone_stats_(zone_stats), |
| 125 graph_zone_scope_(zone_stats_, ZONE_NAME), | 126 graph_zone_scope_(zone_stats_, ZONE_NAME), |
| 126 graph_(jsgraph->graph()), | 127 graph_(jsgraph->graph()), |
| 127 source_positions_(source_positions), | 128 source_positions_(source_positions), |
| 128 machine_(jsgraph->machine()), | 129 machine_(jsgraph->machine()), |
| 129 common_(jsgraph->common()), | 130 common_(jsgraph->common()), |
| 130 javascript_(jsgraph->javascript()), | 131 javascript_(jsgraph->javascript()), |
| 131 jsgraph_(jsgraph), | 132 jsgraph_(jsgraph), |
| 132 instruction_zone_scope_(zone_stats_, ZONE_NAME), | 133 instruction_zone_scope_(zone_stats_, ZONE_NAME), |
| 133 instruction_zone_(instruction_zone_scope_.zone()), | 134 instruction_zone_(instruction_zone_scope_.zone()), |
| 134 register_allocation_zone_scope_(zone_stats_, ZONE_NAME), | 135 register_allocation_zone_scope_(zone_stats_, ZONE_NAME), |
| 135 register_allocation_zone_(register_allocation_zone_scope_.zone()), | 136 register_allocation_zone_(register_allocation_zone_scope_.zone()), |
| 136 protected_instructions_(protected_instructions) {} | 137 protected_instructions_(protected_instructions) { |
| 138 is_asm_ = |
| 139 info->has_shared_info() ? info->shared_info()->asm_function() : false; |
| 140 } |
| 137 | 141 |
| 138 // For machine graph testing entry point. | 142 // For machine graph testing entry point. |
| 139 PipelineData(ZoneStats* zone_stats, CompilationInfo* info, Graph* graph, | 143 PipelineData(ZoneStats* zone_stats, CompilationInfo* info, Graph* graph, |
| 140 Schedule* schedule, SourcePositionTable* source_positions) | 144 Schedule* schedule, SourcePositionTable* source_positions) |
| 141 : isolate_(info->isolate()), | 145 : isolate_(info->isolate()), |
| 142 info_(info), | 146 info_(info), |
| 143 debug_name_(info_->GetDebugName()), | 147 debug_name_(info_->GetDebugName()), |
| 144 zone_stats_(zone_stats), | 148 zone_stats_(zone_stats), |
| 145 graph_zone_scope_(zone_stats_, ZONE_NAME), | 149 graph_zone_scope_(zone_stats_, ZONE_NAME), |
| 146 graph_(graph), | 150 graph_(graph), |
| 147 source_positions_(source_positions), | 151 source_positions_(source_positions), |
| 148 schedule_(schedule), | 152 schedule_(schedule), |
| 149 instruction_zone_scope_(zone_stats_, ZONE_NAME), | 153 instruction_zone_scope_(zone_stats_, ZONE_NAME), |
| 150 instruction_zone_(instruction_zone_scope_.zone()), | 154 instruction_zone_(instruction_zone_scope_.zone()), |
| 151 register_allocation_zone_scope_(zone_stats_, ZONE_NAME), | 155 register_allocation_zone_scope_(zone_stats_, ZONE_NAME), |
| 152 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} | 156 register_allocation_zone_(register_allocation_zone_scope_.zone()) { |
| 153 | 157 is_asm_ = false; |
| 158 } |
| 154 // For register allocation testing entry point. | 159 // For register allocation testing entry point. |
| 155 PipelineData(ZoneStats* zone_stats, CompilationInfo* info, | 160 PipelineData(ZoneStats* zone_stats, CompilationInfo* info, |
| 156 InstructionSequence* sequence) | 161 InstructionSequence* sequence) |
| 157 : isolate_(info->isolate()), | 162 : isolate_(info->isolate()), |
| 158 info_(info), | 163 info_(info), |
| 159 debug_name_(info_->GetDebugName()), | 164 debug_name_(info_->GetDebugName()), |
| 160 zone_stats_(zone_stats), | 165 zone_stats_(zone_stats), |
| 161 graph_zone_scope_(zone_stats_, ZONE_NAME), | 166 graph_zone_scope_(zone_stats_, ZONE_NAME), |
| 162 instruction_zone_scope_(zone_stats_, ZONE_NAME), | 167 instruction_zone_scope_(zone_stats_, ZONE_NAME), |
| 163 instruction_zone_(sequence->zone()), | 168 instruction_zone_(sequence->zone()), |
| 164 sequence_(sequence), | 169 sequence_(sequence), |
| 165 register_allocation_zone_scope_(zone_stats_, ZONE_NAME), | 170 register_allocation_zone_scope_(zone_stats_, ZONE_NAME), |
| 166 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} | 171 register_allocation_zone_(register_allocation_zone_scope_.zone()) { |
| 172 is_asm_ = |
| 173 info->has_shared_info() ? info->shared_info()->asm_function() : false; |
| 174 } |
| 167 | 175 |
| 168 ~PipelineData() { | 176 ~PipelineData() { |
| 169 DeleteRegisterAllocationZone(); | 177 DeleteRegisterAllocationZone(); |
| 170 DeleteInstructionZone(); | 178 DeleteInstructionZone(); |
| 171 DeleteGraphZone(); | 179 DeleteGraphZone(); |
| 172 } | 180 } |
| 173 | 181 |
| 174 Isolate* isolate() const { return isolate_; } | 182 Isolate* isolate() const { return isolate_; } |
| 175 CompilationInfo* info() const { return info_; } | 183 CompilationInfo* info() const { return info_; } |
| 176 ZoneStats* zone_stats() const { return zone_stats_; } | 184 ZoneStats* zone_stats() const { return zone_stats_; } |
| 177 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } | 185 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } |
| 178 bool compilation_failed() const { return compilation_failed_; } | 186 bool compilation_failed() const { return compilation_failed_; } |
| 179 void set_compilation_failed() { compilation_failed_ = true; } | 187 void set_compilation_failed() { compilation_failed_ = true; } |
| 180 | 188 |
| 189 bool is_asm() const { return is_asm_; } |
| 181 bool verify_graph() const { return verify_graph_; } | 190 bool verify_graph() const { return verify_graph_; } |
| 182 void set_verify_graph(bool value) { verify_graph_ = value; } | 191 void set_verify_graph(bool value) { verify_graph_ = value; } |
| 183 | 192 |
| 184 Handle<Code> code() { return code_; } | 193 Handle<Code> code() { return code_; } |
| 185 void set_code(Handle<Code> code) { | 194 void set_code(Handle<Code> code) { |
| 186 DCHECK(code_.is_null()); | 195 DCHECK(code_.is_null()); |
| 187 code_ = code; | 196 code_ = code; |
| 188 } | 197 } |
| 189 | 198 |
| 190 // RawMachineAssembler generally produces graphs which cannot be verified. | 199 // RawMachineAssembler generally produces graphs which cannot be verified. |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 | 330 |
| 322 private: | 331 private: |
| 323 Isolate* const isolate_; | 332 Isolate* const isolate_; |
| 324 CompilationInfo* const info_; | 333 CompilationInfo* const info_; |
| 325 std::unique_ptr<char[]> debug_name_; | 334 std::unique_ptr<char[]> debug_name_; |
| 326 Zone* outer_zone_ = nullptr; | 335 Zone* outer_zone_ = nullptr; |
| 327 ZoneStats* const zone_stats_; | 336 ZoneStats* const zone_stats_; |
| 328 PipelineStatistics* pipeline_statistics_ = nullptr; | 337 PipelineStatistics* pipeline_statistics_ = nullptr; |
| 329 bool compilation_failed_ = false; | 338 bool compilation_failed_ = false; |
| 330 bool verify_graph_ = false; | 339 bool verify_graph_ = false; |
| 340 bool is_asm_ = false; |
| 331 Handle<Code> code_ = Handle<Code>::null(); | 341 Handle<Code> code_ = Handle<Code>::null(); |
| 332 | 342 |
| 333 // All objects in the following group of fields are allocated in graph_zone_. | 343 // All objects in the following group of fields are allocated in graph_zone_. |
| 334 // They are all set to nullptr when the graph_zone_ is destroyed. | 344 // They are all set to nullptr when the graph_zone_ is destroyed. |
| 335 ZoneStats::Scope graph_zone_scope_; | 345 ZoneStats::Scope graph_zone_scope_; |
| 336 Zone* graph_zone_ = nullptr; | 346 Zone* graph_zone_ = nullptr; |
| 337 Graph* graph_ = nullptr; | 347 Graph* graph_ = nullptr; |
| 338 SourcePositionTable* source_positions_ = nullptr; | 348 SourcePositionTable* source_positions_ = nullptr; |
| 339 LoopAssignmentAnalysis* loop_assignment_ = nullptr; | 349 LoopAssignmentAnalysis* loop_assignment_ = nullptr; |
| 340 SimplifiedOperatorBuilder* simplified_ = nullptr; | 350 SimplifiedOperatorBuilder* simplified_ = nullptr; |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 }; | 982 }; |
| 973 | 983 |
| 974 struct LoopExitEliminationPhase { | 984 struct LoopExitEliminationPhase { |
| 975 static const char* phase_name() { return "loop exit elimination"; } | 985 static const char* phase_name() { return "loop exit elimination"; } |
| 976 | 986 |
| 977 void Run(PipelineData* data, Zone* temp_zone) { | 987 void Run(PipelineData* data, Zone* temp_zone) { |
| 978 LoopPeeler::EliminateLoopExits(data->graph(), temp_zone); | 988 LoopPeeler::EliminateLoopExits(data->graph(), temp_zone); |
| 979 } | 989 } |
| 980 }; | 990 }; |
| 981 | 991 |
| 982 struct GenericLoweringPrepPhase { | 992 struct ConcurrentOptimizationPrepPhase { |
| 983 static const char* phase_name() { return "generic lowering prep"; } | 993 static const char* phase_name() { |
| 994 return "concurrent optimization preparation"; |
| 995 } |
| 984 | 996 |
| 985 void Run(PipelineData* data, Zone* temp_zone) { | 997 void Run(PipelineData* data, Zone* temp_zone) { |
| 986 // Make sure we cache these code stubs. | 998 // Make sure we cache these code stubs. |
| 987 data->jsgraph()->CEntryStubConstant(1); | 999 data->jsgraph()->CEntryStubConstant(1); |
| 988 data->jsgraph()->CEntryStubConstant(2); | 1000 data->jsgraph()->CEntryStubConstant(2); |
| 989 data->jsgraph()->CEntryStubConstant(3); | 1001 data->jsgraph()->CEntryStubConstant(3); |
| 1002 |
| 1003 // This is needed for escape analysis. |
| 1004 NodeProperties::SetType(data->jsgraph()->FalseConstant(), Type::Boolean()); |
| 1005 NodeProperties::SetType(data->jsgraph()->TrueConstant(), Type::Boolean()); |
| 990 } | 1006 } |
| 991 }; | 1007 }; |
| 992 | 1008 |
| 993 struct GenericLoweringPhase { | 1009 struct GenericLoweringPhase { |
| 994 static const char* phase_name() { return "generic lowering"; } | 1010 static const char* phase_name() { return "generic lowering"; } |
| 995 | 1011 |
| 996 void Run(PipelineData* data, Zone* temp_zone) { | 1012 void Run(PipelineData* data, Zone* temp_zone) { |
| 997 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); | 1013 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); |
| 998 JSGenericLowering generic_lowering(data->jsgraph()); | 1014 JSGenericLowering generic_lowering(data->jsgraph()); |
| 999 AddReducer(data, &graph_reducer, &generic_lowering); | 1015 AddReducer(data, &graph_reducer, &generic_lowering); |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1533 } else { | 1549 } else { |
| 1534 Run<LoopExitEliminationPhase>(); | 1550 Run<LoopExitEliminationPhase>(); |
| 1535 RunPrintAndVerify("Loop exits eliminated", true); | 1551 RunPrintAndVerify("Loop exits eliminated", true); |
| 1536 } | 1552 } |
| 1537 | 1553 |
| 1538 if (!info()->shared_info()->asm_function()) { | 1554 if (!info()->shared_info()->asm_function()) { |
| 1539 if (FLAG_turbo_load_elimination) { | 1555 if (FLAG_turbo_load_elimination) { |
| 1540 Run<LoadEliminationPhase>(); | 1556 Run<LoadEliminationPhase>(); |
| 1541 RunPrintAndVerify("Load eliminated"); | 1557 RunPrintAndVerify("Load eliminated"); |
| 1542 } | 1558 } |
| 1543 | |
| 1544 if (FLAG_turbo_escape) { | |
| 1545 Run<EscapeAnalysisPhase>(); | |
| 1546 if (data->compilation_failed()) { | |
| 1547 info()->AbortOptimization(kCyclicObjectStateDetectedInEscapeAnalysis); | |
| 1548 data->EndPhaseKind(); | |
| 1549 return false; | |
| 1550 } | |
| 1551 RunPrintAndVerify("Escape Analysed"); | |
| 1552 } | |
| 1553 } | 1559 } |
| 1554 } | 1560 } |
| 1555 | 1561 |
| 1556 // Do some hacky things to prepare generic lowering. | 1562 // Do some hacky things to prepare for the optimization phase. |
| 1557 Run<GenericLoweringPrepPhase>(); | 1563 // (caching handles, etc.). |
| 1564 Run<ConcurrentOptimizationPrepPhase>(); |
| 1558 | 1565 |
| 1559 data->EndPhaseKind(); | 1566 data->EndPhaseKind(); |
| 1560 | 1567 |
| 1561 return true; | 1568 return true; |
| 1562 } | 1569 } |
| 1563 | 1570 |
| 1564 bool PipelineImpl::OptimizeGraph(Linkage* linkage) { | 1571 bool PipelineImpl::OptimizeGraph(Linkage* linkage) { |
| 1565 PipelineData* data = this->data_; | 1572 PipelineData* data = this->data_; |
| 1566 | 1573 |
| 1574 if (!data->is_asm()) { |
| 1575 if (FLAG_turbo_escape) { |
| 1576 Run<EscapeAnalysisPhase>(); |
| 1577 if (data->compilation_failed()) { |
| 1578 info()->AbortOptimization(kCyclicObjectStateDetectedInEscapeAnalysis); |
| 1579 data->EndPhaseKind(); |
| 1580 return false; |
| 1581 } |
| 1582 RunPrintAndVerify("Escape Analysed"); |
| 1583 } |
| 1584 } |
| 1585 |
| 1567 // Perform simplified lowering. This has to run w/o the Typer decorator, | 1586 // Perform simplified lowering. This has to run w/o the Typer decorator, |
| 1568 // because we cannot compute meaningful types anyways, and the computed types | 1587 // because we cannot compute meaningful types anyways, and the computed types |
| 1569 // might even conflict with the representation/truncation logic. | 1588 // might even conflict with the representation/truncation logic. |
| 1570 Run<SimplifiedLoweringPhase>(); | 1589 Run<SimplifiedLoweringPhase>(); |
| 1571 RunPrintAndVerify("Simplified lowering", true); | 1590 RunPrintAndVerify("Simplified lowering", true); |
| 1572 | 1591 |
| 1573 #ifdef DEBUG | 1592 #ifdef DEBUG |
| 1574 // From now on it is invalid to look at types on the nodes, because: | 1593 // From now on it is invalid to look at types on the nodes, because: |
| 1575 // | 1594 // |
| 1576 // (a) The remaining passes (might) run concurrent to the main thread and | 1595 // (a) The remaining passes (might) run concurrent to the main thread and |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 data->DeleteRegisterAllocationZone(); | 2012 data->DeleteRegisterAllocationZone(); |
| 1994 } | 2013 } |
| 1995 | 2014 |
| 1996 CompilationInfo* PipelineImpl::info() const { return data_->info(); } | 2015 CompilationInfo* PipelineImpl::info() const { return data_->info(); } |
| 1997 | 2016 |
| 1998 Isolate* PipelineImpl::isolate() const { return info()->isolate(); } | 2017 Isolate* PipelineImpl::isolate() const { return info()->isolate(); } |
| 1999 | 2018 |
| 2000 } // namespace compiler | 2019 } // namespace compiler |
| 2001 } // namespace internal | 2020 } // namespace internal |
| 2002 } // namespace v8 | 2021 } // namespace v8 |
| OLD | NEW |