comparison src/share/vm/opto/compile.cpp @ 7473:d092d1b31229

8005071: Incremental inlining for JSR 292 Summary: post parse inlining driven by number of live nodes. Reviewed-by: twisti, kvn, jrose
author roland
date Sun, 23 Dec 2012 17:08:22 +0100
parents ad5dd04754ee
children 5b8548391bf3
comparison
equal deleted inserted replaced
7445:cd962e15c08e 7473:d092d1b31229
134 return lo; // inexact match 134 return lo; // inexact match
135 } 135 }
136 136
137 void Compile::register_intrinsic(CallGenerator* cg) { 137 void Compile::register_intrinsic(CallGenerator* cg) {
138 if (_intrinsics == NULL) { 138 if (_intrinsics == NULL) {
139 _intrinsics = new GrowableArray<CallGenerator*>(60); 139 _intrinsics = new (comp_arena())GrowableArray<CallGenerator*>(comp_arena(), 60, 0, NULL);
140 } 140 }
141 // This code is stolen from ciObjectFactory::insert. 141 // This code is stolen from ciObjectFactory::insert.
142 // Really, GrowableArray should have methods for 142 // Really, GrowableArray should have methods for
143 // insert_at, remove_at, and binary_search. 143 // insert_at, remove_at, and binary_search.
144 int len = _intrinsics->length(); 144 int len = _intrinsics->length();
363 record_dead_node(node_idx); 363 record_dead_node(node_idx);
364 } 364 }
365 } 365 }
366 } 366 }
367 367
368 void Compile::remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful) {
369 int shift = 0;
370 for (int i = 0; i < inlines->length(); i++) {
371 CallGenerator* cg = inlines->at(i);
372 CallNode* call = cg->call_node();
373 if (shift > 0) {
374 inlines->at_put(i-shift, cg);
375 }
376 if (!useful.member(call)) {
377 shift++;
378 }
379 }
380 inlines->trunc_to(inlines->length()-shift);
381 }
382
368 // Disconnect all useless nodes by disconnecting those at the boundary. 383 // Disconnect all useless nodes by disconnecting those at the boundary.
369 void Compile::remove_useless_nodes(Unique_Node_List &useful) { 384 void Compile::remove_useless_nodes(Unique_Node_List &useful) {
370 uint next = 0; 385 uint next = 0;
371 while (next < useful.size()) { 386 while (next < useful.size()) {
372 Node *n = useful.at(next++); 387 Node *n = useful.at(next++);
392 Node* n = C->macro_node(i); 407 Node* n = C->macro_node(i);
393 if (!useful.member(n)) { 408 if (!useful.member(n)) {
394 remove_macro_node(n); 409 remove_macro_node(n);
395 } 410 }
396 } 411 }
412 // clean up the late inline lists
413 remove_useless_late_inlines(&_string_late_inlines, useful);
414 remove_useless_late_inlines(&_late_inlines, useful);
397 debug_only(verify_graph_edges(true/*check for no_dead_code*/);) 415 debug_only(verify_graph_edges(true/*check for no_dead_code*/);)
398 } 416 }
399 417
400 //------------------------------frame_size_in_words----------------------------- 418 //------------------------------frame_size_in_words-----------------------------
401 // frame_slots in units of words 419 // frame_slots in units of words
609 #ifndef PRODUCT 627 #ifndef PRODUCT
610 _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), 628 _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")),
611 _printer(IdealGraphPrinter::printer()), 629 _printer(IdealGraphPrinter::printer()),
612 #endif 630 #endif
613 _congraph(NULL), 631 _congraph(NULL),
632 _late_inlines(comp_arena(), 2, 0, NULL),
633 _string_late_inlines(comp_arena(), 2, 0, NULL),
634 _late_inlines_pos(0),
635 _number_of_mh_late_inlines(0),
636 _inlining_progress(false),
637 _inlining_incrementally(false),
614 _print_inlining_list(NULL), 638 _print_inlining_list(NULL),
615 _print_inlining(0) { 639 _print_inlining(0) {
616 C = this; 640 C = this;
617 641
618 CompileWrapper cw(this); 642 CompileWrapper cw(this);
735 // to whatever caller is dynamically above us on the stack. 759 // to whatever caller is dynamically above us on the stack.
736 // This is done by a special, unique RethrowNode bound to root. 760 // This is done by a special, unique RethrowNode bound to root.
737 rethrow_exceptions(kit.transfer_exceptions_into_jvms()); 761 rethrow_exceptions(kit.transfer_exceptions_into_jvms());
738 } 762 }
739 763
740 if (!failing() && has_stringbuilder()) { 764 assert(IncrementalInline || (_late_inlines.length() == 0 && !has_mh_late_inlines()), "incremental inlining is off");
741 { 765
742 // remove useless nodes to make the usage analysis simpler 766 if (_late_inlines.length() == 0 && !has_mh_late_inlines() && !failing() && has_stringbuilder()) {
743 ResourceMark rm; 767 inline_string_calls(true);
744 PhaseRemoveUseless pru(initial_gvn(), &for_igvn); 768 }
745 } 769
746 770 if (failing()) return;
747 {
748 ResourceMark rm;
749 print_method("Before StringOpts", 3);
750 PhaseStringOpts pso(initial_gvn(), &for_igvn);
751 print_method("After StringOpts", 3);
752 }
753
754 // now inline anything that we skipped the first time around
755 while (_late_inlines.length() > 0) {
756 CallGenerator* cg = _late_inlines.pop();
757 cg->do_late_inline();
758 if (failing()) return;
759 }
760 }
761 assert(_late_inlines.length() == 0, "should have been processed");
762 dump_inlining();
763 771
764 print_method("Before RemoveUseless", 3); 772 print_method("Before RemoveUseless", 3);
765 773
766 // Remove clutter produced by parsing. 774 // Remove clutter produced by parsing.
767 if (!failing()) { 775 if (!failing()) {
904 _printer(NULL), 912 _printer(NULL),
905 #endif 913 #endif
906 _dead_node_list(comp_arena()), 914 _dead_node_list(comp_arena()),
907 _dead_node_count(0), 915 _dead_node_count(0),
908 _congraph(NULL), 916 _congraph(NULL),
917 _number_of_mh_late_inlines(0),
918 _inlining_progress(false),
919 _inlining_incrementally(false),
909 _print_inlining_list(NULL), 920 _print_inlining_list(NULL),
910 _print_inlining(0) { 921 _print_inlining(0) {
911 C = this; 922 C = this;
912 923
913 #ifndef PRODUCT 924 #ifndef PRODUCT
1758 igvn.replace_node(n, n->in(1)); 1769 igvn.replace_node(n, n->in(1));
1759 } 1770 }
1760 assert(predicate_count()==0, "should be clean!"); 1771 assert(predicate_count()==0, "should be clean!");
1761 } 1772 }
1762 1773
1774 // StringOpts and late inlining of string methods
1775 void Compile::inline_string_calls(bool parse_time) {
1776 {
1777 // remove useless nodes to make the usage analysis simpler
1778 ResourceMark rm;
1779 PhaseRemoveUseless pru(initial_gvn(), for_igvn());
1780 }
1781
1782 {
1783 ResourceMark rm;
1784 print_method("Before StringOpts", 3);
1785 PhaseStringOpts pso(initial_gvn(), for_igvn());
1786 print_method("After StringOpts", 3);
1787 }
1788
1789 // now inline anything that we skipped the first time around
1790 if (!parse_time) {
1791 _late_inlines_pos = _late_inlines.length();
1792 }
1793
1794 while (_string_late_inlines.length() > 0) {
1795 CallGenerator* cg = _string_late_inlines.pop();
1796 cg->do_late_inline();
1797 if (failing()) return;
1798 }
1799 _string_late_inlines.trunc_to(0);
1800 }
1801
1802 void Compile::inline_incrementally_one(PhaseIterGVN& igvn) {
1803 assert(IncrementalInline, "incremental inlining should be on");
1804 PhaseGVN* gvn = initial_gvn();
1805
1806 set_inlining_progress(false);
1807 for_igvn()->clear();
1808 gvn->replace_with(&igvn);
1809
1810 int i = 0;
1811
1812 for (; i <_late_inlines.length() && !inlining_progress(); i++) {
1813 CallGenerator* cg = _late_inlines.at(i);
1814 _late_inlines_pos = i+1;
1815 cg->do_late_inline();
1816 if (failing()) return;
1817 }
1818 int j = 0;
1819 for (; i < _late_inlines.length(); i++, j++) {
1820 _late_inlines.at_put(j, _late_inlines.at(i));
1821 }
1822 _late_inlines.trunc_to(j);
1823
1824 {
1825 ResourceMark rm;
1826 PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
1827 }
1828
1829 igvn = PhaseIterGVN(gvn);
1830 }
1831
1832 // Perform incremental inlining until bound on number of live nodes is reached
1833 void Compile::inline_incrementally(PhaseIterGVN& igvn) {
1834 PhaseGVN* gvn = initial_gvn();
1835
1836 set_inlining_incrementally(true);
1837 set_inlining_progress(true);
1838 uint low_live_nodes = 0;
1839
1840 while(inlining_progress() && _late_inlines.length() > 0) {
1841
1842 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
1843 if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) {
1844 // PhaseIdealLoop is expensive so we only try it once we are
1845 // out of loop and we only try it again if the previous helped
1846 // got the number of nodes down significantly
1847 PhaseIdealLoop ideal_loop( igvn, false, true );
1848 if (failing()) return;
1849 low_live_nodes = live_nodes();
1850 _major_progress = true;
1851 }
1852
1853 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
1854 break;
1855 }
1856 }
1857
1858 inline_incrementally_one(igvn);
1859
1860 if (failing()) return;
1861
1862 igvn.optimize();
1863
1864 if (failing()) return;
1865 }
1866
1867 assert( igvn._worklist.size() == 0, "should be done with igvn" );
1868
1869 if (_string_late_inlines.length() > 0) {
1870 assert(has_stringbuilder(), "inconsistent");
1871 for_igvn()->clear();
1872 initial_gvn()->replace_with(&igvn);
1873
1874 inline_string_calls(false);
1875
1876 if (failing()) return;
1877
1878 {
1879 ResourceMark rm;
1880 PhaseRemoveUseless pru(initial_gvn(), for_igvn());
1881 }
1882
1883 igvn = PhaseIterGVN(gvn);
1884
1885 igvn.optimize();
1886 }
1887
1888 set_inlining_incrementally(false);
1889 }
1890
1891
1763 //------------------------------Optimize--------------------------------------- 1892 //------------------------------Optimize---------------------------------------
1764 // Given a graph, optimize it. 1893 // Given a graph, optimize it.
1765 void Compile::Optimize() { 1894 void Compile::Optimize() {
1766 TracePhase t1("optimizer", &_t_optimizer, true); 1895 TracePhase t1("optimizer", &_t_optimizer, true);
1767 1896
1787 NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); ) 1916 NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); )
1788 igvn.optimize(); 1917 igvn.optimize();
1789 } 1918 }
1790 1919
1791 print_method("Iter GVN 1", 2); 1920 print_method("Iter GVN 1", 2);
1921
1922 if (failing()) return;
1923
1924 inline_incrementally(igvn);
1925
1926 print_method("Incremental Inline", 2);
1792 1927
1793 if (failing()) return; 1928 if (failing()) return;
1794 1929
1795 // Perform escape analysis 1930 // Perform escape analysis
1796 if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { 1931 if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
1912 } 2047 }
1913 } 2048 }
1914 2049
1915 } // (End scope of igvn; run destructor if necessary for asserts.) 2050 } // (End scope of igvn; run destructor if necessary for asserts.)
1916 2051
2052 dump_inlining();
1917 // A method with only infinite loops has no edges entering loops from root 2053 // A method with only infinite loops has no edges entering loops from root
1918 { 2054 {
1919 NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) 2055 NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); )
1920 if (final_graph_reshaping()) { 2056 if (final_graph_reshaping()) {
1921 assert(failing(), "must bail out w/ explicit message"); 2057 assert(failing(), "must bail out w/ explicit message");
3360 } 3496 }
3361 } 3497 }
3362 3498
3363 void Compile::dump_inlining() { 3499 void Compile::dump_inlining() {
3364 if (PrintInlining) { 3500 if (PrintInlining) {
3501 // Print inlining message for candidates that we couldn't inline
3502 // for lack of space or non constant receiver
3503 for (int i = 0; i < _late_inlines.length(); i++) {
3504 CallGenerator* cg = _late_inlines.at(i);
3505 cg->print_inlining_late("live nodes > LiveNodeCountInliningCutoff");
3506 }
3507 Unique_Node_List useful;
3508 useful.push(root());
3509 for (uint next = 0; next < useful.size(); ++next) {
3510 Node* n = useful.at(next);
3511 if (n->is_Call() && n->as_Call()->generator() != NULL && n->as_Call()->generator()->call_node() == n) {
3512 CallNode* call = n->as_Call();
3513 CallGenerator* cg = call->generator();
3514 cg->print_inlining_late("receiver not constant");
3515 }
3516 uint max = n->len();
3517 for ( uint i = 0; i < max; ++i ) {
3518 Node *m = n->in(i);
3519 if ( m == NULL ) continue;
3520 useful.push(m);
3521 }
3522 }
3365 for (int i = 0; i < _print_inlining_list->length(); i++) { 3523 for (int i = 0; i < _print_inlining_list->length(); i++) {
3366 tty->print(_print_inlining_list->at(i).ss()->as_string()); 3524 tty->print(_print_inlining_list->at(i).ss()->as_string());
3367 } 3525 }
3368 } 3526 }
3369 } 3527 }