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 <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "src/base/adapters.h" | 10 #include "src/base/adapters.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 #include "src/isolate-inl.h" | 66 #include "src/isolate-inl.h" |
67 #include "src/ostreams.h" | 67 #include "src/ostreams.h" |
68 #include "src/register-configuration.h" | 68 #include "src/register-configuration.h" |
69 #include "src/type-info.h" | 69 #include "src/type-info.h" |
70 #include "src/utils.h" | 70 #include "src/utils.h" |
71 | 71 |
72 namespace v8 { | 72 namespace v8 { |
73 namespace internal { | 73 namespace internal { |
74 namespace compiler { | 74 namespace compiler { |
75 | 75 |
76 class PipelineData : public ZoneObject { | 76 class PipelineData { |
77 public: | 77 public: |
78 // For main entry point. | 78 // For main entry point. |
79 PipelineData(ZonePool* zone_pool, CompilationInfo* info, | 79 PipelineData(ZonePool* zone_pool, CompilationInfo* info, |
80 PipelineStatistics* pipeline_statistics) | 80 PipelineStatistics* pipeline_statistics) |
81 : isolate_(info->isolate()), | 81 : isolate_(info->isolate()), |
82 info_(info), | 82 info_(info), |
| 83 debug_name_(info_->GetDebugName()), |
83 outer_zone_(info_->zone()), | 84 outer_zone_(info_->zone()), |
84 zone_pool_(zone_pool), | 85 zone_pool_(zone_pool), |
85 pipeline_statistics_(pipeline_statistics), | 86 pipeline_statistics_(pipeline_statistics), |
86 graph_zone_scope_(zone_pool_), | 87 graph_zone_scope_(zone_pool_), |
87 graph_zone_(graph_zone_scope_.zone()), | 88 graph_zone_(graph_zone_scope_.zone()), |
88 instruction_zone_scope_(zone_pool_), | 89 instruction_zone_scope_(zone_pool_), |
89 instruction_zone_(instruction_zone_scope_.zone()), | 90 instruction_zone_(instruction_zone_scope_.zone()), |
90 register_allocation_zone_scope_(zone_pool_), | 91 register_allocation_zone_scope_(zone_pool_), |
91 register_allocation_zone_(register_allocation_zone_scope_.zone()) { | 92 register_allocation_zone_(register_allocation_zone_scope_.zone()) { |
92 PhaseScope scope(pipeline_statistics, "init pipeline data"); | 93 PhaseScope scope(pipeline_statistics, "init pipeline data"); |
93 graph_ = new (graph_zone_) Graph(graph_zone_); | 94 graph_ = new (graph_zone_) Graph(graph_zone_); |
94 source_positions_ = new (graph_zone_) SourcePositionTable(graph_); | 95 source_positions_ = new (graph_zone_) SourcePositionTable(graph_); |
95 simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_); | 96 simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_); |
96 machine_ = new (graph_zone_) MachineOperatorBuilder( | 97 machine_ = new (graph_zone_) MachineOperatorBuilder( |
97 graph_zone_, MachineType::PointerRepresentation(), | 98 graph_zone_, MachineType::PointerRepresentation(), |
98 InstructionSelector::SupportedMachineOperatorFlags()); | 99 InstructionSelector::SupportedMachineOperatorFlags()); |
99 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); | 100 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); |
100 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); | 101 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); |
101 jsgraph_ = new (graph_zone_) | 102 jsgraph_ = new (graph_zone_) |
102 JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_); | 103 JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_); |
103 } | 104 } |
104 | 105 |
105 // For WASM compile entry point. | 106 // For WASM compile entry point. |
106 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, | 107 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, |
107 SourcePositionTable* source_positions) | 108 SourcePositionTable* source_positions) |
108 : isolate_(info->isolate()), | 109 : isolate_(info->isolate()), |
109 info_(info), | 110 info_(info), |
| 111 debug_name_(info_->GetDebugName()), |
110 zone_pool_(zone_pool), | 112 zone_pool_(zone_pool), |
111 graph_zone_scope_(zone_pool_), | 113 graph_zone_scope_(zone_pool_), |
112 graph_(graph), | 114 graph_(graph), |
113 source_positions_(source_positions), | 115 source_positions_(source_positions), |
114 instruction_zone_scope_(zone_pool_), | 116 instruction_zone_scope_(zone_pool_), |
115 instruction_zone_(instruction_zone_scope_.zone()), | 117 instruction_zone_(instruction_zone_scope_.zone()), |
116 register_allocation_zone_scope_(zone_pool_), | 118 register_allocation_zone_scope_(zone_pool_), |
117 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} | 119 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} |
118 | 120 |
119 // For machine graph testing entry point. | 121 // For machine graph testing entry point. |
120 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, | 122 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, |
121 Schedule* schedule) | 123 Schedule* schedule) |
122 : isolate_(info->isolate()), | 124 : isolate_(info->isolate()), |
123 info_(info), | 125 info_(info), |
| 126 debug_name_(info_->GetDebugName()), |
124 zone_pool_(zone_pool), | 127 zone_pool_(zone_pool), |
125 graph_zone_scope_(zone_pool_), | 128 graph_zone_scope_(zone_pool_), |
126 graph_(graph), | 129 graph_(graph), |
127 source_positions_(new (info->zone()) SourcePositionTable(graph_)), | 130 source_positions_(new (info->zone()) SourcePositionTable(graph_)), |
128 schedule_(schedule), | 131 schedule_(schedule), |
129 instruction_zone_scope_(zone_pool_), | 132 instruction_zone_scope_(zone_pool_), |
130 instruction_zone_(instruction_zone_scope_.zone()), | 133 instruction_zone_(instruction_zone_scope_.zone()), |
131 register_allocation_zone_scope_(zone_pool_), | 134 register_allocation_zone_scope_(zone_pool_), |
132 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} | 135 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} |
133 | 136 |
134 // For register allocation testing entry point. | 137 // For register allocation testing entry point. |
135 PipelineData(ZonePool* zone_pool, CompilationInfo* info, | 138 PipelineData(ZonePool* zone_pool, CompilationInfo* info, |
136 InstructionSequence* sequence) | 139 InstructionSequence* sequence) |
137 : isolate_(info->isolate()), | 140 : isolate_(info->isolate()), |
138 info_(info), | 141 info_(info), |
| 142 debug_name_(info_->GetDebugName()), |
139 zone_pool_(zone_pool), | 143 zone_pool_(zone_pool), |
140 graph_zone_scope_(zone_pool_), | 144 graph_zone_scope_(zone_pool_), |
141 instruction_zone_scope_(zone_pool_), | 145 instruction_zone_scope_(zone_pool_), |
142 instruction_zone_(sequence->zone()), | 146 instruction_zone_(sequence->zone()), |
143 sequence_(sequence), | 147 sequence_(sequence), |
144 register_allocation_zone_scope_(zone_pool_), | 148 register_allocation_zone_scope_(zone_pool_), |
145 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} | 149 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} |
146 | 150 |
147 void Destroy() { | 151 ~PipelineData() { |
148 DeleteRegisterAllocationZone(); | 152 DeleteRegisterAllocationZone(); |
149 DeleteInstructionZone(); | 153 DeleteInstructionZone(); |
150 DeleteGraphZone(); | 154 DeleteGraphZone(); |
151 } | 155 } |
152 | 156 |
153 ~PipelineData() { Destroy(); } | |
154 | |
155 Isolate* isolate() const { return isolate_; } | 157 Isolate* isolate() const { return isolate_; } |
156 CompilationInfo* info() const { return info_; } | 158 CompilationInfo* info() const { return info_; } |
157 ZonePool* zone_pool() const { return zone_pool_; } | 159 ZonePool* zone_pool() const { return zone_pool_; } |
158 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } | 160 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } |
159 bool compilation_failed() const { return compilation_failed_; } | 161 bool compilation_failed() const { return compilation_failed_; } |
160 void set_compilation_failed() { compilation_failed_ = true; } | 162 void set_compilation_failed() { compilation_failed_ = true; } |
161 Handle<Code> code() { return code_; } | 163 Handle<Code> code() { return code_; } |
162 void set_code(Handle<Code> code) { | 164 void set_code(Handle<Code> code) { |
163 DCHECK(code_.is_null()); | 165 DCHECK(code_.is_null()); |
164 code_ = code; | 166 code_ = code; |
165 } | 167 } |
166 BasicBlockProfiler::Data* profiler_data() { return profiler_data_; } | 168 |
167 void set_profiler_data(BasicBlockProfiler::Data* data) { | |
168 profiler_data_ = data; | |
169 } | |
170 std::ostringstream* source_position_output() { | |
171 return &source_position_output_; | |
172 } | |
173 // RawMachineAssembler generally produces graphs which cannot be verified. | 169 // RawMachineAssembler generally produces graphs which cannot be verified. |
174 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } | 170 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } |
175 | 171 |
176 Zone* graph_zone() const { return graph_zone_; } | 172 Zone* graph_zone() const { return graph_zone_; } |
177 Graph* graph() const { return graph_; } | 173 Graph* graph() const { return graph_; } |
178 SourcePositionTable* source_positions() const { | 174 SourcePositionTable* source_positions() const { return source_positions_; } |
179 DCHECK_NOT_NULL(source_positions_); | |
180 return source_positions_; | |
181 } | |
182 MachineOperatorBuilder* machine() const { return machine_; } | 175 MachineOperatorBuilder* machine() const { return machine_; } |
183 CommonOperatorBuilder* common() const { return common_; } | 176 CommonOperatorBuilder* common() const { return common_; } |
184 JSOperatorBuilder* javascript() const { return javascript_; } | 177 JSOperatorBuilder* javascript() const { return javascript_; } |
185 JSGraph* jsgraph() const { return jsgraph_; } | 178 JSGraph* jsgraph() const { return jsgraph_; } |
186 MaybeHandle<Context> native_context() const { | 179 MaybeHandle<Context> native_context() const { |
187 if (info()->is_native_context_specializing()) { | 180 if (info()->is_native_context_specializing()) { |
188 return handle(info()->native_context(), isolate()); | 181 return handle(info()->native_context(), isolate()); |
189 } | 182 } |
190 return MaybeHandle<Context>(); | 183 return MaybeHandle<Context>(); |
191 } | 184 } |
(...skipping 19 matching lines...) Expand all Loading... |
211 | 204 |
212 Zone* instruction_zone() const { return instruction_zone_; } | 205 Zone* instruction_zone() const { return instruction_zone_; } |
213 InstructionSequence* sequence() const { return sequence_; } | 206 InstructionSequence* sequence() const { return sequence_; } |
214 Frame* frame() const { return frame_; } | 207 Frame* frame() const { return frame_; } |
215 | 208 |
216 Zone* register_allocation_zone() const { return register_allocation_zone_; } | 209 Zone* register_allocation_zone() const { return register_allocation_zone_; } |
217 RegisterAllocationData* register_allocation_data() const { | 210 RegisterAllocationData* register_allocation_data() const { |
218 return register_allocation_data_; | 211 return register_allocation_data_; |
219 } | 212 } |
220 | 213 |
| 214 BasicBlockProfiler::Data* profiler_data() const { return profiler_data_; } |
| 215 void set_profiler_data(BasicBlockProfiler::Data* profiler_data) { |
| 216 profiler_data_ = profiler_data; |
| 217 } |
| 218 |
| 219 std::string const& source_position_output() const { |
| 220 return source_position_output_; |
| 221 } |
| 222 void set_source_position_output(std::string const& source_position_output) { |
| 223 source_position_output_ = source_position_output; |
| 224 } |
| 225 |
221 void DeleteGraphZone() { | 226 void DeleteGraphZone() { |
222 if (graph_zone_ == nullptr) return; | 227 if (graph_zone_ == nullptr) return; |
223 graph_zone_scope_.Destroy(); | 228 graph_zone_scope_.Destroy(); |
224 graph_zone_ = nullptr; | 229 graph_zone_ = nullptr; |
225 graph_ = nullptr; | 230 graph_ = nullptr; |
226 source_positions_ = nullptr; | 231 source_positions_ = nullptr; |
227 loop_assignment_ = nullptr; | 232 loop_assignment_ = nullptr; |
228 type_hint_analysis_ = nullptr; | 233 type_hint_analysis_ = nullptr; |
229 simplified_ = nullptr; | 234 simplified_ = nullptr; |
230 machine_ = nullptr; | 235 machine_ = nullptr; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 void InitializeFrameData(CallDescriptor* descriptor) { | 272 void InitializeFrameData(CallDescriptor* descriptor) { |
268 DCHECK(frame_ == nullptr); | 273 DCHECK(frame_ == nullptr); |
269 int fixed_frame_size = 0; | 274 int fixed_frame_size = 0; |
270 if (descriptor != nullptr) { | 275 if (descriptor != nullptr) { |
271 fixed_frame_size = CalculateFixedFrameSize(descriptor); | 276 fixed_frame_size = CalculateFixedFrameSize(descriptor); |
272 } | 277 } |
273 frame_ = new (instruction_zone()) Frame(fixed_frame_size); | 278 frame_ = new (instruction_zone()) Frame(fixed_frame_size); |
274 } | 279 } |
275 | 280 |
276 void InitializeRegisterAllocationData(const RegisterConfiguration* config, | 281 void InitializeRegisterAllocationData(const RegisterConfiguration* config, |
277 CallDescriptor* descriptor, | 282 CallDescriptor* descriptor) { |
278 const char* debug_name) { | |
279 DCHECK(register_allocation_data_ == nullptr); | 283 DCHECK(register_allocation_data_ == nullptr); |
280 register_allocation_data_ = new (register_allocation_zone()) | 284 register_allocation_data_ = new (register_allocation_zone()) |
281 RegisterAllocationData(config, register_allocation_zone(), frame(), | 285 RegisterAllocationData(config, register_allocation_zone(), frame(), |
282 sequence(), debug_name); | 286 sequence(), debug_name_.get()); |
283 } | 287 } |
284 | 288 |
285 private: | 289 private: |
286 Isolate* isolate_; | 290 Isolate* const isolate_; |
287 CompilationInfo* info_; | 291 CompilationInfo* const info_; |
| 292 base::SmartArrayPointer<char> debug_name_; |
288 Zone* outer_zone_ = nullptr; | 293 Zone* outer_zone_ = nullptr; |
289 ZonePool* const zone_pool_; | 294 ZonePool* const zone_pool_; |
290 PipelineStatistics* pipeline_statistics_ = nullptr; | 295 PipelineStatistics* pipeline_statistics_ = nullptr; |
291 bool compilation_failed_ = false; | 296 bool compilation_failed_ = false; |
292 Handle<Code> code_; | 297 Handle<Code> code_ = Handle<Code>::null(); |
293 BasicBlockProfiler::Data* profiler_data_ = nullptr; | |
294 std::ostringstream source_position_output_; | |
295 | 298 |
296 // All objects in the following group of fields are allocated in graph_zone_. | 299 // All objects in the following group of fields are allocated in graph_zone_. |
297 // They are all set to nullptr when the graph_zone_ is destroyed. | 300 // They are all set to nullptr when the graph_zone_ is destroyed. |
298 ZonePool::Scope graph_zone_scope_; | 301 ZonePool::Scope graph_zone_scope_; |
299 Zone* graph_zone_ = nullptr; | 302 Zone* graph_zone_ = nullptr; |
300 Graph* graph_ = nullptr; | 303 Graph* graph_ = nullptr; |
301 SourcePositionTable* source_positions_ = nullptr; | 304 SourcePositionTable* source_positions_ = nullptr; |
302 LoopAssignmentAnalysis* loop_assignment_ = nullptr; | 305 LoopAssignmentAnalysis* loop_assignment_ = nullptr; |
303 TypeHintAnalysis* type_hint_analysis_ = nullptr; | 306 TypeHintAnalysis* type_hint_analysis_ = nullptr; |
304 SimplifiedOperatorBuilder* simplified_ = nullptr; | 307 SimplifiedOperatorBuilder* simplified_ = nullptr; |
(...skipping 12 matching lines...) Expand all Loading... |
317 InstructionSequence* sequence_ = nullptr; | 320 InstructionSequence* sequence_ = nullptr; |
318 Frame* frame_ = nullptr; | 321 Frame* frame_ = nullptr; |
319 | 322 |
320 // All objects in the following group of fields are allocated in | 323 // All objects in the following group of fields are allocated in |
321 // register_allocation_zone_. They are all set to nullptr when the zone is | 324 // register_allocation_zone_. They are all set to nullptr when the zone is |
322 // destroyed. | 325 // destroyed. |
323 ZonePool::Scope register_allocation_zone_scope_; | 326 ZonePool::Scope register_allocation_zone_scope_; |
324 Zone* register_allocation_zone_; | 327 Zone* register_allocation_zone_; |
325 RegisterAllocationData* register_allocation_data_ = nullptr; | 328 RegisterAllocationData* register_allocation_data_ = nullptr; |
326 | 329 |
| 330 // Basic block profiling support. |
| 331 BasicBlockProfiler::Data* profiler_data_ = nullptr; |
| 332 |
| 333 // Source position output for --trace-turbo. |
| 334 std::string source_position_output_; |
| 335 |
327 int CalculateFixedFrameSize(CallDescriptor* descriptor) { | 336 int CalculateFixedFrameSize(CallDescriptor* descriptor) { |
328 if (descriptor->IsJSFunctionCall()) { | 337 if (descriptor->IsJSFunctionCall()) { |
329 return StandardFrameConstants::kFixedSlotCount; | 338 return StandardFrameConstants::kFixedSlotCount; |
330 } | 339 } |
331 return descriptor->IsCFunctionCall() | 340 return descriptor->IsCFunctionCall() |
332 ? (CommonFrameConstants::kFixedSlotCountAboveFp + | 341 ? (CommonFrameConstants::kFixedSlotCountAboveFp + |
333 CommonFrameConstants::kCPSlotCount) | 342 CommonFrameConstants::kCPSlotCount) |
334 : TypedFrameConstants::kFixedSlotCount; | 343 : TypedFrameConstants::kFixedSlotCount; |
335 } | 344 } |
336 | 345 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 phase_name), | 461 phase_name), |
453 zone_scope_(data->zone_pool()) {} | 462 zone_scope_(data->zone_pool()) {} |
454 | 463 |
455 Zone* zone() { return zone_scope_.zone(); } | 464 Zone* zone() { return zone_scope_.zone(); } |
456 | 465 |
457 private: | 466 private: |
458 PhaseScope phase_scope_; | 467 PhaseScope phase_scope_; |
459 ZonePool::Scope zone_scope_; | 468 ZonePool::Scope zone_scope_; |
460 }; | 469 }; |
461 | 470 |
462 class PipelineCompilationJob : public OptimizedCompileJob { | 471 PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info, |
| 472 ZonePool* zone_pool) { |
| 473 if (!FLAG_turbo_stats) return nullptr; |
| 474 |
| 475 PipelineStatistics* pipeline_statistics = |
| 476 new PipelineStatistics(info, zone_pool); |
| 477 pipeline_statistics->BeginPhaseKind("initializing"); |
| 478 |
| 479 FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "w+"); |
| 480 if (json_file != nullptr) { |
| 481 OFStream json_of(json_file); |
| 482 Handle<Script> script = info->script(); |
| 483 base::SmartArrayPointer<char> function_name = info->GetDebugName(); |
| 484 int pos = info->shared_info()->start_position(); |
| 485 json_of << "{\"function\":\"" << function_name.get() |
| 486 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; |
| 487 if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
| 488 DisallowHeapAllocation no_allocation; |
| 489 int start = info->shared_info()->start_position(); |
| 490 int len = info->shared_info()->end_position() - start; |
| 491 String::SubStringRange source(String::cast(script->source()), start, len); |
| 492 for (const auto& c : source) { |
| 493 json_of << AsEscapedUC16ForJSON(c); |
| 494 } |
| 495 } |
| 496 json_of << "\",\n\"phases\":["; |
| 497 fclose(json_file); |
| 498 } |
| 499 |
| 500 return pipeline_statistics; |
| 501 } |
| 502 |
| 503 class PipelineCompilationJob final : public OptimizedCompileJob { |
463 public: | 504 public: |
464 explicit PipelineCompilationJob(CompilationInfo* info) | 505 explicit PipelineCompilationJob(CompilationInfo* info) |
465 : OptimizedCompileJob(info, "TurboFan") {} | 506 : OptimizedCompileJob(info, "TurboFan"), |
| 507 zone_pool_(info->isolate()->allocator()), |
| 508 pipeline_statistics_(CreatePipelineStatistics(info, &zone_pool_)), |
| 509 data_(&zone_pool_, info, pipeline_statistics_.get()), |
| 510 pipeline_(&data_), |
| 511 linkage_(Linkage::ComputeIncoming(info->zone(), info)) {} |
466 | 512 |
467 protected: | 513 protected: |
468 virtual Status CreateGraphImpl(); | 514 Status CreateGraphImpl() final; |
469 virtual Status OptimizeGraphImpl(); | 515 Status OptimizeGraphImpl() final; |
470 virtual Status GenerateCodeImpl(); | 516 Status GenerateCodeImpl() final; |
| 517 |
| 518 private: |
| 519 ZonePool zone_pool_; |
| 520 base::SmartPointer<PipelineStatistics> pipeline_statistics_; |
| 521 PipelineData data_; |
| 522 Pipeline pipeline_; |
| 523 Linkage linkage_; |
471 }; | 524 }; |
472 | 525 |
473 PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { | 526 PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { |
474 if (info()->shared_info()->asm_function()) { | 527 if (info()->shared_info()->asm_function()) { |
475 if (info()->osr_frame()) info()->MarkAsFrameSpecializing(); | 528 if (info()->osr_frame()) info()->MarkAsFrameSpecializing(); |
476 info()->MarkAsFunctionContextSpecializing(); | 529 info()->MarkAsFunctionContextSpecializing(); |
477 } else { | 530 } else { |
478 if (!FLAG_always_opt) { | 531 if (!FLAG_always_opt) { |
479 info()->MarkAsBailoutOnUninitialized(); | 532 info()->MarkAsBailoutOnUninitialized(); |
480 } | 533 } |
481 if (FLAG_native_context_specialization) { | 534 if (FLAG_native_context_specialization) { |
482 info()->MarkAsNativeContextSpecializing(); | 535 info()->MarkAsNativeContextSpecializing(); |
483 } | 536 } |
484 } | 537 } |
485 if (!info()->shared_info()->asm_function() || FLAG_turbo_asm_deoptimization) { | 538 if (!info()->shared_info()->asm_function() || FLAG_turbo_asm_deoptimization) { |
486 info()->MarkAsDeoptimizationEnabled(); | 539 info()->MarkAsDeoptimizationEnabled(); |
487 } | 540 } |
488 if (!info()->shared_info()->HasBytecodeArray()) { | 541 if (!info()->shared_info()->HasBytecodeArray()) { |
489 if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED; | 542 if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED; |
490 } | 543 } |
491 | 544 |
492 Pipeline pipeline(info()); | 545 if (!pipeline_.CreateGraph()) { |
493 pipeline.GenerateCode(); | 546 if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. |
494 if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. | 547 return AbortOptimization(kGraphBuildingFailed); |
495 if (info()->code().is_null()) return AbortOptimization(kGraphBuildingFailed); | 548 } |
496 | 549 |
497 return SUCCEEDED; | 550 return SUCCEEDED; |
498 } | 551 } |
499 | 552 |
500 PipelineCompilationJob::Status PipelineCompilationJob::OptimizeGraphImpl() { | 553 PipelineCompilationJob::Status PipelineCompilationJob::OptimizeGraphImpl() { |
501 // TODO(turbofan): Currently everything is done in the first phase. | 554 if (!pipeline_.OptimizeGraph(&linkage_)) return FAILED; |
502 DCHECK(!info()->code().is_null()); | |
503 return SUCCEEDED; | 555 return SUCCEEDED; |
504 } | 556 } |
505 | 557 |
506 PipelineCompilationJob::Status PipelineCompilationJob::GenerateCodeImpl() { | 558 PipelineCompilationJob::Status PipelineCompilationJob::GenerateCodeImpl() { |
507 // TODO(turbofan): Currently everything is done in the first phase. | 559 Handle<Code> code = pipeline_.GenerateCode(&linkage_); |
508 DCHECK(!info()->code().is_null()); | 560 if (code.is_null()) { |
509 info()->dependencies()->Commit(info()->code()); | 561 if (info()->bailout_reason() == kNoReason) { |
| 562 return AbortOptimization(kCodeGenerationFailed); |
| 563 } |
| 564 return BAILED_OUT; |
| 565 } |
| 566 info()->dependencies()->Commit(code); |
| 567 info()->SetCode(code); |
510 if (info()->is_deoptimization_enabled()) { | 568 if (info()->is_deoptimization_enabled()) { |
511 info()->context()->native_context()->AddOptimizedCode(*info()->code()); | 569 info()->context()->native_context()->AddOptimizedCode(*code); |
512 RegisterWeakObjectsInOptimizedCode(info()->code()); | 570 RegisterWeakObjectsInOptimizedCode(code); |
513 } | 571 } |
514 return SUCCEEDED; | 572 return SUCCEEDED; |
515 } | 573 } |
516 | 574 |
| 575 class PipelineWasmCompilationJob final : public OptimizedCompileJob { |
| 576 public: |
| 577 explicit PipelineWasmCompilationJob(CompilationInfo* info, Graph* graph, |
| 578 CallDescriptor* descriptor, |
| 579 SourcePositionTable* source_positions) |
| 580 : OptimizedCompileJob(info, "TurboFan"), |
| 581 zone_pool_(info->isolate()->allocator()), |
| 582 data_(&zone_pool_, info, graph, source_positions), |
| 583 pipeline_(&data_), |
| 584 linkage_(descriptor) {} |
| 585 |
| 586 protected: |
| 587 Status CreateGraphImpl() final; |
| 588 Status OptimizeGraphImpl() final; |
| 589 Status GenerateCodeImpl() final; |
| 590 |
| 591 private: |
| 592 ZonePool zone_pool_; |
| 593 PipelineData data_; |
| 594 Pipeline pipeline_; |
| 595 Linkage linkage_; |
| 596 }; |
| 597 |
| 598 PipelineWasmCompilationJob::Status |
| 599 PipelineWasmCompilationJob::CreateGraphImpl() { |
| 600 return SUCCEEDED; |
| 601 } |
| 602 |
| 603 PipelineWasmCompilationJob::Status |
| 604 PipelineWasmCompilationJob::OptimizeGraphImpl() { |
| 605 if (!pipeline_.ScheduleAndSelectInstructions(&linkage_)) return FAILED; |
| 606 return SUCCEEDED; |
| 607 } |
| 608 |
| 609 PipelineWasmCompilationJob::Status |
| 610 PipelineWasmCompilationJob::GenerateCodeImpl() { |
| 611 pipeline_.GenerateCode(&linkage_); |
| 612 return SUCCEEDED; |
| 613 } |
| 614 |
517 } // namespace | 615 } // namespace |
518 | 616 |
519 | 617 |
520 template <typename Phase> | 618 template <typename Phase> |
521 void Pipeline::Run() { | 619 void Pipeline::Run() { |
522 PipelineRunScope scope(this->data_, Phase::phase_name()); | 620 PipelineRunScope scope(this->data_, Phase::phase_name()); |
523 Phase phase; | 621 Phase phase; |
524 phase.Run(this->data_, scope.zone()); | 622 phase.Run(this->data_, scope.zone()); |
525 } | 623 } |
526 | 624 |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 } | 1231 } |
1134 }; | 1232 }; |
1135 | 1233 |
1136 | 1234 |
1137 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { | 1235 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { |
1138 if (data_->pipeline_statistics() != nullptr) { | 1236 if (data_->pipeline_statistics() != nullptr) { |
1139 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); | 1237 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); |
1140 } | 1238 } |
1141 } | 1239 } |
1142 | 1240 |
| 1241 void Pipeline::EndPhaseKind() { |
| 1242 if (data_->pipeline_statistics() != nullptr) { |
| 1243 data_->pipeline_statistics()->EndPhaseKind(); |
| 1244 } |
| 1245 } |
1143 | 1246 |
1144 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { | 1247 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { |
1145 if (FLAG_trace_turbo) { | 1248 if (FLAG_trace_turbo) { |
1146 Run<PrintGraphPhase>(phase); | 1249 Run<PrintGraphPhase>(phase); |
1147 } | 1250 } |
1148 if (FLAG_turbo_verify) { | 1251 if (FLAG_turbo_verify) { |
1149 Run<VerifyGraphPhase>(untyped); | 1252 Run<VerifyGraphPhase>(untyped); |
1150 } | 1253 } |
1151 } | 1254 } |
1152 | 1255 |
1153 | 1256 bool Pipeline::CreateGraph() { |
1154 Handle<Code> Pipeline::GenerateCode() { | 1257 PipelineData* data = this->data_; |
1155 ZonePool zone_pool(isolate()->allocator()); | |
1156 base::SmartPointer<PipelineStatistics> pipeline_statistics; | |
1157 | |
1158 if (FLAG_turbo_stats) { | |
1159 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); | |
1160 pipeline_statistics->BeginPhaseKind("initializing"); | |
1161 } | |
1162 | |
1163 if (FLAG_trace_turbo) { | |
1164 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "w+"); | |
1165 if (json_file != nullptr) { | |
1166 OFStream json_of(json_file); | |
1167 Handle<Script> script = info()->script(); | |
1168 base::SmartArrayPointer<char> function_name = info()->GetDebugName(); | |
1169 int pos = info()->shared_info()->start_position(); | |
1170 json_of << "{\"function\":\"" << function_name.get() | |
1171 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; | |
1172 if (!script->IsUndefined() && !script->source()->IsUndefined()) { | |
1173 DisallowHeapAllocation no_allocation; | |
1174 int start = info()->shared_info()->start_position(); | |
1175 int len = info()->shared_info()->end_position() - start; | |
1176 String::SubStringRange source(String::cast(script->source()), start, | |
1177 len); | |
1178 for (const auto& c : source) { | |
1179 json_of << AsEscapedUC16ForJSON(c); | |
1180 } | |
1181 } | |
1182 json_of << "\",\n\"phases\":["; | |
1183 fclose(json_file); | |
1184 } | |
1185 } | |
1186 | |
1187 PipelineData data(&zone_pool, info(), pipeline_statistics.get()); | |
1188 this->data_ = &data; | |
1189 | 1258 |
1190 BeginPhaseKind("graph creation"); | 1259 BeginPhaseKind("graph creation"); |
1191 | 1260 |
1192 if (FLAG_trace_turbo) { | 1261 if (FLAG_trace_turbo) { |
1193 OFStream os(stdout); | 1262 OFStream os(stdout); |
1194 os << "---------------------------------------------------\n" | 1263 os << "---------------------------------------------------\n" |
1195 << "Begin compiling method " << info()->GetDebugName().get() | 1264 << "Begin compiling method " << info()->GetDebugName().get() |
1196 << " using Turbofan" << std::endl; | 1265 << " using Turbofan" << std::endl; |
1197 TurboCfgFile tcf(isolate()); | 1266 TurboCfgFile tcf(isolate()); |
1198 tcf << AsC1VCompilation(info()); | 1267 tcf << AsC1VCompilation(info()); |
1199 } | 1268 } |
1200 | 1269 |
1201 data.source_positions()->AddDecorator(); | 1270 data->source_positions()->AddDecorator(); |
1202 | 1271 |
1203 if (FLAG_loop_assignment_analysis) { | 1272 if (FLAG_loop_assignment_analysis) { |
1204 Run<LoopAssignmentAnalysisPhase>(); | 1273 Run<LoopAssignmentAnalysisPhase>(); |
1205 } | 1274 } |
1206 | 1275 |
1207 Run<TypeHintAnalysisPhase>(); | 1276 Run<TypeHintAnalysisPhase>(); |
1208 | 1277 |
1209 Run<GraphBuilderPhase>(); | 1278 Run<GraphBuilderPhase>(); |
1210 if (data.compilation_failed()) return Handle<Code>::null(); | 1279 if (data->compilation_failed()) { |
| 1280 EndPhaseKind(); |
| 1281 return false; |
| 1282 } |
1211 RunPrintAndVerify("Initial untyped", true); | 1283 RunPrintAndVerify("Initial untyped", true); |
1212 | 1284 |
1213 // Perform OSR deconstruction. | 1285 // Perform OSR deconstruction. |
1214 if (info()->is_osr()) { | 1286 if (info()->is_osr()) { |
1215 Run<OsrDeconstructionPhase>(); | 1287 Run<OsrDeconstructionPhase>(); |
1216 RunPrintAndVerify("OSR deconstruction", true); | 1288 RunPrintAndVerify("OSR deconstruction", true); |
1217 } | 1289 } |
1218 | 1290 |
1219 // Perform function context specialization and inlining (if enabled). | 1291 // Perform function context specialization and inlining (if enabled). |
1220 Run<InliningPhase>(); | 1292 Run<InliningPhase>(); |
1221 RunPrintAndVerify("Inlined", true); | 1293 RunPrintAndVerify("Inlined", true); |
1222 | 1294 |
1223 // Remove dead->live edges from the graph. | 1295 // Remove dead->live edges from the graph. |
1224 Run<EarlyGraphTrimmingPhase>(); | 1296 Run<EarlyGraphTrimmingPhase>(); |
1225 RunPrintAndVerify("Early trimmed", true); | 1297 RunPrintAndVerify("Early trimmed", true); |
1226 | 1298 |
1227 if (FLAG_print_turbo_replay) { | 1299 if (FLAG_print_turbo_replay) { |
1228 // Print a replay of the initial graph. | 1300 // Print a replay of the initial graph. |
1229 GraphReplayPrinter::PrintReplay(data.graph()); | 1301 GraphReplayPrinter::PrintReplay(data->graph()); |
1230 } | 1302 } |
1231 | 1303 |
1232 // Type the graph. | 1304 // Type the graph. |
1233 base::SmartPointer<Typer> typer; | 1305 base::SmartPointer<Typer> typer; |
1234 typer.Reset(new Typer(isolate(), data.graph(), | 1306 typer.Reset(new Typer(isolate(), data->graph(), |
1235 info()->is_deoptimization_enabled() | 1307 info()->is_deoptimization_enabled() |
1236 ? Typer::kDeoptimizationEnabled | 1308 ? Typer::kDeoptimizationEnabled |
1237 : Typer::kNoFlags, | 1309 : Typer::kNoFlags, |
1238 info()->dependencies())); | 1310 info()->dependencies())); |
1239 Run<TyperPhase>(typer.get()); | 1311 Run<TyperPhase>(typer.get()); |
1240 RunPrintAndVerify("Typed"); | 1312 RunPrintAndVerify("Typed"); |
1241 | 1313 |
1242 BeginPhaseKind("lowering"); | 1314 BeginPhaseKind("lowering"); |
1243 | 1315 |
1244 // Lower JSOperators where we can determine types. | 1316 // Lower JSOperators where we can determine types. |
(...skipping 28 matching lines...) Expand all Loading... |
1273 if (FLAG_turbo_cf_optimization) { | 1345 if (FLAG_turbo_cf_optimization) { |
1274 Run<ControlFlowOptimizationPhase>(); | 1346 Run<ControlFlowOptimizationPhase>(); |
1275 RunPrintAndVerify("Control flow optimized"); | 1347 RunPrintAndVerify("Control flow optimized"); |
1276 } | 1348 } |
1277 | 1349 |
1278 // Lower changes that have been inserted before. | 1350 // Lower changes that have been inserted before. |
1279 Run<LateOptimizationPhase>(); | 1351 Run<LateOptimizationPhase>(); |
1280 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1352 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1281 RunPrintAndVerify("Late optimized", true); | 1353 RunPrintAndVerify("Late optimized", true); |
1282 | 1354 |
| 1355 // Kill the Typer and thereby uninstall the decorator (if any). |
| 1356 typer.Reset(nullptr); |
| 1357 |
| 1358 EndPhaseKind(); |
| 1359 |
| 1360 return true; |
| 1361 } |
| 1362 |
| 1363 bool Pipeline::OptimizeGraph(Linkage* linkage) { |
| 1364 PipelineData* data = this->data_; |
| 1365 |
| 1366 BeginPhaseKind("block building"); |
| 1367 |
1283 Run<LateGraphTrimmingPhase>(); | 1368 Run<LateGraphTrimmingPhase>(); |
1284 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1369 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1285 RunPrintAndVerify("Late trimmed", true); | 1370 RunPrintAndVerify("Late trimmed", true); |
1286 | 1371 |
1287 BeginPhaseKind("block building"); | 1372 data->source_positions()->RemoveDecorator(); |
1288 | 1373 |
1289 data.source_positions()->RemoveDecorator(); | 1374 return ScheduleAndSelectInstructions(linkage); |
| 1375 } |
1290 | 1376 |
1291 // Kill the Typer and thereby uninstall the decorator (if any). | 1377 Handle<Code> Pipeline::GenerateCode() { |
1292 typer.Reset(nullptr); | 1378 PipelineData* data = this->data_; |
1293 | 1379 |
1294 return ScheduleAndGenerateCode( | 1380 Linkage linkage(Linkage::ComputeIncoming(data->instruction_zone(), info())); |
1295 Linkage::ComputeIncoming(data.instruction_zone(), info())); | 1381 |
| 1382 if (!CreateGraph()) return Handle<Code>::null(); |
| 1383 if (!OptimizeGraph(&linkage)) return Handle<Code>::null(); |
| 1384 return GenerateCode(&linkage); |
1296 } | 1385 } |
1297 | 1386 |
1298 Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, | 1387 Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, |
1299 CallDescriptor* call_descriptor, | 1388 CallDescriptor* call_descriptor, |
1300 Graph* graph, Schedule* schedule, | 1389 Graph* graph, Schedule* schedule, |
1301 Code::Flags flags, | 1390 Code::Flags flags, |
1302 const char* debug_name) { | 1391 const char* debug_name) { |
1303 CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags); | 1392 CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags); |
1304 | 1393 |
1305 // Construct a pipeline for scheduling and code generation. | 1394 // Construct a pipeline for scheduling and code generation. |
1306 ZonePool zone_pool(isolate->allocator()); | 1395 ZonePool zone_pool(isolate->allocator()); |
1307 PipelineData data(&zone_pool, &info, graph, schedule); | 1396 PipelineData data(&zone_pool, &info, graph, schedule); |
1308 base::SmartPointer<PipelineStatistics> pipeline_statistics; | 1397 base::SmartPointer<PipelineStatistics> pipeline_statistics; |
1309 if (FLAG_turbo_stats) { | 1398 if (FLAG_turbo_stats) { |
1310 pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool)); | 1399 pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool)); |
1311 pipeline_statistics->BeginPhaseKind("stub codegen"); | 1400 pipeline_statistics->BeginPhaseKind("stub codegen"); |
1312 } | 1401 } |
1313 | 1402 |
1314 Pipeline pipeline(&info); | 1403 Pipeline pipeline(&data); |
1315 pipeline.data_ = &data; | |
1316 DCHECK_NOT_NULL(data.schedule()); | 1404 DCHECK_NOT_NULL(data.schedule()); |
1317 | 1405 |
1318 if (FLAG_trace_turbo) { | 1406 if (FLAG_trace_turbo) { |
1319 FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+"); | 1407 FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+"); |
1320 if (json_file != nullptr) { | 1408 if (json_file != nullptr) { |
1321 OFStream json_of(json_file); | 1409 OFStream json_of(json_file); |
1322 json_of << "{\"function\":\"" << info.GetDebugName().get() | 1410 json_of << "{\"function\":\"" << info.GetDebugName().get() |
1323 << "\", \"source\":\"\",\n\"phases\":["; | 1411 << "\", \"source\":\"\",\n\"phases\":["; |
1324 fclose(json_file); | 1412 fclose(json_file); |
1325 } | 1413 } |
1326 pipeline.Run<PrintGraphPhase>("Machine"); | 1414 pipeline.Run<PrintGraphPhase>("Machine"); |
1327 } | 1415 } |
1328 | 1416 |
1329 pipeline.Run<VerifyGraphPhase>(false, true); | 1417 pipeline.Run<VerifyGraphPhase>(false, true); |
1330 return pipeline.ScheduleAndGenerateCode(call_descriptor); | 1418 return pipeline.ScheduleAndGenerateCode(call_descriptor); |
1331 } | 1419 } |
1332 | 1420 |
| 1421 // static |
| 1422 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info) { |
| 1423 ZonePool zone_pool(info->isolate()->allocator()); |
| 1424 base::SmartPointer<PipelineStatistics> pipeline_statistics( |
| 1425 CreatePipelineStatistics(info, &zone_pool)); |
| 1426 PipelineData data(&zone_pool, info, pipeline_statistics.get()); |
| 1427 Pipeline pipeline(&data); |
| 1428 return pipeline.GenerateCode(); |
| 1429 } |
1333 | 1430 |
| 1431 // static |
1334 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1432 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
1335 Graph* graph, | 1433 Graph* graph, |
1336 Schedule* schedule) { | 1434 Schedule* schedule) { |
1337 CallDescriptor* call_descriptor = | 1435 CallDescriptor* call_descriptor = |
1338 Linkage::ComputeIncoming(info->zone(), info); | 1436 Linkage::ComputeIncoming(info->zone(), info); |
1339 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); | 1437 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); |
1340 } | 1438 } |
1341 | 1439 |
1342 | 1440 // static |
1343 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1441 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
1344 CallDescriptor* call_descriptor, | 1442 CallDescriptor* call_descriptor, |
1345 Graph* graph, | 1443 Graph* graph, |
1346 Schedule* schedule) { | 1444 Schedule* schedule) { |
1347 // Construct a pipeline for scheduling and code generation. | 1445 // Construct a pipeline for scheduling and code generation. |
1348 ZonePool zone_pool(info->isolate()->allocator()); | 1446 ZonePool zone_pool(info->isolate()->allocator()); |
1349 PipelineData data(&zone_pool, info, graph, schedule); | 1447 PipelineData data(&zone_pool, info, graph, schedule); |
1350 base::SmartPointer<PipelineStatistics> pipeline_statistics; | 1448 base::SmartPointer<PipelineStatistics> pipeline_statistics; |
1351 if (FLAG_turbo_stats) { | 1449 if (FLAG_turbo_stats) { |
1352 pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool)); | 1450 pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool)); |
1353 pipeline_statistics->BeginPhaseKind("test codegen"); | 1451 pipeline_statistics->BeginPhaseKind("test codegen"); |
1354 } | 1452 } |
1355 | 1453 |
1356 Pipeline pipeline(info); | 1454 Pipeline pipeline(&data); |
1357 pipeline.data_ = &data; | |
1358 if (data.schedule() == nullptr) { | 1455 if (data.schedule() == nullptr) { |
1359 // TODO(rossberg): Should this really be untyped? | 1456 // TODO(rossberg): Should this really be untyped? |
1360 pipeline.RunPrintAndVerify("Machine", true); | 1457 pipeline.RunPrintAndVerify("Machine", true); |
1361 } | 1458 } |
1362 | 1459 |
1363 return pipeline.ScheduleAndGenerateCode(call_descriptor); | 1460 return pipeline.ScheduleAndGenerateCode(call_descriptor); |
1364 } | 1461 } |
1365 | 1462 |
1366 void Pipeline::InitializeWasmCompilation( | 1463 // static |
1367 Zone* pipeline_zone, ZonePool* zone_pool, Graph* graph, | 1464 OptimizedCompileJob* Pipeline::NewCompilationJob(CompilationInfo* info) { |
1368 SourcePositionTable* source_positions) { | 1465 return new PipelineCompilationJob(info); |
1369 data_ = new (pipeline_zone) | |
1370 PipelineData(zone_pool, info(), graph, source_positions); | |
1371 RunPrintAndVerify("Machine", true); | |
1372 } | 1466 } |
1373 | 1467 |
1374 bool Pipeline::ExecuteWasmCompilation(CallDescriptor* descriptor) { | 1468 // static |
1375 return ScheduleGraph(descriptor); | 1469 OptimizedCompileJob* Pipeline::NewWasmCompilationJob( |
1376 } | 1470 CompilationInfo* info, Graph* graph, CallDescriptor* descriptor, |
1377 | 1471 SourcePositionTable* source_positions) { |
1378 Handle<Code> Pipeline::FinalizeWasmCompilation(CallDescriptor* descriptor) { | 1472 return new PipelineWasmCompilationJob(info, graph, descriptor, |
1379 Handle<Code> result = GenerateCode(descriptor); | 1473 source_positions); |
1380 data_->Destroy(); | |
1381 return result; | |
1382 } | |
1383 | |
1384 OptimizedCompileJob* Pipeline::NewCompilationJob(CompilationInfo* info) { | |
1385 return new (info->zone()) PipelineCompilationJob(info); | |
1386 } | 1474 } |
1387 | 1475 |
1388 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, | 1476 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, |
1389 InstructionSequence* sequence, | 1477 InstructionSequence* sequence, |
1390 bool run_verifier) { | 1478 bool run_verifier) { |
1391 CompilationInfo info(ArrayVector("testing"), sequence->isolate(), | 1479 CompilationInfo info(ArrayVector("testing"), sequence->isolate(), |
1392 sequence->zone()); | 1480 sequence->zone()); |
1393 ZonePool zone_pool(sequence->isolate()->allocator()); | 1481 ZonePool zone_pool(sequence->isolate()->allocator()); |
1394 PipelineData data(&zone_pool, &info, sequence); | 1482 PipelineData data(&zone_pool, &info, sequence); |
1395 Pipeline pipeline(&info); | 1483 Pipeline pipeline(&data); |
1396 pipeline.data_ = &data; | |
1397 pipeline.data_->InitializeFrameData(nullptr); | 1484 pipeline.data_->InitializeFrameData(nullptr); |
1398 pipeline.AllocateRegisters(config, nullptr, run_verifier); | 1485 pipeline.AllocateRegisters(config, nullptr, run_verifier); |
1399 return !data.compilation_failed(); | 1486 return !data.compilation_failed(); |
1400 } | 1487 } |
1401 | 1488 |
1402 Handle<Code> Pipeline::ScheduleAndGenerateCode( | 1489 bool Pipeline::ScheduleAndSelectInstructions(Linkage* linkage) { |
1403 CallDescriptor* call_descriptor) { | 1490 CallDescriptor* call_descriptor = linkage->GetIncomingDescriptor(); |
1404 if (ScheduleGraph(call_descriptor)) { | 1491 PipelineData* data = this->data_; |
1405 return GenerateCode(call_descriptor); | |
1406 } else { | |
1407 return Handle<Code>::null(); | |
1408 } | |
1409 } | |
1410 | 1492 |
1411 bool Pipeline::ScheduleGraph(CallDescriptor* call_descriptor) { | |
1412 PipelineData* data = this->data_; | |
1413 DCHECK_NOT_NULL(data); | |
1414 DCHECK_NOT_NULL(data->graph()); | 1493 DCHECK_NOT_NULL(data->graph()); |
1415 | 1494 |
1416 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); | 1495 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); |
1417 TraceSchedule(data->info(), data->schedule()); | 1496 TraceSchedule(data->info(), data->schedule()); |
1418 | 1497 |
1419 if (FLAG_turbo_profiling) { | 1498 if (FLAG_turbo_profiling) { |
1420 data->set_profiler_data(BasicBlockInstrumentor::Instrument( | 1499 data->set_profiler_data(BasicBlockInstrumentor::Instrument( |
1421 info(), data->graph(), data->schedule())); | 1500 info(), data->graph(), data->schedule())); |
1422 } | 1501 } |
1423 | 1502 |
1424 data->InitializeInstructionSequence(call_descriptor); | 1503 data->InitializeInstructionSequence(call_descriptor); |
1425 | 1504 |
1426 data->InitializeFrameData(call_descriptor); | 1505 data->InitializeFrameData(call_descriptor); |
1427 // Select and schedule instructions covering the scheduled graph. | 1506 // Select and schedule instructions covering the scheduled graph. |
1428 Linkage linkage(call_descriptor); | 1507 Run<InstructionSelectionPhase>(linkage); |
1429 Run<InstructionSelectionPhase>(&linkage); | |
1430 | 1508 |
1431 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { | 1509 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { |
1432 TurboCfgFile tcf(isolate()); | 1510 TurboCfgFile tcf(isolate()); |
1433 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), | 1511 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), |
1434 data->sequence()); | 1512 data->sequence()); |
1435 } | 1513 } |
1436 | 1514 |
1437 if (FLAG_trace_turbo) { | 1515 if (FLAG_trace_turbo) { |
| 1516 std::ostringstream source_position_output; |
1438 // Output source position information before the graph is deleted. | 1517 // Output source position information before the graph is deleted. |
1439 data_->source_positions()->Print(*(data->source_position_output())); | 1518 data_->source_positions()->Print(source_position_output); |
| 1519 data_->set_source_position_output(source_position_output.str()); |
1440 } | 1520 } |
1441 | 1521 |
1442 data->DeleteGraphZone(); | 1522 data->DeleteGraphZone(); |
1443 | 1523 |
1444 BeginPhaseKind("register allocation"); | 1524 BeginPhaseKind("register allocation"); |
1445 | 1525 |
1446 bool run_verifier = FLAG_turbo_verify_allocation; | 1526 bool run_verifier = FLAG_turbo_verify_allocation; |
1447 | 1527 |
1448 // Allocate registers. | 1528 // Allocate registers. |
1449 AllocateRegisters( | 1529 AllocateRegisters( |
1450 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), | 1530 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), |
1451 call_descriptor, run_verifier); | 1531 call_descriptor, run_verifier); |
1452 Run<FrameElisionPhase>(); | 1532 Run<FrameElisionPhase>(); |
1453 if (data->compilation_failed()) { | 1533 if (data->compilation_failed()) { |
1454 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 1534 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
| 1535 EndPhaseKind(); |
1455 return false; | 1536 return false; |
1456 } | 1537 } |
1457 | 1538 |
1458 BeginPhaseKind("code generation"); | |
1459 // TODO(mtrofin): move this off to the register allocator. | 1539 // TODO(mtrofin): move this off to the register allocator. |
1460 bool generate_frame_at_start = | 1540 bool generate_frame_at_start = |
1461 data_->sequence()->instruction_blocks().front()->must_construct_frame(); | 1541 data_->sequence()->instruction_blocks().front()->must_construct_frame(); |
1462 // Optimimize jumps. | 1542 // Optimimize jumps. |
1463 if (FLAG_turbo_jt) { | 1543 if (FLAG_turbo_jt) { |
1464 Run<JumpThreadingPhase>(generate_frame_at_start); | 1544 Run<JumpThreadingPhase>(generate_frame_at_start); |
1465 } | 1545 } |
| 1546 |
| 1547 EndPhaseKind(); |
| 1548 |
1466 return true; | 1549 return true; |
1467 } | 1550 } |
1468 | 1551 |
1469 Handle<Code> Pipeline::GenerateCode(CallDescriptor* call_descriptor) { | 1552 Handle<Code> Pipeline::GenerateCode(Linkage* linkage) { |
1470 PipelineData* data = this->data_; | 1553 PipelineData* data = this->data_; |
1471 Linkage linkage(call_descriptor); | 1554 |
| 1555 BeginPhaseKind("code generation"); |
| 1556 |
1472 // Generate final machine code. | 1557 // Generate final machine code. |
1473 Run<GenerateCodePhase>(&linkage); | 1558 Run<GenerateCodePhase>(linkage); |
1474 | 1559 |
1475 Handle<Code> code = data->code(); | 1560 Handle<Code> code = data->code(); |
1476 if (data->profiler_data() != nullptr) { | 1561 if (data->profiler_data()) { |
1477 #if ENABLE_DISASSEMBLER | 1562 #if ENABLE_DISASSEMBLER |
1478 std::ostringstream os; | 1563 std::ostringstream os; |
1479 code->Disassemble(nullptr, os); | 1564 code->Disassemble(nullptr, os); |
1480 data->profiler_data()->SetCode(&os); | 1565 data->profiler_data()->SetCode(&os); |
1481 #endif | 1566 #endif |
1482 } | 1567 } |
1483 | 1568 |
1484 info()->SetCode(code); | 1569 info()->SetCode(code); |
1485 v8::internal::CodeGenerator::PrintCode(code, info()); | 1570 v8::internal::CodeGenerator::PrintCode(code, info()); |
1486 | 1571 |
1487 if (FLAG_trace_turbo) { | 1572 if (FLAG_trace_turbo) { |
1488 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+"); | 1573 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+"); |
1489 if (json_file != nullptr) { | 1574 if (json_file != nullptr) { |
1490 OFStream json_of(json_file); | 1575 OFStream json_of(json_file); |
1491 json_of | 1576 json_of |
1492 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; | 1577 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; |
1493 #if ENABLE_DISASSEMBLER | 1578 #if ENABLE_DISASSEMBLER |
1494 std::stringstream disassembly_stream; | 1579 std::stringstream disassembly_stream; |
1495 code->Disassemble(nullptr, disassembly_stream); | 1580 code->Disassemble(nullptr, disassembly_stream); |
1496 std::string disassembly_string(disassembly_stream.str()); | 1581 std::string disassembly_string(disassembly_stream.str()); |
1497 for (const auto& c : disassembly_string) { | 1582 for (const auto& c : disassembly_string) { |
1498 json_of << AsEscapedUC16ForJSON(c); | 1583 json_of << AsEscapedUC16ForJSON(c); |
1499 } | 1584 } |
1500 #endif // ENABLE_DISASSEMBLER | 1585 #endif // ENABLE_DISASSEMBLER |
1501 json_of << "\"}\n],\n"; | 1586 json_of << "\"}\n],\n"; |
1502 json_of << "\"nodePositions\":"; | 1587 json_of << "\"nodePositions\":"; |
1503 json_of << data->source_position_output()->str(); | 1588 json_of << data->source_position_output(); |
1504 json_of << "}"; | 1589 json_of << "}"; |
1505 fclose(json_file); | 1590 fclose(json_file); |
1506 } | 1591 } |
1507 OFStream os(stdout); | 1592 OFStream os(stdout); |
1508 os << "---------------------------------------------------\n" | 1593 os << "---------------------------------------------------\n" |
1509 << "Finished compiling method " << info()->GetDebugName().get() | 1594 << "Finished compiling method " << info()->GetDebugName().get() |
1510 << " using Turbofan" << std::endl; | 1595 << " using Turbofan" << std::endl; |
1511 } | 1596 } |
| 1597 |
1512 return code; | 1598 return code; |
1513 } | 1599 } |
1514 | 1600 |
| 1601 Handle<Code> Pipeline::ScheduleAndGenerateCode( |
| 1602 CallDescriptor* call_descriptor) { |
| 1603 Linkage linkage(call_descriptor); |
| 1604 |
| 1605 // Schedule the graph, perform instruction selection and register allocation. |
| 1606 if (!ScheduleAndSelectInstructions(&linkage)) return Handle<Code>(); |
| 1607 |
| 1608 // Generate the final machine code. |
| 1609 return GenerateCode(&linkage); |
| 1610 } |
| 1611 |
1515 void Pipeline::AllocateRegisters(const RegisterConfiguration* config, | 1612 void Pipeline::AllocateRegisters(const RegisterConfiguration* config, |
1516 CallDescriptor* descriptor, | 1613 CallDescriptor* descriptor, |
1517 bool run_verifier) { | 1614 bool run_verifier) { |
1518 PipelineData* data = this->data_; | 1615 PipelineData* data = this->data_; |
1519 // Don't track usage for this zone in compiler stats. | 1616 // Don't track usage for this zone in compiler stats. |
1520 base::SmartPointer<Zone> verifier_zone; | 1617 base::SmartPointer<Zone> verifier_zone; |
1521 RegisterAllocatorVerifier* verifier = nullptr; | 1618 RegisterAllocatorVerifier* verifier = nullptr; |
1522 if (run_verifier) { | 1619 if (run_verifier) { |
1523 verifier_zone.Reset(new Zone(isolate()->allocator())); | 1620 verifier_zone.Reset(new Zone(isolate()->allocator())); |
1524 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( | 1621 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( |
1525 verifier_zone.get(), config, data->sequence()); | 1622 verifier_zone.get(), config, data->sequence()); |
1526 } | 1623 } |
1527 | 1624 |
1528 base::SmartArrayPointer<char> debug_name; | |
1529 #ifdef DEBUG | 1625 #ifdef DEBUG |
1530 debug_name = info()->GetDebugName(); | |
1531 data_->sequence()->ValidateEdgeSplitForm(); | 1626 data_->sequence()->ValidateEdgeSplitForm(); |
1532 data_->sequence()->ValidateDeferredBlockEntryPaths(); | 1627 data_->sequence()->ValidateDeferredBlockEntryPaths(); |
1533 data_->sequence()->ValidateDeferredBlockExitPaths(); | 1628 data_->sequence()->ValidateDeferredBlockExitPaths(); |
1534 #endif | 1629 #endif |
1535 | 1630 |
1536 data->InitializeRegisterAllocationData(config, descriptor, debug_name.get()); | 1631 data->InitializeRegisterAllocationData(config, descriptor); |
1537 if (info()->is_osr()) { | 1632 if (info()->is_osr()) { |
1538 OsrHelper osr_helper(info()); | 1633 OsrHelper osr_helper(info()); |
1539 osr_helper.SetupFrame(data->frame()); | 1634 osr_helper.SetupFrame(data->frame()); |
1540 } | 1635 } |
1541 | 1636 |
1542 Run<MeetRegisterConstraintsPhase>(); | 1637 Run<MeetRegisterConstraintsPhase>(); |
1543 Run<ResolvePhisPhase>(); | 1638 Run<ResolvePhisPhase>(); |
1544 Run<BuildLiveRangesPhase>(); | 1639 Run<BuildLiveRangesPhase>(); |
1545 if (FLAG_trace_turbo_graph) { | 1640 if (FLAG_trace_turbo_graph) { |
1546 OFStream os(stdout); | 1641 OFStream os(stdout); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 | 1691 |
1597 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { | 1692 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { |
1598 TurboCfgFile tcf(data->isolate()); | 1693 TurboCfgFile tcf(data->isolate()); |
1599 tcf << AsC1VRegisterAllocationData("CodeGen", | 1694 tcf << AsC1VRegisterAllocationData("CodeGen", |
1600 data->register_allocation_data()); | 1695 data->register_allocation_data()); |
1601 } | 1696 } |
1602 | 1697 |
1603 data->DeleteRegisterAllocationZone(); | 1698 data->DeleteRegisterAllocationZone(); |
1604 } | 1699 } |
1605 | 1700 |
| 1701 CompilationInfo* Pipeline::info() const { return data_->info(); } |
| 1702 |
1606 Isolate* Pipeline::isolate() const { return info()->isolate(); } | 1703 Isolate* Pipeline::isolate() const { return info()->isolate(); } |
1607 | 1704 |
1608 } // namespace compiler | 1705 } // namespace compiler |
1609 } // namespace internal | 1706 } // namespace internal |
1610 } // namespace v8 | 1707 } // namespace v8 |
OLD | NEW |