src/share/vm/opto/divnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8034812 Cdiff src/share/vm/opto/divnode.cpp

src/share/vm/opto/divnode.cpp

Print this page

        

*** 104,114 **** if (d == 1) { // division by +/- 1 if (!d_pos) { // Just negate the value ! q = new (phase->C) SubINode(phase->intcon(0), dividend); } } else if ( is_power_of_2(d) ) { // division by +/- a power of 2 // See if we can simply do a shift without rounding --- 104,114 ---- if (d == 1) { // division by +/- 1 if (!d_pos) { // Just negate the value ! q = new SubINode(phase->intcon(0), dividend); } } else if ( is_power_of_2(d) ) { // division by +/- a power of 2 // See if we can simply do a shift without rounding
*** 141,162 **** // shift is by 2. You need to add 3 to negative dividends and 0 to // positive ones. So (-7+3)>>2 becomes -1, (-4+3)>>2 becomes -1, // (-2+3)>>2 becomes 0, etc. // Compute 0 or -1, based on sign bit ! Node *sign = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N - 1))); // Mask sign bit to the low sign bits ! Node *round = phase->transform(new (phase->C) URShiftINode(sign, phase->intcon(N - l))); // Round up before shifting ! dividend = phase->transform(new (phase->C) AddINode(dividend, round)); } // Shift for division ! q = new (phase->C) RShiftINode(dividend, phase->intcon(l)); if (!d_pos) { ! q = new (phase->C) SubINode(phase->intcon(0), phase->transform(q)); } } else { // Attempt the jint constant divide -> multiply transform found in // "Division by Invariant Integers using Multiplication" // by Granlund and Montgomery --- 141,162 ---- // shift is by 2. You need to add 3 to negative dividends and 0 to // positive ones. So (-7+3)>>2 becomes -1, (-4+3)>>2 becomes -1, // (-2+3)>>2 becomes 0, etc. // Compute 0 or -1, based on sign bit ! Node *sign = phase->transform(new RShiftINode(dividend, phase->intcon(N - 1))); // Mask sign bit to the low sign bits ! Node *round = phase->transform(new URShiftINode(sign, phase->intcon(N - l))); // Round up before shifting ! dividend = phase->transform(new AddINode(dividend, round)); } // Shift for division ! q = new RShiftINode(dividend, phase->intcon(l)); if (!d_pos) { ! q = new SubINode(phase->intcon(0), phase->transform(q)); } } else { // Attempt the jint constant divide -> multiply transform found in // "Division by Invariant Integers using Multiplication" // by Granlund and Montgomery
*** 164,210 **** jint magic_const; jint shift_const; if (magic_int_divide_constants(d, magic_const, shift_const)) { Node *magic = phase->longcon(magic_const); ! Node *dividend_long = phase->transform(new (phase->C) ConvI2LNode(dividend)); // Compute the high half of the dividend x magic multiplication ! Node *mul_hi = phase->transform(new (phase->C) MulLNode(dividend_long, magic)); if (magic_const < 0) { ! mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N))); ! mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi)); // The magic multiplier is too large for a 32 bit constant. We've adjusted // it down by 2^32, but have to add 1 dividend back in after the multiplication. // This handles the "overflow" case described by Granlund and Montgomery. ! mul_hi = phase->transform(new (phase->C) AddINode(dividend, mul_hi)); // Shift over the (adjusted) mulhi if (shift_const != 0) { ! mul_hi = phase->transform(new (phase->C) RShiftINode(mul_hi, phase->intcon(shift_const))); } } else { // No add is required, we can merge the shifts together. ! mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N + shift_const))); ! mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi)); } // Get a 0 or -1 from the sign of the dividend. Node *addend0 = mul_hi; ! Node *addend1 = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N-1))); // If the divisor is negative, swap the order of the input addends; // this has the effect of negating the quotient. if (!d_pos) { Node *temp = addend0; addend0 = addend1; addend1 = temp; } // Adjust the final quotient by subtracting -1 (adding 1) // from the mul_hi. ! q = new (phase->C) SubINode(addend0, addend1); } } return q; } --- 164,210 ---- jint magic_const; jint shift_const; if (magic_int_divide_constants(d, magic_const, shift_const)) { Node *magic = phase->longcon(magic_const); ! Node *dividend_long = phase->transform(new ConvI2LNode(dividend)); // Compute the high half of the dividend x magic multiplication ! Node *mul_hi = phase->transform(new MulLNode(dividend_long, magic)); if (magic_const < 0) { ! mul_hi = phase->transform(new RShiftLNode(mul_hi, phase->intcon(N))); ! mul_hi = phase->transform(new ConvL2INode(mul_hi)); // The magic multiplier is too large for a 32 bit constant. We've adjusted // it down by 2^32, but have to add 1 dividend back in after the multiplication. // This handles the "overflow" case described by Granlund and Montgomery. ! mul_hi = phase->transform(new AddINode(dividend, mul_hi)); // Shift over the (adjusted) mulhi if (shift_const != 0) { ! mul_hi = phase->transform(new RShiftINode(mul_hi, phase->intcon(shift_const))); } } else { // No add is required, we can merge the shifts together. ! mul_hi = phase->transform(new RShiftLNode(mul_hi, phase->intcon(N + shift_const))); ! mul_hi = phase->transform(new ConvL2INode(mul_hi)); } // Get a 0 or -1 from the sign of the dividend. Node *addend0 = mul_hi; ! Node *addend1 = phase->transform(new RShiftINode(dividend, phase->intcon(N-1))); // If the divisor is negative, swap the order of the input addends; // this has the effect of negating the quotient. if (!d_pos) { Node *temp = addend0; addend0 = addend1; addend1 = temp; } // Adjust the final quotient by subtracting -1 (adding 1) // from the mul_hi. ! q = new SubINode(addend0, addend1); } } return q; }
*** 259,269 **** static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) { // If the architecture supports a 64x64 mulhi, there is // no need to synthesize it in ideal nodes. if (Matcher::has_match_rule(Op_MulHiL)) { Node* v = phase->longcon(magic_const); ! return new (phase->C) MulHiLNode(dividend, v); } // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. // (http://www.hackersdelight.org/HDcode/mulhs.c) // --- 259,269 ---- static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) { // If the architecture supports a 64x64 mulhi, there is // no need to synthesize it in ideal nodes. if (Matcher::has_match_rule(Op_MulHiL)) { Node* v = phase->longcon(magic_const); ! return new MulHiLNode(dividend, v); } // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. // (http://www.hackersdelight.org/HDcode/mulhs.c) //
*** 285,330 **** // following inline comments are adapted to 64x64. const int N = 64; // Dummy node to keep intermediate nodes alive during construction ! Node* hook = new (phase->C) Node(4); // u0 = u & 0xFFFFFFFF; u1 = u >> 32; ! Node* u0 = phase->transform(new (phase->C) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); ! Node* u1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N / 2))); hook->init_req(0, u0); hook->init_req(1, u1); // v0 = v & 0xFFFFFFFF; v1 = v >> 32; Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF); Node* v1 = phase->longcon(magic_const >> (N / 2)); // w0 = u0*v0; ! Node* w0 = phase->transform(new (phase->C) MulLNode(u0, v0)); // t = u1*v0 + (w0 >> 32); ! Node* u1v0 = phase->transform(new (phase->C) MulLNode(u1, v0)); ! Node* temp = phase->transform(new (phase->C) URShiftLNode(w0, phase->intcon(N / 2))); ! Node* t = phase->transform(new (phase->C) AddLNode(u1v0, temp)); hook->init_req(2, t); // w1 = t & 0xFFFFFFFF; ! Node* w1 = phase->transform(new (phase->C) AndLNode(t, phase->longcon(0xFFFFFFFF))); hook->init_req(3, w1); // w2 = t >> 32; ! Node* w2 = phase->transform(new (phase->C) RShiftLNode(t, phase->intcon(N / 2))); // w1 = u0*v1 + w1; ! Node* u0v1 = phase->transform(new (phase->C) MulLNode(u0, v1)); ! w1 = phase->transform(new (phase->C) AddLNode(u0v1, w1)); // return u1*v1 + w2 + (w1 >> 32); ! Node* u1v1 = phase->transform(new (phase->C) MulLNode(u1, v1)); ! Node* temp1 = phase->transform(new (phase->C) AddLNode(u1v1, w2)); ! Node* temp2 = phase->transform(new (phase->C) RShiftLNode(w1, phase->intcon(N / 2))); // Remove the bogus extra edges used to keep things alive PhaseIterGVN* igvn = phase->is_IterGVN(); if (igvn != NULL) { igvn->remove_dead_node(hook); --- 285,330 ---- // following inline comments are adapted to 64x64. const int N = 64; // Dummy node to keep intermediate nodes alive during construction ! Node* hook = new Node(4); // u0 = u & 0xFFFFFFFF; u1 = u >> 32; ! Node* u0 = phase->transform(new AndLNode(dividend, phase->longcon(0xFFFFFFFF))); ! Node* u1 = phase->transform(new RShiftLNode(dividend, phase->intcon(N / 2))); hook->init_req(0, u0); hook->init_req(1, u1); // v0 = v & 0xFFFFFFFF; v1 = v >> 32; Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF); Node* v1 = phase->longcon(magic_const >> (N / 2)); // w0 = u0*v0; ! Node* w0 = phase->transform(new MulLNode(u0, v0)); // t = u1*v0 + (w0 >> 32); ! Node* u1v0 = phase->transform(new MulLNode(u1, v0)); ! Node* temp = phase->transform(new URShiftLNode(w0, phase->intcon(N / 2))); ! Node* t = phase->transform(new AddLNode(u1v0, temp)); hook->init_req(2, t); // w1 = t & 0xFFFFFFFF; ! Node* w1 = phase->transform(new AndLNode(t, phase->longcon(0xFFFFFFFF))); hook->init_req(3, w1); // w2 = t >> 32; ! Node* w2 = phase->transform(new RShiftLNode(t, phase->intcon(N / 2))); // w1 = u0*v1 + w1; ! Node* u0v1 = phase->transform(new MulLNode(u0, v1)); ! w1 = phase->transform(new AddLNode(u0v1, w1)); // return u1*v1 + w2 + (w1 >> 32); ! Node* u1v1 = phase->transform(new MulLNode(u1, v1)); ! Node* temp1 = phase->transform(new AddLNode(u1v1, w2)); ! Node* temp2 = phase->transform(new RShiftLNode(w1, phase->intcon(N / 2))); // Remove the bogus extra edges used to keep things alive PhaseIterGVN* igvn = phase->is_IterGVN(); if (igvn != NULL) { igvn->remove_dead_node(hook);
*** 332,342 **** for (int i = 0; i < 4; i++) { hook->set_req(i, NULL); } } ! return new (phase->C) AddLNode(temp1, temp2); } //--------------------------transform_long_divide------------------------------ // Convert a division by constant divisor into an alternate Ideal graph. --- 332,342 ---- for (int i = 0; i < 4; i++) { hook->set_req(i, NULL); } } ! return new AddLNode(temp1, temp2); } //--------------------------transform_long_divide------------------------------ // Convert a division by constant divisor into an alternate Ideal graph.
*** 355,365 **** if (d == 1) { // division by +/- 1 if (!d_pos) { // Just negate the value ! q = new (phase->C) SubLNode(phase->longcon(0), dividend); } } else if ( is_power_of_2_long(d) ) { // division by +/- a power of 2 --- 355,365 ---- if (d == 1) { // division by +/- 1 if (!d_pos) { // Just negate the value ! q = new SubLNode(phase->longcon(0), dividend); } } else if ( is_power_of_2_long(d) ) { // division by +/- a power of 2
*** 394,415 **** // shift is by 2. You need to add 3 to negative dividends and 0 to // positive ones. So (-7+3)>>2 becomes -1, (-4+3)>>2 becomes -1, // (-2+3)>>2 becomes 0, etc. // Compute 0 or -1, based on sign bit ! Node *sign = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N - 1))); // Mask sign bit to the low sign bits ! Node *round = phase->transform(new (phase->C) URShiftLNode(sign, phase->intcon(N - l))); // Round up before shifting ! dividend = phase->transform(new (phase->C) AddLNode(dividend, round)); } // Shift for division ! q = new (phase->C) RShiftLNode(dividend, phase->intcon(l)); if (!d_pos) { ! q = new (phase->C) SubLNode(phase->longcon(0), phase->transform(q)); } } else if ( !Matcher::use_asm_for_ldiv_by_con(d) ) { // Use hardware DIV instruction when // it is faster than code generated below. // Attempt the jlong constant divide -> multiply transform found in // "Division by Invariant Integers using Multiplication" --- 394,415 ---- // shift is by 2. You need to add 3 to negative dividends and 0 to // positive ones. So (-7+3)>>2 becomes -1, (-4+3)>>2 becomes -1, // (-2+3)>>2 becomes 0, etc. // Compute 0 or -1, based on sign bit ! Node *sign = phase->transform(new RShiftLNode(dividend, phase->intcon(N - 1))); // Mask sign bit to the low sign bits ! Node *round = phase->transform(new URShiftLNode(sign, phase->intcon(N - l))); // Round up before shifting ! dividend = phase->transform(new AddLNode(dividend, round)); } // Shift for division ! q = new RShiftLNode(dividend, phase->intcon(l)); if (!d_pos) { ! q = new SubLNode(phase->longcon(0), phase->transform(q)); } } else if ( !Matcher::use_asm_for_ldiv_by_con(d) ) { // Use hardware DIV instruction when // it is faster than code generated below. // Attempt the jlong constant divide -> multiply transform found in // "Division by Invariant Integers using Multiplication"
*** 425,455 **** // The high half of the 128-bit multiply is computed. if (magic_const < 0) { // The magic multiplier is too large for a 64 bit constant. We've adjusted // it down by 2^64, but have to add 1 dividend back in after the multiplication. // This handles the "overflow" case described by Granlund and Montgomery. ! mul_hi = phase->transform(new (phase->C) AddLNode(dividend, mul_hi)); } // Shift over the (adjusted) mulhi if (shift_const != 0) { ! mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(shift_const))); } // Get a 0 or -1 from the sign of the dividend. Node *addend0 = mul_hi; ! Node *addend1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N-1))); // If the divisor is negative, swap the order of the input addends; // this has the effect of negating the quotient. if (!d_pos) { Node *temp = addend0; addend0 = addend1; addend1 = temp; } // Adjust the final quotient by subtracting -1 (adding 1) // from the mul_hi. ! q = new (phase->C) SubLNode(addend0, addend1); } } return q; } --- 425,455 ---- // The high half of the 128-bit multiply is computed. if (magic_const < 0) { // The magic multiplier is too large for a 64 bit constant. We've adjusted // it down by 2^64, but have to add 1 dividend back in after the multiplication. // This handles the "overflow" case described by Granlund and Montgomery. ! mul_hi = phase->transform(new AddLNode(dividend, mul_hi)); } // Shift over the (adjusted) mulhi if (shift_const != 0) { ! mul_hi = phase->transform(new RShiftLNode(mul_hi, phase->intcon(shift_const))); } // Get a 0 or -1 from the sign of the dividend. Node *addend0 = mul_hi; ! Node *addend1 = phase->transform(new RShiftLNode(dividend, phase->intcon(N-1))); // If the divisor is negative, swap the order of the input addends; // this has the effect of negating the quotient. if (!d_pos) { Node *temp = addend0; addend0 = addend1; addend1 = temp; } // Adjust the final quotient by subtracting -1 (adding 1) // from the mul_hi. ! q = new SubLNode(addend0, addend1); } } return q; }
*** 735,745 **** float reciprocal = ((float)1.0) / f; assert( frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); // return multiplication by the reciprocal ! return (new (phase->C) MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); } //============================================================================= //------------------------------Value------------------------------------------ // An DivDNode divides its inputs. The third input is a Control input, used to --- 735,745 ---- float reciprocal = ((float)1.0) / f; assert( frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); // return multiplication by the reciprocal ! return (new MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); } //============================================================================= //------------------------------Value------------------------------------------ // An DivDNode divides its inputs. The third input is a Control input, used to
*** 829,839 **** double reciprocal = 1.0 / d; assert( frexp(reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); // return multiplication by the reciprocal ! return (new (phase->C) MulDNode(in(1), phase->makecon(TypeD::make(reciprocal)))); } //============================================================================= //------------------------------Idealize--------------------------------------- Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) { --- 829,839 ---- double reciprocal = 1.0 / d; assert( frexp(reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); // return multiplication by the reciprocal ! return (new MulDNode(in(1), phase->makecon(TypeD::make(reciprocal)))); } //============================================================================= //------------------------------Idealize--------------------------------------- Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) {
*** 856,866 **** // See if we are MOD'ing by 2^k or 2^k-1. if( !ti->is_con() ) return NULL; jint con = ti->get_con(); ! Node *hook = new (phase->C) Node(1); // First, special check for modulo 2^k-1 if( con >= 0 && con < max_jint && is_power_of_2(con+1) ) { uint k = exact_log2(con+1); // Extract k --- 856,866 ---- // See if we are MOD'ing by 2^k or 2^k-1. if( !ti->is_con() ) return NULL; jint con = ti->get_con(); ! Node *hook = new Node(1); // First, special check for modulo 2^k-1 if( con >= 0 && con < max_jint && is_power_of_2(con+1) ) { uint k = exact_log2(con+1); // Extract k
*** 876,903 **** Node *divisor = in(2); // Also is mask hook->init_req(0, x); // Add a use to x to prevent him from dying // Generate code to reduce X rapidly to nearly 2^k-1. for( int i = 0; i < trip_count; i++ ) { ! Node *xl = phase->transform( new (phase->C) AndINode(x,divisor) ); ! Node *xh = phase->transform( new (phase->C) RShiftINode(x,phase->intcon(k)) ); // Must be signed ! x = phase->transform( new (phase->C) AddINode(xh,xl) ); hook->set_req(0, x); } // Generate sign-fixup code. Was original value positive? // int hack_res = (i >= 0) ? divisor : 1; ! Node *cmp1 = phase->transform( new (phase->C) CmpINode( in(1), phase->intcon(0) ) ); ! Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) ); ! Node *cmov1= phase->transform( new (phase->C) CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) ); // if( x >= hack_res ) x -= divisor; ! Node *sub = phase->transform( new (phase->C) SubINode( x, divisor ) ); ! Node *cmp2 = phase->transform( new (phase->C) CmpINode( x, cmov1 ) ); ! Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) ); // Convention is to not transform the return value of an Ideal // since Ideal is expected to return a modified 'this' or a new node. ! Node *cmov2= new (phase->C) CMoveINode(bol2, x, sub, TypeInt::INT); // cmov2 is now the mod // Now remove the bogus extra edges used to keep things alive if (can_reshape) { phase->is_IterGVN()->remove_dead_node(hook); --- 876,903 ---- Node *divisor = in(2); // Also is mask hook->init_req(0, x); // Add a use to x to prevent him from dying // Generate code to reduce X rapidly to nearly 2^k-1. for( int i = 0; i < trip_count; i++ ) { ! Node *xl = phase->transform( new AndINode(x,divisor) ); ! Node *xh = phase->transform( new RShiftINode(x,phase->intcon(k)) ); // Must be signed ! x = phase->transform( new AddINode(xh,xl) ); hook->set_req(0, x); } // Generate sign-fixup code. Was original value positive? // int hack_res = (i >= 0) ? divisor : 1; ! Node *cmp1 = phase->transform( new CmpINode( in(1), phase->intcon(0) ) ); ! Node *bol1 = phase->transform( new BoolNode( cmp1, BoolTest::ge ) ); ! Node *cmov1= phase->transform( new CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) ); // if( x >= hack_res ) x -= divisor; ! Node *sub = phase->transform( new SubINode( x, divisor ) ); ! Node *cmp2 = phase->transform( new CmpINode( x, cmov1 ) ); ! Node *bol2 = phase->transform( new BoolNode( cmp2, BoolTest::ge ) ); // Convention is to not transform the return value of an Ideal // since Ideal is expected to return a modified 'this' or a new node. ! Node *cmov2= new CMoveINode(bol2, x, sub, TypeInt::INT); // cmov2 is now the mod // Now remove the bogus extra edges used to keep things alive if (can_reshape) { phase->is_IterGVN()->remove_dead_node(hook);
*** 916,926 **** // Get the absolute value of the constant; at this point, we can use this jint pos_con = (con >= 0) ? con : -con; // integer Mod 1 is always 0 ! if( pos_con == 1 ) return new (phase->C) ConINode(TypeInt::ZERO); int log2_con = -1; // If this is a power of two, they maybe we can mask it if( is_power_of_2(pos_con) ) { --- 916,926 ---- // Get the absolute value of the constant; at this point, we can use this jint pos_con = (con >= 0) ? con : -con; // integer Mod 1 is always 0 ! if( pos_con == 1 ) return new ConINode(TypeInt::ZERO); int log2_con = -1; // If this is a power of two, they maybe we can mask it if( is_power_of_2(pos_con) ) {
*** 929,939 **** const Type *dt = phase->type(in(1)); const TypeInt *dti = dt->isa_int(); // See if this can be masked, if the dividend is non-negative if( dti && dti->_lo >= 0 ) ! return ( new (phase->C) AndINode( in(1), phase->intcon( pos_con-1 ) ) ); } // Save in(1) so that it cannot be changed or deleted hook->init_req(0, in(1)); --- 929,939 ---- const Type *dt = phase->type(in(1)); const TypeInt *dti = dt->isa_int(); // See if this can be masked, if the dividend is non-negative if( dti && dti->_lo >= 0 ) ! return ( new AndINode( in(1), phase->intcon( pos_con-1 ) ) ); } // Save in(1) so that it cannot be changed or deleted hook->init_req(0, in(1));
*** 944,959 **** // Re-multiply, using a shift if this is a power of two Node *mult = NULL; if( log2_con >= 0 ) ! mult = phase->transform( new (phase->C) LShiftINode( divide, phase->intcon( log2_con ) ) ); else ! mult = phase->transform( new (phase->C) MulINode( divide, phase->intcon( pos_con ) ) ); // Finally, subtract the multiplied divided value from the original ! result = new (phase->C) SubINode( in(1), mult ); } // Now remove the bogus extra edges used to keep things alive if (can_reshape) { phase->is_IterGVN()->remove_dead_node(hook); --- 944,959 ---- // Re-multiply, using a shift if this is a power of two Node *mult = NULL; if( log2_con >= 0 ) ! mult = phase->transform( new LShiftINode( divide, phase->intcon( log2_con ) ) ); else ! mult = phase->transform( new MulINode( divide, phase->intcon( pos_con ) ) ); // Finally, subtract the multiplied divided value from the original ! result = new SubINode( in(1), mult ); } // Now remove the bogus extra edges used to keep things alive if (can_reshape) { phase->is_IterGVN()->remove_dead_node(hook);
*** 1027,1037 **** // See if we are MOD'ing by 2^k or 2^k-1. if( !tl->is_con() ) return NULL; jlong con = tl->get_con(); ! Node *hook = new (phase->C) Node(1); // Expand mod if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { uint k = exact_log2_long(con+1); // Extract k --- 1027,1037 ---- // See if we are MOD'ing by 2^k or 2^k-1. if( !tl->is_con() ) return NULL; jlong con = tl->get_con(); ! Node *hook = new Node(1); // Expand mod if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { uint k = exact_log2_long(con+1); // Extract k
*** 1049,1076 **** Node *divisor = in(2); // Also is mask hook->init_req(0, x); // Add a use to x to prevent him from dying // Generate code to reduce X rapidly to nearly 2^k-1. for( int i = 0; i < trip_count; i++ ) { ! Node *xl = phase->transform( new (phase->C) AndLNode(x,divisor) ); ! Node *xh = phase->transform( new (phase->C) RShiftLNode(x,phase->intcon(k)) ); // Must be signed ! x = phase->transform( new (phase->C) AddLNode(xh,xl) ); hook->set_req(0, x); // Add a use to x to prevent him from dying } // Generate sign-fixup code. Was original value positive? // long hack_res = (i >= 0) ? divisor : CONST64(1); ! Node *cmp1 = phase->transform( new (phase->C) CmpLNode( in(1), phase->longcon(0) ) ); ! Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) ); ! Node *cmov1= phase->transform( new (phase->C) CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) ); // if( x >= hack_res ) x -= divisor; ! Node *sub = phase->transform( new (phase->C) SubLNode( x, divisor ) ); ! Node *cmp2 = phase->transform( new (phase->C) CmpLNode( x, cmov1 ) ); ! Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) ); // Convention is to not transform the return value of an Ideal // since Ideal is expected to return a modified 'this' or a new node. ! Node *cmov2= new (phase->C) CMoveLNode(bol2, x, sub, TypeLong::LONG); // cmov2 is now the mod // Now remove the bogus extra edges used to keep things alive if (can_reshape) { phase->is_IterGVN()->remove_dead_node(hook); --- 1049,1076 ---- Node *divisor = in(2); // Also is mask hook->init_req(0, x); // Add a use to x to prevent him from dying // Generate code to reduce X rapidly to nearly 2^k-1. for( int i = 0; i < trip_count; i++ ) { ! Node *xl = phase->transform( new AndLNode(x,divisor) ); ! Node *xh = phase->transform( new RShiftLNode(x,phase->intcon(k)) ); // Must be signed ! x = phase->transform( new AddLNode(xh,xl) ); hook->set_req(0, x); // Add a use to x to prevent him from dying } // Generate sign-fixup code. Was original value positive? // long hack_res = (i >= 0) ? divisor : CONST64(1); ! Node *cmp1 = phase->transform( new CmpLNode( in(1), phase->longcon(0) ) ); ! Node *bol1 = phase->transform( new BoolNode( cmp1, BoolTest::ge ) ); ! Node *cmov1= phase->transform( new CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) ); // if( x >= hack_res ) x -= divisor; ! Node *sub = phase->transform( new SubLNode( x, divisor ) ); ! Node *cmp2 = phase->transform( new CmpLNode( x, cmov1 ) ); ! Node *bol2 = phase->transform( new BoolNode( cmp2, BoolTest::ge ) ); // Convention is to not transform the return value of an Ideal // since Ideal is expected to return a modified 'this' or a new node. ! Node *cmov2= new CMoveLNode(bol2, x, sub, TypeLong::LONG); // cmov2 is now the mod // Now remove the bogus extra edges used to keep things alive if (can_reshape) { phase->is_IterGVN()->remove_dead_node(hook);
*** 1089,1099 **** // Get the absolute value of the constant; at this point, we can use this jlong pos_con = (con >= 0) ? con : -con; // integer Mod 1 is always 0 ! if( pos_con == 1 ) return new (phase->C) ConLNode(TypeLong::ZERO); int log2_con = -1; // If this is a power of two, then maybe we can mask it if( is_power_of_2_long(pos_con) ) { --- 1089,1099 ---- // Get the absolute value of the constant; at this point, we can use this jlong pos_con = (con >= 0) ? con : -con; // integer Mod 1 is always 0 ! if( pos_con == 1 ) return new ConLNode(TypeLong::ZERO); int log2_con = -1; // If this is a power of two, then maybe we can mask it if( is_power_of_2_long(pos_con) ) {
*** 1102,1112 **** const Type *dt = phase->type(in(1)); const TypeLong *dtl = dt->isa_long(); // See if this can be masked, if the dividend is non-negative if( dtl && dtl->_lo >= 0 ) ! return ( new (phase->C) AndLNode( in(1), phase->longcon( pos_con-1 ) ) ); } // Save in(1) so that it cannot be changed or deleted hook->init_req(0, in(1)); --- 1102,1112 ---- const Type *dt = phase->type(in(1)); const TypeLong *dtl = dt->isa_long(); // See if this can be masked, if the dividend is non-negative if( dtl && dtl->_lo >= 0 ) ! return ( new AndLNode( in(1), phase->longcon( pos_con-1 ) ) ); } // Save in(1) so that it cannot be changed or deleted hook->init_req(0, in(1));
*** 1117,1132 **** // Re-multiply, using a shift if this is a power of two Node *mult = NULL; if( log2_con >= 0 ) ! mult = phase->transform( new (phase->C) LShiftLNode( divide, phase->intcon( log2_con ) ) ); else ! mult = phase->transform( new (phase->C) MulLNode( divide, phase->longcon( pos_con ) ) ); // Finally, subtract the multiplied divided value from the original ! result = new (phase->C) SubLNode( in(1), mult ); } // Now remove the bogus extra edges used to keep things alive if (can_reshape) { phase->is_IterGVN()->remove_dead_node(hook); --- 1117,1132 ---- // Re-multiply, using a shift if this is a power of two Node *mult = NULL; if( log2_con >= 0 ) ! mult = phase->transform( new LShiftLNode( divide, phase->intcon( log2_con ) ) ); else ! mult = phase->transform( new MulLNode( divide, phase->longcon( pos_con ) ) ); // Finally, subtract the multiplied divided value from the original ! result = new SubLNode( in(1), mult ); } // Now remove the bogus extra edges used to keep things alive if (can_reshape) { phase->is_IterGVN()->remove_dead_node(hook);
*** 1277,1301 **** DivModINode* DivModINode::make(Compile* C, Node* div_or_mod) { Node* n = div_or_mod; assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI, "only div or mod input pattern accepted"); ! DivModINode* divmod = new (C) DivModINode(n->in(0), n->in(1), n->in(2)); ! Node* dproj = new (C) ProjNode(divmod, DivModNode::div_proj_num); ! Node* mproj = new (C) ProjNode(divmod, DivModNode::mod_proj_num); return divmod; } //------------------------------make------------------------------------------ DivModLNode* DivModLNode::make(Compile* C, Node* div_or_mod) { Node* n = div_or_mod; assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL, "only div or mod input pattern accepted"); ! DivModLNode* divmod = new (C) DivModLNode(n->in(0), n->in(1), n->in(2)); ! Node* dproj = new (C) ProjNode(divmod, DivModNode::div_proj_num); ! Node* mproj = new (C) ProjNode(divmod, DivModNode::mod_proj_num); return divmod; } //------------------------------match------------------------------------------ // return result(s) along with their RegMask info --- 1277,1301 ---- DivModINode* DivModINode::make(Compile* C, Node* div_or_mod) { Node* n = div_or_mod; assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI, "only div or mod input pattern accepted"); ! DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2)); ! Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num); ! Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num); return divmod; } //------------------------------make------------------------------------------ DivModLNode* DivModLNode::make(Compile* C, Node* div_or_mod) { Node* n = div_or_mod; assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL, "only div or mod input pattern accepted"); ! DivModLNode* divmod = new DivModLNode(n->in(0), n->in(1), n->in(2)); ! Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num); ! Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num); return divmod; } //------------------------------match------------------------------------------ // return result(s) along with their RegMask info
*** 1306,1316 **** rm = match->divI_proj_mask(); } else { assert(proj->_con == mod_proj_num, "must be div or mod projection"); rm = match->modI_proj_mask(); } ! return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg); } //------------------------------match------------------------------------------ // return result(s) along with their RegMask info --- 1306,1316 ---- rm = match->divI_proj_mask(); } else { assert(proj->_con == mod_proj_num, "must be div or mod projection"); rm = match->modI_proj_mask(); } ! return new MachProjNode(this, proj->_con, rm, ideal_reg); } //------------------------------match------------------------------------------ // return result(s) along with their RegMask info
*** 1321,1327 **** rm = match->divL_proj_mask(); } else { assert(proj->_con == mod_proj_num, "must be div or mod projection"); rm = match->modL_proj_mask(); } ! return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg); } --- 1321,1327 ---- rm = match->divL_proj_mask(); } else { assert(proj->_con == mod_proj_num, "must be div or mod projection"); rm = match->modL_proj_mask(); } ! return new MachProjNode(this, proj->_con, rm, ideal_reg); }
src/share/vm/opto/divnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File