< prev index next >

src/share/vm/opto/parse1.cpp

Print this page

        

@@ -1743,36 +1743,21 @@
         // Reload current state because it may have been updated by ensure_phi
         m = map()->in(j);
         ValueTypeNode* vtm = m->as_ValueType(); // Current value type
         ValueTypeNode* vtn = n->as_ValueType(); // Incoming value type
         if (TraceOptoParse) {
-          tty->print_cr("Merging value types");
 #ifdef ASSERT
+          tty->print_cr("\nMerging value types");
           tty->print_cr("Current:");
-          vtm->dump(1);
+          vtm->dump(2);
           tty->print_cr("Incoming:");
-          vtn->dump(1);
+          vtn->dump(2);
+          tty->cr();
 #endif
         }
-        // Merge oop inputs
-        phi = vtm->get_oop()->as_Phi();
-        phi->set_req(pnum, vtn->get_oop());
-        if (pnum == PhiNode::Input) {
-          // Last merge
-          vtm->set_oop(_gvn.transform_no_reclaim(phi));
-          record_for_igvn(phi);
-        }
-        // Merge field values
-        for (uint index = 0; index < vtm->field_count(); ++index) {
-          phi = vtm->get_field_value(index)->as_Phi();
-          phi->set_req(pnum, vtn->get_field_value(index));
-          if (pnum == PhiNode::Input) {
-            // Last merge
-            vtm->set_field_value(index, _gvn.transform_no_reclaim(phi));
-            record_for_igvn(phi);
-          }
-        }
+        // Do the merge
+        map()->set_req(j, vtm->merge_with(this, vtn, pnum));
       } else if (phi != NULL) {
         assert(n != top() || r->in(pnum) == top(), "live value must not be garbage");
         assert(phi->region() == r, "");
         phi->set_req(pnum, n);  // Then add 'n' to the merge
         if (pnum == PhiNode::Input) {

@@ -1966,14 +1951,22 @@
   if (o->is_Phi() && o->as_Phi()->region() == region) {
     return o->as_Phi();
   }
 
   ValueTypeNode* vt = o->isa_ValueType();
-  if (vt != NULL && vt->get_oop()->is_Phi() && vt->get_oop()->as_Phi()->region() == region) {
+  if (vt != NULL) {
+    // Value types are merged by merging their field values
+    if (vt->get_oop()->is_Phi() && vt->get_oop()->as_Phi()->region() == region) {
     // ValueTypeNode already has Phi inputs
     return NULL;
   }
+    // Create a cloned ValueTypeNode with phi inputs that
+    // represents the merged value type and update the map.
+    vt = vt->clone_with_phis(gvn(), region);
+    map->set_req(idx, vt);
+    return NULL;
+  }
 
   // Now use a Phi here for merging
   assert(!nocreate, "Cannot build a phi for a block already parsed.");
   const JVMState* jvms = map->jvms();
   const Type* t = NULL;

@@ -2003,35 +1996,10 @@
   if (t == Type::TOP || t == Type::HALF) {
     map->set_req(idx, top());
     return NULL;
   }
 
-  // Value types are merged by merging their field values
-  if (vt != NULL) {
-    // Create new ValueTypeNode that represents the merged value type
-    vt = vt->clone()->as_ValueType();
-
-    // Create a PhiNode for merging the oop
-    const TypeValueTypePtr* vtptr = TypeValueTypePtr::make(t->is_valuetype());
-    PhiNode* oop = PhiNode::make(region, vt->get_oop(), vtptr);
-    gvn().set_type(oop, vtptr);
-    vt->set_oop(oop);
-
-    // Create a PhiNode for merging each field value
-    for (uint i = 0; i < vt->field_count(); ++i) {
-      const Type* field_type = Type::get_const_basic_type(vt->get_field_type(i));
-      PhiNode* phi = PhiNode::make(region, vt->get_field_value(i), field_type);
-      gvn().set_type(phi, field_type);
-      vt->set_field_value(i, phi);
-    }
-
-    // Update map to use cloned value type
-    gvn().set_type(vt, t);
-    map->set_req(idx, vt);
-    return NULL;
-  }
-
   PhiNode* phi = PhiNode::make(region, o, t);
   gvn().set_type(phi, t);
   if (C->do_escape_analysis()) record_for_igvn(phi);
   map->set_req(idx, phi);
   return phi;
< prev index next >