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 <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
10 #include "src/compiler/ast-graph-builder.h" | 10 #include "src/compiler/ast-graph-builder.h" |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 void Pipeline::PrintAllocator(const char* phase, | 171 void Pipeline::PrintAllocator(const char* phase, |
172 const RegisterAllocator* allocator) { | 172 const RegisterAllocator* allocator) { |
173 std::ofstream turbo_cfg_stream; | 173 std::ofstream turbo_cfg_stream; |
174 OpenTurboCfgFile(&turbo_cfg_stream); | 174 OpenTurboCfgFile(&turbo_cfg_stream); |
175 turbo_cfg_stream << AsC1VAllocator(phase, allocator); | 175 turbo_cfg_stream << AsC1VAllocator(phase, allocator); |
176 } | 176 } |
177 | 177 |
178 | 178 |
179 class AstGraphBuilderWithPositions : public AstGraphBuilder { | 179 class AstGraphBuilderWithPositions : public AstGraphBuilder { |
180 public: | 180 public: |
181 explicit AstGraphBuilderWithPositions(CompilationInfo* info, JSGraph* jsgraph, | 181 explicit AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info, |
| 182 JSGraph* jsgraph, |
182 SourcePositionTable* source_positions) | 183 SourcePositionTable* source_positions) |
183 : AstGraphBuilder(info, jsgraph), source_positions_(source_positions) {} | 184 : AstGraphBuilder(local_zone, info, jsgraph), |
| 185 source_positions_(source_positions) {} |
184 | 186 |
185 bool CreateGraph() { | 187 bool CreateGraph() { |
186 SourcePositionTable::Scope pos(source_positions_, | 188 SourcePositionTable::Scope pos(source_positions_, |
187 SourcePosition::Unknown()); | 189 SourcePosition::Unknown()); |
188 return AstGraphBuilder::CreateGraph(); | 190 return AstGraphBuilder::CreateGraph(); |
189 } | 191 } |
190 | 192 |
191 #define DEF_VISIT(type) \ | 193 #define DEF_VISIT(type) \ |
192 virtual void Visit##type(type* node) OVERRIDE { \ | 194 virtual void Visit##type(type* node) OVERRIDE { \ |
193 SourcePositionTable::Scope pos(source_positions_, \ | 195 SourcePositionTable::Scope pos(source_positions_, \ |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 // typer could sweep over later. | 248 // typer could sweep over later. |
247 Typer typer(&graph, info()->context()); | 249 Typer typer(&graph, info()->context()); |
248 MachineOperatorBuilder machine; | 250 MachineOperatorBuilder machine; |
249 CommonOperatorBuilder common(zone()); | 251 CommonOperatorBuilder common(zone()); |
250 JSOperatorBuilder javascript(zone()); | 252 JSOperatorBuilder javascript(zone()); |
251 JSGraph jsgraph(&graph, &common, &javascript, &machine); | 253 JSGraph jsgraph(&graph, &common, &javascript, &machine); |
252 Node* context_node; | 254 Node* context_node; |
253 { | 255 { |
254 PhaseStats graph_builder_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 256 PhaseStats graph_builder_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
255 "graph builder"); | 257 "graph builder"); |
256 AstGraphBuilderWithPositions graph_builder(info(), &jsgraph, | 258 ZonePool::Scope zone_scope(&zone_pool); |
257 &source_positions); | 259 AstGraphBuilderWithPositions graph_builder(zone_scope.zone(), info(), |
| 260 &jsgraph, &source_positions); |
258 graph_builder.CreateGraph(); | 261 graph_builder.CreateGraph(); |
259 context_node = graph_builder.GetFunctionContext(); | 262 context_node = graph_builder.GetFunctionContext(); |
260 } | 263 } |
261 { | 264 { |
262 PhaseStats phi_reducer_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 265 PhaseStats phi_reducer_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
263 "phi reduction"); | 266 "phi reduction"); |
264 PhiReducer phi_reducer; | 267 PhiReducer phi_reducer; |
265 GraphReducer graph_reducer(&graph); | 268 GraphReducer graph_reducer(&graph); |
266 graph_reducer.AddReducer(&phi_reducer); | 269 graph_reducer.AddReducer(&phi_reducer); |
267 graph_reducer.ReduceGraph(); | 270 graph_reducer.ReduceGraph(); |
268 // TODO(mstarzinger): Running reducer once ought to be enough for everyone. | 271 // TODO(mstarzinger): Running reducer once ought to be enough for everyone. |
269 graph_reducer.ReduceGraph(); | 272 graph_reducer.ReduceGraph(); |
270 graph_reducer.ReduceGraph(); | 273 graph_reducer.ReduceGraph(); |
271 } | 274 } |
272 | 275 |
273 VerifyAndPrintGraph(&graph, "Initial untyped", true); | 276 VerifyAndPrintGraph(&graph, "Initial untyped", true); |
274 | 277 |
275 if (info()->is_context_specializing()) { | 278 if (info()->is_context_specializing()) { |
276 SourcePositionTable::Scope pos(&source_positions, | 279 SourcePositionTable::Scope pos(&source_positions, |
277 SourcePosition::Unknown()); | 280 SourcePosition::Unknown()); |
278 // Specialize the code to the context as aggressively as possible. | 281 // Specialize the code to the context as aggressively as possible. |
279 JSContextSpecializer spec(info(), &jsgraph, context_node); | 282 JSContextSpecializer spec(info(), &jsgraph, context_node); |
280 spec.SpecializeToContext(); | 283 spec.SpecializeToContext(); |
281 VerifyAndPrintGraph(&graph, "Context specialized", true); | 284 VerifyAndPrintGraph(&graph, "Context specialized", true); |
282 } | 285 } |
283 | 286 |
284 if (info()->is_inlining_enabled()) { | 287 if (info()->is_inlining_enabled()) { |
285 SourcePositionTable::Scope pos(&source_positions, | 288 SourcePositionTable::Scope pos(&source_positions, |
286 SourcePosition::Unknown()); | 289 SourcePosition::Unknown()); |
287 JSInliner inliner(info(), &jsgraph); | 290 ZonePool::Scope zone_scope(&zone_pool); |
| 291 JSInliner inliner(zone_scope.zone(), info(), &jsgraph); |
288 inliner.Inline(); | 292 inliner.Inline(); |
289 VerifyAndPrintGraph(&graph, "Inlined", true); | 293 VerifyAndPrintGraph(&graph, "Inlined", true); |
290 } | 294 } |
291 | 295 |
292 // Print a replay of the initial graph. | 296 // Print a replay of the initial graph. |
293 if (FLAG_print_turbo_replay) { | 297 if (FLAG_print_turbo_replay) { |
294 GraphReplayPrinter::PrintReplay(&graph); | 298 GraphReplayPrinter::PrintReplay(&graph); |
295 } | 299 } |
296 | 300 |
297 // Bailout here in case target architecture is not supported. | 301 // Bailout here in case target architecture is not supported. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 | 364 |
361 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 365 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
362 VerifyAndPrintGraph(&graph, "Lowered changes", true); | 366 VerifyAndPrintGraph(&graph, "Lowered changes", true); |
363 } | 367 } |
364 | 368 |
365 { | 369 { |
366 SourcePositionTable::Scope pos(&source_positions, | 370 SourcePositionTable::Scope pos(&source_positions, |
367 SourcePosition::Unknown()); | 371 SourcePosition::Unknown()); |
368 PhaseStats control_reducer_stats( | 372 PhaseStats control_reducer_stats( |
369 info(), &zone_pool, PhaseStats::CREATE_GRAPH, "control reduction"); | 373 info(), &zone_pool, PhaseStats::CREATE_GRAPH, "control reduction"); |
370 ControlReducer::ReduceGraph(&jsgraph, &common); | 374 ZonePool::Scope zone_scope(&zone_pool); |
| 375 ControlReducer::ReduceGraph(zone_scope.zone(), &jsgraph, &common); |
371 | 376 |
372 VerifyAndPrintGraph(&graph, "Control reduced"); | 377 VerifyAndPrintGraph(&graph, "Control reduced"); |
373 } | 378 } |
374 } | 379 } |
375 | 380 |
376 { | 381 { |
377 // Lower any remaining generic JSOperators. | 382 // Lower any remaining generic JSOperators. |
378 PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 383 PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
379 "generic lowering"); | 384 "generic lowering"); |
380 SourcePositionTable::Scope pos(&source_positions, | 385 SourcePositionTable::Scope pos(&source_positions, |
(...skipping 10 matching lines...) Expand all Loading... |
391 source_positions.RemoveDecorator(); | 396 source_positions.RemoveDecorator(); |
392 | 397 |
393 Handle<Code> code = Handle<Code>::null(); | 398 Handle<Code> code = Handle<Code>::null(); |
394 { | 399 { |
395 // Compute a schedule. | 400 // Compute a schedule. |
396 Schedule* schedule = ComputeSchedule(&zone_pool, &graph); | 401 Schedule* schedule = ComputeSchedule(&zone_pool, &graph); |
397 // Generate optimized code. | 402 // Generate optimized code. |
398 PhaseStats codegen_stats(info(), &zone_pool, PhaseStats::CODEGEN, | 403 PhaseStats codegen_stats(info(), &zone_pool, PhaseStats::CODEGEN, |
399 "codegen"); | 404 "codegen"); |
400 Linkage linkage(info()); | 405 Linkage linkage(info()); |
401 code = GenerateCode(&linkage, &graph, schedule, &source_positions); | 406 code = |
| 407 GenerateCode(&zone_pool, &linkage, &graph, schedule, &source_positions); |
402 info()->SetCode(code); | 408 info()->SetCode(code); |
403 } | 409 } |
404 | 410 |
405 // Print optimized code. | 411 // Print optimized code. |
406 v8::internal::CodeGenerator::PrintCode(code, info()); | 412 v8::internal::CodeGenerator::PrintCode(code, info()); |
407 | 413 |
408 if (FLAG_trace_turbo) { | 414 if (FLAG_trace_turbo) { |
409 OFStream os(stdout); | 415 OFStream os(stdout); |
410 os << "--------------------------------------------------\n" | 416 os << "--------------------------------------------------\n" |
411 << "Finished compiling method " | 417 << "Finished compiling method " |
(...skipping 11 matching lines...) Expand all Loading... |
423 Schedule* schedule = Scheduler::ComputeSchedule(zone_pool, graph); | 429 Schedule* schedule = Scheduler::ComputeSchedule(zone_pool, graph); |
424 TraceSchedule(schedule); | 430 TraceSchedule(schedule); |
425 if (VerifyGraphs()) ScheduleVerifier::Run(schedule); | 431 if (VerifyGraphs()) ScheduleVerifier::Run(schedule); |
426 return schedule; | 432 return schedule; |
427 } | 433 } |
428 | 434 |
429 | 435 |
430 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, | 436 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, |
431 Graph* graph, | 437 Graph* graph, |
432 Schedule* schedule) { | 438 Schedule* schedule) { |
| 439 ZonePool zone_pool(isolate()); |
433 CHECK(SupportedBackend()); | 440 CHECK(SupportedBackend()); |
434 if (schedule == NULL) { | 441 if (schedule == NULL) { |
435 // TODO(rossberg): Should this really be untyped? | 442 // TODO(rossberg): Should this really be untyped? |
436 VerifyAndPrintGraph(graph, "Machine", true); | 443 VerifyAndPrintGraph(graph, "Machine", true); |
437 ZonePool zone_pool(isolate()); | |
438 schedule = ComputeSchedule(&zone_pool, graph); | 444 schedule = ComputeSchedule(&zone_pool, graph); |
439 } | 445 } |
440 TraceSchedule(schedule); | 446 TraceSchedule(schedule); |
441 | 447 |
442 SourcePositionTable source_positions(graph); | 448 SourcePositionTable source_positions(graph); |
443 Handle<Code> code = GenerateCode(linkage, graph, schedule, &source_positions); | 449 Handle<Code> code = |
| 450 GenerateCode(&zone_pool, linkage, graph, schedule, &source_positions); |
444 #if ENABLE_DISASSEMBLER | 451 #if ENABLE_DISASSEMBLER |
445 if (!code.is_null() && FLAG_print_opt_code) { | 452 if (!code.is_null() && FLAG_print_opt_code) { |
446 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | 453 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
447 OFStream os(tracing_scope.file()); | 454 OFStream os(tracing_scope.file()); |
448 code->Disassemble("test code", os); | 455 code->Disassemble("test code", os); |
449 } | 456 } |
450 #endif | 457 #endif |
451 return code; | 458 return code; |
452 } | 459 } |
453 | 460 |
454 | 461 |
455 Handle<Code> Pipeline::GenerateCode(Linkage* linkage, Graph* graph, | 462 Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage, |
456 Schedule* schedule, | 463 Graph* graph, Schedule* schedule, |
457 SourcePositionTable* source_positions) { | 464 SourcePositionTable* source_positions) { |
458 DCHECK_NOT_NULL(graph); | 465 DCHECK_NOT_NULL(graph); |
459 DCHECK_NOT_NULL(linkage); | 466 DCHECK_NOT_NULL(linkage); |
460 DCHECK_NOT_NULL(schedule); | 467 DCHECK_NOT_NULL(schedule); |
461 CHECK(SupportedBackend()); | 468 CHECK(SupportedBackend()); |
462 | 469 |
463 BasicBlockProfiler::Data* profiler_data = NULL; | 470 BasicBlockProfiler::Data* profiler_data = NULL; |
464 if (FLAG_turbo_profiling) { | 471 if (FLAG_turbo_profiling) { |
465 profiler_data = BasicBlockInstrumentor::Instrument(info_, graph, schedule); | 472 profiler_data = BasicBlockInstrumentor::Instrument(info_, graph, schedule); |
466 } | 473 } |
467 | 474 |
468 Zone* instruction_zone = schedule->zone(); | 475 Zone* instruction_zone = schedule->zone(); |
469 InstructionSequence sequence(instruction_zone, graph, schedule); | 476 InstructionSequence sequence(instruction_zone, graph, schedule); |
470 | 477 |
471 // Select and schedule instructions covering the scheduled graph. | 478 // Select and schedule instructions covering the scheduled graph. |
472 { | 479 { |
473 InstructionSelector selector(linkage, &sequence, schedule, | 480 ZonePool::Scope zone_scope(zone_pool); |
474 source_positions); | 481 InstructionSelector selector(zone_scope.zone(), linkage, &sequence, |
| 482 schedule, source_positions); |
475 selector.SelectInstructions(); | 483 selector.SelectInstructions(); |
476 } | 484 } |
477 | 485 |
478 if (FLAG_trace_turbo) { | 486 if (FLAG_trace_turbo) { |
479 OFStream os(stdout); | 487 OFStream os(stdout); |
480 os << "----- Instruction sequence before register allocation -----\n" | 488 os << "----- Instruction sequence before register allocation -----\n" |
481 << sequence; | 489 << sequence; |
482 PrintScheduleAndInstructions("CodeGen", schedule, source_positions, | 490 PrintScheduleAndInstructions("CodeGen", schedule, source_positions, |
483 &sequence); | 491 &sequence); |
484 } | 492 } |
485 | 493 |
486 // Allocate registers. | 494 // Allocate registers. |
487 Frame frame; | 495 Frame frame; |
488 { | 496 { |
489 int node_count = graph->NodeCount(); | 497 int node_count = graph->NodeCount(); |
490 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { | 498 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { |
491 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); | 499 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); |
492 return Handle<Code>::null(); | 500 return Handle<Code>::null(); |
493 } | 501 } |
494 RegisterAllocator allocator(&frame, linkage->info(), &sequence); | 502 ZonePool::Scope zone_scope(zone_pool); |
495 if (!allocator.Allocate()) { | 503 RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(), |
| 504 &sequence); |
| 505 if (!allocator.Allocate(zone_pool)) { |
496 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 506 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
497 return Handle<Code>::null(); | 507 return Handle<Code>::null(); |
498 } | 508 } |
499 if (FLAG_trace_turbo) { | 509 if (FLAG_trace_turbo) { |
500 PrintAllocator("CodeGen", &allocator); | 510 PrintAllocator("CodeGen", &allocator); |
501 } | 511 } |
502 } | 512 } |
503 | 513 |
504 if (FLAG_trace_turbo) { | 514 if (FLAG_trace_turbo) { |
505 OFStream os(stdout); | 515 OFStream os(stdout); |
(...skipping 20 matching lines...) Expand all Loading... |
526 } | 536 } |
527 | 537 |
528 | 538 |
529 void Pipeline::TearDown() { | 539 void Pipeline::TearDown() { |
530 InstructionOperand::TearDownCaches(); | 540 InstructionOperand::TearDownCaches(); |
531 } | 541 } |
532 | 542 |
533 } // namespace compiler | 543 } // namespace compiler |
534 } // namespace internal | 544 } // namespace internal |
535 } // namespace v8 | 545 } // namespace v8 |
OLD | NEW |