< prev index next >

src/hotspot/share/opto/vector.cpp

Print this page

        

@@ -39,10 +39,11 @@
 
   C->for_igvn()->clear();
   C->initial_gvn()->replace_with(&_igvn);
 
   expand_vunbox_nodes();
+  scalarize_vbox_nodes();
 
   C->inline_vector_reboxing_calls();
 
   expand_vbox_nodes();
   eliminate_vbox_alloc_nodes();

@@ -67,10 +68,32 @@
     _igvn = PhaseIterGVN(C->initial_gvn());
     _igvn.optimize();
   }
 }
 
+void PhaseVector::scalarize_vbox_nodes() {
+  if (C->failing())  return;
+
+  if (!EnableVectorReboxing) {
+    return; // don't scalarize vector boxes
+  }
+
+  int macro_idx = C->macro_count() - 1;
+  while (macro_idx >= 0) {
+    Node * n = C->macro_node(macro_idx);
+    assert(n->is_macro(), "only macro nodes expected here");
+    if (n->Opcode() == Op_VectorBox) {
+      VectorBoxNode* vbox = static_cast<VectorBoxNode*>(n);
+      scalarize_vbox_node(vbox);
+      if (C->failing())  return;
+      C->print_method(PHASE_SCALARIZE_VBOX, vbox, 3);
+    }
+    if (C->failing())  return;
+    macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
+  }
+}
+
 void PhaseVector::expand_vbox_nodes() {
   if (C->failing())  return;
 
   int macro_idx = C->macro_count() - 1;
   while (macro_idx >= 0) {

@@ -132,10 +155,119 @@
   }
   new_jvms->set_map(map);
   return new_jvms;
 }
 
+void PhaseVector::scalarize_vbox_node(VectorBoxNode* vec_box) {
+  Node* vec_value = vec_box->in(VectorBoxNode::Value);
+  PhaseGVN& gvn = *C->initial_gvn();
+
+  // Process merged VBAs
+
+  if (EnableVectorAggressiveReboxing) {
+    Unique_Node_List calls(C->comp_arena());
+    for (DUIterator_Fast imax, i = vec_box->fast_outs(imax); i < imax; i++) {
+      Node* use = vec_box->fast_out(i);
+      if (use->is_CallJava()) {
+        CallJavaNode* call = use->as_CallJava();
+        if (call->has_non_debug_use(vec_box) && vec_box->in(VectorBoxNode::Box)->is_Phi()) {
+          calls.push(call);
+        }
+      }
+    }
+
+    while (calls.size() > 0) {
+      CallJavaNode* call = calls.pop()->as_CallJava();
+      // Attach new VBA to the call and use it instead of Phi (VBA ... VBA).
+
+      JVMState* jvms = clone_jvms(C, call);
+      GraphKit kit(jvms);
+      PhaseGVN& gvn = kit.gvn();
+
+      // Adjust JVMS from post-call to pre-call state: put args on stack
+      uint nargs = call->method()->arg_size();
+      kit.ensure_stack(kit.sp() + nargs);
+      for (uint i = TypeFunc::Parms; i < call->tf()->domain()->cnt(); i++) {
+        kit.push(call->in(i));
+      }
+      jvms = kit.sync_jvms();
+
+      Node* new_vbox = NULL;
+      {
+        PreserveReexecuteState prs(&kit);
+
+        kit.jvms()->set_should_reexecute(true);
+
+        const TypeInstPtr* vbox_type = vec_box->box_type();
+        const TypeVect* vect_type = vec_box->vec_type();
+        Node* vect = vec_box->in(VectorBoxNode::Value);
+
+        VectorBoxAllocateNode* alloc = new VectorBoxAllocateNode(C, vbox_type);
+        kit.set_edges_for_java_call(alloc, /*must_throw=*/false, /*separate_io_proj=*/true);
+        kit.make_slow_call_ex(alloc, C->env()->Throwable_klass(), /*separate_io_proj=*/true, /*deoptimize=*/true);
+        kit.set_i_o(gvn.transform( new ProjNode(alloc, TypeFunc::I_O) ));
+        kit.set_all_memory(gvn.transform( new ProjNode(alloc, TypeFunc::Memory) ));
+        Node* ret = gvn.transform(new ProjNode(alloc, TypeFunc::Parms));
+
+        new_vbox = gvn.transform(new VectorBoxNode(C, ret, vect, vbox_type, vect_type));
+
+        kit.replace_in_map(vec_box, new_vbox);
+      }
+
+      kit.dec_sp(nargs);
+      jvms = kit.sync_jvms();
+
+      call->set_req(TypeFunc::Control , kit.control());
+      call->set_req(TypeFunc::I_O     , kit.i_o());
+      call->set_req(TypeFunc::Memory  , kit.reset_memory());
+      call->set_req(TypeFunc::FramePtr, kit.frameptr());
+      call->replace_edge(vec_box, new_vbox);
+
+      C->record_for_igvn(call);
+    }
+  }
+
+  // Process debug uses at safepoints
+  Unique_Node_List safepoints(C->comp_arena());
+
+  for (DUIterator_Fast imax, i = vec_box->fast_outs(imax); i < imax; i++) {
+    Node* use = vec_box->fast_out(i);
+    if (use->is_SafePoint()) {
+      SafePointNode* sfpt = use->as_SafePoint();
+      if (!sfpt->is_Call() || !sfpt->as_Call()->has_non_debug_use(vec_box)) {
+        safepoints.push(sfpt);
+      }
+    }
+  }
+
+  while (safepoints.size() > 0) {
+    SafePointNode* sfpt = safepoints.pop()->as_SafePoint();
+
+    uint first_ind = (sfpt->req() - sfpt->jvms()->scloff());
+    Node* sobj = new SafePointScalarObjectNode(vec_box->box_type(),
+#ifdef ASSERT
+                                               NULL,
+#endif // ASSERT
+                                               first_ind, /*n_fields=*/1);
+    sobj->init_req(0, C->root());
+    sfpt->add_req(vec_value);
+
+    sobj = gvn.transform(sobj);
+
+    JVMState *jvms = sfpt->jvms();
+
+    jvms->set_endoff(sfpt->req());
+    // Now make a pass over the debug information replacing any references
+    // to the allocated object with "sobj"
+    int start = jvms->debug_start();
+    int end   = jvms->debug_end();
+    sfpt->replace_edges_in_range(vec_box, sobj, start, end);
+
+    C->record_for_igvn(sfpt);
+  }
+}
+
 void PhaseVector::expand_vbox_node(VectorBoxNode* vec_box) {
   if (vec_box->outcnt() > 0) {
     Node* vbox = vec_box->in(VectorBoxNode::Box);
     Node* vect = vec_box->in(VectorBoxNode::Value);
     Node* result = expand_vbox_node_helper(vbox, vect, vec_box->box_type(), vec_box->vec_type());
< prev index next >