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

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

Issue 1678203002: Remove more feature in product mode (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months 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 | « runtime/vm/parser_test.cc ('k') | runtime/vm/profiler.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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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/precompiler.h" 5 #include "vm/precompiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/branch_optimizer.h" 9 #include "vm/branch_optimizer.h"
10 #include "vm/cha.h" 10 #include "vm/cha.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 "In precompilation collects all dynamic function names in order to" 52 "In precompilation collects all dynamic function names in order to"
53 " identify unique targets"); 53 " identify unique targets");
54 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); 54 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets");
55 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); 55 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");
56 DEFINE_FLAG(int, max_speculative_inlining_attempts, 1, 56 DEFINE_FLAG(int, max_speculative_inlining_attempts, 1,
57 "Max number of attempts with speculative inlining (precompilation only)"); 57 "Max number of attempts with speculative inlining (precompilation only)");
58 58
59 DECLARE_FLAG(bool, allocation_sinking); 59 DECLARE_FLAG(bool, allocation_sinking);
60 DECLARE_FLAG(bool, common_subexpression_elimination); 60 DECLARE_FLAG(bool, common_subexpression_elimination);
61 DECLARE_FLAG(bool, constant_propagation); 61 DECLARE_FLAG(bool, constant_propagation);
62 DECLARE_FLAG(bool, disassemble);
63 DECLARE_FLAG(bool, disassemble_optimized);
64 DECLARE_FLAG(bool, loop_invariant_code_motion); 62 DECLARE_FLAG(bool, loop_invariant_code_motion);
65 DECLARE_FLAG(bool, print_flow_graph); 63 DECLARE_FLAG(bool, print_flow_graph);
66 DECLARE_FLAG(bool, print_flow_graph_optimized); 64 DECLARE_FLAG(bool, print_flow_graph_optimized);
67 DECLARE_FLAG(bool, range_analysis); 65 DECLARE_FLAG(bool, range_analysis);
68 DECLARE_FLAG(bool, trace_compiler); 66 DECLARE_FLAG(bool, trace_compiler);
69 DECLARE_FLAG(bool, trace_optimizing_compiler); 67 DECLARE_FLAG(bool, trace_optimizing_compiler);
70 DECLARE_FLAG(bool, trace_bailout); 68 DECLARE_FLAG(bool, trace_bailout);
71 DECLARE_FLAG(bool, use_inlining); 69 DECLARE_FLAG(bool, use_inlining);
72 DECLARE_FLAG(bool, verify_compiler); 70 DECLARE_FLAG(bool, verify_compiler);
73 DECLARE_FLAG(bool, precompilation); 71 DECLARE_FLAG(bool, precompilation);
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 } 735 }
738 UNREACHABLE(); 736 UNREACHABLE();
739 return Object::null(); 737 return Object::null();
740 } 738 }
741 739
742 740
743 RawObject* Precompiler::ExecuteOnce(SequenceNode* fragment) { 741 RawObject* Precompiler::ExecuteOnce(SequenceNode* fragment) {
744 LongJumpScope jump; 742 LongJumpScope jump;
745 if (setjmp(*jump.Set()) == 0) { 743 if (setjmp(*jump.Set()) == 0) {
746 Thread* const thread = Thread::Current(); 744 Thread* const thread = Thread::Current();
747 if (FLAG_trace_compiler) { 745 if (FLAG_support_ast_printer && FLAG_trace_compiler) {
748 THR_Print("compiling expression: "); 746 THR_Print("compiling expression: ");
749 AstPrinter::PrintNode(fragment); 747 AstPrinter::PrintNode(fragment);
750 } 748 }
751 749
752 // Create a dummy function object for the code generator. 750 // Create a dummy function object for the code generator.
753 // The function needs to be associated with a named Class: the interface 751 // The function needs to be associated with a named Class: the interface
754 // Function fits the bill. 752 // Function fits the bill.
755 const char* kEvalConst = "eval_const"; 753 const char* kEvalConst = "eval_const";
756 const Function& func = Function::ZoneHandle(Function::New( 754 const Function& func = Function::ZoneHandle(Function::New(
757 String::Handle(Symbols::New(kEvalConst)), 755 String::Handle(Symbols::New(kEvalConst)),
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 // If optimized_result_code is not NULL then it is caller's responsibility 1618 // If optimized_result_code is not NULL then it is caller's responsibility
1621 // to install code. 1619 // to install code.
1622 bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { 1620 bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
1623 ASSERT(FLAG_precompilation); 1621 ASSERT(FLAG_precompilation);
1624 const Function& function = parsed_function()->function(); 1622 const Function& function = parsed_function()->function();
1625 if (optimized() && !function.IsOptimizable()) { 1623 if (optimized() && !function.IsOptimizable()) {
1626 return false; 1624 return false;
1627 } 1625 }
1628 bool is_compiled = false; 1626 bool is_compiled = false;
1629 Zone* const zone = thread()->zone(); 1627 Zone* const zone = thread()->zone();
1628 #ifndef PRODUCT
1630 TimelineStream* compiler_timeline = isolate()->GetCompilerStream(); 1629 TimelineStream* compiler_timeline = isolate()->GetCompilerStream();
1630 #endif // !PRODUCT
1631 CSTAT_TIMER_SCOPE(thread(), codegen_timer); 1631 CSTAT_TIMER_SCOPE(thread(), codegen_timer);
1632 HANDLESCOPE(thread()); 1632 HANDLESCOPE(thread());
1633 1633
1634 // We may reattempt compilation if the function needs to be assembled using 1634 // We may reattempt compilation if the function needs to be assembled using
1635 // far branches on ARM and MIPS. In the else branch of the setjmp call, 1635 // far branches on ARM and MIPS. In the else branch of the setjmp call,
1636 // done is set to false, and use_far_branches is set to true if there is a 1636 // done is set to false, and use_far_branches is set to true if there is a
1637 // longjmp from the ARM or MIPS assemblers. In all other paths through this 1637 // longjmp from the ARM or MIPS assemblers. In all other paths through this
1638 // while loop, done is set to true. use_far_branches is always false on ia32 1638 // while loop, done is set to true. use_far_branches is always false on ia32
1639 // and x64. 1639 // and x64.
1640 bool done = false; 1640 bool done = false;
(...skipping 14 matching lines...) Expand all
1655 // Class hierarchy analysis is registered with the isolate in the 1655 // Class hierarchy analysis is registered with the isolate in the
1656 // constructor and unregisters itself upon destruction. 1656 // constructor and unregisters itself upon destruction.
1657 CHA cha(thread()); 1657 CHA cha(thread());
1658 1658
1659 // TimerScope needs an isolate to be properly terminated in case of a 1659 // TimerScope needs an isolate to be properly terminated in case of a
1660 // LongJump. 1660 // LongJump.
1661 { 1661 {
1662 CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer); 1662 CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer);
1663 ZoneGrowableArray<const ICData*>* ic_data_array = 1663 ZoneGrowableArray<const ICData*>* ic_data_array =
1664 new(zone) ZoneGrowableArray<const ICData*>(); 1664 new(zone) ZoneGrowableArray<const ICData*>();
1665 #ifndef PRODUCT
1665 TimelineDurationScope tds(thread(), 1666 TimelineDurationScope tds(thread(),
1666 compiler_timeline, 1667 compiler_timeline,
1667 "BuildFlowGraph"); 1668 "BuildFlowGraph");
1669 #endif // !PRODUCT
1668 flow_graph = pipeline->BuildFlowGraph(zone, 1670 flow_graph = pipeline->BuildFlowGraph(zone,
1669 parsed_function(), 1671 parsed_function(),
1670 *ic_data_array, 1672 *ic_data_array,
1671 Compiler::kNoOSRDeoptId); 1673 Compiler::kNoOSRDeoptId);
1672 } 1674 }
1673 1675
1674 const bool print_flow_graph = 1676 const bool print_flow_graph =
1675 (FLAG_print_flow_graph || 1677 (FLAG_print_flow_graph ||
1676 (optimized() && FLAG_print_flow_graph_optimized)) && 1678 (optimized() && FLAG_print_flow_graph_optimized)) &&
1677 FlowGraphPrinter::ShouldPrint(function); 1679 FlowGraphPrinter::ShouldPrint(function);
1678 1680
1679 if (print_flow_graph) { 1681 if (print_flow_graph) {
1680 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 1682 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
1681 } 1683 }
1682 1684
1683 if (optimized()) { 1685 if (optimized()) {
1686 #ifndef PRODUCT
1684 TimelineDurationScope tds(thread(), 1687 TimelineDurationScope tds(thread(),
1685 compiler_timeline, 1688 compiler_timeline,
1686 "ComputeSSA"); 1689 "ComputeSSA");
1690 #endif // !PRODUCT
1687 CSTAT_TIMER_SCOPE(thread(), ssa_timer); 1691 CSTAT_TIMER_SCOPE(thread(), ssa_timer);
1688 // Transform to SSA (virtual register 0 and no inlining arguments). 1692 // Transform to SSA (virtual register 0 and no inlining arguments).
1689 flow_graph->ComputeSSA(0, NULL); 1693 flow_graph->ComputeSSA(0, NULL);
1690 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1694 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1691 if (print_flow_graph) { 1695 if (print_flow_graph) {
1692 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); 1696 FlowGraphPrinter::PrintGraph("After SSA", flow_graph);
1693 } 1697 }
1694 } 1698 }
1695 1699
1696 // Maps inline_id_to_function[inline_id] -> function. Top scope 1700 // Maps inline_id_to_function[inline_id] -> function. Top scope
1697 // function has inline_id 0. The map is populated by the inliner. 1701 // function has inline_id 0. The map is populated by the inliner.
1698 GrowableArray<const Function*> inline_id_to_function; 1702 GrowableArray<const Function*> inline_id_to_function;
1699 // For a given inlining-id(index) specifies the caller's inlining-id. 1703 // For a given inlining-id(index) specifies the caller's inlining-id.
1700 GrowableArray<intptr_t> caller_inline_id; 1704 GrowableArray<intptr_t> caller_inline_id;
1701 // Collect all instance fields that are loaded in the graph and 1705 // Collect all instance fields that are loaded in the graph and
1702 // have non-generic type feedback attached to them that can 1706 // have non-generic type feedback attached to them that can
1703 // potentially affect optimizations. 1707 // potentially affect optimizations.
1704 if (optimized()) { 1708 if (optimized()) {
1709 #ifndef PRODUCT
1705 TimelineDurationScope tds(thread(), 1710 TimelineDurationScope tds(thread(),
1706 compiler_timeline, 1711 compiler_timeline,
1707 "OptimizationPasses"); 1712 "OptimizationPasses");
1713 #endif // !PRODUCT
1708 inline_id_to_function.Add(&function); 1714 inline_id_to_function.Add(&function);
1709 // Top scope function has no caller (-1). 1715 // Top scope function has no caller (-1).
1710 caller_inline_id.Add(-1); 1716 caller_inline_id.Add(-1);
1711 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer); 1717 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer);
1712 1718
1713 FlowGraphOptimizer optimizer(flow_graph, 1719 FlowGraphOptimizer optimizer(flow_graph,
1714 use_speculative_inlining, 1720 use_speculative_inlining,
1715 &inlining_black_list); 1721 &inlining_black_list);
1716 optimizer.PopulateWithICData(); 1722 optimizer.PopulateWithICData();
1717 1723
1718 optimizer.ApplyClassIds(); 1724 optimizer.ApplyClassIds();
1719 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1725 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1720 1726
1721 FlowGraphTypePropagator::Propagate(flow_graph); 1727 FlowGraphTypePropagator::Propagate(flow_graph);
1722 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1728 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1723 1729
1724 optimizer.ApplyICData(); 1730 optimizer.ApplyICData();
1725 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1731 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1726 1732
1727 // Optimize (a << b) & c patterns, merge operations. 1733 // Optimize (a << b) & c patterns, merge operations.
1728 // Run early in order to have more opportunity to optimize left shifts. 1734 // Run early in order to have more opportunity to optimize left shifts.
1729 optimizer.TryOptimizePatterns(); 1735 optimizer.TryOptimizePatterns();
1730 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1736 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1731 1737
1732 FlowGraphInliner::SetInliningId(flow_graph, 0); 1738 FlowGraphInliner::SetInliningId(flow_graph, 0);
1733 1739
1734 // Inlining (mutates the flow graph) 1740 // Inlining (mutates the flow graph)
1735 if (FLAG_use_inlining) { 1741 if (FLAG_use_inlining) {
1742 #ifndef PRODUCT
1736 TimelineDurationScope tds2(thread(), 1743 TimelineDurationScope tds2(thread(),
1737 compiler_timeline, 1744 compiler_timeline,
1738 "Inlining"); 1745 "Inlining");
1746 #endif // !PRODUCT
1739 CSTAT_TIMER_SCOPE(thread(), graphinliner_timer); 1747 CSTAT_TIMER_SCOPE(thread(), graphinliner_timer);
1740 // Propagate types to create more inlining opportunities. 1748 // Propagate types to create more inlining opportunities.
1741 FlowGraphTypePropagator::Propagate(flow_graph); 1749 FlowGraphTypePropagator::Propagate(flow_graph);
1742 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1750 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1743 1751
1744 // Use propagated class-ids to create more inlining opportunities. 1752 // Use propagated class-ids to create more inlining opportunities.
1745 optimizer.ApplyClassIds(); 1753 optimizer.ApplyClassIds();
1746 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1754 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1747 1755
1748 FlowGraphInliner inliner(flow_graph, 1756 FlowGraphInliner inliner(flow_graph,
1749 &inline_id_to_function, 1757 &inline_id_to_function,
1750 &caller_inline_id, 1758 &caller_inline_id,
1751 use_speculative_inlining, 1759 use_speculative_inlining,
1752 &inlining_black_list); 1760 &inlining_black_list);
1753 inliner.Inline(); 1761 inliner.Inline();
1754 // Use lists are maintained and validated by the inliner. 1762 // Use lists are maintained and validated by the inliner.
1755 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1763 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1756 } 1764 }
1757 1765
1758 // Propagate types and eliminate more type tests. 1766 // Propagate types and eliminate more type tests.
1759 FlowGraphTypePropagator::Propagate(flow_graph); 1767 FlowGraphTypePropagator::Propagate(flow_graph);
1760 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1768 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1761 1769
1762 { 1770 {
1771 #ifndef PRODUCT
1763 TimelineDurationScope tds2(thread(), 1772 TimelineDurationScope tds2(thread(),
1764 compiler_timeline, 1773 compiler_timeline,
1765 "ApplyClassIds"); 1774 "ApplyClassIds");
1775 #endif // !PRODUCT
1766 // Use propagated class-ids to optimize further. 1776 // Use propagated class-ids to optimize further.
1767 optimizer.ApplyClassIds(); 1777 optimizer.ApplyClassIds();
1768 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1778 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1769 } 1779 }
1770 1780
1771 // Propagate types for potentially newly added instructions by 1781 // Propagate types for potentially newly added instructions by
1772 // ApplyClassIds(). Must occur before canonicalization. 1782 // ApplyClassIds(). Must occur before canonicalization.
1773 FlowGraphTypePropagator::Propagate(flow_graph); 1783 FlowGraphTypePropagator::Propagate(flow_graph);
1774 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1784 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1775 1785
1776 // Do optimizations that depend on the propagated type information. 1786 // Do optimizations that depend on the propagated type information.
1777 if (optimizer.Canonicalize()) { 1787 if (optimizer.Canonicalize()) {
1778 // Invoke Canonicalize twice in order to fully canonicalize patterns 1788 // Invoke Canonicalize twice in order to fully canonicalize patterns
1779 // like "if (a & const == 0) { }". 1789 // like "if (a & const == 0) { }".
1780 optimizer.Canonicalize(); 1790 optimizer.Canonicalize();
1781 } 1791 }
1782 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1792 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1783 1793
1784 { 1794 {
1795 #ifndef PRODUCT
1785 TimelineDurationScope tds2(thread(), 1796 TimelineDurationScope tds2(thread(),
1786 compiler_timeline, 1797 compiler_timeline,
1787 "BranchSimplifier"); 1798 "BranchSimplifier");
1799 #endif // !PRODUCT
1788 BranchSimplifier::Simplify(flow_graph); 1800 BranchSimplifier::Simplify(flow_graph);
1789 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1801 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1790 1802
1791 IfConverter::Simplify(flow_graph); 1803 IfConverter::Simplify(flow_graph);
1792 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1804 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1793 } 1805 }
1794 1806
1795 if (FLAG_constant_propagation) { 1807 if (FLAG_constant_propagation) {
1808 #ifndef PRODUCT
1796 TimelineDurationScope tds2(thread(), 1809 TimelineDurationScope tds2(thread(),
1797 compiler_timeline, 1810 compiler_timeline,
1798 "ConstantPropagation"); 1811 "ConstantPropagation");
1812 #endif // !PRODUCT
1799 ConstantPropagator::Optimize(flow_graph); 1813 ConstantPropagator::Optimize(flow_graph);
1800 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1814 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1801 // A canonicalization pass to remove e.g. smi checks on smi constants. 1815 // A canonicalization pass to remove e.g. smi checks on smi constants.
1802 optimizer.Canonicalize(); 1816 optimizer.Canonicalize();
1803 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1817 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1804 // Canonicalization introduced more opportunities for constant 1818 // Canonicalization introduced more opportunities for constant
1805 // propagation. 1819 // propagation.
1806 ConstantPropagator::Optimize(flow_graph); 1820 ConstantPropagator::Optimize(flow_graph);
1807 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1821 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1808 } 1822 }
1809 1823
1810 // Optimistically convert loop phis that have a single non-smi input 1824 // Optimistically convert loop phis that have a single non-smi input
1811 // coming from the loop pre-header into smi-phis. 1825 // coming from the loop pre-header into smi-phis.
1812 if (FLAG_loop_invariant_code_motion) { 1826 if (FLAG_loop_invariant_code_motion) {
1813 LICM licm(flow_graph); 1827 LICM licm(flow_graph);
1814 licm.OptimisticallySpecializeSmiPhis(); 1828 licm.OptimisticallySpecializeSmiPhis();
1815 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1829 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1816 } 1830 }
1817 1831
1818 // Propagate types and eliminate even more type tests. 1832 // Propagate types and eliminate even more type tests.
1819 // Recompute types after constant propagation to infer more precise 1833 // Recompute types after constant propagation to infer more precise
1820 // types for uses that were previously reached by now eliminated phis. 1834 // types for uses that were previously reached by now eliminated phis.
1821 FlowGraphTypePropagator::Propagate(flow_graph); 1835 FlowGraphTypePropagator::Propagate(flow_graph);
1822 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1836 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1823 1837
1824 { 1838 {
1839 #ifndef PRODUCT
1825 TimelineDurationScope tds2(thread(), 1840 TimelineDurationScope tds2(thread(),
1826 compiler_timeline, 1841 compiler_timeline,
1827 "SelectRepresentations"); 1842 "SelectRepresentations");
1843 #endif // !PRODUCT
1828 // Where beneficial convert Smi operations into Int32 operations. 1844 // Where beneficial convert Smi operations into Int32 operations.
1829 // Only meanigful for 32bit platforms right now. 1845 // Only meanigful for 32bit platforms right now.
1830 optimizer.WidenSmiToInt32(); 1846 optimizer.WidenSmiToInt32();
1831 1847
1832 // Unbox doubles. Performed after constant propagation to minimize 1848 // Unbox doubles. Performed after constant propagation to minimize
1833 // interference from phis merging double values and tagged 1849 // interference from phis merging double values and tagged
1834 // values coming from dead paths. 1850 // values coming from dead paths.
1835 optimizer.SelectRepresentations(); 1851 optimizer.SelectRepresentations();
1836 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1852 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1837 } 1853 }
1838 1854
1839 { 1855 {
1856 #ifndef PRODUCT
1840 TimelineDurationScope tds2(thread(), 1857 TimelineDurationScope tds2(thread(),
1841 compiler_timeline, 1858 compiler_timeline,
1842 "CommonSubexpressionElinination"); 1859 "CommonSubexpressionElinination");
1860 #endif // !PRODUCT
1843 if (FLAG_common_subexpression_elimination || 1861 if (FLAG_common_subexpression_elimination ||
1844 FLAG_loop_invariant_code_motion) { 1862 FLAG_loop_invariant_code_motion) {
1845 flow_graph->ComputeBlockEffects(); 1863 flow_graph->ComputeBlockEffects();
1846 } 1864 }
1847 1865
1848 if (FLAG_common_subexpression_elimination) { 1866 if (FLAG_common_subexpression_elimination) {
1849 if (DominatorBasedCSE::Optimize(flow_graph)) { 1867 if (DominatorBasedCSE::Optimize(flow_graph)) {
1850 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1868 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1851 optimizer.Canonicalize(); 1869 optimizer.Canonicalize();
1852 // Do another round of CSE to take secondary effects into account: 1870 // Do another round of CSE to take secondary effects into account:
(...skipping 17 matching lines...) Expand all
1870 flow_graph->RemoveRedefinitions(); 1888 flow_graph->RemoveRedefinitions();
1871 } 1889 }
1872 1890
1873 // Optimize (a << b) & c patterns, merge operations. 1891 // Optimize (a << b) & c patterns, merge operations.
1874 // Run after CSE in order to have more opportunity to merge 1892 // Run after CSE in order to have more opportunity to merge
1875 // instructions that have same inputs. 1893 // instructions that have same inputs.
1876 optimizer.TryOptimizePatterns(); 1894 optimizer.TryOptimizePatterns();
1877 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1895 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1878 1896
1879 { 1897 {
1898 #ifndef PRODUCT
1880 TimelineDurationScope tds2(thread(), 1899 TimelineDurationScope tds2(thread(),
1881 compiler_timeline, 1900 compiler_timeline,
1882 "DeadStoreElimination"); 1901 "DeadStoreElimination");
1902 #endif // !PRODUCT
1883 DeadStoreElimination::Optimize(flow_graph); 1903 DeadStoreElimination::Optimize(flow_graph);
1884 } 1904 }
1885 1905
1886 if (FLAG_range_analysis) { 1906 if (FLAG_range_analysis) {
1907 #ifndef PRODUCT
1887 TimelineDurationScope tds2(thread(), 1908 TimelineDurationScope tds2(thread(),
1888 compiler_timeline, 1909 compiler_timeline,
1889 "RangeAnalysis"); 1910 "RangeAnalysis");
1911 #endif // !PRODUCT
1890 // Propagate types after store-load-forwarding. Some phis may have 1912 // Propagate types after store-load-forwarding. Some phis may have
1891 // become smi phis that can be processed by range analysis. 1913 // become smi phis that can be processed by range analysis.
1892 FlowGraphTypePropagator::Propagate(flow_graph); 1914 FlowGraphTypePropagator::Propagate(flow_graph);
1893 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1915 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1894 1916
1895 // We have to perform range analysis after LICM because it 1917 // We have to perform range analysis after LICM because it
1896 // optimistically moves CheckSmi through phis into loop preheaders 1918 // optimistically moves CheckSmi through phis into loop preheaders
1897 // making some phis smi. 1919 // making some phis smi.
1898 optimizer.InferIntRanges(); 1920 optimizer.InferIntRanges();
1899 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1921 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1900 } 1922 }
1901 1923
1902 if (FLAG_constant_propagation) { 1924 if (FLAG_constant_propagation) {
1925 #ifndef PRODUCT
1903 TimelineDurationScope tds2(thread(), 1926 TimelineDurationScope tds2(thread(),
1904 compiler_timeline, 1927 compiler_timeline,
1905 "ConstantPropagator::OptimizeBranches"); 1928 "ConstantPropagator::OptimizeBranches");
1929 #endif // !PRODUCT
1906 // Constant propagation can use information from range analysis to 1930 // Constant propagation can use information from range analysis to
1907 // find unreachable branch targets and eliminate branches that have 1931 // find unreachable branch targets and eliminate branches that have
1908 // the same true- and false-target. 1932 // the same true- and false-target.
1909 ConstantPropagator::OptimizeBranches(flow_graph); 1933 ConstantPropagator::OptimizeBranches(flow_graph);
1910 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1934 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1911 } 1935 }
1912 1936
1913 // Recompute types after code movement was done to ensure correct 1937 // Recompute types after code movement was done to ensure correct
1914 // reaching types for hoisted values. 1938 // reaching types for hoisted values.
1915 FlowGraphTypePropagator::Propagate(flow_graph); 1939 FlowGraphTypePropagator::Propagate(flow_graph);
1916 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1940 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1917 1941
1918 { 1942 {
1943 #ifndef PRODUCT
1919 TimelineDurationScope tds2(thread(), 1944 TimelineDurationScope tds2(thread(),
1920 compiler_timeline, 1945 compiler_timeline,
1921 "TryCatchAnalyzer::Optimize"); 1946 "TryCatchAnalyzer::Optimize");
1947 #endif // !PRODUCT
1922 // Optimize try-blocks. 1948 // Optimize try-blocks.
1923 TryCatchAnalyzer::Optimize(flow_graph); 1949 TryCatchAnalyzer::Optimize(flow_graph);
1924 } 1950 }
1925 1951
1926 // Detach environments from the instructions that can't deoptimize. 1952 // Detach environments from the instructions that can't deoptimize.
1927 // Do it before we attempt to perform allocation sinking to minimize 1953 // Do it before we attempt to perform allocation sinking to minimize
1928 // amount of materializations it has to perform. 1954 // amount of materializations it has to perform.
1929 optimizer.EliminateEnvironments(); 1955 optimizer.EliminateEnvironments();
1930 1956
1931 { 1957 {
1958 #ifndef PRODUCT
1932 TimelineDurationScope tds2(thread(), 1959 TimelineDurationScope tds2(thread(),
1933 compiler_timeline, 1960 compiler_timeline,
1934 "EliminateDeadPhis"); 1961 "EliminateDeadPhis");
1962 #endif // !PRODUCT
1935 DeadCodeElimination::EliminateDeadPhis(flow_graph); 1963 DeadCodeElimination::EliminateDeadPhis(flow_graph);
1936 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1964 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1937 } 1965 }
1938 1966
1939 if (optimizer.Canonicalize()) { 1967 if (optimizer.Canonicalize()) {
1940 optimizer.Canonicalize(); 1968 optimizer.Canonicalize();
1941 } 1969 }
1942 1970
1943 // Attempt to sink allocations of temporary non-escaping objects to 1971 // Attempt to sink allocations of temporary non-escaping objects to
1944 // the deoptimization path. 1972 // the deoptimization path.
1945 AllocationSinking* sinking = NULL; 1973 AllocationSinking* sinking = NULL;
1946 if (FLAG_allocation_sinking && 1974 if (FLAG_allocation_sinking &&
1947 (flow_graph->graph_entry()->SuccessorCount() == 1)) { 1975 (flow_graph->graph_entry()->SuccessorCount() == 1)) {
1976 #ifndef PRODUCT
1948 TimelineDurationScope tds2(thread(), 1977 TimelineDurationScope tds2(thread(),
1949 compiler_timeline, 1978 compiler_timeline,
1950 "AllocationSinking::Optimize"); 1979 "AllocationSinking::Optimize");
1980 #endif // !PRODUCT
1951 // TODO(fschneider): Support allocation sinking with try-catch. 1981 // TODO(fschneider): Support allocation sinking with try-catch.
1952 sinking = new AllocationSinking(flow_graph); 1982 sinking = new AllocationSinking(flow_graph);
1953 sinking->Optimize(); 1983 sinking->Optimize();
1954 } 1984 }
1955 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1985 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1956 1986
1957 DeadCodeElimination::EliminateDeadPhis(flow_graph); 1987 DeadCodeElimination::EliminateDeadPhis(flow_graph);
1958 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1988 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1959 1989
1960 FlowGraphTypePropagator::Propagate(flow_graph); 1990 FlowGraphTypePropagator::Propagate(flow_graph);
1961 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 1991 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1962 1992
1963 { 1993 {
1994 #ifndef PRODUCT
1964 TimelineDurationScope tds2(thread(), 1995 TimelineDurationScope tds2(thread(),
1965 compiler_timeline, 1996 compiler_timeline,
1966 "SelectRepresentations"); 1997 "SelectRepresentations");
1998 #endif // !PRODUCT
1967 // Ensure that all phis inserted by optimization passes have 1999 // Ensure that all phis inserted by optimization passes have
1968 // consistent representations. 2000 // consistent representations.
1969 optimizer.SelectRepresentations(); 2001 optimizer.SelectRepresentations();
1970 } 2002 }
1971 2003
1972 if (optimizer.Canonicalize()) { 2004 if (optimizer.Canonicalize()) {
1973 // To fully remove redundant boxing (e.g. BoxDouble used only in 2005 // To fully remove redundant boxing (e.g. BoxDouble used only in
1974 // environments and UnboxDouble instructions) instruction we 2006 // environments and UnboxDouble instructions) instruction we
1975 // first need to replace all their uses and then fold them away. 2007 // first need to replace all their uses and then fold them away.
1976 // For now we just repeat Canonicalize twice to do that. 2008 // For now we just repeat Canonicalize twice to do that.
1977 // TODO(vegorov): implement a separate representation folding pass. 2009 // TODO(vegorov): implement a separate representation folding pass.
1978 optimizer.Canonicalize(); 2010 optimizer.Canonicalize();
1979 } 2011 }
1980 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2012 DEBUG_ASSERT(flow_graph->VerifyUseLists());
1981 2013
1982 if (sinking != NULL) { 2014 if (sinking != NULL) {
2015 #ifndef PRODUCT
1983 TimelineDurationScope tds2( 2016 TimelineDurationScope tds2(
1984 thread(), 2017 thread(),
1985 compiler_timeline, 2018 compiler_timeline,
1986 "AllocationSinking::DetachMaterializations"); 2019 "AllocationSinking::DetachMaterializations");
2020 #endif // !PRODUCT
1987 // Remove all MaterializeObject instructions inserted by allocation 2021 // Remove all MaterializeObject instructions inserted by allocation
1988 // sinking from the flow graph and let them float on the side 2022 // sinking from the flow graph and let them float on the side
1989 // referenced only from environments. Register allocator will consider 2023 // referenced only from environments. Register allocator will consider
1990 // them as part of a deoptimization environment. 2024 // them as part of a deoptimization environment.
1991 sinking->DetachMaterializations(); 2025 sinking->DetachMaterializations();
1992 } 2026 }
1993 2027
1994 // Compute and store graph informations (call & instruction counts) 2028 // Compute and store graph informations (call & instruction counts)
1995 // to be later used by the inliner. 2029 // to be later used by the inliner.
1996 FlowGraphInliner::CollectGraphInfo(flow_graph, true); 2030 FlowGraphInliner::CollectGraphInfo(flow_graph, true);
1997 2031
1998 { 2032 {
2033 #ifndef PRODUCT
1999 TimelineDurationScope tds2(thread(), 2034 TimelineDurationScope tds2(thread(),
2000 compiler_timeline, 2035 compiler_timeline,
2001 "AllocateRegisters"); 2036 "AllocateRegisters");
2037 #endif // !PRODUCT
2002 // Perform register allocation on the SSA graph. 2038 // Perform register allocation on the SSA graph.
2003 FlowGraphAllocator allocator(*flow_graph); 2039 FlowGraphAllocator allocator(*flow_graph);
2004 allocator.AllocateRegisters(); 2040 allocator.AllocateRegisters();
2005 } 2041 }
2006 2042
2007 if (print_flow_graph) { 2043 if (print_flow_graph) {
2008 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); 2044 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
2009 } 2045 }
2010 } 2046 }
2011 2047
2012 ASSERT(inline_id_to_function.length() == caller_inline_id.length()); 2048 ASSERT(inline_id_to_function.length() == caller_inline_id.length());
2013 Assembler assembler(use_far_branches); 2049 Assembler assembler(use_far_branches);
2014 FlowGraphCompiler graph_compiler(&assembler, flow_graph, 2050 FlowGraphCompiler graph_compiler(&assembler, flow_graph,
2015 *parsed_function(), optimized(), 2051 *parsed_function(), optimized(),
2016 inline_id_to_function, 2052 inline_id_to_function,
2017 caller_inline_id); 2053 caller_inline_id);
2018 { 2054 {
2019 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer); 2055 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer);
2056 #ifndef PRODUCT
2020 TimelineDurationScope tds(thread(), 2057 TimelineDurationScope tds(thread(),
2021 compiler_timeline, 2058 compiler_timeline,
2022 "CompileGraph"); 2059 "CompileGraph");
2060 #endif // !PRODUCT
2023 graph_compiler.CompileGraph(); 2061 graph_compiler.CompileGraph();
2024 pipeline->FinalizeCompilation(); 2062 pipeline->FinalizeCompilation();
2025 } 2063 }
2026 { 2064 {
2065 #ifndef PRODUCT
2027 TimelineDurationScope tds(thread(), 2066 TimelineDurationScope tds(thread(),
2028 compiler_timeline, 2067 compiler_timeline,
2029 "FinalizeCompilation"); 2068 "FinalizeCompilation");
2069 #endif // !PRODUCT
2030 ASSERT(thread()->IsMutatorThread()); 2070 ASSERT(thread()->IsMutatorThread());
2031 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); 2071 FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
2032 } 2072 }
2033 // Mark that this isolate now has compiled code. 2073 // Mark that this isolate now has compiled code.
2034 isolate()->set_has_compiled_code(true); 2074 isolate()->set_has_compiled_code(true);
2035 // Exit the loop and the function with the correct result value. 2075 // Exit the loop and the function with the correct result value.
2036 is_compiled = true; 2076 is_compiled = true;
2037 done = true; 2077 done = true;
2038 } else { 2078 } else {
2039 // We bailed out or we encountered an error. 2079 // We bailed out or we encountered an error.
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 CompilationPipeline::New(thread->zone(), function); 2230 CompilationPipeline::New(thread->zone(), function);
2191 2231
2192 ASSERT(FLAG_precompilation); 2232 ASSERT(FLAG_precompilation);
2193 const bool optimized = function.IsOptimizable(); // False for natives. 2233 const bool optimized = function.IsOptimizable(); // False for natives.
2194 return PrecompileFunctionHelper(pipeline, function, optimized); 2234 return PrecompileFunctionHelper(pipeline, function, optimized);
2195 } 2235 }
2196 2236
2197 #endif // DART_PRECOMPILER 2237 #endif // DART_PRECOMPILER
2198 2238
2199 } // namespace dart 2239 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser_test.cc ('k') | runtime/vm/profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698