src/hotspot/share/opto/compile.cpp
changeset 53594 47a8fdf84424
parent 53429 1b292ae4eb50
child 53632 d620a4a1d5ed
equal deleted inserted replaced
53593:1ceebbe2c1da 53594:47a8fdf84424
   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();
  2150 
  2145 
  2151     inline_string_calls(false);
  2146     inline_string_calls(false);
  2152 
  2147 
  2153     if (failing())  return;
  2148     if (failing())  return;
  2154 
  2149 
  2155     {
  2150     inline_incrementally_cleanup(igvn);
  2156       TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]);
       
  2157       ResourceMark rm;
       
  2158       PhaseRemoveUseless pru(initial_gvn(), for_igvn());
       
  2159     }
       
  2160 
       
  2161     {
       
  2162       TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
       
  2163       igvn = PhaseIterGVN(gvn);
       
  2164       igvn.optimize();
       
  2165     }
       
  2166   }
  2151   }
  2167 
  2152 
  2168   set_inlining_incrementally(false);
  2153   set_inlining_incrementally(false);
  2169 }
  2154 }
  2170 
  2155