mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-30 20:55:34 +00:00
8214172: GC interface entry points for loop opts
Reviewed-by: kvn, rkennke
This commit is contained in:
parent
bb50695ff9
commit
8849b1c7b7
@ -60,6 +60,7 @@ class ConnectionGraph;
|
||||
class GraphKit;
|
||||
class IdealKit;
|
||||
class Node;
|
||||
class PhaseIdealLoop;
|
||||
class PhaseGVN;
|
||||
class PhaseMacroExpand;
|
||||
class Type;
|
||||
@ -277,9 +278,12 @@ public:
|
||||
// Allow barrier sets to have shared state that is preserved across a compilation unit.
|
||||
// This could for example comprise macro nodes to be expanded during macro expansion.
|
||||
virtual void* create_barrier_state(Arena* comp_arena) const { return NULL; }
|
||||
// If the BarrierSetC2 state has kept macro nodes in its compilation unit state to be
|
||||
// expanded later, then now is the time to do so.
|
||||
virtual bool expand_macro_nodes(PhaseMacroExpand* macro) const { return false; }
|
||||
// If the BarrierSetC2 state has barrier nodes in its compilation
|
||||
// unit state to be expanded later, then now is the time to do so.
|
||||
virtual bool expand_barriers(Compile* C, PhaseIterGVN& igvn) const { return false; }
|
||||
virtual bool optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const { return false; }
|
||||
virtual bool strip_mined_loops_expanded(LoopOptsMode mode) const { return false; }
|
||||
virtual bool is_gc_specific_loop_opts_pass(LoopOptsMode mode) const { return false; }
|
||||
|
||||
virtual bool has_special_unique_user(const Node* node) const { return false; }
|
||||
|
||||
|
||||
@ -996,9 +996,8 @@ void ZBarrierSetC2::expand_loadbarrier_optimized(PhaseMacroExpand* phase, LoadBa
|
||||
return;
|
||||
}
|
||||
|
||||
bool ZBarrierSetC2::expand_macro_nodes(PhaseMacroExpand* macro) const {
|
||||
Compile* C = Compile::current();
|
||||
PhaseIterGVN &igvn = macro->igvn();
|
||||
bool ZBarrierSetC2::expand_barriers(Compile* C, PhaseIterGVN& igvn) const {
|
||||
PhaseMacroExpand macro(igvn);
|
||||
ZBarrierSetC2State* s = state();
|
||||
if (s->load_barrier_count() > 0) {
|
||||
#ifdef ASSERT
|
||||
@ -1018,7 +1017,7 @@ bool ZBarrierSetC2::expand_macro_nodes(PhaseMacroExpand* macro) const {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
expand_loadbarrier_node(macro, n);
|
||||
expand_loadbarrier_node(¯o, n);
|
||||
assert(s->load_barrier_count() < load_barrier_count, "must have deleted a node from load barrier list");
|
||||
if (C->failing()) return true;
|
||||
}
|
||||
@ -1027,7 +1026,7 @@ bool ZBarrierSetC2::expand_macro_nodes(PhaseMacroExpand* macro) const {
|
||||
LoadBarrierNode* n = s->load_barrier_node(load_barrier_count - 1);
|
||||
assert(!(igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())), "should have been processed already");
|
||||
assert(!n->can_be_eliminated(), "should have been processed already");
|
||||
expand_loadbarrier_node(macro, n);
|
||||
expand_loadbarrier_node(¯o, n);
|
||||
assert(s->load_barrier_count() < load_barrier_count, "must have deleted a node from load barrier list");
|
||||
if (C->failing()) return true;
|
||||
}
|
||||
@ -1623,4 +1622,4 @@ bool ZBarrierSetC2::escape_add_final_edges(ConnectionGraph* conn_graph, PhaseGVN
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,9 +200,9 @@ public:
|
||||
virtual void unregister_potential_barrier_node(Node* node) const;
|
||||
virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const;
|
||||
virtual Node* step_over_gc_barrier(Node* c) const;
|
||||
// If the BarrierSetC2 state has kept macro nodes in its compilation unit state to be
|
||||
// If the BarrierSetC2 state has kept barrier nodes in its compilation unit state to be
|
||||
// expanded later, then now is the time to do so.
|
||||
virtual bool expand_macro_nodes(PhaseMacroExpand* macro) const;
|
||||
virtual bool expand_barriers(Compile* C, PhaseIterGVN& igvn) const;
|
||||
|
||||
static void find_dominating_barriers(PhaseIterGVN& igvn);
|
||||
static void loop_optimize_gc_barrier(PhaseIdealLoop* phase, Node* node, bool last_round);
|
||||
|
||||
@ -1122,7 +1122,7 @@ void Compile::Init(int aliaslevel) {
|
||||
set_decompile_count(0);
|
||||
|
||||
set_do_freq_based_layout(_directive->BlockLayoutByFrequencyOption);
|
||||
set_num_loop_opts(LoopOptsCount);
|
||||
_loop_opts_cnt = LoopOptsCount;
|
||||
set_do_inlining(Inline);
|
||||
set_max_inline_size(MaxInlineSize);
|
||||
set_freq_inline_size(FreqInlineSize);
|
||||
@ -2169,14 +2169,14 @@ void Compile::inline_incrementally(PhaseIterGVN& igvn) {
|
||||
}
|
||||
|
||||
|
||||
bool Compile::optimize_loops(int& loop_opts_cnt, PhaseIterGVN& igvn, LoopOptsMode mode) {
|
||||
if(loop_opts_cnt > 0) {
|
||||
bool Compile::optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode) {
|
||||
if(_loop_opts_cnt > 0) {
|
||||
debug_only( int cnt = 0; );
|
||||
while(major_progress() && (loop_opts_cnt > 0)) {
|
||||
while(major_progress() && (_loop_opts_cnt > 0)) {
|
||||
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
|
||||
assert( cnt++ < 40, "infinite cycle in loop optimization" );
|
||||
PhaseIdealLoop ideal_loop(igvn, mode);
|
||||
loop_opts_cnt--;
|
||||
_loop_opts_cnt--;
|
||||
if (failing()) return false;
|
||||
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
|
||||
}
|
||||
@ -2202,7 +2202,6 @@ void Compile::Optimize() {
|
||||
#endif
|
||||
|
||||
ResourceMark rm;
|
||||
int loop_opts_cnt;
|
||||
|
||||
print_inlining_reinit();
|
||||
|
||||
@ -2305,28 +2304,27 @@ void Compile::Optimize() {
|
||||
// peeling, unrolling, etc.
|
||||
|
||||
// Set loop opts counter
|
||||
loop_opts_cnt = num_loop_opts();
|
||||
if((loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) {
|
||||
if((_loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) {
|
||||
{
|
||||
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
|
||||
PhaseIdealLoop ideal_loop(igvn, LoopOptsDefault);
|
||||
loop_opts_cnt--;
|
||||
_loop_opts_cnt--;
|
||||
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP1, 2);
|
||||
if (failing()) return;
|
||||
}
|
||||
// Loop opts pass if partial peeling occurred in previous pass
|
||||
if(PartialPeelLoop && major_progress() && (loop_opts_cnt > 0)) {
|
||||
if(PartialPeelLoop && major_progress() && (_loop_opts_cnt > 0)) {
|
||||
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
|
||||
PhaseIdealLoop ideal_loop(igvn, LoopOptsSkipSplitIf);
|
||||
loop_opts_cnt--;
|
||||
_loop_opts_cnt--;
|
||||
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP2, 2);
|
||||
if (failing()) return;
|
||||
}
|
||||
// Loop opts pass for loop-unrolling before CCP
|
||||
if(major_progress() && (loop_opts_cnt > 0)) {
|
||||
if(major_progress() && (_loop_opts_cnt > 0)) {
|
||||
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
|
||||
PhaseIdealLoop ideal_loop(igvn, LoopOptsSkipSplitIf);
|
||||
loop_opts_cnt--;
|
||||
_loop_opts_cnt--;
|
||||
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP3, 2);
|
||||
}
|
||||
if (!failing()) {
|
||||
@ -2361,7 +2359,7 @@ void Compile::Optimize() {
|
||||
|
||||
// Loop transforms on the ideal graph. Range Check Elimination,
|
||||
// peeling, unrolling, etc.
|
||||
if (!optimize_loops(loop_opts_cnt, igvn, LoopOptsDefault)) {
|
||||
if (!optimize_loops(igvn, LoopOptsDefault)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2404,6 +2402,16 @@ void Compile::Optimize() {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
TracePhase tp("barrierExpand", &timers[_t_barrierExpand]);
|
||||
print_method(PHASE_BEFORE_BARRIER_EXPAND, 2);
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
if (bs->expand_barriers(this, igvn)) {
|
||||
assert(failing(), "must bail out w/ explicit message");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (opaque4_count() > 0) {
|
||||
C->remove_opaque4_nodes(igvn);
|
||||
igvn.optimize();
|
||||
|
||||
@ -369,7 +369,6 @@ class Compile : public Phase {
|
||||
address _stub_entry_point; // Compile code entry for generated stub, or NULL
|
||||
|
||||
// Control of this compilation.
|
||||
int _num_loop_opts; // Number of iterations for doing loop optimiztions
|
||||
int _max_inline_size; // Max inline size for this compilation
|
||||
int _freq_inline_size; // Max hot method inline size for this compilation
|
||||
int _fixed_slots; // count of frame slots not allocated by the register
|
||||
@ -413,6 +412,7 @@ class Compile : public Phase {
|
||||
// JSR 292
|
||||
bool _has_method_handle_invokes; // True if this method has MethodHandle invokes.
|
||||
RTMState _rtm_state; // State of Restricted Transactional Memory usage
|
||||
int _loop_opts_cnt; // loop opts round
|
||||
|
||||
// Compilation environment.
|
||||
Arena _comp_arena; // Arena with lifetime equivalent to Compile
|
||||
@ -653,8 +653,6 @@ class Compile : public Phase {
|
||||
int inlining_incrementally() const { return _inlining_incrementally; }
|
||||
void set_major_progress() { _major_progress++; }
|
||||
void clear_major_progress() { _major_progress = 0; }
|
||||
int num_loop_opts() const { return _num_loop_opts; }
|
||||
void set_num_loop_opts(int n) { _num_loop_opts = n; }
|
||||
int max_inline_size() const { return _max_inline_size; }
|
||||
void set_freq_inline_size(int n) { _freq_inline_size = n; }
|
||||
int freq_inline_size() const { return _freq_inline_size; }
|
||||
@ -1087,7 +1085,7 @@ class Compile : public Phase {
|
||||
void inline_incrementally(PhaseIterGVN& igvn);
|
||||
void inline_string_calls(bool parse_time);
|
||||
void inline_boxing_calls(PhaseIterGVN& igvn);
|
||||
bool optimize_loops(int& loop_opts_cnt, PhaseIterGVN& igvn, LoopOptsMode mode);
|
||||
bool optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode);
|
||||
|
||||
// Matching, CFG layout, allocation, code generation
|
||||
PhaseCFG* cfg() { return _cfg; }
|
||||
|
||||
@ -2774,9 +2774,12 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
// Nothing to do, so get out
|
||||
bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only;
|
||||
bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only &&
|
||||
!bs->is_gc_specific_loop_opts_pass(mode);
|
||||
bool do_expensive_nodes = C->should_optimize_expensive_nodes(_igvn);
|
||||
bool strip_mined_loops_expanded = bs->strip_mined_loops_expanded(mode);
|
||||
if (stop_early && !do_expensive_nodes) {
|
||||
_igvn.optimize(); // Cleanup NeverBranches
|
||||
return;
|
||||
@ -2854,8 +2857,9 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
|
||||
|
||||
// Given early legal placement, try finding counted loops. This placement
|
||||
// is good enough to discover most loop invariants.
|
||||
if( !_verify_me && !_verify_only )
|
||||
if (!_verify_me && !_verify_only && !strip_mined_loops_expanded) {
|
||||
_ltree_root->counted_loop( this );
|
||||
}
|
||||
|
||||
// Find latest loop placement. Find ideal loop placement.
|
||||
visited.Clear();
|
||||
@ -2926,6 +2930,14 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bs->optimize_loops(this, mode, visited, nstack, worklist)) {
|
||||
_igvn.optimize();
|
||||
if (C->log() != NULL) {
|
||||
log_loop_tree(_ltree_root, _ltree_root, C->log());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReassociateInvariants) {
|
||||
// Reassociate invariants and prep for split_thru_phi
|
||||
for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
|
||||
@ -4136,7 +4148,7 @@ void PhaseIdealLoop::build_loop_late( VectorSet &visited, Node_List &worklist, N
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that no data node is schedules in the outer loop of a strip
|
||||
// Verify that no data node is scheduled in the outer loop of a strip
|
||||
// mined loop.
|
||||
void PhaseIdealLoop::verify_strip_mined_scheduling(Node *n, Node* least) {
|
||||
#ifdef ASSERT
|
||||
@ -4145,7 +4157,9 @@ void PhaseIdealLoop::verify_strip_mined_scheduling(Node *n, Node* least) {
|
||||
}
|
||||
IdealLoopTree* loop = get_loop(least);
|
||||
Node* head = loop->_head;
|
||||
if (head->is_OuterStripMinedLoop()) {
|
||||
if (head->is_OuterStripMinedLoop() &&
|
||||
// Verification can't be applied to fully built strip mined loops
|
||||
head->as_Loop()->outer_loop_end()->in(1)->find_int_con(-1) == 0) {
|
||||
Node* sfpt = head->as_Loop()->outer_safepoint();
|
||||
ResourceMark rm;
|
||||
Unique_Node_List wq;
|
||||
|
||||
@ -2600,6 +2600,5 @@ bool PhaseMacroExpand::expand_macro_nodes() {
|
||||
_igvn.set_delay_transform(false);
|
||||
_igvn.optimize();
|
||||
if (C->failing()) return true;
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
return bs->expand_macro_nodes(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -83,6 +83,7 @@ void Phase::print_timers() {
|
||||
tty->print_cr (" Cond Const Prop: %7.3f s", timers[_t_ccp].seconds());
|
||||
tty->print_cr (" GVN 2: %7.3f s", timers[_t_iterGVN2].seconds());
|
||||
tty->print_cr (" Macro Expand: %7.3f s", timers[_t_macroExpand].seconds());
|
||||
tty->print_cr (" Barrier Expand: %7.3f s", timers[_t_barrierExpand].seconds());
|
||||
tty->print_cr (" Graph Reshape: %7.3f s", timers[_t_graphReshaping].seconds());
|
||||
|
||||
double other = timers[_t_optimizer].seconds() -
|
||||
@ -95,6 +96,7 @@ void Phase::print_timers() {
|
||||
timers[_t_ccp].seconds() +
|
||||
timers[_t_iterGVN2].seconds() +
|
||||
timers[_t_macroExpand].seconds() +
|
||||
timers[_t_barrierExpand].seconds() +
|
||||
timers[_t_graphReshaping].seconds());
|
||||
if (other > 0) {
|
||||
tty->print_cr(" Other: %7.3f s", other);
|
||||
|
||||
@ -80,6 +80,7 @@ public:
|
||||
_t_ccp,
|
||||
_t_iterGVN2,
|
||||
_t_macroExpand,
|
||||
_t_barrierExpand,
|
||||
_t_graphReshaping,
|
||||
_t_matcher,
|
||||
_t_scheduler,
|
||||
|
||||
@ -52,6 +52,7 @@ enum CompilerPhaseType {
|
||||
PHASE_MATCHING,
|
||||
PHASE_INCREMENTAL_INLINE,
|
||||
PHASE_INCREMENTAL_BOXING_INLINE,
|
||||
PHASE_BEFORE_BARRIER_EXPAND,
|
||||
PHASE_BEFORE_MACRO_EXPANSION,
|
||||
PHASE_END,
|
||||
PHASE_FAILURE,
|
||||
@ -89,6 +90,7 @@ class CompilerPhaseTypeHelper {
|
||||
case PHASE_MATCHING: return "After matching";
|
||||
case PHASE_INCREMENTAL_INLINE: return "Incremental Inline";
|
||||
case PHASE_INCREMENTAL_BOXING_INLINE: return "Incremental Boxing Inline";
|
||||
case PHASE_BEFORE_BARRIER_EXPAND: return "Before Barrier Expand";
|
||||
case PHASE_BEFORE_MACRO_EXPANSION: return "Before macro expansion";
|
||||
case PHASE_END: return "End";
|
||||
case PHASE_FAILURE: return "Failure";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user