hotspot/src/share/vm/opto/compile.cpp
changeset 1135 9487203e5789
parent 1055 f4fb9fb08038
child 1137 26c7642c3642
--- a/hotspot/src/share/vm/opto/compile.cpp	Wed Sep 10 14:29:32 2008 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Sep 10 18:23:32 2008 -0700
@@ -1967,6 +1967,7 @@
           !n->is_Proj() &&
           nop != Op_CreateEx &&
           nop != Op_CheckCastPP &&
+          nop != Op_DecodeN &&
           !n->is_Mem() ) {
         Node *x = n->clone();
         call->set_req( TypeFunc::Parms, x );
@@ -2075,20 +2076,27 @@
   case Op_CmpP:
     // Do this transformation here to preserve CmpPNode::sub() and
     // other TypePtr related Ideal optimizations (for example, ptr nullness).
-    if( n->in(1)->is_DecodeN() ) {
+    if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) {
+      Node* in1 = n->in(1);
+      Node* in2 = n->in(2);
+      if (!in1->is_DecodeN()) {
+        in2 = in1;
+        in1 = n->in(2);
+      }
+      assert(in1->is_DecodeN(), "sanity");
+
       Compile* C = Compile::current();
-      Node* in2 = NULL;
-      if( n->in(2)->is_DecodeN() ) {
-        in2 = n->in(2)->in(1);
-      } else if ( n->in(2)->Opcode() == Op_ConP ) {
-        const Type* t = n->in(2)->bottom_type();
+      Node* new_in2 = NULL;
+      if (in2->is_DecodeN()) {
+        new_in2 = in2->in(1);
+      } else if (in2->Opcode() == Op_ConP) {
+        const Type* t = in2->bottom_type();
         if (t == TypePtr::NULL_PTR) {
-          Node *in1 = n->in(1);
           if (Matcher::clone_shift_expressions) {
             // x86, ARM and friends can handle 2 adds in addressing mode.
             // Decode a narrow oop and do implicit NULL check in address
             // [R12 + narrow_oop_reg<<3 + offset]
-            in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
+            new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
           } else {
             // Don't replace CmpP(o ,null) if 'o' is used in AddP
             // to generate implicit NULL check on Sparc where
@@ -2099,16 +2107,22 @@
                 break;
             }
             if (i >= in1->outcnt()) {
-              in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
+              new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
             }
           }
         } else if (t->isa_oopptr()) {
-          in2 = ConNode::make(C, t->make_narrowoop());
+          new_in2 = ConNode::make(C, t->make_narrowoop());
         }
       }
-      if( in2 != NULL ) {
-        Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2);
+      if (new_in2 != NULL) {
+        Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2);
         n->subsume_by( cmpN );
+        if (in1->outcnt() == 0) {
+          in1->disconnect_inputs(NULL);
+        }
+        if (in2->outcnt() == 0) {
+          in2->disconnect_inputs(NULL);
+        }
       }
     }
     break;
@@ -2214,6 +2228,9 @@
 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(),
 // requires that the walk visits a node's inputs before visiting the node.
 static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &fpu ) {
+  ResourceArea *area = Thread::current()->resource_area();
+  Unique_Node_List sfpt(area);
+
   fpu._visited.set(root->_idx); // first, mark node as visited
   uint cnt = root->req();
   Node *n = root;
@@ -2224,6 +2241,8 @@
       Node* m = n->in(i);
       ++i;
       if (m != NULL && !fpu._visited.test_set(m->_idx)) {
+        if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL)
+          sfpt.push(m);
         cnt = m->req();
         nstack.push(n, i); // put on stack parent and next input's index
         n = m;
@@ -2240,6 +2259,41 @@
       nstack.pop();        // Shift to the next node on stack
     }
   }
+
+  // Go over safepoints nodes to skip DecodeN nodes for debug edges.
+  // It could be done for an uncommon traps or any safepoints/calls
+  // if the DecodeN node is referenced only in a debug info.
+  while (sfpt.size() > 0) {
+    n = sfpt.pop();
+    JVMState *jvms = n->as_SafePoint()->jvms();
+    assert(jvms != NULL, "sanity");
+    int start = jvms->debug_start();
+    int end   = n->req();
+    bool is_uncommon = (n->is_CallStaticJava() &&
+                        n->as_CallStaticJava()->uncommon_trap_request() != 0);
+    for (int j = start; j < end; j++) {
+      Node* in = n->in(j);
+      if (in->is_DecodeN()) {
+        bool safe_to_skip = true;
+        if (!is_uncommon ) {
+          // Is it safe to skip?
+          for (uint i = 0; i < in->outcnt(); i++) {
+            Node* u = in->raw_out(i);
+            if (!u->is_SafePoint() ||
+                 u->is_Call() && u->as_Call()->has_non_debug_use(n)) {
+              safe_to_skip = false;
+            }
+          }
+        }
+        if (safe_to_skip) {
+          n->set_req(j, in->in(1));
+        }
+        if (in->outcnt() == 0) {
+          in->disconnect_inputs(NULL);
+        }
+      }
+    }
+  }
 }
 
 //------------------------------final_graph_reshaping--------------------------