--- old/src/share/vm/opto/matcher.cpp 2015-09-21 11:51:33.325104217 +0200 +++ new/src/share/vm/opto/matcher.cpp 2015-09-21 11:51:32.928934291 +0200 @@ -2045,6 +2045,33 @@ // and then expanded into the inline_cache_reg and a method_oop register // defined in ad_.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);