Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: runtime/vm/compiler.cc

Issue 1523833003: Add more compiler timeline durations (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/compiler.h" 5 #include "vm/compiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 8
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/block_scheduler.h" 10 #include "vm/block_scheduler.h"
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 bool optimized, 407 bool optimized,
408 intptr_t osr_id) { 408 intptr_t osr_id) {
409 const Function& function = parsed_function->function(); 409 const Function& function = parsed_function->function();
410 if (optimized && !function.IsOptimizable()) { 410 if (optimized && !function.IsOptimizable()) {
411 return false; 411 return false;
412 } 412 }
413 bool is_compiled = false; 413 bool is_compiled = false;
414 Thread* const thread = Thread::Current(); 414 Thread* const thread = Thread::Current();
415 Zone* const zone = thread->zone(); 415 Zone* const zone = thread->zone();
416 Isolate* const isolate = thread->isolate(); 416 Isolate* const isolate = thread->isolate();
417 TimelineStream* compiler_timeline = isolate->GetCompilerStream();
417 CSTAT_TIMER_SCOPE(thread, codegen_timer); 418 CSTAT_TIMER_SCOPE(thread, codegen_timer);
418 HANDLESCOPE(thread); 419 HANDLESCOPE(thread);
419 420
420 // Get current generation count so that we can check and ensure that the code 421 // Get current generation count so that we can check and ensure that the code
421 // was not invalidated while we were compiling in the background. 422 // was not invalidated while we were compiling in the background.
422 uint32_t cha_invalidation_gen_at_start = isolate->cha_invalidation_gen(); 423 uint32_t cha_invalidation_gen_at_start = isolate->cha_invalidation_gen();
423 uint32_t field_invalidation_gen_at_start = isolate->field_invalidation_gen(); 424 uint32_t field_invalidation_gen_at_start = isolate->field_invalidation_gen();
424 uint32_t prefix_invalidation_gen_at_start = 425 uint32_t prefix_invalidation_gen_at_start =
425 isolate->prefix_invalidation_gen(); 426 isolate->prefix_invalidation_gen();
426 427
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 if (FLAG_print_ic_data_map) { 469 if (FLAG_print_ic_data_map) {
469 for (intptr_t i = 0; i < ic_data_array->length(); i++) { 470 for (intptr_t i = 0; i < ic_data_array->length(); i++) {
470 if ((*ic_data_array)[i] != NULL) { 471 if ((*ic_data_array)[i] != NULL) {
471 THR_Print("%" Pd " ", i); 472 THR_Print("%" Pd " ", i);
472 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); 473 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]);
473 } 474 }
474 } 475 }
475 } 476 }
476 } 477 }
477 478
479 TimelineDurationScope tds(thread,
480 compiler_timeline,
481 "BuildFlowGraph");
478 flow_graph = pipeline->BuildFlowGraph(zone, 482 flow_graph = pipeline->BuildFlowGraph(zone,
479 parsed_function, 483 parsed_function,
480 *ic_data_array, 484 *ic_data_array,
481 osr_id); 485 osr_id);
482 } 486 }
483 487
484 const bool print_flow_graph = 488 const bool print_flow_graph =
485 (FLAG_print_flow_graph || 489 (FLAG_print_flow_graph ||
486 (optimized && FLAG_print_flow_graph_optimized)) && 490 (optimized && FLAG_print_flow_graph_optimized)) &&
487 FlowGraphPrinter::ShouldPrint(function); 491 FlowGraphPrinter::ShouldPrint(function);
488 492
489 if (print_flow_graph) { 493 if (print_flow_graph) {
490 if (osr_id == Compiler::kNoOSRDeoptId) { 494 if (osr_id == Compiler::kNoOSRDeoptId) {
491 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 495 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
492 } else { 496 } else {
493 FlowGraphPrinter::PrintGraph("For OSR", flow_graph); 497 FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
494 } 498 }
495 } 499 }
496 500
497 BlockScheduler block_scheduler(flow_graph); 501 BlockScheduler block_scheduler(flow_graph);
498 const bool reorder_blocks = 502 const bool reorder_blocks =
499 FlowGraph::ShouldReorderBlocks(function, optimized); 503 FlowGraph::ShouldReorderBlocks(function, optimized);
500 if (reorder_blocks) { 504 if (reorder_blocks) {
505 TimelineDurationScope tds(thread,
506 compiler_timeline,
507 "BlockScheduler::AssignEdgeWeights");
501 block_scheduler.AssignEdgeWeights(); 508 block_scheduler.AssignEdgeWeights();
502 } 509 }
503 510
504 if (optimized) { 511 if (optimized) {
512 TimelineDurationScope tds(thread,
513 compiler_timeline,
514 "ComputeSSA");
505 CSTAT_TIMER_SCOPE(thread, ssa_timer); 515 CSTAT_TIMER_SCOPE(thread, ssa_timer);
506 // Transform to SSA (virtual register 0 and no inlining arguments). 516 // Transform to SSA (virtual register 0 and no inlining arguments).
507 flow_graph->ComputeSSA(0, NULL); 517 flow_graph->ComputeSSA(0, NULL);
508 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 518 DEBUG_ASSERT(flow_graph->VerifyUseLists());
509 if (print_flow_graph) { 519 if (print_flow_graph) {
510 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); 520 FlowGraphPrinter::PrintGraph("After SSA", flow_graph);
511 } 521 }
512 } 522 }
513 523
514 // Maps inline_id_to_function[inline_id] -> function. Top scope 524 // Maps inline_id_to_function[inline_id] -> function. Top scope
515 // function has inline_id 0. The map is populated by the inliner. 525 // function has inline_id 0. The map is populated by the inliner.
516 GrowableArray<const Function*> inline_id_to_function; 526 GrowableArray<const Function*> inline_id_to_function;
517 // For a given inlining-id(index) specifies the caller's inlining-id. 527 // For a given inlining-id(index) specifies the caller's inlining-id.
518 GrowableArray<intptr_t> caller_inline_id; 528 GrowableArray<intptr_t> caller_inline_id;
519 // Collect all instance fields that are loaded in the graph and 529 // Collect all instance fields that are loaded in the graph and
520 // have non-generic type feedback attached to them that can 530 // have non-generic type feedback attached to them that can
521 // potentially affect optimizations. 531 // potentially affect optimizations.
522 if (optimized) { 532 if (optimized) {
533 TimelineDurationScope tds(thread,
534 compiler_timeline,
535 "OptimizationPasses");
523 inline_id_to_function.Add(&function); 536 inline_id_to_function.Add(&function);
524 // Top scope function has no caller (-1). 537 // Top scope function has no caller (-1).
525 caller_inline_id.Add(-1); 538 caller_inline_id.Add(-1);
526 CSTAT_TIMER_SCOPE(thread, graphoptimizer_timer); 539 CSTAT_TIMER_SCOPE(thread, graphoptimizer_timer);
527 540
528 FlowGraphOptimizer optimizer(flow_graph, 541 FlowGraphOptimizer optimizer(flow_graph,
529 use_speculative_inlining, 542 use_speculative_inlining,
530 &inlining_black_list); 543 &inlining_black_list);
531 if (Compiler::always_optimize()) { 544 if (Compiler::always_optimize()) {
532 optimizer.PopulateWithICData(); 545 optimizer.PopulateWithICData();
533 546
534 optimizer.ApplyClassIds(); 547 optimizer.ApplyClassIds();
535 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 548 DEBUG_ASSERT(flow_graph->VerifyUseLists());
536 549
537 FlowGraphTypePropagator::Propagate(flow_graph); 550 FlowGraphTypePropagator::Propagate(flow_graph);
538 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 551 DEBUG_ASSERT(flow_graph->VerifyUseLists());
539 } 552 }
540 optimizer.ApplyICData(); 553 optimizer.ApplyICData();
541 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 554 DEBUG_ASSERT(flow_graph->VerifyUseLists());
542 555
543 // Optimize (a << b) & c patterns, merge operations. 556 // Optimize (a << b) & c patterns, merge operations.
544 // Run early in order to have more opportunity to optimize left shifts. 557 // Run early in order to have more opportunity to optimize left shifts.
545 optimizer.TryOptimizePatterns(); 558 optimizer.TryOptimizePatterns();
546 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 559 DEBUG_ASSERT(flow_graph->VerifyUseLists());
547 560
548 FlowGraphInliner::SetInliningId(flow_graph, 0); 561 FlowGraphInliner::SetInliningId(flow_graph, 0);
549 562
550 // Inlining (mutates the flow graph) 563 // Inlining (mutates the flow graph)
551 if (FLAG_use_inlining) { 564 if (FLAG_use_inlining) {
565 TimelineDurationScope tds2(thread,
566 compiler_timeline,
567 "Inlining");
552 CSTAT_TIMER_SCOPE(thread, graphinliner_timer); 568 CSTAT_TIMER_SCOPE(thread, graphinliner_timer);
553 // Propagate types to create more inlining opportunities. 569 // Propagate types to create more inlining opportunities.
554 FlowGraphTypePropagator::Propagate(flow_graph); 570 FlowGraphTypePropagator::Propagate(flow_graph);
555 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 571 DEBUG_ASSERT(flow_graph->VerifyUseLists());
556 572
557 // Use propagated class-ids to create more inlining opportunities. 573 // Use propagated class-ids to create more inlining opportunities.
558 optimizer.ApplyClassIds(); 574 optimizer.ApplyClassIds();
559 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 575 DEBUG_ASSERT(flow_graph->VerifyUseLists());
560 576
561 FlowGraphInliner inliner(flow_graph, 577 FlowGraphInliner inliner(flow_graph,
562 &inline_id_to_function, 578 &inline_id_to_function,
563 &caller_inline_id, 579 &caller_inline_id,
564 use_speculative_inlining, 580 use_speculative_inlining,
565 &inlining_black_list); 581 &inlining_black_list);
566 inliner.Inline(); 582 inliner.Inline();
567 // Use lists are maintained and validated by the inliner. 583 // Use lists are maintained and validated by the inliner.
568 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 584 DEBUG_ASSERT(flow_graph->VerifyUseLists());
569 } 585 }
570 586
571 // Propagate types and eliminate more type tests. 587 // Propagate types and eliminate more type tests.
572 FlowGraphTypePropagator::Propagate(flow_graph); 588 FlowGraphTypePropagator::Propagate(flow_graph);
573 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 589 DEBUG_ASSERT(flow_graph->VerifyUseLists());
574 590
575 // Use propagated class-ids to optimize further. 591 {
576 optimizer.ApplyClassIds(); 592 TimelineDurationScope tds2(thread,
577 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 593 compiler_timeline,
594 "ApplyClassIds");
595 // Use propagated class-ids to optimize further.
596 optimizer.ApplyClassIds();
597 DEBUG_ASSERT(flow_graph->VerifyUseLists());
598 }
578 599
579 // Propagate types for potentially newly added instructions by 600 // Propagate types for potentially newly added instructions by
580 // ApplyClassIds(). Must occur before canonicalization. 601 // ApplyClassIds(). Must occur before canonicalization.
581 FlowGraphTypePropagator::Propagate(flow_graph); 602 FlowGraphTypePropagator::Propagate(flow_graph);
582 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 603 DEBUG_ASSERT(flow_graph->VerifyUseLists());
583 604
584 // Do optimizations that depend on the propagated type information. 605 // Do optimizations that depend on the propagated type information.
585 if (optimizer.Canonicalize()) { 606 if (optimizer.Canonicalize()) {
586 // Invoke Canonicalize twice in order to fully canonicalize patterns 607 // Invoke Canonicalize twice in order to fully canonicalize patterns
587 // like "if (a & const == 0) { }". 608 // like "if (a & const == 0) { }".
588 optimizer.Canonicalize(); 609 optimizer.Canonicalize();
589 } 610 }
590 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 611 DEBUG_ASSERT(flow_graph->VerifyUseLists());
591 612
592 BranchSimplifier::Simplify(flow_graph); 613 {
593 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 614 TimelineDurationScope tds2(thread,
615 compiler_timeline,
616 "BranchSimplifier");
617 BranchSimplifier::Simplify(flow_graph);
618 DEBUG_ASSERT(flow_graph->VerifyUseLists());
594 619
595 IfConverter::Simplify(flow_graph); 620 IfConverter::Simplify(flow_graph);
596 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 621 DEBUG_ASSERT(flow_graph->VerifyUseLists());
622 }
597 623
598 if (FLAG_constant_propagation) { 624 if (FLAG_constant_propagation) {
625 TimelineDurationScope tds2(thread,
626 compiler_timeline,
627 "ConstantPropagation");
599 ConstantPropagator::Optimize(flow_graph); 628 ConstantPropagator::Optimize(flow_graph);
600 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 629 DEBUG_ASSERT(flow_graph->VerifyUseLists());
601 // A canonicalization pass to remove e.g. smi checks on smi constants. 630 // A canonicalization pass to remove e.g. smi checks on smi constants.
602 optimizer.Canonicalize(); 631 optimizer.Canonicalize();
603 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 632 DEBUG_ASSERT(flow_graph->VerifyUseLists());
604 // Canonicalization introduced more opportunities for constant 633 // Canonicalization introduced more opportunities for constant
605 // propagation. 634 // propagation.
606 ConstantPropagator::Optimize(flow_graph); 635 ConstantPropagator::Optimize(flow_graph);
607 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 636 DEBUG_ASSERT(flow_graph->VerifyUseLists());
608 } 637 }
609 638
610 // Optimistically convert loop phis that have a single non-smi input 639 // Optimistically convert loop phis that have a single non-smi input
611 // coming from the loop pre-header into smi-phis. 640 // coming from the loop pre-header into smi-phis.
612 if (FLAG_loop_invariant_code_motion) { 641 if (FLAG_loop_invariant_code_motion) {
613 LICM licm(flow_graph); 642 LICM licm(flow_graph);
614 licm.OptimisticallySpecializeSmiPhis(); 643 licm.OptimisticallySpecializeSmiPhis();
615 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 644 DEBUG_ASSERT(flow_graph->VerifyUseLists());
616 } 645 }
617 646
618 // Propagate types and eliminate even more type tests. 647 // Propagate types and eliminate even more type tests.
619 // Recompute types after constant propagation to infer more precise 648 // Recompute types after constant propagation to infer more precise
620 // types for uses that were previously reached by now eliminated phis. 649 // types for uses that were previously reached by now eliminated phis.
621 FlowGraphTypePropagator::Propagate(flow_graph); 650 FlowGraphTypePropagator::Propagate(flow_graph);
622 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 651 DEBUG_ASSERT(flow_graph->VerifyUseLists());
623 652
624 // Where beneficial convert Smi operations into Int32 operations. 653 {
625 // Only meanigful for 32bit platforms right now. 654 TimelineDurationScope tds2(thread,
626 optimizer.WidenSmiToInt32(); 655 compiler_timeline,
656 "SelectRepresentations");
657 // Where beneficial convert Smi operations into Int32 operations.
658 // Only meanigful for 32bit platforms right now.
659 optimizer.WidenSmiToInt32();
627 660
628 // Unbox doubles. Performed after constant propagation to minimize 661 // Unbox doubles. Performed after constant propagation to minimize
629 // interference from phis merging double values and tagged 662 // interference from phis merging double values and tagged
630 // values coming from dead paths. 663 // values coming from dead paths.
631 optimizer.SelectRepresentations(); 664 optimizer.SelectRepresentations();
632 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 665 DEBUG_ASSERT(flow_graph->VerifyUseLists());
633
634 if (FLAG_common_subexpression_elimination ||
635 FLAG_loop_invariant_code_motion) {
636 flow_graph->ComputeBlockEffects();
637 } 666 }
638 667
639 if (FLAG_common_subexpression_elimination) { 668 {
640 if (DominatorBasedCSE::Optimize(flow_graph)) { 669 TimelineDurationScope tds2(thread,
641 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 670 compiler_timeline,
642 optimizer.Canonicalize(); 671 "CommonSubexpressionElinination");
643 // Do another round of CSE to take secondary effects into account: 672 if (FLAG_common_subexpression_elimination ||
644 // e.g. when eliminating dependent loads (a.x[0] + a.x[0]) 673 FLAG_loop_invariant_code_motion) {
645 // TODO(fschneider): Change to a one-pass optimization pass. 674 flow_graph->ComputeBlockEffects();
675 }
676
677 if (FLAG_common_subexpression_elimination) {
646 if (DominatorBasedCSE::Optimize(flow_graph)) { 678 if (DominatorBasedCSE::Optimize(flow_graph)) {
679 DEBUG_ASSERT(flow_graph->VerifyUseLists());
647 optimizer.Canonicalize(); 680 optimizer.Canonicalize();
681 // Do another round of CSE to take secondary effects into account:
682 // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
683 // TODO(fschneider): Change to a one-pass optimization pass.
684 if (DominatorBasedCSE::Optimize(flow_graph)) {
685 optimizer.Canonicalize();
686 }
687 DEBUG_ASSERT(flow_graph->VerifyUseLists());
648 } 688 }
689 }
690
691 // Run loop-invariant code motion right after load elimination since
692 // it depends on the numbering of loads from the previous
693 // load-elimination.
694 if (FLAG_loop_invariant_code_motion) {
695 LICM licm(flow_graph);
696 licm.Optimize();
649 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 697 DEBUG_ASSERT(flow_graph->VerifyUseLists());
650 } 698 }
699 flow_graph->RemoveRedefinitions();
651 } 700 }
652 701
653 // Run loop-invariant code motion right after load elimination since it
654 // depends on the numbering of loads from the previous load-elimination.
655 if (FLAG_loop_invariant_code_motion) {
656 LICM licm(flow_graph);
657 licm.Optimize();
658 DEBUG_ASSERT(flow_graph->VerifyUseLists());
659 }
660 flow_graph->RemoveRedefinitions();
661
662 // Optimize (a << b) & c patterns, merge operations. 702 // Optimize (a << b) & c patterns, merge operations.
663 // Run after CSE in order to have more opportunity to merge 703 // Run after CSE in order to have more opportunity to merge
664 // instructions that have same inputs. 704 // instructions that have same inputs.
665 optimizer.TryOptimizePatterns(); 705 optimizer.TryOptimizePatterns();
666 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 706 DEBUG_ASSERT(flow_graph->VerifyUseLists());
667 707
668 DeadStoreElimination::Optimize(flow_graph); 708 {
709 TimelineDurationScope tds2(thread,
710 compiler_timeline,
711 "DeadStoreElimination");
712 DeadStoreElimination::Optimize(flow_graph);
713 }
669 714
670 if (FLAG_range_analysis) { 715 if (FLAG_range_analysis) {
716 TimelineDurationScope tds2(thread,
717 compiler_timeline,
718 "RangeAnalysis");
671 // Propagate types after store-load-forwarding. Some phis may have 719 // Propagate types after store-load-forwarding. Some phis may have
672 // become smi phis that can be processed by range analysis. 720 // become smi phis that can be processed by range analysis.
673 FlowGraphTypePropagator::Propagate(flow_graph); 721 FlowGraphTypePropagator::Propagate(flow_graph);
674 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 722 DEBUG_ASSERT(flow_graph->VerifyUseLists());
675 723
676 // We have to perform range analysis after LICM because it 724 // We have to perform range analysis after LICM because it
677 // optimistically moves CheckSmi through phis into loop preheaders 725 // optimistically moves CheckSmi through phis into loop preheaders
678 // making some phis smi. 726 // making some phis smi.
679 optimizer.InferIntRanges(); 727 optimizer.InferIntRanges();
680 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 728 DEBUG_ASSERT(flow_graph->VerifyUseLists());
681 } 729 }
682 730
683 if (FLAG_constant_propagation) { 731 if (FLAG_constant_propagation) {
732 TimelineDurationScope tds2(thread,
733 compiler_timeline,
734 "ConstantPropagator::OptimizeBranches");
684 // Constant propagation can use information from range analysis to 735 // Constant propagation can use information from range analysis to
685 // find unreachable branch targets and eliminate branches that have 736 // find unreachable branch targets and eliminate branches that have
686 // the same true- and false-target. 737 // the same true- and false-target.
687 ConstantPropagator::OptimizeBranches(flow_graph); 738 ConstantPropagator::OptimizeBranches(flow_graph);
688 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 739 DEBUG_ASSERT(flow_graph->VerifyUseLists());
689 } 740 }
690 741
691 // Recompute types after code movement was done to ensure correct 742 // Recompute types after code movement was done to ensure correct
692 // reaching types for hoisted values. 743 // reaching types for hoisted values.
693 FlowGraphTypePropagator::Propagate(flow_graph); 744 FlowGraphTypePropagator::Propagate(flow_graph);
694 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 745 DEBUG_ASSERT(flow_graph->VerifyUseLists());
695 746
696 // Optimize try-blocks. 747 {
697 TryCatchAnalyzer::Optimize(flow_graph); 748 TimelineDurationScope tds2(thread,
749 compiler_timeline,
750 "TryCatchAnalyzer::Optimize");
751 // Optimize try-blocks.
752 TryCatchAnalyzer::Optimize(flow_graph);
753 }
698 754
699 // Detach environments from the instructions that can't deoptimize. 755 // Detach environments from the instructions that can't deoptimize.
700 // Do it before we attempt to perform allocation sinking to minimize 756 // Do it before we attempt to perform allocation sinking to minimize
701 // amount of materializations it has to perform. 757 // amount of materializations it has to perform.
702 optimizer.EliminateEnvironments(); 758 optimizer.EliminateEnvironments();
703 759
704 DeadCodeElimination::EliminateDeadPhis(flow_graph); 760 {
705 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 761 TimelineDurationScope tds2(thread,
762 compiler_timeline,
763 "EliminateDeadPhis");
764 DeadCodeElimination::EliminateDeadPhis(flow_graph);
765 DEBUG_ASSERT(flow_graph->VerifyUseLists());
766 }
706 767
707 if (optimizer.Canonicalize()) { 768 if (optimizer.Canonicalize()) {
708 optimizer.Canonicalize(); 769 optimizer.Canonicalize();
709 } 770 }
710 771
711 // Attempt to sink allocations of temporary non-escaping objects to 772 // Attempt to sink allocations of temporary non-escaping objects to
712 // the deoptimization path. 773 // the deoptimization path.
713 AllocationSinking* sinking = NULL; 774 AllocationSinking* sinking = NULL;
714 if (FLAG_allocation_sinking && 775 if (FLAG_allocation_sinking &&
715 (flow_graph->graph_entry()->SuccessorCount() == 1)) { 776 (flow_graph->graph_entry()->SuccessorCount() == 1)) {
777 TimelineDurationScope tds2(thread,
778 compiler_timeline,
779 "AllocationSinking::Optimize");
716 // TODO(fschneider): Support allocation sinking with try-catch. 780 // TODO(fschneider): Support allocation sinking with try-catch.
717 sinking = new AllocationSinking(flow_graph); 781 sinking = new AllocationSinking(flow_graph);
718 sinking->Optimize(); 782 sinking->Optimize();
719 } 783 }
720 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 784 DEBUG_ASSERT(flow_graph->VerifyUseLists());
721 785
722 DeadCodeElimination::EliminateDeadPhis(flow_graph); 786 DeadCodeElimination::EliminateDeadPhis(flow_graph);
723 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 787 DEBUG_ASSERT(flow_graph->VerifyUseLists());
724 788
725 FlowGraphTypePropagator::Propagate(flow_graph); 789 FlowGraphTypePropagator::Propagate(flow_graph);
726 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 790 DEBUG_ASSERT(flow_graph->VerifyUseLists());
727 791
728 // Ensure that all phis inserted by optimization passes have consistent 792 {
729 // representations. 793 TimelineDurationScope tds2(thread,
730 optimizer.SelectRepresentations(); 794 compiler_timeline,
795 "SelectRepresentations");
796 // Ensure that all phis inserted by optimization passes have
797 // consistent representations.
798 optimizer.SelectRepresentations();
799 }
731 800
732 if (optimizer.Canonicalize()) { 801 if (optimizer.Canonicalize()) {
733 // To fully remove redundant boxing (e.g. BoxDouble used only in 802 // To fully remove redundant boxing (e.g. BoxDouble used only in
734 // environments and UnboxDouble instructions) instruction we 803 // environments and UnboxDouble instructions) instruction we
735 // first need to replace all their uses and then fold them away. 804 // first need to replace all their uses and then fold them away.
736 // For now we just repeat Canonicalize twice to do that. 805 // For now we just repeat Canonicalize twice to do that.
737 // TODO(vegorov): implement a separate representation folding pass. 806 // TODO(vegorov): implement a separate representation folding pass.
738 optimizer.Canonicalize(); 807 optimizer.Canonicalize();
739 } 808 }
740 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 809 DEBUG_ASSERT(flow_graph->VerifyUseLists());
741 810
742 if (sinking != NULL) { 811 if (sinking != NULL) {
812 TimelineDurationScope tds2(
813 thread,
814 compiler_timeline,
815 "AllocationSinking::DetachMaterializations");
743 // Remove all MaterializeObject instructions inserted by allocation 816 // Remove all MaterializeObject instructions inserted by allocation
744 // sinking from the flow graph and let them float on the side 817 // sinking from the flow graph and let them float on the side
745 // referenced only from environments. Register allocator will consider 818 // referenced only from environments. Register allocator will consider
746 // them as part of a deoptimization environment. 819 // them as part of a deoptimization environment.
747 sinking->DetachMaterializations(); 820 sinking->DetachMaterializations();
748 } 821 }
749 822
750 // Compute and store graph informations (call & instruction counts) 823 // Compute and store graph informations (call & instruction counts)
751 // to be later used by the inliner. 824 // to be later used by the inliner.
752 FlowGraphInliner::CollectGraphInfo(flow_graph, true); 825 FlowGraphInliner::CollectGraphInfo(flow_graph, true);
753 826
754 // Perform register allocation on the SSA graph. 827 {
755 FlowGraphAllocator allocator(*flow_graph); 828 TimelineDurationScope tds2(thread,
756 allocator.AllocateRegisters(); 829 compiler_timeline,
757 if (reorder_blocks) block_scheduler.ReorderBlocks(); 830 "AllocateRegisters");
831 // Perform register allocation on the SSA graph.
832 FlowGraphAllocator allocator(*flow_graph);
833 allocator.AllocateRegisters();
834 }
835
836 if (reorder_blocks) {
837 TimelineDurationScope tds(thread,
838 compiler_timeline,
839 "BlockScheduler::ReorderBlocks");
840 block_scheduler.ReorderBlocks();
841 }
758 842
759 if (print_flow_graph) { 843 if (print_flow_graph) {
760 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); 844 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
761 } 845 }
762 } 846 }
763 847
764 ASSERT(inline_id_to_function.length() == caller_inline_id.length()); 848 ASSERT(inline_id_to_function.length() == caller_inline_id.length());
765 Assembler assembler(use_far_branches); 849 Assembler assembler(use_far_branches);
766 FlowGraphCompiler graph_compiler(&assembler, flow_graph, 850 FlowGraphCompiler graph_compiler(&assembler, flow_graph,
767 *parsed_function, optimized, 851 *parsed_function, optimized,
768 inline_id_to_function, 852 inline_id_to_function,
769 caller_inline_id); 853 caller_inline_id);
770 { 854 {
771 CSTAT_TIMER_SCOPE(thread, graphcompiler_timer); 855 CSTAT_TIMER_SCOPE(thread, graphcompiler_timer);
856 TimelineDurationScope tds(thread,
857 compiler_timeline,
858 "CompileGraph");
772 graph_compiler.CompileGraph(); 859 graph_compiler.CompileGraph();
773 pipeline->FinalizeCompilation(); 860 pipeline->FinalizeCompilation();
774 } 861 }
775 { 862 {
863 TimelineDurationScope tds(thread,
864 compiler_timeline,
865 "FinalizeCompilation");
776 // This part of compilation must be at a safepoint. 866 // This part of compilation must be at a safepoint.
777 if (!Thread::Current()->IsMutatorThread()) { 867 if (!Thread::Current()->IsMutatorThread()) {
778 // Stop mutator thread before creating the instruction object and 868 // Stop mutator thread before creating the instruction object and
779 // installing code. 869 // installing code.
780 // Mutator thread may not run code while we are creating the 870 // Mutator thread may not run code while we are creating the
781 // instruction object, since the creation of instruction object 871 // instruction object, since the creation of instruction object
782 // changes code page access permissions (makes them temporary not 872 // changes code page access permissions (makes them temporary not
783 // executable). 873 // executable).
784 isolate->thread_registry()->SafepointThreads(); 874 isolate->thread_registry()->SafepointThreads();
785 } 875 }
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 } 1978 }
1889 1979
1890 1980
1891 void BackgroundCompiler::EnsureInit(Thread* thread) { 1981 void BackgroundCompiler::EnsureInit(Thread* thread) {
1892 UNREACHABLE(); 1982 UNREACHABLE();
1893 } 1983 }
1894 1984
1895 #endif // DART_PRECOMPILED 1985 #endif // DART_PRECOMPILED
1896 1986
1897 } // namespace dart 1987 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698