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 |