631
632
633 Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci,
634 bool subsume_loads, bool do_escape_analysis, bool eliminate_boxing, DirectiveSet* directive)
635 : Phase(Compiler),
636 _compile_id(ci_env->compile_id()),
637 _save_argument_registers(false),
638 _subsume_loads(subsume_loads),
639 _do_escape_analysis(do_escape_analysis),
640 _eliminate_boxing(eliminate_boxing),
641 _method(target),
642 _entry_bci(osr_bci),
643 _stub_function(NULL),
644 _stub_name(NULL),
645 _stub_entry_point(NULL),
646 _max_node_limit(MaxNodeLimit),
647 _orig_pc_slot(0),
648 _orig_pc_slot_offset_in_bytes(0),
649 _inlining_progress(false),
650 _inlining_incrementally(false),
651 _has_reserved_stack_access(target->has_reserved_stack_access()),
652 #ifndef PRODUCT
653 _trace_opto_output(directive->TraceOptoOutputOption),
654 #endif
655 _has_method_handle_invokes(false),
656 _comp_arena(mtCompiler),
657 _barrier_set_state(BarrierSet::barrier_set()->barrier_set_c2()->create_barrier_state(comp_arena())),
658 _env(ci_env),
659 _directive(directive),
660 _log(ci_env->log()),
661 _failure_reason(NULL),
662 _congraph(NULL),
663 #ifndef PRODUCT
664 _printer(IdealGraphPrinter::printer()),
665 #endif
666 _dead_node_list(comp_arena()),
667 _dead_node_count(0),
668 _node_arena(mtCompiler),
669 _old_arena(mtCompiler),
670 _mach_constant_base_node(NULL),
2047 while (_boxing_late_inlines.length() > 0) {
2048 CallGenerator* cg = _boxing_late_inlines.pop();
2049 cg->do_late_inline();
2050 if (failing()) return;
2051 }
2052 _boxing_late_inlines.trunc_to(0);
2053
2054 {
2055 ResourceMark rm;
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);
2064 }
2065 }
2066
2067 void Compile::inline_incrementally_one(PhaseIterGVN& igvn) {
2068 assert(IncrementalInline, "incremental inlining should be on");
2069 PhaseGVN* gvn = initial_gvn();
2070
2071 set_inlining_progress(false);
2072 for_igvn()->clear();
2073 gvn->replace_with(&igvn);
2074
2075 {
2076 TracePhase tp("incrementalInline_inline", &timers[_t_incrInline_inline]);
2077 int i = 0;
2078 for (; i <_late_inlines.length() && !inlining_progress(); i++) {
2079 CallGenerator* cg = _late_inlines.at(i);
2080 _late_inlines_pos = i+1;
2081 cg->do_late_inline();
2082 if (failing()) return;
2083 }
2084 int j = 0;
2085 for (; i < _late_inlines.length(); i++, j++) {
2086 _late_inlines.at_put(j, _late_inlines.at(i));
2087 }
2088 _late_inlines.trunc_to(j);
2089 }
2090
2091 {
2092 TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]);
2093 ResourceMark rm;
2094 PhaseRemoveUseless pru(gvn, for_igvn());
2095 }
2096
2097 {
2098 TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
2099 igvn = PhaseIterGVN(gvn);
2100 }
2101 }
2102
2103 // Perform incremental inlining until bound on number of live nodes is reached
2104 void Compile::inline_incrementally(PhaseIterGVN& igvn) {
2105 TracePhase tp("incrementalInline", &timers[_t_incrInline]);
2106
2107 PhaseGVN* gvn = initial_gvn();
2108
2109 set_inlining_incrementally(true);
2110 set_inlining_progress(true);
2111 uint low_live_nodes = 0;
2112
2113 while(inlining_progress() && _late_inlines.length() > 0) {
2114
2115 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
2116 if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) {
2117 TracePhase tp("incrementalInline_ideal", &timers[_t_incrInline_ideal]);
2118 // 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
2120 // helped got the number of nodes down significantly
2121 PhaseIdealLoop ideal_loop(igvn, LoopOptsNone);
2122 if (failing()) return;
2123 low_live_nodes = live_nodes();
2124 _major_progress = true;
2125 }
2126
2127 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
2128 break;
2129 }
2130 }
2131
2132 inline_incrementally_one(igvn);
2133
2134 if (failing()) return;
2135
2136 {
2137 TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
2138 igvn.optimize();
2139 }
2140
2141 if (failing()) return;
2142 }
2143
2144 assert( igvn._worklist.size() == 0, "should be done with igvn" );
2145
2146 if (_string_late_inlines.length() > 0) {
2147 assert(has_stringbuilder(), "inconsistent");
2148 for_igvn()->clear();
2149 initial_gvn()->replace_with(&igvn);
2150
2151 inline_string_calls(false);
2152
2153 if (failing()) return;
2154
2155 {
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 }
2167
2168 set_inlining_incrementally(false);
2169 }
2170
2171
2172 bool Compile::optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode) {
2173 if(_loop_opts_cnt > 0) {
2174 debug_only( int cnt = 0; );
2175 while(major_progress() && (_loop_opts_cnt > 0)) {
2176 TracePhase tp("idealLoop", &timers[_t_idealLoop]);
2177 assert( cnt++ < 40, "infinite cycle in loop optimization" );
2178 PhaseIdealLoop ideal_loop(igvn, mode);
2179 _loop_opts_cnt--;
2180 if (failing()) return false;
2181 if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
2182 }
2183 }
2184 return true;
2185 }
|
631
632
633 Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci,
634 bool subsume_loads, bool do_escape_analysis, bool eliminate_boxing, DirectiveSet* directive)
635 : Phase(Compiler),
636 _compile_id(ci_env->compile_id()),
637 _save_argument_registers(false),
638 _subsume_loads(subsume_loads),
639 _do_escape_analysis(do_escape_analysis),
640 _eliminate_boxing(eliminate_boxing),
641 _method(target),
642 _entry_bci(osr_bci),
643 _stub_function(NULL),
644 _stub_name(NULL),
645 _stub_entry_point(NULL),
646 _max_node_limit(MaxNodeLimit),
647 _orig_pc_slot(0),
648 _orig_pc_slot_offset_in_bytes(0),
649 _inlining_progress(false),
650 _inlining_incrementally(false),
651 _do_cleanup(false),
652 _has_reserved_stack_access(target->has_reserved_stack_access()),
653 #ifndef PRODUCT
654 _trace_opto_output(directive->TraceOptoOutputOption),
655 #endif
656 _has_method_handle_invokes(false),
657 _comp_arena(mtCompiler),
658 _barrier_set_state(BarrierSet::barrier_set()->barrier_set_c2()->create_barrier_state(comp_arena())),
659 _env(ci_env),
660 _directive(directive),
661 _log(ci_env->log()),
662 _failure_reason(NULL),
663 _congraph(NULL),
664 #ifndef PRODUCT
665 _printer(IdealGraphPrinter::printer()),
666 #endif
667 _dead_node_list(comp_arena()),
668 _dead_node_count(0),
669 _node_arena(mtCompiler),
670 _old_arena(mtCompiler),
671 _mach_constant_base_node(NULL),
2048 while (_boxing_late_inlines.length() > 0) {
2049 CallGenerator* cg = _boxing_late_inlines.pop();
2050 cg->do_late_inline();
2051 if (failing()) return;
2052 }
2053 _boxing_late_inlines.trunc_to(0);
2054
2055 {
2056 ResourceMark rm;
2057 PhaseRemoveUseless pru(gvn, for_igvn());
2058 }
2059
2060 igvn = PhaseIterGVN(gvn);
2061 igvn.optimize();
2062
2063 set_inlining_progress(false);
2064 set_inlining_incrementally(false);
2065 }
2066 }
2067
2068 bool Compile::inline_incrementally_one() {
2069 assert(IncrementalInline, "incremental inlining should be on");
2070
2071 TracePhase tp("incrementalInline_inline", &timers[_t_incrInline_inline]);
2072 set_inlining_progress(false);
2073 set_do_cleanup(false);
2074 int i = 0;
2075 for (; i <_late_inlines.length() && !inlining_progress(); i++) {
2076 CallGenerator* cg = _late_inlines.at(i);
2077 _late_inlines_pos = i+1;
2078 cg->do_late_inline();
2079 if (failing()) return false;
2080 }
2081 int j = 0;
2082 for (; i < _late_inlines.length(); i++, j++) {
2083 _late_inlines.at_put(j, _late_inlines.at(i));
2084 }
2085 _late_inlines.trunc_to(j);
2086 assert(inlining_progress() || _late_inlines.length() == 0, "");
2087
2088 bool needs_cleanup = do_cleanup() || over_inlining_cutoff();
2089
2090 set_inlining_progress(false);
2091 set_do_cleanup(false);
2092 return (_late_inlines.length() > 0) && !needs_cleanup;
2093 }
2094
2095 PhaseIterGVN& Compile::inline_incrementally_cleanup(PhaseIterGVN& igvn) {
2096 {
2097 TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]);
2098 ResourceMark rm;
2099 PhaseRemoveUseless pru(initial_gvn(), for_igvn());
2100 }
2101 {
2102 TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
2103 igvn = PhaseIterGVN(initial_gvn());
2104 igvn.optimize();
2105 }
2106 return igvn;
2107 }
2108
2109 // Perform incremental inlining until bound on number of live nodes is reached
2110 void Compile::inline_incrementally(PhaseIterGVN& igvn) {
2111 TracePhase tp("incrementalInline", &timers[_t_incrInline]);
2112
2113 set_inlining_incrementally(true);
2114 uint low_live_nodes = 0;
2115
2116 while(_late_inlines.length() > 0) {
2117 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
2118 if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) {
2119 TracePhase tp("incrementalInline_ideal", &timers[_t_incrInline_ideal]);
2120 // PhaseIdealLoop is expensive so we only try it once we are
2121 // out of live nodes and we only try it again if the previous
2122 // helped got the number of nodes down significantly
2123 PhaseIdealLoop ideal_loop(igvn, LoopOptsNone);
2124 if (failing()) return;
2125 low_live_nodes = live_nodes();
2126 _major_progress = true;
2127 }
2128
2129 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
2130 break;
2131 }
2132 }
2133
2134 for_igvn()->clear();
2135 initial_gvn()->replace_with(&igvn);
2136
2137 while (inline_incrementally_one()) {
2138 assert(!failing(), "inconsistent");
2139 }
2140
2141 if (failing()) return;
2142
2143 igvn = inline_incrementally_cleanup(igvn);
2144
2145 if (failing()) return;
2146 }
2147 assert( igvn._worklist.size() == 0, "should be done with igvn" );
2148
2149 if (_string_late_inlines.length() > 0) {
2150 assert(has_stringbuilder(), "inconsistent");
2151 for_igvn()->clear();
2152 initial_gvn()->replace_with(&igvn);
2153
2154 inline_string_calls(false);
2155
2156 if (failing()) return;
2157
2158 igvn = inline_incrementally_cleanup(igvn);
2159 }
2160
2161 set_inlining_incrementally(false);
2162 }
2163
2164
2165 bool Compile::optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode) {
2166 if(_loop_opts_cnt > 0) {
2167 debug_only( int cnt = 0; );
2168 while(major_progress() && (_loop_opts_cnt > 0)) {
2169 TracePhase tp("idealLoop", &timers[_t_idealLoop]);
2170 assert( cnt++ < 40, "infinite cycle in loop optimization" );
2171 PhaseIdealLoop ideal_loop(igvn, mode);
2172 _loop_opts_cnt--;
2173 if (failing()) return false;
2174 if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
2175 }
2176 }
2177 return true;
2178 }
|