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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 #include "src/compiler/verifier.h" | 49 #include "src/compiler/verifier.h" |
50 #include "src/compiler/zone-pool.h" | 50 #include "src/compiler/zone-pool.h" |
51 #include "src/ostreams.h" | 51 #include "src/ostreams.h" |
52 #include "src/type-info.h" | 52 #include "src/type-info.h" |
53 #include "src/utils.h" | 53 #include "src/utils.h" |
54 | 54 |
55 namespace v8 { | 55 namespace v8 { |
56 namespace internal { | 56 namespace internal { |
57 namespace compiler { | 57 namespace compiler { |
58 | 58 |
59 class PipelineData { | 59 namespace { |
| 60 |
| 61 PipelineStatistics* NewPipelineStatistics(CompilationInfo* const info, |
| 62 ZonePool* const zone_pool) { |
| 63 if (FLAG_turbo_stats) { |
| 64 PipelineStatistics* pipeline_statistics = |
| 65 new PipelineStatistics(info, zone_pool); |
| 66 pipeline_statistics->BeginPhaseKind("initializing"); |
| 67 return pipeline_statistics; |
| 68 } |
| 69 return nullptr; |
| 70 } |
| 71 |
| 72 } // namespace |
| 73 |
| 74 |
| 75 class PipelineData final { |
60 public: | 76 public: |
61 // For main entry point. | 77 // For main entry point. |
62 PipelineData(ZonePool* zone_pool, CompilationInfo* info, | 78 explicit PipelineData(CompilationInfo* info) |
63 PipelineStatistics* pipeline_statistics) | |
64 : isolate_(info->isolate()), | 79 : isolate_(info->isolate()), |
65 info_(info), | 80 info_(info), |
66 outer_zone_(info_->zone()), | 81 outer_zone_(info_->zone()), |
67 zone_pool_(zone_pool), | 82 pipeline_statistics_(NewPipelineStatistics(info, zone_pool())), |
68 pipeline_statistics_(pipeline_statistics), | |
69 compilation_failed_(false), | 83 compilation_failed_(false), |
70 code_(Handle<Code>::null()), | 84 code_(Handle<Code>::null()), |
71 graph_zone_scope_(zone_pool_), | 85 graph_zone_scope_(&zone_pool_), |
72 graph_zone_(graph_zone_scope_.zone()), | 86 graph_zone_(graph_zone_scope_.zone()), |
73 graph_(nullptr), | 87 graph_(nullptr), |
74 loop_assignment_(nullptr), | 88 loop_assignment_(nullptr), |
75 machine_(nullptr), | 89 machine_(nullptr), |
76 common_(nullptr), | 90 common_(nullptr), |
77 javascript_(nullptr), | 91 javascript_(nullptr), |
78 jsgraph_(nullptr), | 92 jsgraph_(nullptr), |
79 js_type_feedback_(nullptr), | 93 js_type_feedback_(nullptr), |
80 typer_(nullptr), | |
81 schedule_(nullptr), | 94 schedule_(nullptr), |
82 instruction_zone_scope_(zone_pool_), | 95 linkage_(nullptr), |
| 96 profiler_data_(nullptr), |
| 97 instruction_zone_scope_(&zone_pool_), |
83 instruction_zone_(instruction_zone_scope_.zone()), | 98 instruction_zone_(instruction_zone_scope_.zone()), |
84 sequence_(nullptr), | 99 sequence_(nullptr), |
85 frame_(nullptr), | 100 frame_(nullptr), |
86 register_allocation_zone_scope_(zone_pool_), | 101 register_allocation_zone_scope_(&zone_pool_), |
87 register_allocation_zone_(register_allocation_zone_scope_.zone()), | 102 register_allocation_zone_(register_allocation_zone_scope_.zone()), |
88 register_allocation_data_(nullptr) { | 103 register_allocation_data_(nullptr) { |
89 PhaseScope scope(pipeline_statistics, "init pipeline data"); | 104 PhaseScope scope(pipeline_statistics(), "init pipeline data"); |
90 graph_ = new (graph_zone_) Graph(graph_zone_); | 105 graph_ = new (graph_zone_) Graph(graph_zone_); |
91 source_positions_.Reset(new SourcePositionTable(graph_)); | 106 source_positions_.Reset(new SourcePositionTable(graph_)); |
92 machine_ = new (graph_zone_) MachineOperatorBuilder( | 107 machine_ = new (graph_zone_) MachineOperatorBuilder( |
93 graph_zone_, kMachPtr, | 108 graph_zone_, kMachPtr, |
94 InstructionSelector::SupportedMachineOperatorFlags()); | 109 InstructionSelector::SupportedMachineOperatorFlags()); |
95 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); | 110 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); |
96 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); | 111 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); |
97 jsgraph_ = new (graph_zone_) | 112 jsgraph_ = new (graph_zone_) |
98 JSGraph(isolate_, graph_, common_, javascript_, machine_); | 113 JSGraph(isolate_, graph_, common_, javascript_, machine_); |
99 typer_.Reset(new Typer(isolate_, graph_, info_->context())); | |
100 } | 114 } |
101 | 115 |
102 // For machine graph testing entry point. | 116 // For machine graph testing entry point. |
103 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, | 117 PipelineData(CompilationInfo* info, Graph* graph, Schedule* schedule) |
104 Schedule* schedule) | |
105 : isolate_(info->isolate()), | 118 : isolate_(info->isolate()), |
106 info_(info), | 119 info_(info), |
107 outer_zone_(nullptr), | 120 outer_zone_(nullptr), |
108 zone_pool_(zone_pool), | |
109 pipeline_statistics_(nullptr), | 121 pipeline_statistics_(nullptr), |
110 compilation_failed_(false), | 122 compilation_failed_(false), |
111 code_(Handle<Code>::null()), | 123 code_(Handle<Code>::null()), |
112 graph_zone_scope_(zone_pool_), | 124 graph_zone_scope_(&zone_pool_), |
113 graph_zone_(nullptr), | 125 graph_zone_(nullptr), |
114 graph_(graph), | 126 graph_(graph), |
115 source_positions_(new SourcePositionTable(graph_)), | 127 source_positions_(new SourcePositionTable(graph_)), |
116 loop_assignment_(nullptr), | 128 loop_assignment_(nullptr), |
117 machine_(nullptr), | 129 machine_(nullptr), |
118 common_(nullptr), | 130 common_(nullptr), |
119 javascript_(nullptr), | 131 javascript_(nullptr), |
120 jsgraph_(nullptr), | 132 jsgraph_(nullptr), |
121 js_type_feedback_(nullptr), | 133 js_type_feedback_(nullptr), |
122 typer_(nullptr), | |
123 schedule_(schedule), | 134 schedule_(schedule), |
124 instruction_zone_scope_(zone_pool_), | 135 linkage_(nullptr), |
| 136 profiler_data_(nullptr), |
| 137 instruction_zone_scope_(&zone_pool_), |
125 instruction_zone_(instruction_zone_scope_.zone()), | 138 instruction_zone_(instruction_zone_scope_.zone()), |
126 sequence_(nullptr), | 139 sequence_(nullptr), |
127 frame_(nullptr), | 140 frame_(nullptr), |
128 register_allocation_zone_scope_(zone_pool_), | 141 register_allocation_zone_scope_(&zone_pool_), |
129 register_allocation_zone_(register_allocation_zone_scope_.zone()), | 142 register_allocation_zone_(register_allocation_zone_scope_.zone()), |
130 register_allocation_data_(nullptr) {} | 143 register_allocation_data_(nullptr) {} |
131 | 144 |
132 // For register allocation testing entry point. | 145 // For register allocation testing entry point. |
133 PipelineData(ZonePool* zone_pool, CompilationInfo* info, | 146 PipelineData(CompilationInfo* info, InstructionSequence* sequence) |
134 InstructionSequence* sequence) | |
135 : isolate_(info->isolate()), | 147 : isolate_(info->isolate()), |
136 info_(info), | 148 info_(info), |
137 outer_zone_(nullptr), | 149 outer_zone_(nullptr), |
138 zone_pool_(zone_pool), | |
139 pipeline_statistics_(nullptr), | 150 pipeline_statistics_(nullptr), |
140 compilation_failed_(false), | 151 compilation_failed_(false), |
141 code_(Handle<Code>::null()), | 152 code_(Handle<Code>::null()), |
142 graph_zone_scope_(zone_pool_), | 153 graph_zone_scope_(&zone_pool_), |
143 graph_zone_(nullptr), | 154 graph_zone_(nullptr), |
144 graph_(nullptr), | 155 graph_(nullptr), |
145 loop_assignment_(nullptr), | 156 loop_assignment_(nullptr), |
146 machine_(nullptr), | 157 machine_(nullptr), |
147 common_(nullptr), | 158 common_(nullptr), |
148 javascript_(nullptr), | 159 javascript_(nullptr), |
149 jsgraph_(nullptr), | 160 jsgraph_(nullptr), |
150 js_type_feedback_(nullptr), | 161 js_type_feedback_(nullptr), |
151 typer_(nullptr), | |
152 schedule_(nullptr), | 162 schedule_(nullptr), |
153 instruction_zone_scope_(zone_pool_), | 163 linkage_(nullptr), |
| 164 profiler_data_(nullptr), |
| 165 instruction_zone_scope_(&zone_pool_), |
154 instruction_zone_(sequence->zone()), | 166 instruction_zone_(sequence->zone()), |
155 sequence_(sequence), | 167 sequence_(sequence), |
156 frame_(nullptr), | 168 frame_(nullptr), |
157 register_allocation_zone_scope_(zone_pool_), | 169 register_allocation_zone_scope_(&zone_pool_), |
158 register_allocation_zone_(register_allocation_zone_scope_.zone()), | 170 register_allocation_zone_(register_allocation_zone_scope_.zone()), |
159 register_allocation_data_(nullptr) {} | 171 register_allocation_data_(nullptr) {} |
160 | 172 |
161 ~PipelineData() { | 173 ~PipelineData() { |
162 DeleteRegisterAllocationZone(); | 174 DeleteRegisterAllocationZone(); |
163 DeleteInstructionZone(); | 175 DeleteInstructionZone(); |
164 DeleteGraphZone(); | 176 DeleteGraphZone(); |
165 } | 177 } |
166 | 178 |
167 Isolate* isolate() const { return isolate_; } | 179 Isolate* isolate() const { return isolate_; } |
168 CompilationInfo* info() const { return info_; } | 180 CompilationInfo* info() const { return info_; } |
169 ZonePool* zone_pool() const { return zone_pool_; } | 181 ZonePool* zone_pool() { return &zone_pool_; } |
170 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } | 182 PipelineStatistics* pipeline_statistics() const { |
| 183 return pipeline_statistics_.get(); |
| 184 } |
171 bool compilation_failed() const { return compilation_failed_; } | 185 bool compilation_failed() const { return compilation_failed_; } |
172 void set_compilation_failed() { compilation_failed_ = true; } | 186 void set_compilation_failed() { compilation_failed_ = true; } |
173 Handle<Code> code() { return code_; } | 187 Handle<Code> code() { return code_; } |
174 void set_code(Handle<Code> code) { | 188 void set_code(Handle<Code> code) { |
175 DCHECK(code_.is_null()); | 189 DCHECK(code_.is_null()); |
176 code_ = code; | 190 code_ = code; |
177 } | 191 } |
178 | 192 |
179 // RawMachineAssembler generally produces graphs which cannot be verified. | 193 // RawMachineAssembler generally produces graphs which cannot be verified. |
180 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } | 194 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } |
181 | 195 |
182 Zone* graph_zone() const { return graph_zone_; } | 196 Zone* graph_zone() const { return graph_zone_; } |
183 Graph* graph() const { return graph_; } | 197 Graph* graph() const { return graph_; } |
184 SourcePositionTable* source_positions() const { | 198 SourcePositionTable* source_positions() const { |
185 return source_positions_.get(); | 199 return source_positions_.get(); |
186 } | 200 } |
187 MachineOperatorBuilder* machine() const { return machine_; } | 201 MachineOperatorBuilder* machine() const { return machine_; } |
188 CommonOperatorBuilder* common() const { return common_; } | 202 CommonOperatorBuilder* common() const { return common_; } |
189 JSOperatorBuilder* javascript() const { return javascript_; } | 203 JSOperatorBuilder* javascript() const { return javascript_; } |
190 JSGraph* jsgraph() const { return jsgraph_; } | 204 JSGraph* jsgraph() const { return jsgraph_; } |
191 JSTypeFeedbackTable* js_type_feedback() { return js_type_feedback_; } | 205 JSTypeFeedbackTable* js_type_feedback() { return js_type_feedback_; } |
192 void set_js_type_feedback(JSTypeFeedbackTable* js_type_feedback) { | 206 void set_js_type_feedback(JSTypeFeedbackTable* js_type_feedback) { |
193 js_type_feedback_ = js_type_feedback; | 207 js_type_feedback_ = js_type_feedback; |
194 } | 208 } |
195 Typer* typer() const { return typer_.get(); } | |
196 | 209 |
197 LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; } | 210 LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; } |
198 void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) { | 211 void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) { |
199 DCHECK(!loop_assignment_); | 212 DCHECK(!loop_assignment_); |
200 loop_assignment_ = loop_assignment; | 213 loop_assignment_ = loop_assignment; |
201 } | 214 } |
202 | 215 |
203 Schedule* schedule() const { return schedule_; } | 216 Schedule* schedule() const { return schedule_; } |
204 void set_schedule(Schedule* schedule) { | 217 void set_schedule(Schedule* schedule) { |
205 DCHECK(!schedule_); | 218 DCHECK(!schedule_); |
206 schedule_ = schedule; | 219 schedule_ = schedule; |
207 } | 220 } |
208 | 221 |
209 Zone* instruction_zone() const { return instruction_zone_; } | 222 Zone* instruction_zone() const { return instruction_zone_; } |
210 InstructionSequence* sequence() const { return sequence_; } | 223 InstructionSequence* sequence() const { return sequence_; } |
211 Frame* frame() const { return frame_; } | 224 Frame* frame() const { return frame_; } |
212 | 225 |
| 226 Linkage* linkage() const { return linkage_; } |
| 227 void set_linkage(Linkage* linkage) { linkage_ = linkage; } |
| 228 |
| 229 BasicBlockProfiler::Data* profiler_data() const { return profiler_data_; } |
| 230 |
213 Zone* register_allocation_zone() const { return register_allocation_zone_; } | 231 Zone* register_allocation_zone() const { return register_allocation_zone_; } |
214 RegisterAllocationData* register_allocation_data() const { | 232 RegisterAllocationData* register_allocation_data() const { |
215 return register_allocation_data_; | 233 return register_allocation_data_; |
216 } | 234 } |
217 | 235 |
218 void DeleteGraphZone() { | 236 void DeleteGraphZone() { |
219 // Destroy objects with destructors first. | 237 // Destroy objects with destructors first. |
220 source_positions_.Reset(nullptr); | 238 source_positions_.Reset(nullptr); |
221 typer_.Reset(nullptr); | |
222 if (graph_zone_ == nullptr) return; | 239 if (graph_zone_ == nullptr) return; |
223 // Destroy zone and clear pointers. | 240 // Destroy zone and clear pointers. |
224 graph_zone_scope_.Destroy(); | 241 graph_zone_scope_.Destroy(); |
225 graph_zone_ = nullptr; | 242 graph_zone_ = nullptr; |
226 graph_ = nullptr; | 243 graph_ = nullptr; |
227 loop_assignment_ = nullptr; | 244 loop_assignment_ = nullptr; |
228 machine_ = nullptr; | 245 machine_ = nullptr; |
229 common_ = nullptr; | 246 common_ = nullptr; |
230 javascript_ = nullptr; | 247 javascript_ = nullptr; |
231 jsgraph_ = nullptr; | 248 jsgraph_ = nullptr; |
(...skipping 11 matching lines...) Expand all Loading... |
243 | 260 |
244 void DeleteRegisterAllocationZone() { | 261 void DeleteRegisterAllocationZone() { |
245 if (register_allocation_zone_ == nullptr) return; | 262 if (register_allocation_zone_ == nullptr) return; |
246 register_allocation_zone_scope_.Destroy(); | 263 register_allocation_zone_scope_.Destroy(); |
247 register_allocation_zone_ = nullptr; | 264 register_allocation_zone_ = nullptr; |
248 register_allocation_data_ = nullptr; | 265 register_allocation_data_ = nullptr; |
249 } | 266 } |
250 | 267 |
251 void InitializeInstructionSequence() { | 268 void InitializeInstructionSequence() { |
252 DCHECK(sequence_ == nullptr); | 269 DCHECK(sequence_ == nullptr); |
| 270 if (FLAG_turbo_profiling) { |
| 271 profiler_data_ = |
| 272 BasicBlockInstrumentor::Instrument(info(), graph(), schedule()); |
| 273 } |
253 InstructionBlocks* instruction_blocks = | 274 InstructionBlocks* instruction_blocks = |
254 InstructionSequence::InstructionBlocksFor(instruction_zone(), | 275 InstructionSequence::InstructionBlocksFor(instruction_zone(), |
255 schedule()); | 276 schedule()); |
256 sequence_ = new (instruction_zone()) InstructionSequence( | 277 sequence_ = new (instruction_zone()) InstructionSequence( |
257 info()->isolate(), instruction_zone(), instruction_blocks); | 278 info()->isolate(), instruction_zone(), instruction_blocks); |
258 } | 279 } |
259 | 280 |
260 void InitializeRegisterAllocationData(const RegisterConfiguration* config, | 281 void InitializeRegisterAllocationData(const RegisterConfiguration* config, |
261 const char* debug_name) { | 282 const char* debug_name) { |
262 DCHECK(frame_ == nullptr); | 283 DCHECK(frame_ == nullptr); |
263 DCHECK(register_allocation_data_ == nullptr); | 284 DCHECK(register_allocation_data_ == nullptr); |
264 frame_ = new (instruction_zone()) Frame(); | 285 frame_ = new (instruction_zone()) Frame(); |
265 register_allocation_data_ = new (register_allocation_zone()) | 286 register_allocation_data_ = new (register_allocation_zone()) |
266 RegisterAllocationData(config, register_allocation_zone(), frame(), | 287 RegisterAllocationData(config, register_allocation_zone(), frame(), |
267 sequence(), debug_name); | 288 sequence(), debug_name); |
268 } | 289 } |
269 | 290 |
| 291 std::ostringstream& source_position_output() { |
| 292 return source_position_output_; |
| 293 } |
| 294 |
270 private: | 295 private: |
271 Isolate* isolate_; | 296 Isolate* isolate_; |
272 CompilationInfo* info_; | 297 CompilationInfo* info_; |
273 Zone* outer_zone_; | 298 Zone* outer_zone_; |
274 ZonePool* const zone_pool_; | 299 ZonePool zone_pool_; |
275 PipelineStatistics* pipeline_statistics_; | 300 SmartPointer<PipelineStatistics> pipeline_statistics_; |
276 bool compilation_failed_; | 301 bool compilation_failed_; |
277 Handle<Code> code_; | 302 Handle<Code> code_; |
278 | 303 |
279 // All objects in the following group of fields are allocated in graph_zone_. | 304 // All objects in the following group of fields are allocated in graph_zone_. |
280 // They are all set to NULL when the graph_zone_ is destroyed. | 305 // They are all set to NULL when the graph_zone_ is destroyed. |
281 ZonePool::Scope graph_zone_scope_; | 306 ZonePool::Scope graph_zone_scope_; |
282 Zone* graph_zone_; | 307 Zone* graph_zone_; |
283 Graph* graph_; | 308 Graph* graph_; |
284 // TODO(dcarney): make this into a ZoneObject. | 309 // TODO(dcarney): make this into a ZoneObject. |
285 SmartPointer<SourcePositionTable> source_positions_; | 310 SmartPointer<SourcePositionTable> source_positions_; |
286 LoopAssignmentAnalysis* loop_assignment_; | 311 LoopAssignmentAnalysis* loop_assignment_; |
287 MachineOperatorBuilder* machine_; | 312 MachineOperatorBuilder* machine_; |
288 CommonOperatorBuilder* common_; | 313 CommonOperatorBuilder* common_; |
289 JSOperatorBuilder* javascript_; | 314 JSOperatorBuilder* javascript_; |
290 JSGraph* jsgraph_; | 315 JSGraph* jsgraph_; |
291 JSTypeFeedbackTable* js_type_feedback_; | 316 JSTypeFeedbackTable* js_type_feedback_; |
292 // TODO(dcarney): make this into a ZoneObject. | 317 // TODO(dcarney): make this into a ZoneObject. |
293 SmartPointer<Typer> typer_; | |
294 Schedule* schedule_; | 318 Schedule* schedule_; |
| 319 Linkage* linkage_; |
| 320 BasicBlockProfiler::Data* profiler_data_; |
| 321 std::ostringstream source_position_output_; |
295 | 322 |
296 // All objects in the following group of fields are allocated in | 323 // All objects in the following group of fields are allocated in |
297 // instruction_zone_. They are all set to NULL when the instruction_zone_ is | 324 // instruction_zone_. They are all set to NULL when the instruction_zone_ is |
298 // destroyed. | 325 // destroyed. |
299 ZonePool::Scope instruction_zone_scope_; | 326 ZonePool::Scope instruction_zone_scope_; |
300 Zone* instruction_zone_; | 327 Zone* instruction_zone_; |
301 InstructionSequence* sequence_; | 328 InstructionSequence* sequence_; |
302 Frame* frame_; | 329 Frame* frame_; |
303 | 330 |
304 // All objects in the following group of fields are allocated in | 331 // All objects in the following group of fields are allocated in |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 Zone* zone() { return zone_scope_.zone(); } | 470 Zone* zone() { return zone_scope_.zone(); } |
444 | 471 |
445 private: | 472 private: |
446 PhaseScope phase_scope_; | 473 PhaseScope phase_scope_; |
447 ZonePool::Scope zone_scope_; | 474 ZonePool::Scope zone_scope_; |
448 }; | 475 }; |
449 | 476 |
450 } // namespace | 477 } // namespace |
451 | 478 |
452 | 479 |
| 480 Pipeline::Pipeline(CompilationInfo* info) : Pipeline(new PipelineData(info)) {} |
| 481 |
| 482 |
| 483 Pipeline::~Pipeline() { delete data_; } |
| 484 |
| 485 |
| 486 CompilationInfo* Pipeline::info() const { return data()->info(); } |
| 487 |
| 488 |
453 template <typename Phase> | 489 template <typename Phase> |
454 void Pipeline::Run() { | 490 void Pipeline::Run() { |
455 PipelineRunScope scope(this->data_, Phase::phase_name()); | 491 PipelineRunScope scope(data(), Phase::phase_name()); |
456 Phase phase; | 492 Phase phase; |
457 phase.Run(this->data_, scope.zone()); | 493 phase.Run(data(), scope.zone()); |
458 } | 494 } |
459 | 495 |
460 | 496 |
461 template <typename Phase, typename Arg0> | 497 template <typename Phase, typename Arg0> |
462 void Pipeline::Run(Arg0 arg_0) { | 498 void Pipeline::Run(Arg0 arg_0) { |
463 PipelineRunScope scope(this->data_, Phase::phase_name()); | 499 PipelineRunScope scope(data(), Phase::phase_name()); |
464 Phase phase; | 500 Phase phase; |
465 phase.Run(this->data_, scope.zone(), arg_0); | 501 phase.Run(data(), scope.zone(), arg_0); |
466 } | 502 } |
467 | 503 |
468 | 504 |
469 struct LoopAssignmentAnalysisPhase { | 505 struct LoopAssignmentAnalysisPhase { |
470 static const char* phase_name() { return "loop assignment analysis"; } | 506 static const char* phase_name() { return "loop assignment analysis"; } |
471 | 507 |
472 void Run(PipelineData* data, Zone* temp_zone) { | 508 void Run(PipelineData* data, Zone* temp_zone) { |
473 AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info()); | 509 AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info()); |
474 LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze(); | 510 LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze(); |
475 data->set_loop_assignment(loop_assignment); | 511 data->set_loop_assignment(loop_assignment); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 temp_zone, data->info(), data->jsgraph()); | 551 temp_zone, data->info(), data->jsgraph()); |
516 AddReducer(data, &graph_reducer, &inliner); | 552 AddReducer(data, &graph_reducer, &inliner); |
517 graph_reducer.ReduceGraph(); | 553 graph_reducer.ReduceGraph(); |
518 } | 554 } |
519 }; | 555 }; |
520 | 556 |
521 | 557 |
522 struct TyperPhase { | 558 struct TyperPhase { |
523 static const char* phase_name() { return "typer"; } | 559 static const char* phase_name() { return "typer"; } |
524 | 560 |
525 void Run(PipelineData* data, Zone* temp_zone) { data->typer()->Run(); } | 561 void Run(PipelineData* data, Zone* temp_zone, Typer* typer) { typer->Run(); } |
526 }; | 562 }; |
527 | 563 |
528 | 564 |
529 struct OsrDeconstructionPhase { | 565 struct OsrDeconstructionPhase { |
530 static const char* phase_name() { return "OSR deconstruction"; } | 566 static const char* phase_name() { return "OSR deconstruction"; } |
531 | 567 |
532 void Run(PipelineData* data, Zone* temp_zone) { | 568 void Run(PipelineData* data, Zone* temp_zone) { |
533 OsrHelper osr_helper(data->info()); | 569 OsrHelper osr_helper(data->info()); |
534 osr_helper.Deconstruct(data->jsgraph(), data->common(), temp_zone); | 570 osr_helper.Deconstruct(data->jsgraph(), data->common(), temp_zone); |
535 } | 571 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 : Scheduler::kNoFlags); | 731 : Scheduler::kNoFlags); |
696 if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule); | 732 if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule); |
697 data->set_schedule(schedule); | 733 data->set_schedule(schedule); |
698 } | 734 } |
699 }; | 735 }; |
700 | 736 |
701 | 737 |
702 struct InstructionSelectionPhase { | 738 struct InstructionSelectionPhase { |
703 static const char* phase_name() { return "select instructions"; } | 739 static const char* phase_name() { return "select instructions"; } |
704 | 740 |
705 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { | 741 void Run(PipelineData* data, Zone* temp_zone) { |
706 InstructionSelector selector( | 742 InstructionSelector selector( |
707 temp_zone, data->graph()->NodeCount(), linkage, data->sequence(), | 743 temp_zone, data->graph()->NodeCount(), data->linkage(), |
708 data->schedule(), data->source_positions(), | 744 data->sequence(), data->schedule(), data->source_positions(), |
709 data->info()->is_source_positions_enabled() | 745 data->info()->is_source_positions_enabled() |
710 ? InstructionSelector::kAllSourcePositions | 746 ? InstructionSelector::kAllSourcePositions |
711 : InstructionSelector::kCallSourcePositions); | 747 : InstructionSelector::kCallSourcePositions); |
712 selector.SelectInstructions(); | 748 selector.SelectInstructions(); |
713 } | 749 } |
714 }; | 750 }; |
715 | 751 |
716 | 752 |
717 struct MeetRegisterConstraintsPhase { | 753 struct MeetRegisterConstraintsPhase { |
718 static const char* phase_name() { return "meet register constraints"; } | 754 static const char* phase_name() { return "meet register constraints"; } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence())) { | 891 if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence())) { |
856 JumpThreading::ApplyForwarding(result, data->sequence()); | 892 JumpThreading::ApplyForwarding(result, data->sequence()); |
857 } | 893 } |
858 } | 894 } |
859 }; | 895 }; |
860 | 896 |
861 | 897 |
862 struct GenerateCodePhase { | 898 struct GenerateCodePhase { |
863 static const char* phase_name() { return "generate code"; } | 899 static const char* phase_name() { return "generate code"; } |
864 | 900 |
865 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { | 901 void Run(PipelineData* data, Zone* temp_zone) { |
866 CodeGenerator generator(data->frame(), linkage, data->sequence(), | 902 CodeGenerator generator(data->frame(), data->linkage(), data->sequence(), |
867 data->info()); | 903 data->info()); |
868 data->set_code(generator.GenerateCode()); | 904 data->set_code(generator.GenerateCode()); |
869 } | 905 } |
870 }; | 906 }; |
871 | 907 |
872 | 908 |
873 struct PrintGraphPhase { | 909 struct PrintGraphPhase { |
874 static const char* phase_name() { return nullptr; } | 910 static const char* phase_name() { return nullptr; } |
875 | 911 |
876 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { | 912 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { | 960 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { |
925 if (FLAG_trace_turbo) { | 961 if (FLAG_trace_turbo) { |
926 Run<PrintGraphPhase>(phase); | 962 Run<PrintGraphPhase>(phase); |
927 } | 963 } |
928 if (FLAG_turbo_verify) { | 964 if (FLAG_turbo_verify) { |
929 Run<VerifyGraphPhase>(untyped); | 965 Run<VerifyGraphPhase>(untyped); |
930 } | 966 } |
931 } | 967 } |
932 | 968 |
933 | 969 |
934 Handle<Code> Pipeline::GenerateCode() { | 970 bool Pipeline::CreateGraph() { |
935 // TODO(mstarzinger): This is just a temporary hack to make TurboFan work, | 971 // TODO(mstarzinger): This is just a temporary hack to make TurboFan work, |
936 // the correct solution is to restore the context register after invoking | 972 // the correct solution is to restore the context register after invoking |
937 // builtins from full-codegen. | 973 // builtins from full-codegen. |
938 Handle<SharedFunctionInfo> shared = info()->shared_info(); | 974 Handle<SharedFunctionInfo> shared = info()->shared_info(); |
939 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { | 975 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { |
940 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); | 976 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); |
941 Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id); | 977 Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id); |
942 if (*info()->closure() == builtin) return Handle<Code>::null(); | 978 if (*info()->closure() == builtin) return false; |
943 } | 979 } |
944 | 980 |
945 // TODO(dslomov): support turbo optimization of subclass constructors. | 981 // TODO(dslomov): support turbo optimization of subclass constructors. |
946 if (IsSubclassConstructor(shared->kind())) { | 982 if (IsSubclassConstructor(shared->kind())) { |
947 shared->DisableOptimization(kSuperReference); | 983 shared->DisableOptimization(kSuperReference); |
948 return Handle<Code>::null(); | 984 return false; |
949 } | |
950 | |
951 ZonePool zone_pool; | |
952 SmartPointer<PipelineStatistics> pipeline_statistics; | |
953 | |
954 if (FLAG_turbo_stats) { | |
955 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); | |
956 pipeline_statistics->BeginPhaseKind("initializing"); | |
957 } | 985 } |
958 | 986 |
959 if (FLAG_trace_turbo) { | 987 if (FLAG_trace_turbo) { |
960 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "w+"); | 988 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "w+"); |
961 if (json_file != nullptr) { | 989 if (json_file != nullptr) { |
962 OFStream json_of(json_file); | 990 OFStream json_of(json_file); |
963 Handle<Script> script = info()->script(); | 991 Handle<Script> script = info()->script(); |
964 FunctionLiteral* function = info()->function(); | 992 FunctionLiteral* function = info()->function(); |
965 SmartArrayPointer<char> function_name = | 993 SmartArrayPointer<char> function_name = |
966 info()->shared_info()->DebugName()->ToCString(); | 994 info()->shared_info()->DebugName()->ToCString(); |
967 int pos = info()->shared_info()->start_position(); | 995 int pos = info()->shared_info()->start_position(); |
968 json_of << "{\"function\":\"" << function_name.get() | 996 json_of << "{\"function\":\"" << function_name.get() |
969 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; | 997 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; |
970 if (!script->IsUndefined() && !script->source()->IsUndefined()) { | 998 if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
971 DisallowHeapAllocation no_allocation; | 999 DisallowHeapAllocation no_allocation; |
972 int start = function->start_position(); | 1000 int start = function->start_position(); |
973 int len = function->end_position() - start; | 1001 int len = function->end_position() - start; |
974 String::SubStringRange source(String::cast(script->source()), start, | 1002 String::SubStringRange source(String::cast(script->source()), start, |
975 len); | 1003 len); |
976 for (const auto& c : source) { | 1004 for (const auto& c : source) { |
977 json_of << AsEscapedUC16ForJSON(c); | 1005 json_of << AsEscapedUC16ForJSON(c); |
978 } | 1006 } |
979 } | 1007 } |
980 json_of << "\",\n\"phases\":["; | 1008 json_of << "\",\n\"phases\":["; |
981 fclose(json_file); | 1009 fclose(json_file); |
982 } | 1010 } |
983 } | 1011 } |
984 | 1012 |
985 PipelineData data(&zone_pool, info(), pipeline_statistics.get()); | |
986 this->data_ = &data; | |
987 | |
988 if (info()->is_type_feedback_enabled()) { | 1013 if (info()->is_type_feedback_enabled()) { |
989 data.set_js_type_feedback(new (data.graph_zone()) | 1014 data()->set_js_type_feedback(new (data()->graph_zone()) |
990 JSTypeFeedbackTable(data.graph_zone())); | 1015 JSTypeFeedbackTable(data()->graph_zone())); |
991 } | 1016 } |
992 | 1017 |
993 BeginPhaseKind("graph creation"); | 1018 BeginPhaseKind("graph creation"); |
994 | 1019 |
995 if (FLAG_trace_turbo) { | 1020 if (FLAG_trace_turbo) { |
996 OFStream os(stdout); | 1021 OFStream os(stdout); |
997 os << "---------------------------------------------------\n" | 1022 os << "---------------------------------------------------\n" |
998 << "Begin compiling method " << GetDebugName(info()).get() | 1023 << "Begin compiling method " << GetDebugName(info()).get() |
999 << " using Turbofan" << std::endl; | 1024 << " using Turbofan" << std::endl; |
1000 TurboCfgFile tcf(isolate()); | 1025 TurboCfgFile tcf(isolate()); |
1001 tcf << AsC1VCompilation(info()); | 1026 tcf << AsC1VCompilation(info()); |
1002 } | 1027 } |
1003 | 1028 |
1004 data.source_positions()->AddDecorator(); | 1029 data()->source_positions()->AddDecorator(); |
1005 | 1030 |
1006 if (FLAG_loop_assignment_analysis) { | 1031 if (FLAG_loop_assignment_analysis) { |
1007 Run<LoopAssignmentAnalysisPhase>(); | 1032 Run<LoopAssignmentAnalysisPhase>(); |
1008 } | 1033 } |
1009 | 1034 |
1010 Run<GraphBuilderPhase>(info()->is_context_specializing()); | 1035 Run<GraphBuilderPhase>(info()->is_context_specializing()); |
1011 if (data.compilation_failed()) return Handle<Code>::null(); | 1036 if (data()->compilation_failed()) return false; |
1012 RunPrintAndVerify("Initial untyped", true); | 1037 RunPrintAndVerify("Initial untyped", true); |
1013 | 1038 |
1014 Run<EarlyControlReductionPhase>(); | 1039 Run<EarlyControlReductionPhase>(); |
1015 RunPrintAndVerify("Early Control reduced", true); | 1040 RunPrintAndVerify("Early Control reduced", true); |
1016 | 1041 |
1017 if (info()->is_context_specializing()) { | 1042 if (info()->is_context_specializing()) { |
1018 // Specialize the code to the context as aggressively as possible. | 1043 // Specialize the code to the context as aggressively as possible. |
1019 Run<ContextSpecializerPhase>(); | 1044 Run<ContextSpecializerPhase>(); |
1020 RunPrintAndVerify("Context specialized", true); | 1045 RunPrintAndVerify("Context specialized", true); |
1021 } | 1046 } |
1022 | 1047 |
1023 Run<InliningPhase>(); | 1048 Run<InliningPhase>(); |
1024 RunPrintAndVerify("Inlined", true); | 1049 RunPrintAndVerify("Inlined", true); |
1025 | 1050 |
1026 if (FLAG_print_turbo_replay) { | 1051 if (FLAG_print_turbo_replay) { |
1027 // Print a replay of the initial graph. | 1052 // Print a replay of the initial graph. |
1028 GraphReplayPrinter::PrintReplay(data.graph()); | 1053 GraphReplayPrinter::PrintReplay(data()->graph()); |
1029 } | 1054 } |
1030 | 1055 |
1031 // Bailout here in case target architecture is not supported. | 1056 // Bailout here in case target architecture is not supported. |
1032 if (!SupportedTarget()) return Handle<Code>::null(); | 1057 if (!SupportedTarget()) return false; |
1033 | 1058 |
| 1059 SmartPointer<Typer> typer; |
1034 if (info()->is_typing_enabled()) { | 1060 if (info()->is_typing_enabled()) { |
1035 // Type the graph. | 1061 // Type the graph. |
1036 Run<TyperPhase>(); | 1062 typer.Reset(new Typer(isolate(), data()->graph(), info()->context())); |
| 1063 Run<TyperPhase>(typer.get()); |
1037 RunPrintAndVerify("Typed"); | 1064 RunPrintAndVerify("Typed"); |
1038 } | 1065 } |
1039 | 1066 |
1040 BeginPhaseKind("lowering"); | 1067 BeginPhaseKind("lowering"); |
1041 | 1068 |
1042 if (info()->is_typing_enabled()) { | 1069 if (info()->is_typing_enabled()) { |
1043 // Lower JSOperators where we can determine types. | 1070 // Lower JSOperators where we can determine types. |
1044 Run<TypedLoweringPhase>(); | 1071 Run<TypedLoweringPhase>(); |
1045 RunPrintAndVerify("Lowered typed"); | 1072 RunPrintAndVerify("Lowered typed"); |
1046 | 1073 |
(...skipping 25 matching lines...) Expand all Loading... |
1072 // Lower changes that have been inserted before. | 1099 // Lower changes that have been inserted before. |
1073 Run<ChangeLoweringPhase>(); | 1100 Run<ChangeLoweringPhase>(); |
1074 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1101 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1075 RunPrintAndVerify("Lowered changes", true); | 1102 RunPrintAndVerify("Lowered changes", true); |
1076 | 1103 |
1077 Run<LateControlReductionPhase>(); | 1104 Run<LateControlReductionPhase>(); |
1078 RunPrintAndVerify("Late Control reduced"); | 1105 RunPrintAndVerify("Late Control reduced"); |
1079 } else { | 1106 } else { |
1080 if (info()->is_osr()) { | 1107 if (info()->is_osr()) { |
1081 Run<OsrDeconstructionPhase>(); | 1108 Run<OsrDeconstructionPhase>(); |
1082 if (info()->bailout_reason() != kNoReason) return Handle<Code>::null(); | 1109 if (info()->bailout_reason() != kNoReason) return false; |
1083 RunPrintAndVerify("OSR deconstruction"); | 1110 RunPrintAndVerify("OSR deconstruction"); |
1084 } | 1111 } |
1085 } | 1112 } |
1086 | 1113 |
1087 // Lower any remaining generic JSOperators. | 1114 // Lower any remaining generic JSOperators. |
1088 Run<GenericLoweringPhase>(); | 1115 Run<GenericLoweringPhase>(); |
1089 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1116 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1090 RunPrintAndVerify("Lowered generic", true); | 1117 RunPrintAndVerify("Lowered generic", true); |
1091 | 1118 |
1092 BeginPhaseKind("block building"); | 1119 BeginPhaseKind("block building"); |
1093 | 1120 |
1094 data.source_positions()->RemoveDecorator(); | 1121 data()->source_positions()->RemoveDecorator(); |
1095 | 1122 return true; |
1096 return ScheduleAndGenerateCode( | |
1097 Linkage::ComputeIncoming(data.instruction_zone(), info())); | |
1098 } | 1123 } |
1099 | 1124 |
1100 | 1125 |
| 1126 bool Pipeline::OptimizeGraph() { |
| 1127 return ScheduleAndAllocateRegisters( |
| 1128 Linkage::ComputeIncoming(data()->instruction_zone(), info())); |
| 1129 } |
| 1130 |
| 1131 |
| 1132 Handle<Code> Pipeline::GenerateCode() { |
| 1133 if (!CreateGraph()) return Handle<Code>::null(); |
| 1134 return ScheduleAndGenerateCode( |
| 1135 Linkage::ComputeIncoming(data()->instruction_zone(), info())); |
| 1136 } |
| 1137 |
| 1138 |
1101 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1139 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
1102 Graph* graph, | 1140 Graph* graph, |
1103 Schedule* schedule) { | 1141 Schedule* schedule) { |
1104 CallDescriptor* call_descriptor = | 1142 CallDescriptor* call_descriptor = |
1105 Linkage::ComputeIncoming(info->zone(), info); | 1143 Linkage::ComputeIncoming(info->zone(), info); |
1106 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); | 1144 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); |
1107 } | 1145 } |
1108 | 1146 |
1109 | 1147 |
1110 Handle<Code> Pipeline::GenerateCodeForTesting(Isolate* isolate, | 1148 Handle<Code> Pipeline::GenerateCodeForTesting(Isolate* isolate, |
1111 CallDescriptor* call_descriptor, | 1149 CallDescriptor* call_descriptor, |
1112 Graph* graph, | 1150 Graph* graph, |
1113 Schedule* schedule) { | 1151 Schedule* schedule) { |
1114 FakeStubForTesting stub(isolate); | 1152 FakeStubForTesting stub(isolate); |
1115 CompilationInfo info(&stub, isolate, graph->zone()); | 1153 CompilationInfo info(&stub, isolate, graph->zone()); |
1116 return GenerateCodeForTesting(&info, call_descriptor, graph, schedule); | 1154 return GenerateCodeForTesting(&info, call_descriptor, graph, schedule); |
1117 } | 1155 } |
1118 | 1156 |
1119 | 1157 |
1120 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1158 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
1121 CallDescriptor* call_descriptor, | 1159 CallDescriptor* call_descriptor, |
1122 Graph* graph, | 1160 Graph* graph, |
1123 Schedule* schedule) { | 1161 Schedule* schedule) { |
1124 // Construct a pipeline for scheduling and code generation. | 1162 // Construct a pipeline for scheduling and code generation. |
1125 ZonePool zone_pool; | 1163 PipelineData* data = new PipelineData(info, graph, schedule); |
1126 PipelineData data(&zone_pool, info, graph, schedule); | |
1127 SmartPointer<PipelineStatistics> pipeline_statistics; | 1164 SmartPointer<PipelineStatistics> pipeline_statistics; |
1128 if (FLAG_turbo_stats) { | 1165 if (FLAG_turbo_stats) { |
1129 pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool)); | 1166 pipeline_statistics.Reset(new PipelineStatistics(info, data->zone_pool())); |
1130 pipeline_statistics->BeginPhaseKind("test codegen"); | 1167 pipeline_statistics->BeginPhaseKind("test codegen"); |
1131 } | 1168 } |
1132 | 1169 |
1133 Pipeline pipeline(info); | 1170 Pipeline pipeline(data); |
1134 pipeline.data_ = &data; | 1171 if (data->schedule() == nullptr) { |
1135 if (data.schedule() == nullptr) { | |
1136 // TODO(rossberg): Should this really be untyped? | 1172 // TODO(rossberg): Should this really be untyped? |
1137 pipeline.RunPrintAndVerify("Machine", true); | 1173 pipeline.RunPrintAndVerify("Machine", true); |
1138 } | 1174 } |
1139 | 1175 |
1140 return pipeline.ScheduleAndGenerateCode(call_descriptor); | 1176 return pipeline.ScheduleAndGenerateCode(call_descriptor); |
1141 } | 1177 } |
1142 | 1178 |
1143 | 1179 |
1144 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, | 1180 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, |
1145 InstructionSequence* sequence, | 1181 InstructionSequence* sequence, |
1146 bool run_verifier) { | 1182 bool run_verifier) { |
1147 FakeStubForTesting stub(sequence->isolate()); | 1183 FakeStubForTesting stub(sequence->isolate()); |
1148 CompilationInfo info(&stub, sequence->isolate(), sequence->zone()); | 1184 CompilationInfo info(&stub, sequence->isolate(), sequence->zone()); |
1149 ZonePool zone_pool; | 1185 PipelineData* data = new PipelineData(&info, sequence); |
1150 PipelineData data(&zone_pool, &info, sequence); | 1186 Pipeline pipeline(data); |
1151 Pipeline pipeline(&info); | |
1152 pipeline.data_ = &data; | |
1153 pipeline.AllocateRegisters(config, run_verifier); | 1187 pipeline.AllocateRegisters(config, run_verifier); |
1154 return !data.compilation_failed(); | 1188 return !data->compilation_failed(); |
1155 } | 1189 } |
1156 | 1190 |
1157 | 1191 |
1158 Handle<Code> Pipeline::ScheduleAndGenerateCode( | 1192 bool Pipeline::ScheduleAndAllocateRegisters(CallDescriptor* call_descriptor) { |
1159 CallDescriptor* call_descriptor) { | 1193 PipelineData* data = this->data(); |
1160 PipelineData* data = this->data_; | |
1161 | 1194 |
1162 DCHECK_NOT_NULL(data->graph()); | 1195 DCHECK_NOT_NULL(data->graph()); |
1163 CHECK(SupportedBackend()); | 1196 CHECK(SupportedBackend()); |
1164 | 1197 |
1165 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); | 1198 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); |
1166 TraceSchedule(data->info(), data->schedule()); | 1199 TraceSchedule(data->info(), data->schedule()); |
1167 | 1200 |
1168 BasicBlockProfiler::Data* profiler_data = NULL; | |
1169 if (FLAG_turbo_profiling) { | |
1170 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), | |
1171 data->schedule()); | |
1172 } | |
1173 | |
1174 data->InitializeInstructionSequence(); | 1201 data->InitializeInstructionSequence(); |
1175 | 1202 |
1176 // Select and schedule instructions covering the scheduled graph. | 1203 // Select and schedule instructions covering the scheduled graph. |
1177 Linkage linkage(call_descriptor); | 1204 data->set_linkage(new (data->info()->zone()) Linkage(call_descriptor)); |
1178 Run<InstructionSelectionPhase>(&linkage); | 1205 Run<InstructionSelectionPhase>(); |
1179 | 1206 |
1180 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { | 1207 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { |
1181 TurboCfgFile tcf(isolate()); | 1208 TurboCfgFile tcf(isolate()); |
1182 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), | 1209 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), |
1183 data->sequence()); | 1210 data->sequence()); |
1184 } | 1211 } |
1185 | 1212 |
1186 std::ostringstream source_position_output; | |
1187 if (FLAG_trace_turbo) { | 1213 if (FLAG_trace_turbo) { |
1188 // Output source position information before the graph is deleted. | 1214 // Output source position information before the graph is deleted. |
1189 data_->source_positions()->Print(source_position_output); | 1215 data->source_positions()->Print(data->source_position_output()); |
1190 } | 1216 } |
1191 | 1217 |
1192 data->DeleteGraphZone(); | 1218 data->DeleteGraphZone(); |
1193 | 1219 |
1194 BeginPhaseKind("register allocation"); | 1220 BeginPhaseKind("register allocation"); |
1195 | 1221 |
1196 bool run_verifier = FLAG_turbo_verify_allocation; | 1222 bool run_verifier = FLAG_turbo_verify_allocation; |
1197 // Allocate registers. | 1223 // Allocate registers. |
1198 AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier); | 1224 AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier); |
1199 if (data->compilation_failed()) { | 1225 if (data->compilation_failed()) { |
1200 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 1226 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
1201 return Handle<Code>(); | 1227 return false; |
1202 } | 1228 } |
1203 | 1229 |
1204 BeginPhaseKind("code generation"); | 1230 BeginPhaseKind("code generation"); |
1205 | 1231 |
1206 // Optimimize jumps. | 1232 // Optimimize jumps. |
1207 if (FLAG_turbo_jt) { | 1233 if (FLAG_turbo_jt) { |
1208 Run<JumpThreadingPhase>(); | 1234 Run<JumpThreadingPhase>(); |
1209 } | 1235 } |
1210 | 1236 |
| 1237 return true; |
| 1238 } |
| 1239 |
| 1240 |
| 1241 Handle<Code> Pipeline::DoGenerateCode() { |
| 1242 PipelineData* data = this->data_; |
| 1243 |
1211 // Generate final machine code. | 1244 // Generate final machine code. |
1212 Run<GenerateCodePhase>(&linkage); | 1245 Run<GenerateCodePhase>(); |
1213 | 1246 |
1214 Handle<Code> code = data->code(); | 1247 Handle<Code> code = data->code(); |
1215 if (profiler_data != NULL) { | 1248 if (data->profiler_data()) { |
1216 #if ENABLE_DISASSEMBLER | 1249 #if ENABLE_DISASSEMBLER |
1217 std::ostringstream os; | 1250 std::ostringstream os; |
1218 code->Disassemble(NULL, os); | 1251 code->Disassemble(NULL, os); |
1219 profiler_data->SetCode(&os); | 1252 data->profiler_data()->SetCode(&os); |
1220 #endif | 1253 #endif |
1221 } | 1254 } |
1222 | 1255 |
1223 info()->SetCode(code); | 1256 info()->SetCode(code); |
1224 v8::internal::CodeGenerator::PrintCode(code, info()); | 1257 v8::internal::CodeGenerator::PrintCode(code, info()); |
1225 | 1258 |
1226 if (FLAG_trace_turbo) { | 1259 if (FLAG_trace_turbo) { |
1227 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "a+"); | 1260 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "a+"); |
1228 if (json_file != nullptr) { | 1261 if (json_file != nullptr) { |
1229 OFStream json_of(json_file); | 1262 OFStream json_of(json_file); |
1230 json_of | 1263 json_of |
1231 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; | 1264 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; |
1232 #if ENABLE_DISASSEMBLER | 1265 #if ENABLE_DISASSEMBLER |
1233 std::stringstream disassembly_stream; | 1266 std::stringstream disassembly_stream; |
1234 code->Disassemble(NULL, disassembly_stream); | 1267 code->Disassemble(NULL, disassembly_stream); |
1235 std::string disassembly_string(disassembly_stream.str()); | 1268 std::string disassembly_string(disassembly_stream.str()); |
1236 for (const auto& c : disassembly_string) { | 1269 for (const auto& c : disassembly_string) { |
1237 json_of << AsEscapedUC16ForJSON(c); | 1270 json_of << AsEscapedUC16ForJSON(c); |
1238 } | 1271 } |
1239 #endif // ENABLE_DISASSEMBLER | 1272 #endif // ENABLE_DISASSEMBLER |
1240 json_of << "\"}\n],\n"; | 1273 json_of << "\"}\n],\n"; |
1241 json_of << "\"nodePositions\":"; | 1274 json_of << "\"nodePositions\":"; |
1242 json_of << source_position_output.str(); | 1275 json_of << data->source_position_output().str(); |
1243 json_of << "}"; | 1276 json_of << "}"; |
1244 fclose(json_file); | 1277 fclose(json_file); |
1245 } | 1278 } |
1246 OFStream os(stdout); | 1279 OFStream os(stdout); |
1247 os << "---------------------------------------------------\n" | 1280 os << "---------------------------------------------------\n" |
1248 << "Finished compiling method " << GetDebugName(info()).get() | 1281 << "Finished compiling method " << GetDebugName(info()).get() |
1249 << " using Turbofan" << std::endl; | 1282 << " using Turbofan" << std::endl; |
1250 } | 1283 } |
1251 | 1284 |
1252 return code; | 1285 return code; |
1253 } | 1286 } |
1254 | 1287 |
1255 | 1288 |
| 1289 Handle<Code> Pipeline::ScheduleAndGenerateCode( |
| 1290 CallDescriptor* call_descriptor) { |
| 1291 if (!ScheduleAndAllocateRegisters(call_descriptor)) { |
| 1292 return Handle<Code>::null(); |
| 1293 } |
| 1294 return DoGenerateCode(); |
| 1295 } |
| 1296 |
| 1297 |
1256 void Pipeline::AllocateRegisters(const RegisterConfiguration* config, | 1298 void Pipeline::AllocateRegisters(const RegisterConfiguration* config, |
1257 bool run_verifier) { | 1299 bool run_verifier) { |
1258 PipelineData* data = this->data_; | 1300 PipelineData* data = this->data(); |
1259 | 1301 |
1260 // Don't track usage for this zone in compiler stats. | 1302 // Don't track usage for this zone in compiler stats. |
1261 SmartPointer<Zone> verifier_zone; | 1303 SmartPointer<Zone> verifier_zone; |
1262 RegisterAllocatorVerifier* verifier = nullptr; | 1304 RegisterAllocatorVerifier* verifier = nullptr; |
1263 if (run_verifier) { | 1305 if (run_verifier) { |
1264 verifier_zone.Reset(new Zone()); | 1306 verifier_zone.Reset(new Zone()); |
1265 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( | 1307 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( |
1266 verifier_zone.get(), config, data->sequence()); | 1308 verifier_zone.get(), config, data->sequence()); |
1267 } | 1309 } |
1268 | 1310 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1329 tcf << AsC1VRegisterAllocationData("CodeGen", | 1371 tcf << AsC1VRegisterAllocationData("CodeGen", |
1330 data->register_allocation_data()); | 1372 data->register_allocation_data()); |
1331 } | 1373 } |
1332 | 1374 |
1333 data->DeleteRegisterAllocationZone(); | 1375 data->DeleteRegisterAllocationZone(); |
1334 } | 1376 } |
1335 | 1377 |
1336 } // namespace compiler | 1378 } // namespace compiler |
1337 } // namespace internal | 1379 } // namespace internal |
1338 } // namespace v8 | 1380 } // namespace v8 |
OLD | NEW |