8213381: Hook to allow GC to inject Node::Ideal() calls
authorrkennke
Tue, 06 Nov 2018 23:03:05 +0100
changeset 52429 b64514ff68fd
parent 52428 0e8084c8cbb7
child 52430 4ee78b5583f9
8213381: Hook to allow GC to inject Node::Ideal() calls Reviewed-by: kvn, eosterlund, roland
src/hotspot/share/gc/shared/c2/barrierSetC2.hpp
src/hotspot/share/opto/loopnode.cpp
src/hotspot/share/opto/loopopts.cpp
src/hotspot/share/opto/memnode.cpp
src/hotspot/share/opto/phaseX.cpp
src/hotspot/share/opto/phaseX.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,
--- 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
--- 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;
--- 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 {
--- 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);
--- 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);)
 };