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 <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/base/platform/elapsed-timer.h" | 7 #include "src/base/platform/elapsed-timer.h" |
8 #include "src/compiler/ast-graph-builder.h" | 8 #include "src/compiler/ast-graph-builder.h" |
9 #include "src/compiler/basic-block-instrumentor.h" | 9 #include "src/compiler/basic-block-instrumentor.h" |
10 #include "src/compiler/change-lowering.h" | 10 #include "src/compiler/change-lowering.h" |
(...skipping 20 matching lines...) Expand all Loading... | |
31 #include "src/compiler/value-numbering-reducer.h" | 31 #include "src/compiler/value-numbering-reducer.h" |
32 #include "src/compiler/verifier.h" | 32 #include "src/compiler/verifier.h" |
33 #include "src/compiler/zone-pool.h" | 33 #include "src/compiler/zone-pool.h" |
34 #include "src/ostreams.h" | 34 #include "src/ostreams.h" |
35 #include "src/utils.h" | 35 #include "src/utils.h" |
36 | 36 |
37 namespace v8 { | 37 namespace v8 { |
38 namespace internal { | 38 namespace internal { |
39 namespace compiler { | 39 namespace compiler { |
40 | 40 |
41 class PipelineData { | |
42 public: | |
43 explicit PipelineData(CompilationInfo* info, ZonePool* zone_pool, | |
44 PipelineStatistics* pipeline_statistics) | |
45 : isolate_(info->zone()->isolate()), | |
46 outer_zone_(info->zone()), | |
47 zone_pool_(zone_pool), | |
48 pipeline_statistics_(pipeline_statistics), | |
49 graph_zone_scope_(zone_pool_), | |
50 graph_zone_(graph_zone_scope_.zone()), | |
51 graph_(new (graph_zone()) Graph(graph_zone())), | |
52 source_positions_(new (graph_zone()) SourcePositionTable(graph())), | |
53 machine_(new (graph_zone()) MachineOperatorBuilder()), | |
54 common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())), | |
55 javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())), | |
56 jsgraph_(new (graph_zone()) | |
57 JSGraph(graph(), common(), javascript(), machine())), | |
58 typer_(new (graph_zone()) Typer(graph(), info->context())), | |
59 schedule_(NULL), | |
60 instruction_zone_scope_(zone_pool_), | |
61 instruction_zone_(instruction_zone_scope_.zone()) {} | |
62 | |
63 // For machine graph testing only. | |
64 PipelineData(Graph* graph, Schedule* schedule, ZonePool* zone_pool) | |
65 : isolate_(graph->zone()->isolate()), | |
66 outer_zone_(NULL), | |
67 zone_pool_(zone_pool), | |
68 pipeline_statistics_(NULL), | |
69 graph_zone_scope_(zone_pool_), | |
70 graph_zone_(NULL), | |
71 graph_(graph), | |
72 source_positions_(new (graph->zone()) SourcePositionTable(graph)), | |
73 machine_(NULL), | |
74 common_(NULL), | |
75 javascript_(NULL), | |
76 jsgraph_(NULL), | |
77 typer_(NULL), | |
78 schedule_(schedule), | |
79 instruction_zone_scope_(zone_pool_), | |
80 instruction_zone_(instruction_zone_scope_.zone()) {} | |
81 | |
82 ~PipelineData() { | |
83 DeleteInstructionZone(); | |
84 DeleteGraphZone(); | |
85 } | |
86 | |
87 Isolate* isolate() const { return isolate_; } | |
88 ZonePool* zone_pool() const { return zone_pool_; } | |
89 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } | |
90 | |
91 Zone* graph_zone() const { return graph_zone_; } | |
92 Graph* graph() const { return graph_; } | |
93 SourcePositionTable* source_positions() const { return source_positions_; } | |
94 MachineOperatorBuilder* machine() const { return machine_; } | |
95 CommonOperatorBuilder* common() const { return common_; } | |
96 JSOperatorBuilder* javascript() const { return javascript_; } | |
97 JSGraph* jsgraph() const { return jsgraph_; } | |
98 Typer* typer() const { return typer_; } | |
99 Schedule* schedule() const { return schedule_; } | |
100 void set_schedule(Schedule* schedule) { | |
101 DCHECK_EQ(NULL, schedule_); | |
102 schedule_ = schedule; | |
103 } | |
104 | |
105 Zone* instruction_zone() const { return instruction_zone_; } | |
106 | |
107 void DeleteGraphZone() { | |
108 if (graph_zone_ == NULL) return; | |
109 graph_zone_scope_.Destroy(); | |
110 graph_zone_ = NULL; | |
111 graph_ = NULL; | |
112 source_positions_ = NULL; | |
113 machine_ = NULL; | |
114 common_ = NULL; | |
115 javascript_ = NULL; | |
116 jsgraph_ = NULL; | |
117 typer_ = NULL; | |
Michael Starzinger
2014/10/23 12:18:36
If the schedule lives in the graph-zone, then we s
| |
118 } | |
119 | |
120 void DeleteInstructionZone() { | |
121 if (instruction_zone_ == NULL) return; | |
122 instruction_zone_scope_.Destroy(); | |
123 instruction_zone_ = NULL; | |
124 } | |
125 | |
126 size_t GetOuterZoneAllocationSize() { | |
127 if (outer_zone_ == NULL) return 0; | |
128 return static_cast<size_t>(outer_zone_->allocation_size()); | |
129 } | |
130 | |
131 private: | |
132 Isolate* isolate_; | |
133 Zone* outer_zone_; | |
134 ZonePool* zone_pool_; | |
135 PipelineStatistics* pipeline_statistics_; | |
136 | |
137 // graph_zone_ contains everything up to instruction_zone_. | |
Michael Starzinger
2014/10/23 12:18:36
As discussed offline: Can we make the comment here
| |
138 ZonePool::Scope graph_zone_scope_; | |
139 Zone* graph_zone_; | |
140 Graph* graph_; | |
141 SourcePositionTable* source_positions_; | |
142 MachineOperatorBuilder* machine_; | |
143 CommonOperatorBuilder* common_; | |
144 JSOperatorBuilder* javascript_; | |
145 JSGraph* jsgraph_; | |
146 Typer* typer_; | |
147 Schedule* schedule_; | |
148 | |
Michael Starzinger
2014/10/23 12:18:36
Likewise we should add a comment here stating that
| |
149 ZonePool::Scope instruction_zone_scope_; | |
150 Zone* instruction_zone_; | |
151 | |
152 DISALLOW_COPY_AND_ASSIGN(PipelineData); | |
153 }; | |
154 | |
155 | |
41 static inline bool VerifyGraphs() { | 156 static inline bool VerifyGraphs() { |
42 #ifdef DEBUG | 157 #ifdef DEBUG |
43 return true; | 158 return true; |
44 #else | 159 #else |
45 return FLAG_turbo_verify; | 160 return FLAG_turbo_verify; |
46 #endif | 161 #endif |
47 } | 162 } |
48 | 163 |
49 | 164 |
50 void Pipeline::PrintCompilationStart() { | 165 void Pipeline::PrintCompilationStart() { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 | 301 |
187 if (FLAG_trace_turbo) { | 302 if (FLAG_trace_turbo) { |
188 OFStream os(stdout); | 303 OFStream os(stdout); |
189 os << "---------------------------------------------------\n" | 304 os << "---------------------------------------------------\n" |
190 << "Begin compiling method " | 305 << "Begin compiling method " |
191 << info()->function()->debug_name()->ToCString().get() | 306 << info()->function()->debug_name()->ToCString().get() |
192 << " using Turbofan" << std::endl; | 307 << " using Turbofan" << std::endl; |
193 PrintCompilationStart(); | 308 PrintCompilationStart(); |
194 } | 309 } |
195 | 310 |
196 // Build the graph. | 311 // Initialize the graph and builders. |
197 Graph graph(zone()); | 312 PipelineData data(info(), &zone_pool, pipeline_statistics.get()); |
198 SourcePositionTable source_positions(&graph); | 313 |
199 source_positions.AddDecorator(); | 314 data.source_positions()->AddDecorator(); |
200 // TODO(turbofan): there is no need to type anything during initial graph | 315 |
201 // construction. This is currently only needed for the node cache, which the | |
202 // typer could sweep over later. | |
203 Typer typer(&graph, info()->context()); | |
204 MachineOperatorBuilder machine; | |
205 CommonOperatorBuilder common(zone()); | |
206 JSOperatorBuilder javascript(zone()); | |
207 JSGraph jsgraph(&graph, &common, &javascript, &machine); | |
208 Node* context_node; | 316 Node* context_node; |
209 { | 317 { |
210 PhaseScope phase_scope(pipeline_statistics.get(), "graph builder"); | 318 PhaseScope phase_scope(pipeline_statistics.get(), "graph builder"); |
211 ZonePool::Scope zone_scope(&zone_pool); | 319 ZonePool::Scope zone_scope(data.zone_pool()); |
212 AstGraphBuilderWithPositions graph_builder(zone_scope.zone(), info(), | 320 AstGraphBuilderWithPositions graph_builder( |
213 &jsgraph, &source_positions); | 321 zone_scope.zone(), info(), data.jsgraph(), data.source_positions()); |
214 graph_builder.CreateGraph(); | 322 graph_builder.CreateGraph(); |
215 context_node = graph_builder.GetFunctionContext(); | 323 context_node = graph_builder.GetFunctionContext(); |
216 } | 324 } |
217 { | 325 { |
218 PhaseScope phase_scope(pipeline_statistics.get(), "phi reduction"); | 326 PhaseScope phase_scope(pipeline_statistics.get(), "phi reduction"); |
219 PhiReducer phi_reducer; | 327 PhiReducer phi_reducer; |
220 GraphReducer graph_reducer(&graph); | 328 GraphReducer graph_reducer(data.graph()); |
221 graph_reducer.AddReducer(&phi_reducer); | 329 graph_reducer.AddReducer(&phi_reducer); |
222 graph_reducer.ReduceGraph(); | 330 graph_reducer.ReduceGraph(); |
223 // TODO(mstarzinger): Running reducer once ought to be enough for everyone. | 331 // TODO(mstarzinger): Running reducer once ought to be enough for everyone. |
224 graph_reducer.ReduceGraph(); | 332 graph_reducer.ReduceGraph(); |
225 graph_reducer.ReduceGraph(); | 333 graph_reducer.ReduceGraph(); |
226 } | 334 } |
227 | 335 |
228 VerifyAndPrintGraph(&graph, "Initial untyped", true); | 336 VerifyAndPrintGraph(data.graph(), "Initial untyped", true); |
229 | 337 |
230 if (info()->is_context_specializing()) { | 338 if (info()->is_context_specializing()) { |
231 SourcePositionTable::Scope pos(&source_positions, | 339 SourcePositionTable::Scope pos(data.source_positions(), |
232 SourcePosition::Unknown()); | 340 SourcePosition::Unknown()); |
233 // Specialize the code to the context as aggressively as possible. | 341 // Specialize the code to the context as aggressively as possible. |
234 JSContextSpecializer spec(info(), &jsgraph, context_node); | 342 JSContextSpecializer spec(info(), data.jsgraph(), context_node); |
235 spec.SpecializeToContext(); | 343 spec.SpecializeToContext(); |
236 VerifyAndPrintGraph(&graph, "Context specialized", true); | 344 VerifyAndPrintGraph(data.graph(), "Context specialized", true); |
237 } | 345 } |
238 | 346 |
239 if (info()->is_inlining_enabled()) { | 347 if (info()->is_inlining_enabled()) { |
240 PhaseScope phase_scope(pipeline_statistics.get(), "inlining"); | 348 PhaseScope phase_scope(pipeline_statistics.get(), "inlining"); |
241 SourcePositionTable::Scope pos(&source_positions, | 349 SourcePositionTable::Scope pos(data.source_positions(), |
242 SourcePosition::Unknown()); | 350 SourcePosition::Unknown()); |
243 ZonePool::Scope zone_scope(&zone_pool); | 351 ZonePool::Scope zone_scope(data.zone_pool()); |
244 JSInliner inliner(zone_scope.zone(), info(), &jsgraph); | 352 JSInliner inliner(zone_scope.zone(), info(), data.jsgraph()); |
245 inliner.Inline(); | 353 inliner.Inline(); |
246 VerifyAndPrintGraph(&graph, "Inlined", true); | 354 VerifyAndPrintGraph(data.graph(), "Inlined", true); |
247 } | 355 } |
248 | 356 |
249 // Print a replay of the initial graph. | 357 // Print a replay of the initial graph. |
250 if (FLAG_print_turbo_replay) { | 358 if (FLAG_print_turbo_replay) { |
251 GraphReplayPrinter::PrintReplay(&graph); | 359 GraphReplayPrinter::PrintReplay(data.graph()); |
252 } | 360 } |
253 | 361 |
254 // Bailout here in case target architecture is not supported. | 362 // Bailout here in case target architecture is not supported. |
255 if (!SupportedTarget()) return Handle<Code>::null(); | 363 if (!SupportedTarget()) return Handle<Code>::null(); |
256 | 364 |
257 if (info()->is_typing_enabled()) { | 365 if (info()->is_typing_enabled()) { |
258 { | 366 { |
259 // Type the graph. | 367 // Type the graph. |
260 PhaseScope phase_scope(pipeline_statistics.get(), "typer"); | 368 PhaseScope phase_scope(pipeline_statistics.get(), "typer"); |
261 typer.Run(); | 369 data.typer()->Run(); |
262 VerifyAndPrintGraph(&graph, "Typed"); | 370 VerifyAndPrintGraph(data.graph(), "Typed"); |
263 } | 371 } |
264 } | 372 } |
265 | 373 |
266 if (!pipeline_statistics.is_empty()) { | 374 if (!pipeline_statistics.is_empty()) { |
267 pipeline_statistics->BeginPhaseKind("lowering"); | 375 pipeline_statistics->BeginPhaseKind("lowering"); |
268 } | 376 } |
269 | 377 |
270 if (info()->is_typing_enabled()) { | 378 if (info()->is_typing_enabled()) { |
271 { | 379 { |
272 // Lower JSOperators where we can determine types. | 380 // Lower JSOperators where we can determine types. |
273 PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering"); | 381 PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering"); |
274 SourcePositionTable::Scope pos(&source_positions, | 382 SourcePositionTable::Scope pos(data.source_positions(), |
275 SourcePosition::Unknown()); | 383 SourcePosition::Unknown()); |
276 ValueNumberingReducer vn_reducer(zone()); | 384 ValueNumberingReducer vn_reducer(data.graph_zone()); |
277 JSTypedLowering lowering(&jsgraph); | 385 JSTypedLowering lowering(data.jsgraph()); |
278 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 386 SimplifiedOperatorReducer simple_reducer(data.jsgraph()); |
279 GraphReducer graph_reducer(&graph); | 387 GraphReducer graph_reducer(data.graph()); |
280 graph_reducer.AddReducer(&vn_reducer); | 388 graph_reducer.AddReducer(&vn_reducer); |
281 graph_reducer.AddReducer(&lowering); | 389 graph_reducer.AddReducer(&lowering); |
282 graph_reducer.AddReducer(&simple_reducer); | 390 graph_reducer.AddReducer(&simple_reducer); |
283 graph_reducer.ReduceGraph(); | 391 graph_reducer.ReduceGraph(); |
284 | 392 |
285 VerifyAndPrintGraph(&graph, "Lowered typed"); | 393 VerifyAndPrintGraph(data.graph(), "Lowered typed"); |
286 } | 394 } |
287 { | 395 { |
288 // Lower simplified operators and insert changes. | 396 // Lower simplified operators and insert changes. |
289 PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering"); | 397 PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering"); |
290 SourcePositionTable::Scope pos(&source_positions, | 398 SourcePositionTable::Scope pos(data.source_positions(), |
291 SourcePosition::Unknown()); | 399 SourcePosition::Unknown()); |
292 SimplifiedLowering lowering(&jsgraph); | 400 SimplifiedLowering lowering(data.jsgraph()); |
293 lowering.LowerAllNodes(); | 401 lowering.LowerAllNodes(); |
294 ValueNumberingReducer vn_reducer(zone()); | 402 ValueNumberingReducer vn_reducer(data.graph_zone()); |
295 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 403 SimplifiedOperatorReducer simple_reducer(data.jsgraph()); |
296 GraphReducer graph_reducer(&graph); | 404 GraphReducer graph_reducer(data.graph()); |
297 graph_reducer.AddReducer(&vn_reducer); | 405 graph_reducer.AddReducer(&vn_reducer); |
298 graph_reducer.AddReducer(&simple_reducer); | 406 graph_reducer.AddReducer(&simple_reducer); |
299 graph_reducer.ReduceGraph(); | 407 graph_reducer.ReduceGraph(); |
300 | 408 |
301 VerifyAndPrintGraph(&graph, "Lowered simplified"); | 409 VerifyAndPrintGraph(data.graph(), "Lowered simplified"); |
302 } | 410 } |
303 { | 411 { |
304 // Lower changes that have been inserted before. | 412 // Lower changes that have been inserted before. |
305 PhaseScope phase_scope(pipeline_statistics.get(), "change lowering"); | 413 PhaseScope phase_scope(pipeline_statistics.get(), "change lowering"); |
306 SourcePositionTable::Scope pos(&source_positions, | 414 SourcePositionTable::Scope pos(data.source_positions(), |
307 SourcePosition::Unknown()); | 415 SourcePosition::Unknown()); |
308 Linkage linkage(info()); | 416 Linkage linkage(info()); |
309 ValueNumberingReducer vn_reducer(zone()); | 417 ValueNumberingReducer vn_reducer(data.graph_zone()); |
310 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 418 SimplifiedOperatorReducer simple_reducer(data.jsgraph()); |
311 ChangeLowering lowering(&jsgraph, &linkage); | 419 ChangeLowering lowering(data.jsgraph(), &linkage); |
312 MachineOperatorReducer mach_reducer(&jsgraph); | 420 MachineOperatorReducer mach_reducer(data.jsgraph()); |
313 GraphReducer graph_reducer(&graph); | 421 GraphReducer graph_reducer(data.graph()); |
314 // TODO(titzer): Figure out if we should run all reducers at once here. | 422 // TODO(titzer): Figure out if we should run all reducers at once here. |
315 graph_reducer.AddReducer(&vn_reducer); | 423 graph_reducer.AddReducer(&vn_reducer); |
316 graph_reducer.AddReducer(&simple_reducer); | 424 graph_reducer.AddReducer(&simple_reducer); |
317 graph_reducer.AddReducer(&lowering); | 425 graph_reducer.AddReducer(&lowering); |
318 graph_reducer.AddReducer(&mach_reducer); | 426 graph_reducer.AddReducer(&mach_reducer); |
319 graph_reducer.ReduceGraph(); | 427 graph_reducer.ReduceGraph(); |
320 | 428 |
321 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 429 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
322 VerifyAndPrintGraph(&graph, "Lowered changes", true); | 430 VerifyAndPrintGraph(data.graph(), "Lowered changes", true); |
323 } | 431 } |
324 | 432 |
325 { | 433 { |
326 PhaseScope phase_scope(pipeline_statistics.get(), "control reduction"); | 434 PhaseScope phase_scope(pipeline_statistics.get(), "control reduction"); |
327 SourcePositionTable::Scope pos(&source_positions, | 435 SourcePositionTable::Scope pos(data.source_positions(), |
328 SourcePosition::Unknown()); | 436 SourcePosition::Unknown()); |
329 ZonePool::Scope zone_scope(&zone_pool); | 437 ZonePool::Scope zone_scope(data.zone_pool()); |
330 ControlReducer::ReduceGraph(zone_scope.zone(), &jsgraph, &common); | 438 ControlReducer::ReduceGraph(zone_scope.zone(), data.jsgraph(), |
439 data.common()); | |
331 | 440 |
332 VerifyAndPrintGraph(&graph, "Control reduced"); | 441 VerifyAndPrintGraph(data.graph(), "Control reduced"); |
333 } | 442 } |
334 } | 443 } |
335 | 444 |
336 { | 445 { |
337 // Lower any remaining generic JSOperators. | 446 // Lower any remaining generic JSOperators. |
338 PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering"); | 447 PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering"); |
339 SourcePositionTable::Scope pos(&source_positions, | 448 SourcePositionTable::Scope pos(data.source_positions(), |
340 SourcePosition::Unknown()); | 449 SourcePosition::Unknown()); |
341 JSGenericLowering lowering(info(), &jsgraph); | 450 JSGenericLowering lowering(info(), data.jsgraph()); |
342 GraphReducer graph_reducer(&graph); | 451 GraphReducer graph_reducer(data.graph()); |
343 graph_reducer.AddReducer(&lowering); | 452 graph_reducer.AddReducer(&lowering); |
344 graph_reducer.ReduceGraph(); | 453 graph_reducer.ReduceGraph(); |
345 | 454 |
346 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 455 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
347 VerifyAndPrintGraph(&graph, "Lowered generic", true); | 456 VerifyAndPrintGraph(data.graph(), "Lowered generic", true); |
348 } | 457 } |
349 | 458 |
350 if (!pipeline_statistics.is_empty()) { | 459 if (!pipeline_statistics.is_empty()) { |
351 pipeline_statistics->BeginPhaseKind("code generation"); | 460 pipeline_statistics->BeginPhaseKind("code generation"); |
352 } | 461 } |
353 | 462 |
354 source_positions.RemoveDecorator(); | 463 data.source_positions()->RemoveDecorator(); |
355 | 464 |
356 Schedule* schedule; | 465 // Compute a schedule. |
357 { | 466 ComputeSchedule(&data); |
358 PhaseScope phase_scope(pipeline_statistics.get(), "scheduling"); | |
359 // Compute a schedule. | |
360 schedule = ComputeSchedule(&zone_pool, &graph); | |
361 } | |
362 | 467 |
363 Handle<Code> code = Handle<Code>::null(); | 468 Handle<Code> code = Handle<Code>::null(); |
364 { | 469 { |
365 // Generate optimized code. | 470 // Generate optimized code. |
366 Linkage linkage(info()); | 471 Linkage linkage(info()); |
367 code = GenerateCode(pipeline_statistics.get(), &zone_pool, &linkage, &graph, | 472 code = GenerateCode(&linkage, &data); |
368 schedule, &source_positions); | |
369 info()->SetCode(code); | 473 info()->SetCode(code); |
370 } | 474 } |
371 | 475 |
372 // Print optimized code. | 476 // Print optimized code. |
373 v8::internal::CodeGenerator::PrintCode(code, info()); | 477 v8::internal::CodeGenerator::PrintCode(code, info()); |
374 | 478 |
375 if (FLAG_trace_turbo) { | 479 if (FLAG_trace_turbo) { |
376 OFStream os(stdout); | 480 OFStream os(stdout); |
377 os << "--------------------------------------------------\n" | 481 os << "--------------------------------------------------\n" |
378 << "Finished compiling method " | 482 << "Finished compiling method " |
379 << info()->function()->debug_name()->ToCString().get() | 483 << info()->function()->debug_name()->ToCString().get() |
380 << " using Turbofan" << std::endl; | 484 << " using Turbofan" << std::endl; |
381 } | 485 } |
382 | 486 |
383 return code; | 487 return code; |
384 } | 488 } |
385 | 489 |
386 | 490 |
387 Schedule* Pipeline::ComputeSchedule(ZonePool* zone_pool, Graph* graph) { | 491 void Pipeline::ComputeSchedule(PipelineData* data) { |
388 Schedule* schedule = Scheduler::ComputeSchedule(zone_pool, graph); | 492 PhaseScope phase_scope(data->pipeline_statistics(), "scheduling"); |
493 Schedule* schedule = | |
494 Scheduler::ComputeSchedule(data->zone_pool(), data->graph()); | |
389 TraceSchedule(schedule); | 495 TraceSchedule(schedule); |
390 if (VerifyGraphs()) ScheduleVerifier::Run(schedule); | 496 if (VerifyGraphs()) ScheduleVerifier::Run(schedule); |
391 return schedule; | 497 data->set_schedule(schedule); |
392 } | 498 } |
393 | 499 |
394 | 500 |
395 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, | 501 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, |
396 Graph* graph, | 502 Graph* graph, |
397 Schedule* schedule) { | 503 Schedule* schedule) { |
398 ZonePool zone_pool(isolate()); | 504 ZonePool zone_pool(isolate()); |
399 CHECK(SupportedBackend()); | 505 CHECK(SupportedBackend()); |
506 PipelineData data(graph, schedule, &zone_pool); | |
400 if (schedule == NULL) { | 507 if (schedule == NULL) { |
401 // TODO(rossberg): Should this really be untyped? | 508 // TODO(rossberg): Should this really be untyped? |
402 VerifyAndPrintGraph(graph, "Machine", true); | 509 VerifyAndPrintGraph(graph, "Machine", true); |
403 schedule = ComputeSchedule(&zone_pool, graph); | 510 ComputeSchedule(&data); |
511 } else { | |
512 TraceSchedule(schedule); | |
404 } | 513 } |
405 TraceSchedule(schedule); | |
406 | 514 |
407 SourcePositionTable source_positions(graph); | 515 Handle<Code> code = GenerateCode(linkage, &data); |
408 Handle<Code> code = GenerateCode(NULL, &zone_pool, linkage, graph, schedule, | |
409 &source_positions); | |
410 #if ENABLE_DISASSEMBLER | 516 #if ENABLE_DISASSEMBLER |
411 if (!code.is_null() && FLAG_print_opt_code) { | 517 if (!code.is_null() && FLAG_print_opt_code) { |
412 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | 518 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
413 OFStream os(tracing_scope.file()); | 519 OFStream os(tracing_scope.file()); |
414 code->Disassemble("test code", os); | 520 code->Disassemble("test code", os); |
415 } | 521 } |
416 #endif | 522 #endif |
417 return code; | 523 return code; |
418 } | 524 } |
419 | 525 |
420 | 526 |
421 Handle<Code> Pipeline::GenerateCode(PipelineStatistics* pipeline_statistics, | 527 Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) { |
422 ZonePool* zone_pool, Linkage* linkage, | |
423 Graph* graph, Schedule* schedule, | |
424 SourcePositionTable* source_positions) { | |
425 DCHECK_NOT_NULL(graph); | |
426 DCHECK_NOT_NULL(linkage); | 528 DCHECK_NOT_NULL(linkage); |
427 DCHECK_NOT_NULL(schedule); | 529 DCHECK_NOT_NULL(data->graph()); |
530 DCHECK_NOT_NULL(data->schedule()); | |
428 CHECK(SupportedBackend()); | 531 CHECK(SupportedBackend()); |
429 | 532 |
430 BasicBlockProfiler::Data* profiler_data = NULL; | 533 BasicBlockProfiler::Data* profiler_data = NULL; |
431 if (FLAG_turbo_profiling) { | 534 if (FLAG_turbo_profiling) { |
432 profiler_data = BasicBlockInstrumentor::Instrument(info_, graph, schedule); | 535 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), |
536 data->schedule()); | |
433 } | 537 } |
434 | 538 |
435 Zone* instruction_zone = schedule->zone(); | 539 InstructionSequence sequence(data->instruction_zone(), data->graph(), |
436 InstructionSequence sequence(instruction_zone, graph, schedule); | 540 data->schedule()); |
437 | 541 |
438 // Select and schedule instructions covering the scheduled graph. | 542 // Select and schedule instructions covering the scheduled graph. |
439 { | 543 { |
440 PhaseScope phase_scope(pipeline_statistics, "select instructions"); | 544 PhaseScope phase_scope(data->pipeline_statistics(), "select instructions"); |
441 ZonePool::Scope zone_scope(zone_pool); | 545 ZonePool::Scope zone_scope(data->zone_pool()); |
442 InstructionSelector selector(zone_scope.zone(), linkage, &sequence, | 546 InstructionSelector selector(zone_scope.zone(), linkage, &sequence, |
443 schedule, source_positions); | 547 data->schedule(), data->source_positions()); |
444 selector.SelectInstructions(); | 548 selector.SelectInstructions(); |
445 } | 549 } |
446 | 550 |
447 if (FLAG_trace_turbo) { | 551 if (FLAG_trace_turbo) { |
448 OFStream os(stdout); | 552 OFStream os(stdout); |
449 os << "----- Instruction sequence before register allocation -----\n" | 553 os << "----- Instruction sequence before register allocation -----\n" |
450 << sequence; | 554 << sequence; |
451 PrintScheduleAndInstructions("CodeGen", schedule, source_positions, | 555 PrintScheduleAndInstructions("CodeGen", data->schedule(), |
452 &sequence); | 556 data->source_positions(), &sequence); |
453 } | 557 } |
454 | 558 |
559 data->DeleteGraphZone(); | |
560 | |
455 // Allocate registers. | 561 // Allocate registers. |
456 Frame frame; | 562 Frame frame; |
457 { | 563 { |
458 int node_count = graph->NodeCount(); | 564 int node_count = sequence.VirtualRegisterCount(); |
459 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { | 565 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { |
460 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); | 566 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); |
461 return Handle<Code>::null(); | 567 return Handle<Code>::null(); |
462 } | 568 } |
463 ZonePool::Scope zone_scope(zone_pool); | 569 ZonePool::Scope zone_scope(data->zone_pool()); |
464 RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(), | 570 RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(), |
465 &sequence); | 571 &sequence); |
466 if (!allocator.Allocate(pipeline_statistics)) { | 572 if (!allocator.Allocate(data->pipeline_statistics())) { |
467 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 573 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
468 return Handle<Code>::null(); | 574 return Handle<Code>::null(); |
469 } | 575 } |
470 if (FLAG_trace_turbo) { | 576 if (FLAG_trace_turbo) { |
471 PrintAllocator("CodeGen", &allocator); | 577 PrintAllocator("CodeGen", &allocator); |
472 } | 578 } |
473 } | 579 } |
474 | 580 |
475 if (FLAG_trace_turbo) { | 581 if (FLAG_trace_turbo) { |
476 OFStream os(stdout); | 582 OFStream os(stdout); |
477 os << "----- Instruction sequence after register allocation -----\n" | 583 os << "----- Instruction sequence after register allocation -----\n" |
478 << sequence; | 584 << sequence; |
479 } | 585 } |
480 | 586 |
481 // Generate native sequence. | 587 // Generate native sequence. |
482 Handle<Code> code; | 588 Handle<Code> code; |
483 { | 589 { |
484 PhaseScope phase_scope(pipeline_statistics, "generate code"); | 590 PhaseScope phase_scope(data->pipeline_statistics(), "generate code"); |
485 CodeGenerator generator(&frame, linkage, &sequence); | 591 CodeGenerator generator(&frame, linkage, &sequence); |
486 code = generator.GenerateCode(); | 592 code = generator.GenerateCode(); |
487 } | 593 } |
488 if (profiler_data != NULL) { | 594 if (profiler_data != NULL) { |
489 #if ENABLE_DISASSEMBLER | 595 #if ENABLE_DISASSEMBLER |
490 std::ostringstream os; | 596 std::ostringstream os; |
491 code->Disassemble(NULL, os); | 597 code->Disassemble(NULL, os); |
492 profiler_data->SetCode(&os); | 598 profiler_data->SetCode(&os); |
493 #endif | 599 #endif |
494 } | 600 } |
495 return code; | 601 return code; |
496 } | 602 } |
497 | 603 |
498 | 604 |
499 void Pipeline::SetUp() { | 605 void Pipeline::SetUp() { |
500 InstructionOperand::SetUpCaches(); | 606 InstructionOperand::SetUpCaches(); |
501 } | 607 } |
502 | 608 |
503 | 609 |
504 void Pipeline::TearDown() { | 610 void Pipeline::TearDown() { |
505 InstructionOperand::TearDownCaches(); | 611 InstructionOperand::TearDownCaches(); |
506 } | 612 } |
507 | 613 |
508 } // namespace compiler | 614 } // namespace compiler |
509 } // namespace internal | 615 } // namespace internal |
510 } // namespace v8 | 616 } // namespace v8 |
OLD | NEW |