646 _max_node_limit(MaxNodeLimit), |
646 _max_node_limit(MaxNodeLimit), |
647 _orig_pc_slot(0), |
647 _orig_pc_slot(0), |
648 _orig_pc_slot_offset_in_bytes(0), |
648 _orig_pc_slot_offset_in_bytes(0), |
649 _inlining_progress(false), |
649 _inlining_progress(false), |
650 _inlining_incrementally(false), |
650 _inlining_incrementally(false), |
|
651 _do_cleanup(false), |
651 _has_reserved_stack_access(target->has_reserved_stack_access()), |
652 _has_reserved_stack_access(target->has_reserved_stack_access()), |
652 #ifndef PRODUCT |
653 #ifndef PRODUCT |
653 _trace_opto_output(directive->TraceOptoOutputOption), |
654 _trace_opto_output(directive->TraceOptoOutputOption), |
654 #endif |
655 #endif |
655 _has_method_handle_invokes(false), |
656 _has_method_handle_invokes(false), |
2049 cg->do_late_inline(); |
2050 cg->do_late_inline(); |
2050 if (failing()) return; |
2051 if (failing()) return; |
2051 } |
2052 } |
2052 _boxing_late_inlines.trunc_to(0); |
2053 _boxing_late_inlines.trunc_to(0); |
2053 |
2054 |
2054 { |
2055 inline_incrementally_cleanup(igvn); |
2055 ResourceMark rm; |
2056 |
2056 PhaseRemoveUseless pru(gvn, for_igvn()); |
|
2057 } |
|
2058 |
|
2059 igvn = PhaseIterGVN(gvn); |
|
2060 igvn.optimize(); |
|
2061 |
|
2062 set_inlining_progress(false); |
|
2063 set_inlining_incrementally(false); |
2057 set_inlining_incrementally(false); |
2064 } |
2058 } |
2065 } |
2059 } |
2066 |
2060 |
2067 void Compile::inline_incrementally_one(PhaseIterGVN& igvn) { |
2061 bool Compile::inline_incrementally_one() { |
2068 assert(IncrementalInline, "incremental inlining should be on"); |
2062 assert(IncrementalInline, "incremental inlining should be on"); |
2069 PhaseGVN* gvn = initial_gvn(); |
2063 |
2070 |
2064 TracePhase tp("incrementalInline_inline", &timers[_t_incrInline_inline]); |
2071 set_inlining_progress(false); |
2065 set_inlining_progress(false); |
2072 for_igvn()->clear(); |
2066 set_do_cleanup(false); |
2073 gvn->replace_with(&igvn); |
2067 int i = 0; |
2074 |
2068 for (; i <_late_inlines.length() && !inlining_progress(); i++) { |
2075 { |
2069 CallGenerator* cg = _late_inlines.at(i); |
2076 TracePhase tp("incrementalInline_inline", &timers[_t_incrInline_inline]); |
2070 _late_inlines_pos = i+1; |
2077 int i = 0; |
2071 cg->do_late_inline(); |
2078 for (; i <_late_inlines.length() && !inlining_progress(); i++) { |
2072 if (failing()) return false; |
2079 CallGenerator* cg = _late_inlines.at(i); |
2073 } |
2080 _late_inlines_pos = i+1; |
2074 int j = 0; |
2081 cg->do_late_inline(); |
2075 for (; i < _late_inlines.length(); i++, j++) { |
2082 if (failing()) return; |
2076 _late_inlines.at_put(j, _late_inlines.at(i)); |
2083 } |
2077 } |
2084 int j = 0; |
2078 _late_inlines.trunc_to(j); |
2085 for (; i < _late_inlines.length(); i++, j++) { |
2079 assert(inlining_progress() || _late_inlines.length() == 0, ""); |
2086 _late_inlines.at_put(j, _late_inlines.at(i)); |
2080 |
2087 } |
2081 bool needs_cleanup = do_cleanup() || over_inlining_cutoff(); |
2088 _late_inlines.trunc_to(j); |
2082 |
2089 } |
2083 set_inlining_progress(false); |
2090 |
2084 set_do_cleanup(false); |
|
2085 return (_late_inlines.length() > 0) && !needs_cleanup; |
|
2086 } |
|
2087 |
|
2088 void Compile::inline_incrementally_cleanup(PhaseIterGVN& igvn) { |
2091 { |
2089 { |
2092 TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]); |
2090 TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]); |
2093 ResourceMark rm; |
2091 ResourceMark rm; |
2094 PhaseRemoveUseless pru(gvn, for_igvn()); |
2092 PhaseRemoveUseless pru(initial_gvn(), for_igvn()); |
2095 } |
2093 } |
2096 |
|
2097 { |
2094 { |
2098 TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]); |
2095 TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]); |
2099 igvn = PhaseIterGVN(gvn); |
2096 igvn = PhaseIterGVN(initial_gvn()); |
|
2097 igvn.optimize(); |
2100 } |
2098 } |
2101 } |
2099 } |
2102 |
2100 |
2103 // Perform incremental inlining until bound on number of live nodes is reached |
2101 // Perform incremental inlining until bound on number of live nodes is reached |
2104 void Compile::inline_incrementally(PhaseIterGVN& igvn) { |
2102 void Compile::inline_incrementally(PhaseIterGVN& igvn) { |
2105 TracePhase tp("incrementalInline", &timers[_t_incrInline]); |
2103 TracePhase tp("incrementalInline", &timers[_t_incrInline]); |
2106 |
2104 |
2107 PhaseGVN* gvn = initial_gvn(); |
|
2108 |
|
2109 set_inlining_incrementally(true); |
2105 set_inlining_incrementally(true); |
2110 set_inlining_progress(true); |
|
2111 uint low_live_nodes = 0; |
2106 uint low_live_nodes = 0; |
2112 |
2107 |
2113 while(inlining_progress() && _late_inlines.length() > 0) { |
2108 while (_late_inlines.length() > 0) { |
2114 |
|
2115 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { |
2109 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { |
2116 if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) { |
2110 if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) { |
2117 TracePhase tp("incrementalInline_ideal", &timers[_t_incrInline_ideal]); |
2111 TracePhase tp("incrementalInline_ideal", &timers[_t_incrInline_ideal]); |
2118 // PhaseIdealLoop is expensive so we only try it once we are |
2112 // PhaseIdealLoop is expensive so we only try it once we are |
2119 // out of live nodes and we only try it again if the previous |
2113 // out of live nodes and we only try it again if the previous |
2123 low_live_nodes = live_nodes(); |
2117 low_live_nodes = live_nodes(); |
2124 _major_progress = true; |
2118 _major_progress = true; |
2125 } |
2119 } |
2126 |
2120 |
2127 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { |
2121 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { |
2128 break; |
2122 break; // finish |
2129 } |
2123 } |
2130 } |
2124 } |
2131 |
2125 |
2132 inline_incrementally_one(igvn); |
2126 for_igvn()->clear(); |
|
2127 initial_gvn()->replace_with(&igvn); |
|
2128 |
|
2129 while (inline_incrementally_one()) { |
|
2130 assert(!failing(), "inconsistent"); |
|
2131 } |
2133 |
2132 |
2134 if (failing()) return; |
2133 if (failing()) return; |
2135 |
2134 |
2136 { |
2135 inline_incrementally_cleanup(igvn); |
2137 TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]); |
|
2138 igvn.optimize(); |
|
2139 } |
|
2140 |
2136 |
2141 if (failing()) return; |
2137 if (failing()) return; |
2142 } |
2138 } |
2143 |
|
2144 assert( igvn._worklist.size() == 0, "should be done with igvn" ); |
2139 assert( igvn._worklist.size() == 0, "should be done with igvn" ); |
2145 |
2140 |
2146 if (_string_late_inlines.length() > 0) { |
2141 if (_string_late_inlines.length() > 0) { |
2147 assert(has_stringbuilder(), "inconsistent"); |
2142 assert(has_stringbuilder(), "inconsistent"); |
2148 for_igvn()->clear(); |
2143 for_igvn()->clear(); |