< prev index next >

src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp

Print this page
rev 56032 : 8228839: Non-CFG nodes have control edges to calls, instead of the call's control projection
Reviewed-by:

@@ -879,10 +879,22 @@
   }
 }
 
 #endif // end verification code
 
+// If a call is the control, we really wants its control projetion
+static Node* normalize_ctrl(Node* node) {
+ if (node->is_Call()) {
+   node = node->as_Call()->proj_out(TypeFunc::Control);
+ }
+ return node;
+}
+
+static Node* get_ctrl_normalized(PhaseIdealLoop *phase, Node* node) {
+  return normalize_ctrl(phase->get_ctrl(node));
+}
+
 static void call_catch_cleanup_one(PhaseIdealLoop* phase, LoadNode* load, Node* ctrl);
 
 // This code is cloning all uses of a load that is between a call and the catch blocks,
 // to each use.
 

@@ -892,11 +904,11 @@
     // This node is floating - doesn't need to be cloned.
     assert(node != start_ctrl, "check");
     return false;
   }
 
-  Node* ctrl = phase->get_ctrl(node);
+  Node* ctrl = get_ctrl_normalized(phase, node);
   if (ctrl != start_ctrl) {
     // We are in a successor block - the node is ok.
     return false; // Unwind
   }
 

@@ -909,11 +921,10 @@
     fixup_uses_in_catch(phase, start_ctrl, n);
   }
 
   // Now all successors are outside
   // - Clone this node to both successors
-  int no_succs = node->outcnt();
   assert(!node->is_Store(), "Stores not expected here");
 
   // In some very rare cases a load that doesn't need a barrier will end up here
   // Treat it as a LoadP and the insertion of phis will be done correctly.
   if (node->is_Load()) {

@@ -933,11 +944,11 @@
         new_ctrl = use;
       } else if (use->is_CFG()) {
         new_ctrl = use->in(0);
         assert (new_ctrl != NULL, "");
       } else {
-        new_ctrl = phase->get_ctrl(use);
+        new_ctrl = get_ctrl_normalized(phase, use);
       }
 
       phase->set_ctrl(clone, new_ctrl);
 
       if (phase->C->directive()->ZTraceLoadBarriersOption) tty->print_cr("  Clone op %i as %i to control %i", node->_idx, clone->_idx, new_ctrl->_idx);

@@ -1026,11 +1037,12 @@
   for (unsigned int i = 0; i  < load->outcnt(); i++) {
     Node* load_use_control = NULL;
     Node* load_use = load->raw_out(i);
 
     if (phase->has_ctrl(load_use)) {
-      load_use_control = phase->get_ctrl(load_use);
+      load_use_control = get_ctrl_normalized(phase, load_use);
+      assert(load_use_control != ctrl, "sanity");
     } else {
       load_use_control = load_use->in(0);
     }
     assert(load_use_control != NULL, "sanity");
     if (trace) tty->print_cr("  Handling use: %i, with control: %i", load_use->_idx, load_use_control->_idx);

@@ -1210,11 +1222,11 @@
 
 // Sort out the loads that are between a call ant its catch blocks
 static void process_catch_cleanup_candidate(PhaseIdealLoop* phase, LoadNode* load) {
   bool trace = phase->C->directive()->ZTraceLoadBarriersOption;
 
-  Node* ctrl = phase->get_ctrl(load);
+  Node* ctrl = get_ctrl_normalized(phase, load);
   if (!ctrl->is_Proj() || (ctrl->in(0) == NULL) || !ctrl->in(0)->isa_Call()) {
     return;
   }
 
   Node* catch_node = ctrl->isa_Proj()->raw_out(0);

@@ -1583,10 +1595,11 @@
 
   // create barrier
   Node* barrier = new LoadBarrierNode(C, NULL, load->in(LoadNode::Memory), NULL, load->in(LoadNode::Address), load_has_weak_barrier(load));
   Node* barrier_val = new ProjNode(barrier, LoadBarrierNode::Oop);
   Node* barrier_ctrl = new ProjNode(barrier, LoadBarrierNode::Control);
+  ctrl = normalize_ctrl(ctrl);
 
   if (trace) tty->print_cr("Insert load %i with barrier: %i and ctrl : %i", load->_idx, barrier->_idx, ctrl->_idx);
 
   // Splice control
   // - insert barrier control diamond between loads ctrl and ctrl successor on path to block end.
< prev index next >