hotspot/src/share/vm/opto/matcher.cpp
changeset 33082 c3e302e8e429
parent 32202 7e7ad8b06f5b
child 33158 f4e6c593ba73
--- a/hotspot/src/share/vm/opto/matcher.cpp	Thu Sep 24 20:13:04 2015 +0300
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Thu Sep 17 16:53:42 2015 +0200
@@ -2045,6 +2045,33 @@
 // and then expanded into the inline_cache_reg and a method_oop register
 //   defined in ad_<arch>.cpp
 
+// Check for shift by small constant as well
+static bool clone_shift(Node* shift, Matcher* matcher, MStack& mstack, VectorSet& address_visited) {
+  if (shift->Opcode() == Op_LShiftX && shift->in(2)->is_Con() &&
+      shift->in(2)->get_int() <= 3 &&
+      // Are there other uses besides address expressions?
+      !matcher->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 (conv->Opcode() == Op_ConvI2L &&
+        conv->as_Type()->type()->is_long()->_lo >= 0 &&
+        // Are there other uses besides address expressions?
+        !matcher->is_visited(conv)) {
+      address_visited.set(conv->_idx); // Flag as address_visited
+      mstack.push(conv->in(1), Pre_Visit);
+    } else
+#endif
+      mstack.push(conv, Pre_Visit);
+    return true;
+  }
+  return false;
+}
+
 
 //------------------------------find_shared------------------------------------
 // Set bits if Node is shared or otherwise a root
@@ -2205,7 +2232,10 @@
 #endif
 
         // Clone addressing expressions as they are "free" in memory access instructions
-        if( mem_op && i == MemNode::Address && mop == Op_AddP ) {
+        if (mem_op && i == MemNode::Address && mop == Op_AddP &&
+            // When there are other uses besides address expressions
+            // put it on stack and mark as shared.
+            !is_visited(m)) {
           // 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.
@@ -2213,10 +2243,7 @@
           // besides address expressions.
 
           Node *off = m->in(AddPNode::Offset);
-          if( off->is_Con() &&
-              // When there are other uses besides address expressions
-              // put it on stack and mark as shared.
-              !is_visited(m) ) {
+          if (off->is_Con()) {
             address_visited.test_set(m->_idx); // Flag as address_visited
             Node *adr = m->in(AddPNode::Address);
 
@@ -2229,28 +2256,7 @@
                 !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 &&
-                  // 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( 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(conv, Pre_Visit);
-              } else {
+              if (!clone_shift(shift, this, mstack, address_visited)) {
                 mstack.push(shift, Pre_Visit);
               }
               mstack.push(adr->in(AddPNode::Address), Pre_Visit);
@@ -2263,6 +2269,12 @@
             mstack.push(off, Visit);
             mstack.push(m->in(AddPNode::Base), Pre_Visit);
             continue; // for(int i = ...)
+          } else if (clone_shift_expressions &&
+                     clone_shift(off, this, mstack, address_visited)) {
+              address_visited.test_set(m->_idx); // Flag as address_visited
+              mstack.push(m->in(AddPNode::Address), Pre_Visit);
+              mstack.push(m->in(AddPNode::Base), Pre_Visit);
+              continue;
           } // if( off->is_Con() )
         }   // if( mem_op &&
         mstack.push(m, Pre_Visit);