# HG changeset patch # User kvn # Date 1487793094 0 # Node ID 6db7a35e08ae1910d033ab3b2e899477c69b9353 # Parent b223ed3405bf8f33674cb8ef48b2da6efe585095# Parent 73607b4788cbc3913825554d6bf1df9a8aace20b Merge diff -r b223ed3405bf -r 6db7a35e08ae hotspot/src/cpu/s390/vm/s390.ad --- a/hotspot/src/cpu/s390/vm/s390.ad Wed Feb 22 12:34:32 2017 -0500 +++ b/hotspot/src/cpu/s390/vm/s390.ad Wed Feb 22 19:51:34 2017 +0000 @@ -6770,6 +6770,7 @@ format %{ "SLL $dst,$src,$nbits\t# use RISC-like SLLG also for int" %} ins_encode %{ int Nbit = $nbits$$constant; + assert((Nbit & (BitsPerJavaInteger - 1)) == Nbit, "Check shift mask in ideal graph"); __ z_sllg($dst$$Register, $src$$Register, Nbit & (BitsPerJavaInteger - 1), Z_R0); %} ins_pipe(pipe_class_dummy); @@ -6843,6 +6844,7 @@ format %{ "SRA $dst,$src" %} ins_encode %{ int Nbit = $src$$constant; + assert((Nbit & (BitsPerJavaInteger - 1)) == Nbit, "Check shift mask in ideal graph"); __ z_sra($dst$$Register, Nbit & (BitsPerJavaInteger - 1), Z_R0); %} ins_pipe(pipe_class_dummy); @@ -6895,6 +6897,7 @@ format %{ "SRL $dst,$src" %} ins_encode %{ int Nbit = $src$$constant; + assert((Nbit & (BitsPerJavaInteger - 1)) == Nbit, "Check shift mask in ideal graph"); __ z_srl($dst$$Register, Nbit & (BitsPerJavaInteger - 1), Z_R0); %} ins_pipe(pipe_class_dummy); diff -r b223ed3405bf -r 6db7a35e08ae hotspot/src/share/vm/opto/mulnode.cpp --- a/hotspot/src/share/vm/opto/mulnode.cpp Wed Feb 22 12:34:32 2017 -0500 +++ b/hotspot/src/share/vm/opto/mulnode.cpp Wed Feb 22 19:51:34 2017 +0000 @@ -630,23 +630,42 @@ } //============================================================================= + +static int getShiftCon(PhaseGVN *phase, Node *shiftNode, int retVal) { + const Type *t = phase->type(shiftNode->in(2)); + if (t == Type::TOP) return retVal; // Right input is dead. + const TypeInt *t2 = t->isa_int(); + if (!t2 || !t2->is_con()) return retVal; // Right input is a constant. + + return t2->get_con(); +} + +static int maskShiftAmount(PhaseGVN *phase, Node *shiftNode, int nBits) { + int shift = getShiftCon(phase, shiftNode, 0); + int maskedShift = shift & (nBits - 1); + + if (maskedShift == 0) return 0; // Let Identity() handle 0 shift count. + + if (shift != maskedShift) { + shiftNode->set_req(2, phase->intcon(maskedShift)); // Replace shift count with masked value. + } + + return maskedShift; +} + //------------------------------Identity--------------------------------------- Node* LShiftINode::Identity(PhaseGVN* phase) { - const TypeInt *ti = phase->type( in(2) )->isa_int(); // shift count is an int - return ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerInt - 1 ) ) == 0 ) ? in(1) : this; + return ((getShiftCon(phase, this, -1) & (BitsPerJavaInteger - 1)) == 0) ? in(1) : this; } //------------------------------Ideal------------------------------------------ // If the right input is a constant, and the left input is an add of a // constant, flatten the tree: (X+con1)< X<type( in(2) ); - if( t == Type::TOP ) return NULL; // Right input is dead - const TypeInt *t2 = t->isa_int(); - if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant - const int con = t2->get_con() & ( BitsPerInt - 1 ); // masked shift count - - if ( con == 0 ) return NULL; // let Identity() handle 0 shift count + int con = maskShiftAmount(phase, this, BitsPerJavaInteger); + if (con == 0) { + return NULL; + } // Left input is an add of a constant? Node *add1 = in(1); @@ -744,21 +763,17 @@ //============================================================================= //------------------------------Identity--------------------------------------- Node* LShiftLNode::Identity(PhaseGVN* phase) { - const TypeInt *ti = phase->type( in(2) )->isa_int(); // shift count is an int - return ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerLong - 1 ) ) == 0 ) ? in(1) : this; + return ((getShiftCon(phase, this, -1) & (BitsPerJavaLong - 1)) == 0) ? in(1) : this; } //------------------------------Ideal------------------------------------------ // If the right input is a constant, and the left input is an add of a // constant, flatten the tree: (X+con1)< X<type( in(2) ); - if( t == Type::TOP ) return NULL; // Right input is dead - const TypeInt *t2 = t->isa_int(); - if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant - const int con = t2->get_con() & ( BitsPerLong - 1 ); // masked shift count - - if ( con == 0 ) return NULL; // let Identity() handle 0 shift count + int con = maskShiftAmount(phase, this, BitsPerJavaLong); + if (con == 0) { + return NULL; + } // Left input is an add of a constant? Node *add1 = in(1); @@ -853,26 +868,24 @@ //============================================================================= //------------------------------Identity--------------------------------------- Node* RShiftINode::Identity(PhaseGVN* phase) { - const TypeInt *t2 = phase->type(in(2))->isa_int(); - if( !t2 ) return this; - if ( t2->is_con() && ( t2->get_con() & ( BitsPerInt - 1 ) ) == 0 ) - return in(1); + int shift = getShiftCon(phase, this, -1); + if (shift == -1) return this; + if ((shift & (BitsPerJavaInteger - 1)) == 0) return in(1); // Check for useless sign-masking - if( in(1)->Opcode() == Op_LShiftI && + if (in(1)->Opcode() == Op_LShiftI && in(1)->req() == 3 && - in(1)->in(2) == in(2) && - t2->is_con() ) { - uint shift = t2->get_con(); + in(1)->in(2) == in(2)) { shift &= BitsPerJavaInteger-1; // semantics of Java shifts // Compute masks for which this shifting doesn't change - int lo = (-1 << (BitsPerJavaInteger - shift-1)); // FFFF8000 + int lo = (-1 << (BitsPerJavaInteger - ((uint)shift)-1)); // FFFF8000 int hi = ~lo; // 00007FFF const TypeInt *t11 = phase->type(in(1)->in(1))->isa_int(); - if( !t11 ) return this; + if (!t11) return this; // Does actual value fit inside of mask? - if( lo <= t11->_lo && t11->_hi <= hi ) + if (lo <= t11->_lo && t11->_hi <= hi) { return in(1)->in(1); // Then shifting is a nop + } } return this; @@ -881,15 +894,13 @@ //------------------------------Ideal------------------------------------------ Node *RShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) { // Inputs may be TOP if they are dead. - const TypeInt *t1 = phase->type( in(1) )->isa_int(); - if( !t1 ) return NULL; // Left input is an integer - const TypeInt *t2 = phase->type( in(2) )->isa_int(); - if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant + const TypeInt *t1 = phase->type(in(1))->isa_int(); + if (!t1) return NULL; // Left input is an integer const TypeInt *t3; // type of in(1).in(2) - int shift = t2->get_con(); - shift &= BitsPerJavaInteger-1; // semantics of Java shifts - - if ( shift == 0 ) return NULL; // let Identity() handle 0 shift count + int shift = maskShiftAmount(phase, this, BitsPerJavaInteger); + if (shift == 0) { + return NULL; + } // Check for (x & 0xFF000000) >> 24, whose mask can be made smaller. // Such expressions arise normally from shift chains like (byte)(x >> 24). @@ -1003,8 +1014,8 @@ //============================================================================= //------------------------------Identity--------------------------------------- Node* RShiftLNode::Identity(PhaseGVN* phase) { - const TypeInt *ti = phase->type( in(2) )->isa_int(); // shift count is an int - return ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerLong - 1 ) ) == 0 ) ? in(1) : this; + const TypeInt *ti = phase->type(in(2))->isa_int(); // Shift count is an int. + return (ti && ti->is_con() && (ti->get_con() & (BitsPerJavaLong - 1)) == 0) ? in(1) : this; } //------------------------------Value------------------------------------------ @@ -1061,25 +1072,25 @@ //============================================================================= //------------------------------Identity--------------------------------------- Node* URShiftINode::Identity(PhaseGVN* phase) { - const TypeInt *ti = phase->type( in(2) )->isa_int(); - if ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerInt - 1 ) ) == 0 ) return in(1); + int shift = getShiftCon(phase, this, -1); + if ((shift & (BitsPerJavaInteger - 1)) == 0) return in(1); // Check for "((x << LogBytesPerWord) + (wordSize-1)) >> LogBytesPerWord" which is just "x". // Happens during new-array length computation. // Safe if 'x' is in the range [0..(max_int>>LogBytesPerWord)] Node *add = in(1); - if( add->Opcode() == Op_AddI ) { - const TypeInt *t2 = phase->type(add->in(2))->isa_int(); - if( t2 && t2->is_con(wordSize - 1) && - add->in(1)->Opcode() == Op_LShiftI ) { - // Check that shift_counts are LogBytesPerWord + if (add->Opcode() == Op_AddI) { + const TypeInt *t2 = phase->type(add->in(2))->isa_int(); + if (t2 && t2->is_con(wordSize - 1) && + add->in(1)->Opcode() == Op_LShiftI) { + // Check that shift_counts are LogBytesPerWord. Node *lshift_count = add->in(1)->in(2); const TypeInt *t_lshift_count = phase->type(lshift_count)->isa_int(); - if( t_lshift_count && t_lshift_count->is_con(LogBytesPerWord) && - t_lshift_count == phase->type(in(2)) ) { + if (t_lshift_count && t_lshift_count->is_con(LogBytesPerWord) && + t_lshift_count == phase->type(in(2))) { Node *x = add->in(1)->in(1); const TypeInt *t_x = phase->type(x)->isa_int(); - if( t_x != NULL && 0 <= t_x->_lo && t_x->_hi <= (max_jint>>LogBytesPerWord) ) { + if (t_x != NULL && 0 <= t_x->_lo && t_x->_hi <= (max_jint>>LogBytesPerWord)) { return x; } } @@ -1091,10 +1102,11 @@ //------------------------------Ideal------------------------------------------ Node *URShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) { - const TypeInt *t2 = phase->type( in(2) )->isa_int(); - if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant - const int con = t2->get_con() & 31; // Shift count is always masked - if ( con == 0 ) return NULL; // let Identity() handle a 0 shift count + int con = maskShiftAmount(phase, this, BitsPerJavaInteger); + if (con == 0) { + return NULL; + } + // We'll be wanting the right-shift amount as a mask of that many bits const int mask = right_n_bits(BitsPerJavaInteger - con); @@ -1117,7 +1129,8 @@ // If Q is "X << z" the rounding is useless. Look for patterns like // ((X<>> Z and replace with (X + Y>>>Z) & Z-mask. Node *add = in(1); - if( in1_op == Op_AddI ) { + const TypeInt *t2 = phase->type(in(2))->isa_int(); + if (in1_op == Op_AddI) { Node *lshl = add->in(1); if( lshl->Opcode() == Op_LShiftI && phase->type(lshl->in(2)) == t2 ) { @@ -1231,17 +1244,16 @@ //============================================================================= //------------------------------Identity--------------------------------------- Node* URShiftLNode::Identity(PhaseGVN* phase) { - const TypeInt *ti = phase->type( in(2) )->isa_int(); // shift count is an int - return ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerLong - 1 ) ) == 0 ) ? in(1) : this; + return ((getShiftCon(phase, this, -1) & (BitsPerJavaLong - 1)) == 0) ? in(1) : this; } //------------------------------Ideal------------------------------------------ Node *URShiftLNode::Ideal(PhaseGVN *phase, bool can_reshape) { - const TypeInt *t2 = phase->type( in(2) )->isa_int(); - if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant - const int con = t2->get_con() & ( BitsPerLong - 1 ); // Shift count is always masked - if ( con == 0 ) return NULL; // let Identity() handle a 0 shift count - // note: mask computation below does not work for 0 shift count + int con = maskShiftAmount(phase, this, BitsPerJavaLong); + if (con == 0) { + return NULL; + } + // We'll be wanting the right-shift amount as a mask of that many bits const jlong mask = jlong(max_julong >> con); @@ -1250,7 +1262,8 @@ // If Q is "X << z" the rounding is useless. Look for patterns like // ((X<>> Z and replace with (X + Y>>>Z) & Z-mask. Node *add = in(1); - if( add->Opcode() == Op_AddL ) { + const TypeInt *t2 = phase->type(in(2))->isa_int(); + if (add->Opcode() == Op_AddL) { Node *lshl = add->in(1); if( lshl->Opcode() == Op_LShiftL && phase->type(lshl->in(2)) == t2 ) {