diff src/share/vm/opto/matcher.cpp @ 628:7bb995fbd3c0

Merge
author trims
date Thu, 12 Mar 2009 18:16:36 -0700
parents 0fbdb4381b99 98cb887364d3
children bd441136a5ce
line wrap: on
line diff
--- a/src/share/vm/opto/matcher.cpp	Mon Mar 09 13:34:00 2009 -0700
+++ b/src/share/vm/opto/matcher.cpp	Thu Mar 12 18:16:36 2009 -0700
@@ -897,7 +897,7 @@
 #ifdef ASSERT
           _new2old_map.map(m->_idx, n);
 #endif
-          mstack.push(m, Post_Visit, n, i); // Don't neet to visit
+          mstack.push(m, Post_Visit, n, i); // Don't need to visit
           mstack.push(m->in(0), Visit, m, 0);
         } else {
           mstack.push(m, Visit, n, i);
@@ -1267,7 +1267,7 @@
     }
   }
 
-  // Not forceably cloning.  If shared, put it into a register.
+  // Not forceable cloning.  If shared, put it into a register.
   return shared;
 }
 
@@ -1542,7 +1542,7 @@
   // This is what my child will give me.
   int opnd_class_instance = s->_rule[op];
   // Choose between operand class or not.
-  // This is what I will recieve.
+  // This is what I will receive.
   int catch_op = (FIRST_OPERAND_CLASS <= op && op < NUM_OPERANDS) ? opnd_class_instance : op;
   // New rule for child.  Chase operand classes to get the actual rule.
   int newrule = s->_rule[catch_op];
@@ -1707,11 +1707,18 @@
 void Matcher::find_shared( Node *n ) {
   // Allocate stack of size C->unique() * 2 to avoid frequent realloc
   MStack mstack(C->unique() * 2);
+  // Mark nodes as address_visited if they are inputs to an address expression
+  VectorSet address_visited(Thread::current()->resource_area());
   mstack.push(n, Visit);     // Don't need to pre-visit root node
   while (mstack.is_nonempty()) {
     n = mstack.node();       // Leave node on stack
     Node_State nstate = mstack.state();
+    uint nop = n->Opcode();
     if (nstate == Pre_Visit) {
+      if (address_visited.test(n->_idx)) { // Visited in address already?
+        // Flag as visited and shared now.
+        set_visited(n);
+      }
       if (is_visited(n)) {   // Visited already?
         // Node is shared and has no reason to clone.  Flag it as shared.
         // This causes it to match into a register for the sharing.
@@ -1726,7 +1733,7 @@
       set_visited(n);   // Flag as visited now
       bool mem_op = false;
 
-      switch( n->Opcode() ) {  // Handle some opcodes special
+      switch( nop ) {  // Handle some opcodes special
       case Op_Phi:             // Treat Phis as shared roots
       case Op_Parm:
       case Op_Proj:            // All handled specially during matching
@@ -1887,34 +1894,51 @@
             // to have a single use so force sharing here.
             set_shared(m->in(AddPNode::Base)->in(1));
           }
+
+          // Some inputs for address expression are not put on stack
+          // to avoid marking them as shared and forcing them into register
+          // if they are used only in address expressions.
+          // But they should be marked as shared if there are other uses
+          // besides address expressions.
+
           Node *off = m->in(AddPNode::Offset);
-          if( off->is_Con() ) {
-            set_visited(m);  // Flag as visited now
+          if( off->is_Con() &&
+              // When there are other uses besides address expressions
+              // put it on stack and mark as shared.
+              !is_visited(m) ) {
+            address_visited.test_set(m->_idx); // Flag as address_visited
             Node *adr = m->in(AddPNode::Address);
 
             // Intel, ARM and friends can handle 2 adds in addressing mode
             if( clone_shift_expressions && adr->is_AddP() &&
                 // AtomicAdd is not an addressing expression.
                 // Cheap to find it by looking for screwy base.
-                !adr->in(AddPNode::Base)->is_top() ) {
-              set_visited(adr);  // Flag as visited now
+                !adr->in(AddPNode::Base)->is_top() &&
+                // Are there other uses besides address expressions?
+                !is_visited(adr) ) {
+              address_visited.set(adr->_idx); // Flag as address_visited
               Node *shift = adr->in(AddPNode::Offset);
               // Check for shift by small constant as well
               if( shift->Opcode() == Op_LShiftX && shift->in(2)->is_Con() &&
-                  shift->in(2)->get_int() <= 3 ) {
-                set_visited(shift);  // Flag as visited now
+                  shift->in(2)->get_int() <= 3 &&
+                  // Are there other uses besides address expressions?
+                  !is_visited(shift) ) {
+                address_visited.set(shift->_idx); // Flag as address_visited
                 mstack.push(shift->in(2), Visit);
+                Node *conv = shift->in(1);
 #ifdef _LP64
                 // Allow Matcher to match the rule which bypass
                 // ConvI2L operation for an array index on LP64
                 // if the index value is positive.
-                if( shift->in(1)->Opcode() == Op_ConvI2L &&
-                    shift->in(1)->as_Type()->type()->is_long()->_lo >= 0 ) {
-                  set_visited(shift->in(1));  // Flag as visited now
-                  mstack.push(shift->in(1)->in(1), Pre_Visit);
+                if( conv->Opcode() == Op_ConvI2L &&
+                    conv->as_Type()->type()->is_long()->_lo >= 0 &&
+                    // Are there other uses besides address expressions?
+                    !is_visited(conv) ) {
+                  address_visited.set(conv->_idx); // Flag as address_visited
+                  mstack.push(conv->in(1), Pre_Visit);
                 } else
 #endif
-                mstack.push(shift->in(1), Pre_Visit);
+                mstack.push(conv, Pre_Visit);
               } else {
                 mstack.push(shift, Pre_Visit);
               }
@@ -1942,7 +1966,7 @@
       // BoolNode::match_edge always returns a zero.
 
       // We reorder the Op_If in a pre-order manner, so we can visit without
-      // accidently sharing the Cmp (the Bool and the If make 2 users).
+      // accidentally sharing the Cmp (the Bool and the If make 2 users).
       n->add_req( n->in(1)->in(1) ); // Add the Cmp next to the Bool
     }
     else if (nstate == Post_Visit) {