| 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 |