# HG changeset patch # User rkennke # Date 1541541785 -3600 # Node ID b64514ff68fd794e4464c764407a0dd206561855 # Parent 0e8084c8cbb75deff837ebf5fa6e397700707885 8213381: Hook to allow GC to inject Node::Ideal() calls Reviewed-by: kvn, eosterlund, roland diff -r 0e8084c8cbb7 -r b64514ff68fd src/hotspot/share/gc/shared/c2/barrierSetC2.hpp --- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp Tue Nov 06 10:10:18 2018 -0800 +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp Tue Nov 06 23:03:05 2018 +0100 @@ -245,6 +245,9 @@ Node*& fast_oop_ctrl, Node*& fast_oop_rawmem, intx prefetch_lines) const; + virtual Node* ideal_node(PhaseGVN* phase, Node* n, bool can_reshape) const { return NULL; } + virtual Node* identity_node(PhaseGVN* phase, Node* n) const { return n; } + // These are general helper methods used by C2 enum ArrayCopyPhase { Parsing, diff -r 0e8084c8cbb7 -r b64514ff68fd src/hotspot/share/opto/loopnode.cpp --- a/src/hotspot/share/opto/loopnode.cpp Tue Nov 06 10:10:18 2018 -0800 +++ b/src/hotspot/share/opto/loopnode.cpp Tue Nov 06 23:03:05 2018 +0100 @@ -1750,7 +1750,7 @@ // disappear it. In JavaGrande I have a case where this useless // Phi is the loop limit and prevents recognizing a CountedLoop // which in turn prevents removing an empty loop. - Node *id_old_phi = old_phi->Identity( &igvn ); + Node *id_old_phi = igvn.apply_identity(old_phi); if( id_old_phi != old_phi ) { // Found a simple identity? // Note that I cannot call 'replace_node' here, because // that will yank the edge from old_phi to the Region and diff -r 0e8084c8cbb7 -r b64514ff68fd src/hotspot/share/opto/loopopts.cpp --- a/src/hotspot/share/opto/loopopts.cpp Tue Nov 06 10:10:18 2018 -0800 +++ b/src/hotspot/share/opto/loopopts.cpp Tue Nov 06 23:03:05 2018 +0100 @@ -129,7 +129,7 @@ // otherwise it will be not updated during igvn->transform since // igvn->type(x) is set to x->Value() already. x->raise_bottom_type(t); - Node *y = x->Identity(&_igvn); + Node *y = _igvn.apply_identity(x); if (y != x) { wins++; x = y; diff -r 0e8084c8cbb7 -r b64514ff68fd src/hotspot/share/opto/memnode.cpp --- a/src/hotspot/share/opto/memnode.cpp Tue Nov 06 10:10:18 2018 -0800 +++ b/src/hotspot/share/opto/memnode.cpp Tue Nov 06 23:03:05 2018 +0100 @@ -1404,7 +1404,7 @@ // Do nothing here if Identity will find a value // (to avoid infinite chain of value phis generation). - if (!phase->eqv(this, this->Identity(phase))) + if (!phase->eqv(this, phase->apply_identity(this))) return NULL; // Select Region to split through. @@ -1494,7 +1494,7 @@ // otherwise it will be not updated during igvn->transform since // igvn->type(x) is set to x->Value() already. x->raise_bottom_type(t); - Node *y = x->Identity(igvn); + Node *y = igvn->apply_identity(x); if (y != x) { x = y; } else { diff -r 0e8084c8cbb7 -r b64514ff68fd src/hotspot/share/opto/phaseX.cpp --- a/src/hotspot/share/opto/phaseX.cpp Tue Nov 06 10:10:18 2018 -0800 +++ b/src/hotspot/share/opto/phaseX.cpp Tue Nov 06 23:03:05 2018 +0100 @@ -769,6 +769,22 @@ //============================================================================= +Node* PhaseGVN::apply_ideal(Node* k, bool can_reshape) { + Node* i = BarrierSet::barrier_set()->barrier_set_c2()->ideal_node(this, k, can_reshape); + if (i == NULL) { + i = k->Ideal(this, can_reshape); + } + return i; +} + +Node* PhaseGVN::apply_identity(Node* k) { + Node* i = BarrierSet::barrier_set()->barrier_set_c2()->identity_node(this, k); + if (i == k) { + i = k->Identity(this); + } + return i; +} + //------------------------------transform-------------------------------------- // Return a node which computes the same function as this node, but in a // faster or cheaper fashion. @@ -786,7 +802,7 @@ Node *k = n; NOT_PRODUCT( uint loop_count = 0; ) while( 1 ) { - Node *i = k->Ideal(this, /*can_reshape=*/false); + Node *i = apply_ideal(k, /*can_reshape=*/false); if( !i ) break; assert( i->_idx >= k->_idx, "Idealize should return new nodes, use Identity to return old nodes" ); k = i; @@ -823,7 +839,7 @@ } // Now check for Identities - Node *i = k->Identity(this); // Look for a nearby replacement + Node *i = apply_identity(k); // Look for a nearby replacement if( i != k ) { // Found? Return replacement! NOT_PRODUCT( set_progress(); ) return i; @@ -1213,7 +1229,7 @@ DEBUG_ONLY(dead_loop_check(k);) DEBUG_ONLY(bool is_new = (k->outcnt() == 0);) C->remove_modified_node(k); - Node* i = k->Ideal(this, /*can_reshape=*/true); + Node* i = apply_ideal(k, /*can_reshape=*/true); assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); #ifndef PRODUCT verify_step(k); @@ -1255,7 +1271,7 @@ // Try idealizing again DEBUG_ONLY(is_new = (k->outcnt() == 0);) C->remove_modified_node(k); - i = k->Ideal(this, /*can_reshape=*/true); + i = apply_ideal(k, /*can_reshape=*/true); assert(i != k || is_new || (i->outcnt() > 0), "don't return dead nodes"); #ifndef PRODUCT verify_step(k); @@ -1297,7 +1313,7 @@ } // Now check for Identities - i = k->Identity(this); // Look for a nearby replacement + i = apply_identity(k); // Look for a nearby replacement if (i != k) { // Found? Return replacement! NOT_PRODUCT(set_progress();) add_users_to_worklist(k); diff -r 0e8084c8cbb7 -r b64514ff68fd src/hotspot/share/opto/phaseX.hpp --- a/src/hotspot/share/opto/phaseX.hpp Tue Nov 06 10:10:18 2018 -0800 +++ b/src/hotspot/share/opto/phaseX.hpp Tue Nov 06 23:03:05 2018 +0100 @@ -425,6 +425,12 @@ bool is_dominator(Node *d, Node *n) { return is_dominator_helper(d, n, true); } + // Helper to call Node::Ideal() and BarrierSetC2::ideal_node(). + Node* apply_ideal(Node* i, bool can_reshape); + + // Helper to call Node::Identity() and BarrierSetC2::identity_node(). + Node* apply_identity(Node* n); + // Check for a simple dead loop when a data node references itself. DEBUG_ONLY(void dead_loop_check(Node *n);) };