Mercurial > hg > graal-compiler
comparison src/share/vm/opto/divnode.cpp @ 6948:e522a00b91aa
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Nov 2012 23:14:12 +0100 |
parents | b9a9ed0f8eeb |
children |
comparison
equal
deleted
inserted
replaced
6711:ae13cc658b80 | 6948:e522a00b91aa |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
102 | 102 |
103 if (d == 1) { | 103 if (d == 1) { |
104 // division by +/- 1 | 104 // division by +/- 1 |
105 if (!d_pos) { | 105 if (!d_pos) { |
106 // Just negate the value | 106 // Just negate the value |
107 q = new (phase->C, 3) SubINode(phase->intcon(0), dividend); | 107 q = new (phase->C) SubINode(phase->intcon(0), dividend); |
108 } | 108 } |
109 } else if ( is_power_of_2(d) ) { | 109 } else if ( is_power_of_2(d) ) { |
110 // division by +/- a power of 2 | 110 // division by +/- a power of 2 |
111 | 111 |
112 // See if we can simply do a shift without rounding | 112 // See if we can simply do a shift without rounding |
139 // shift is by 2. You need to add 3 to negative dividends and 0 to | 139 // shift is by 2. You need to add 3 to negative dividends and 0 to |
140 // positive ones. So (-7+3)>>2 becomes -1, (-4+3)>>2 becomes -1, | 140 // positive ones. So (-7+3)>>2 becomes -1, (-4+3)>>2 becomes -1, |
141 // (-2+3)>>2 becomes 0, etc. | 141 // (-2+3)>>2 becomes 0, etc. |
142 | 142 |
143 // Compute 0 or -1, based on sign bit | 143 // Compute 0 or -1, based on sign bit |
144 Node *sign = phase->transform(new (phase->C, 3) RShiftINode(dividend, phase->intcon(N - 1))); | 144 Node *sign = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N - 1))); |
145 // Mask sign bit to the low sign bits | 145 // Mask sign bit to the low sign bits |
146 Node *round = phase->transform(new (phase->C, 3) URShiftINode(sign, phase->intcon(N - l))); | 146 Node *round = phase->transform(new (phase->C) URShiftINode(sign, phase->intcon(N - l))); |
147 // Round up before shifting | 147 // Round up before shifting |
148 dividend = phase->transform(new (phase->C, 3) AddINode(dividend, round)); | 148 dividend = phase->transform(new (phase->C) AddINode(dividend, round)); |
149 } | 149 } |
150 | 150 |
151 // Shift for division | 151 // Shift for division |
152 q = new (phase->C, 3) RShiftINode(dividend, phase->intcon(l)); | 152 q = new (phase->C) RShiftINode(dividend, phase->intcon(l)); |
153 | 153 |
154 if (!d_pos) { | 154 if (!d_pos) { |
155 q = new (phase->C, 3) SubINode(phase->intcon(0), phase->transform(q)); | 155 q = new (phase->C) SubINode(phase->intcon(0), phase->transform(q)); |
156 } | 156 } |
157 } else { | 157 } else { |
158 // Attempt the jint constant divide -> multiply transform found in | 158 // Attempt the jint constant divide -> multiply transform found in |
159 // "Division by Invariant Integers using Multiplication" | 159 // "Division by Invariant Integers using Multiplication" |
160 // by Granlund and Montgomery | 160 // by Granlund and Montgomery |
162 | 162 |
163 jint magic_const; | 163 jint magic_const; |
164 jint shift_const; | 164 jint shift_const; |
165 if (magic_int_divide_constants(d, magic_const, shift_const)) { | 165 if (magic_int_divide_constants(d, magic_const, shift_const)) { |
166 Node *magic = phase->longcon(magic_const); | 166 Node *magic = phase->longcon(magic_const); |
167 Node *dividend_long = phase->transform(new (phase->C, 2) ConvI2LNode(dividend)); | 167 Node *dividend_long = phase->transform(new (phase->C) ConvI2LNode(dividend)); |
168 | 168 |
169 // Compute the high half of the dividend x magic multiplication | 169 // Compute the high half of the dividend x magic multiplication |
170 Node *mul_hi = phase->transform(new (phase->C, 3) MulLNode(dividend_long, magic)); | 170 Node *mul_hi = phase->transform(new (phase->C) MulLNode(dividend_long, magic)); |
171 | 171 |
172 if (magic_const < 0) { | 172 if (magic_const < 0) { |
173 mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(N))); | 173 mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N))); |
174 mul_hi = phase->transform(new (phase->C, 2) ConvL2INode(mul_hi)); | 174 mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi)); |
175 | 175 |
176 // The magic multiplier is too large for a 32 bit constant. We've adjusted | 176 // The magic multiplier is too large for a 32 bit constant. We've adjusted |
177 // it down by 2^32, but have to add 1 dividend back in after the multiplication. | 177 // it down by 2^32, but have to add 1 dividend back in after the multiplication. |
178 // This handles the "overflow" case described by Granlund and Montgomery. | 178 // This handles the "overflow" case described by Granlund and Montgomery. |
179 mul_hi = phase->transform(new (phase->C, 3) AddINode(dividend, mul_hi)); | 179 mul_hi = phase->transform(new (phase->C) AddINode(dividend, mul_hi)); |
180 | 180 |
181 // Shift over the (adjusted) mulhi | 181 // Shift over the (adjusted) mulhi |
182 if (shift_const != 0) { | 182 if (shift_const != 0) { |
183 mul_hi = phase->transform(new (phase->C, 3) RShiftINode(mul_hi, phase->intcon(shift_const))); | 183 mul_hi = phase->transform(new (phase->C) RShiftINode(mul_hi, phase->intcon(shift_const))); |
184 } | 184 } |
185 } else { | 185 } else { |
186 // No add is required, we can merge the shifts together. | 186 // No add is required, we can merge the shifts together. |
187 mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(N + shift_const))); | 187 mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N + shift_const))); |
188 mul_hi = phase->transform(new (phase->C, 2) ConvL2INode(mul_hi)); | 188 mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi)); |
189 } | 189 } |
190 | 190 |
191 // Get a 0 or -1 from the sign of the dividend. | 191 // Get a 0 or -1 from the sign of the dividend. |
192 Node *addend0 = mul_hi; | 192 Node *addend0 = mul_hi; |
193 Node *addend1 = phase->transform(new (phase->C, 3) RShiftINode(dividend, phase->intcon(N-1))); | 193 Node *addend1 = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N-1))); |
194 | 194 |
195 // If the divisor is negative, swap the order of the input addends; | 195 // If the divisor is negative, swap the order of the input addends; |
196 // this has the effect of negating the quotient. | 196 // this has the effect of negating the quotient. |
197 if (!d_pos) { | 197 if (!d_pos) { |
198 Node *temp = addend0; addend0 = addend1; addend1 = temp; | 198 Node *temp = addend0; addend0 = addend1; addend1 = temp; |
199 } | 199 } |
200 | 200 |
201 // Adjust the final quotient by subtracting -1 (adding 1) | 201 // Adjust the final quotient by subtracting -1 (adding 1) |
202 // from the mul_hi. | 202 // from the mul_hi. |
203 q = new (phase->C, 3) SubINode(addend0, addend1); | 203 q = new (phase->C) SubINode(addend0, addend1); |
204 } | 204 } |
205 } | 205 } |
206 | 206 |
207 return q; | 207 return q; |
208 } | 208 } |
257 static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) { | 257 static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) { |
258 // If the architecture supports a 64x64 mulhi, there is | 258 // If the architecture supports a 64x64 mulhi, there is |
259 // no need to synthesize it in ideal nodes. | 259 // no need to synthesize it in ideal nodes. |
260 if (Matcher::has_match_rule(Op_MulHiL)) { | 260 if (Matcher::has_match_rule(Op_MulHiL)) { |
261 Node* v = phase->longcon(magic_const); | 261 Node* v = phase->longcon(magic_const); |
262 return new (phase->C, 3) MulHiLNode(dividend, v); | 262 return new (phase->C) MulHiLNode(dividend, v); |
263 } | 263 } |
264 | 264 |
265 // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. | 265 // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. |
266 // (http://www.hackersdelight.org/HDcode/mulhs.c) | 266 // (http://www.hackersdelight.org/HDcode/mulhs.c) |
267 // | 267 // |
283 // following inline comments are adapted to 64x64. | 283 // following inline comments are adapted to 64x64. |
284 | 284 |
285 const int N = 64; | 285 const int N = 64; |
286 | 286 |
287 // Dummy node to keep intermediate nodes alive during construction | 287 // Dummy node to keep intermediate nodes alive during construction |
288 Node* hook = new (phase->C, 4) Node(4); | 288 Node* hook = new (phase->C) Node(4); |
289 | 289 |
290 // u0 = u & 0xFFFFFFFF; u1 = u >> 32; | 290 // u0 = u & 0xFFFFFFFF; u1 = u >> 32; |
291 Node* u0 = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); | 291 Node* u0 = phase->transform(new (phase->C) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); |
292 Node* u1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2))); | 292 Node* u1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N / 2))); |
293 hook->init_req(0, u0); | 293 hook->init_req(0, u0); |
294 hook->init_req(1, u1); | 294 hook->init_req(1, u1); |
295 | 295 |
296 // v0 = v & 0xFFFFFFFF; v1 = v >> 32; | 296 // v0 = v & 0xFFFFFFFF; v1 = v >> 32; |
297 Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF); | 297 Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF); |
298 Node* v1 = phase->longcon(magic_const >> (N / 2)); | 298 Node* v1 = phase->longcon(magic_const >> (N / 2)); |
299 | 299 |
300 // w0 = u0*v0; | 300 // w0 = u0*v0; |
301 Node* w0 = phase->transform(new (phase->C, 3) MulLNode(u0, v0)); | 301 Node* w0 = phase->transform(new (phase->C) MulLNode(u0, v0)); |
302 | 302 |
303 // t = u1*v0 + (w0 >> 32); | 303 // t = u1*v0 + (w0 >> 32); |
304 Node* u1v0 = phase->transform(new (phase->C, 3) MulLNode(u1, v0)); | 304 Node* u1v0 = phase->transform(new (phase->C) MulLNode(u1, v0)); |
305 Node* temp = phase->transform(new (phase->C, 3) URShiftLNode(w0, phase->intcon(N / 2))); | 305 Node* temp = phase->transform(new (phase->C) URShiftLNode(w0, phase->intcon(N / 2))); |
306 Node* t = phase->transform(new (phase->C, 3) AddLNode(u1v0, temp)); | 306 Node* t = phase->transform(new (phase->C) AddLNode(u1v0, temp)); |
307 hook->init_req(2, t); | 307 hook->init_req(2, t); |
308 | 308 |
309 // w1 = t & 0xFFFFFFFF; | 309 // w1 = t & 0xFFFFFFFF; |
310 Node* w1 = phase->transform(new (phase->C, 3) AndLNode(t, phase->longcon(0xFFFFFFFF))); | 310 Node* w1 = phase->transform(new (phase->C) AndLNode(t, phase->longcon(0xFFFFFFFF))); |
311 hook->init_req(3, w1); | 311 hook->init_req(3, w1); |
312 | 312 |
313 // w2 = t >> 32; | 313 // w2 = t >> 32; |
314 Node* w2 = phase->transform(new (phase->C, 3) RShiftLNode(t, phase->intcon(N / 2))); | 314 Node* w2 = phase->transform(new (phase->C) RShiftLNode(t, phase->intcon(N / 2))); |
315 | 315 |
316 // w1 = u0*v1 + w1; | 316 // w1 = u0*v1 + w1; |
317 Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1)); | 317 Node* u0v1 = phase->transform(new (phase->C) MulLNode(u0, v1)); |
318 w1 = phase->transform(new (phase->C, 3) AddLNode(u0v1, w1)); | 318 w1 = phase->transform(new (phase->C) AddLNode(u0v1, w1)); |
319 | 319 |
320 // return u1*v1 + w2 + (w1 >> 32); | 320 // return u1*v1 + w2 + (w1 >> 32); |
321 Node* u1v1 = phase->transform(new (phase->C, 3) MulLNode(u1, v1)); | 321 Node* u1v1 = phase->transform(new (phase->C) MulLNode(u1, v1)); |
322 Node* temp1 = phase->transform(new (phase->C, 3) AddLNode(u1v1, w2)); | 322 Node* temp1 = phase->transform(new (phase->C) AddLNode(u1v1, w2)); |
323 Node* temp2 = phase->transform(new (phase->C, 3) RShiftLNode(w1, phase->intcon(N / 2))); | 323 Node* temp2 = phase->transform(new (phase->C) RShiftLNode(w1, phase->intcon(N / 2))); |
324 | 324 |
325 // Remove the bogus extra edges used to keep things alive | 325 // Remove the bogus extra edges used to keep things alive |
326 PhaseIterGVN* igvn = phase->is_IterGVN(); | 326 PhaseIterGVN* igvn = phase->is_IterGVN(); |
327 if (igvn != NULL) { | 327 if (igvn != NULL) { |
328 igvn->remove_dead_node(hook); | 328 igvn->remove_dead_node(hook); |
330 for (int i = 0; i < 4; i++) { | 330 for (int i = 0; i < 4; i++) { |
331 hook->set_req(i, NULL); | 331 hook->set_req(i, NULL); |
332 } | 332 } |
333 } | 333 } |
334 | 334 |
335 return new (phase->C, 3) AddLNode(temp1, temp2); | 335 return new (phase->C) AddLNode(temp1, temp2); |
336 } | 336 } |
337 | 337 |
338 | 338 |
339 //--------------------------transform_long_divide------------------------------ | 339 //--------------------------transform_long_divide------------------------------ |
340 // Convert a division by constant divisor into an alternate Ideal graph. | 340 // Convert a division by constant divisor into an alternate Ideal graph. |
353 | 353 |
354 if (d == 1) { | 354 if (d == 1) { |
355 // division by +/- 1 | 355 // division by +/- 1 |
356 if (!d_pos) { | 356 if (!d_pos) { |
357 // Just negate the value | 357 // Just negate the value |
358 q = new (phase->C, 3) SubLNode(phase->longcon(0), dividend); | 358 q = new (phase->C) SubLNode(phase->longcon(0), dividend); |
359 } | 359 } |
360 } else if ( is_power_of_2_long(d) ) { | 360 } else if ( is_power_of_2_long(d) ) { |
361 | 361 |
362 // division by +/- a power of 2 | 362 // division by +/- a power of 2 |
363 | 363 |
392 // shift is by 2. You need to add 3 to negative dividends and 0 to | 392 // shift is by 2. You need to add 3 to negative dividends and 0 to |
393 // positive ones. So (-7+3)>>2 becomes -1, (-4+3)>>2 becomes -1, | 393 // positive ones. So (-7+3)>>2 becomes -1, (-4+3)>>2 becomes -1, |
394 // (-2+3)>>2 becomes 0, etc. | 394 // (-2+3)>>2 becomes 0, etc. |
395 | 395 |
396 // Compute 0 or -1, based on sign bit | 396 // Compute 0 or -1, based on sign bit |
397 Node *sign = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N - 1))); | 397 Node *sign = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N - 1))); |
398 // Mask sign bit to the low sign bits | 398 // Mask sign bit to the low sign bits |
399 Node *round = phase->transform(new (phase->C, 3) URShiftLNode(sign, phase->intcon(N - l))); | 399 Node *round = phase->transform(new (phase->C) URShiftLNode(sign, phase->intcon(N - l))); |
400 // Round up before shifting | 400 // Round up before shifting |
401 dividend = phase->transform(new (phase->C, 3) AddLNode(dividend, round)); | 401 dividend = phase->transform(new (phase->C) AddLNode(dividend, round)); |
402 } | 402 } |
403 | 403 |
404 // Shift for division | 404 // Shift for division |
405 q = new (phase->C, 3) RShiftLNode(dividend, phase->intcon(l)); | 405 q = new (phase->C) RShiftLNode(dividend, phase->intcon(l)); |
406 | 406 |
407 if (!d_pos) { | 407 if (!d_pos) { |
408 q = new (phase->C, 3) SubLNode(phase->longcon(0), phase->transform(q)); | 408 q = new (phase->C) SubLNode(phase->longcon(0), phase->transform(q)); |
409 } | 409 } |
410 } else if ( !Matcher::use_asm_for_ldiv_by_con(d) ) { // Use hardware DIV instruction when | 410 } else if ( !Matcher::use_asm_for_ldiv_by_con(d) ) { // Use hardware DIV instruction when |
411 // it is faster than code generated below. | 411 // it is faster than code generated below. |
412 // Attempt the jlong constant divide -> multiply transform found in | 412 // Attempt the jlong constant divide -> multiply transform found in |
413 // "Division by Invariant Integers using Multiplication" | 413 // "Division by Invariant Integers using Multiplication" |
423 // The high half of the 128-bit multiply is computed. | 423 // The high half of the 128-bit multiply is computed. |
424 if (magic_const < 0) { | 424 if (magic_const < 0) { |
425 // The magic multiplier is too large for a 64 bit constant. We've adjusted | 425 // The magic multiplier is too large for a 64 bit constant. We've adjusted |
426 // it down by 2^64, but have to add 1 dividend back in after the multiplication. | 426 // it down by 2^64, but have to add 1 dividend back in after the multiplication. |
427 // This handles the "overflow" case described by Granlund and Montgomery. | 427 // This handles the "overflow" case described by Granlund and Montgomery. |
428 mul_hi = phase->transform(new (phase->C, 3) AddLNode(dividend, mul_hi)); | 428 mul_hi = phase->transform(new (phase->C) AddLNode(dividend, mul_hi)); |
429 } | 429 } |
430 | 430 |
431 // Shift over the (adjusted) mulhi | 431 // Shift over the (adjusted) mulhi |
432 if (shift_const != 0) { | 432 if (shift_const != 0) { |
433 mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(shift_const))); | 433 mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(shift_const))); |
434 } | 434 } |
435 | 435 |
436 // Get a 0 or -1 from the sign of the dividend. | 436 // Get a 0 or -1 from the sign of the dividend. |
437 Node *addend0 = mul_hi; | 437 Node *addend0 = mul_hi; |
438 Node *addend1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N-1))); | 438 Node *addend1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N-1))); |
439 | 439 |
440 // If the divisor is negative, swap the order of the input addends; | 440 // If the divisor is negative, swap the order of the input addends; |
441 // this has the effect of negating the quotient. | 441 // this has the effect of negating the quotient. |
442 if (!d_pos) { | 442 if (!d_pos) { |
443 Node *temp = addend0; addend0 = addend1; addend1 = temp; | 443 Node *temp = addend0; addend0 = addend1; addend1 = temp; |
444 } | 444 } |
445 | 445 |
446 // Adjust the final quotient by subtracting -1 (adding 1) | 446 // Adjust the final quotient by subtracting -1 (adding 1) |
447 // from the mul_hi. | 447 // from the mul_hi. |
448 q = new (phase->C, 3) SubLNode(addend0, addend1); | 448 q = new (phase->C) SubLNode(addend0, addend1); |
449 } | 449 } |
450 } | 450 } |
451 | 451 |
452 return q; | 452 return q; |
453 } | 453 } |
733 float reciprocal = ((float)1.0) / f; | 733 float reciprocal = ((float)1.0) / f; |
734 | 734 |
735 assert( frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); | 735 assert( frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); |
736 | 736 |
737 // return multiplication by the reciprocal | 737 // return multiplication by the reciprocal |
738 return (new (phase->C, 3) MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); | 738 return (new (phase->C) MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); |
739 } | 739 } |
740 | 740 |
741 //============================================================================= | 741 //============================================================================= |
742 //------------------------------Value------------------------------------------ | 742 //------------------------------Value------------------------------------------ |
743 // An DivDNode divides its inputs. The third input is a Control input, used to | 743 // An DivDNode divides its inputs. The third input is a Control input, used to |
827 double reciprocal = 1.0 / d; | 827 double reciprocal = 1.0 / d; |
828 | 828 |
829 assert( frexp(reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); | 829 assert( frexp(reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); |
830 | 830 |
831 // return multiplication by the reciprocal | 831 // return multiplication by the reciprocal |
832 return (new (phase->C, 3) MulDNode(in(1), phase->makecon(TypeD::make(reciprocal)))); | 832 return (new (phase->C) MulDNode(in(1), phase->makecon(TypeD::make(reciprocal)))); |
833 } | 833 } |
834 | 834 |
835 //============================================================================= | 835 //============================================================================= |
836 //------------------------------Idealize--------------------------------------- | 836 //------------------------------Idealize--------------------------------------- |
837 Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) { | 837 Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) { |
854 | 854 |
855 // See if we are MOD'ing by 2^k or 2^k-1. | 855 // See if we are MOD'ing by 2^k or 2^k-1. |
856 if( !ti->is_con() ) return NULL; | 856 if( !ti->is_con() ) return NULL; |
857 jint con = ti->get_con(); | 857 jint con = ti->get_con(); |
858 | 858 |
859 Node *hook = new (phase->C, 1) Node(1); | 859 Node *hook = new (phase->C) Node(1); |
860 | 860 |
861 // First, special check for modulo 2^k-1 | 861 // First, special check for modulo 2^k-1 |
862 if( con >= 0 && con < max_jint && is_power_of_2(con+1) ) { | 862 if( con >= 0 && con < max_jint && is_power_of_2(con+1) ) { |
863 uint k = exact_log2(con+1); // Extract k | 863 uint k = exact_log2(con+1); // Extract k |
864 | 864 |
874 Node *divisor = in(2); // Also is mask | 874 Node *divisor = in(2); // Also is mask |
875 | 875 |
876 hook->init_req(0, x); // Add a use to x to prevent him from dying | 876 hook->init_req(0, x); // Add a use to x to prevent him from dying |
877 // Generate code to reduce X rapidly to nearly 2^k-1. | 877 // Generate code to reduce X rapidly to nearly 2^k-1. |
878 for( int i = 0; i < trip_count; i++ ) { | 878 for( int i = 0; i < trip_count; i++ ) { |
879 Node *xl = phase->transform( new (phase->C, 3) AndINode(x,divisor) ); | 879 Node *xl = phase->transform( new (phase->C) AndINode(x,divisor) ); |
880 Node *xh = phase->transform( new (phase->C, 3) RShiftINode(x,phase->intcon(k)) ); // Must be signed | 880 Node *xh = phase->transform( new (phase->C) RShiftINode(x,phase->intcon(k)) ); // Must be signed |
881 x = phase->transform( new (phase->C, 3) AddINode(xh,xl) ); | 881 x = phase->transform( new (phase->C) AddINode(xh,xl) ); |
882 hook->set_req(0, x); | 882 hook->set_req(0, x); |
883 } | 883 } |
884 | 884 |
885 // Generate sign-fixup code. Was original value positive? | 885 // Generate sign-fixup code. Was original value positive? |
886 // int hack_res = (i >= 0) ? divisor : 1; | 886 // int hack_res = (i >= 0) ? divisor : 1; |
887 Node *cmp1 = phase->transform( new (phase->C, 3) CmpINode( in(1), phase->intcon(0) ) ); | 887 Node *cmp1 = phase->transform( new (phase->C) CmpINode( in(1), phase->intcon(0) ) ); |
888 Node *bol1 = phase->transform( new (phase->C, 2) BoolNode( cmp1, BoolTest::ge ) ); | 888 Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) ); |
889 Node *cmov1= phase->transform( new (phase->C, 4) CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) ); | 889 Node *cmov1= phase->transform( new (phase->C) CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) ); |
890 // if( x >= hack_res ) x -= divisor; | 890 // if( x >= hack_res ) x -= divisor; |
891 Node *sub = phase->transform( new (phase->C, 3) SubINode( x, divisor ) ); | 891 Node *sub = phase->transform( new (phase->C) SubINode( x, divisor ) ); |
892 Node *cmp2 = phase->transform( new (phase->C, 3) CmpINode( x, cmov1 ) ); | 892 Node *cmp2 = phase->transform( new (phase->C) CmpINode( x, cmov1 ) ); |
893 Node *bol2 = phase->transform( new (phase->C, 2) BoolNode( cmp2, BoolTest::ge ) ); | 893 Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) ); |
894 // Convention is to not transform the return value of an Ideal | 894 // Convention is to not transform the return value of an Ideal |
895 // since Ideal is expected to return a modified 'this' or a new node. | 895 // since Ideal is expected to return a modified 'this' or a new node. |
896 Node *cmov2= new (phase->C, 4) CMoveINode(bol2, x, sub, TypeInt::INT); | 896 Node *cmov2= new (phase->C) CMoveINode(bol2, x, sub, TypeInt::INT); |
897 // cmov2 is now the mod | 897 // cmov2 is now the mod |
898 | 898 |
899 // Now remove the bogus extra edges used to keep things alive | 899 // Now remove the bogus extra edges used to keep things alive |
900 if (can_reshape) { | 900 if (can_reshape) { |
901 phase->is_IterGVN()->remove_dead_node(hook); | 901 phase->is_IterGVN()->remove_dead_node(hook); |
914 | 914 |
915 // Get the absolute value of the constant; at this point, we can use this | 915 // Get the absolute value of the constant; at this point, we can use this |
916 jint pos_con = (con >= 0) ? con : -con; | 916 jint pos_con = (con >= 0) ? con : -con; |
917 | 917 |
918 // integer Mod 1 is always 0 | 918 // integer Mod 1 is always 0 |
919 if( pos_con == 1 ) return new (phase->C, 1) ConINode(TypeInt::ZERO); | 919 if( pos_con == 1 ) return new (phase->C) ConINode(TypeInt::ZERO); |
920 | 920 |
921 int log2_con = -1; | 921 int log2_con = -1; |
922 | 922 |
923 // If this is a power of two, they maybe we can mask it | 923 // If this is a power of two, they maybe we can mask it |
924 if( is_power_of_2(pos_con) ) { | 924 if( is_power_of_2(pos_con) ) { |
927 const Type *dt = phase->type(in(1)); | 927 const Type *dt = phase->type(in(1)); |
928 const TypeInt *dti = dt->isa_int(); | 928 const TypeInt *dti = dt->isa_int(); |
929 | 929 |
930 // See if this can be masked, if the dividend is non-negative | 930 // See if this can be masked, if the dividend is non-negative |
931 if( dti && dti->_lo >= 0 ) | 931 if( dti && dti->_lo >= 0 ) |
932 return ( new (phase->C, 3) AndINode( in(1), phase->intcon( pos_con-1 ) ) ); | 932 return ( new (phase->C) AndINode( in(1), phase->intcon( pos_con-1 ) ) ); |
933 } | 933 } |
934 | 934 |
935 // Save in(1) so that it cannot be changed or deleted | 935 // Save in(1) so that it cannot be changed or deleted |
936 hook->init_req(0, in(1)); | 936 hook->init_req(0, in(1)); |
937 | 937 |
942 | 942 |
943 // Re-multiply, using a shift if this is a power of two | 943 // Re-multiply, using a shift if this is a power of two |
944 Node *mult = NULL; | 944 Node *mult = NULL; |
945 | 945 |
946 if( log2_con >= 0 ) | 946 if( log2_con >= 0 ) |
947 mult = phase->transform( new (phase->C, 3) LShiftINode( divide, phase->intcon( log2_con ) ) ); | 947 mult = phase->transform( new (phase->C) LShiftINode( divide, phase->intcon( log2_con ) ) ); |
948 else | 948 else |
949 mult = phase->transform( new (phase->C, 3) MulINode( divide, phase->intcon( pos_con ) ) ); | 949 mult = phase->transform( new (phase->C) MulINode( divide, phase->intcon( pos_con ) ) ); |
950 | 950 |
951 // Finally, subtract the multiplied divided value from the original | 951 // Finally, subtract the multiplied divided value from the original |
952 result = new (phase->C, 3) SubINode( in(1), mult ); | 952 result = new (phase->C) SubINode( in(1), mult ); |
953 } | 953 } |
954 | 954 |
955 // Now remove the bogus extra edges used to keep things alive | 955 // Now remove the bogus extra edges used to keep things alive |
956 if (can_reshape) { | 956 if (can_reshape) { |
957 phase->is_IterGVN()->remove_dead_node(hook); | 957 phase->is_IterGVN()->remove_dead_node(hook); |
1025 | 1025 |
1026 // See if we are MOD'ing by 2^k or 2^k-1. | 1026 // See if we are MOD'ing by 2^k or 2^k-1. |
1027 if( !tl->is_con() ) return NULL; | 1027 if( !tl->is_con() ) return NULL; |
1028 jlong con = tl->get_con(); | 1028 jlong con = tl->get_con(); |
1029 | 1029 |
1030 Node *hook = new (phase->C, 1) Node(1); | 1030 Node *hook = new (phase->C) Node(1); |
1031 | 1031 |
1032 // Expand mod | 1032 // Expand mod |
1033 if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { | 1033 if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { |
1034 uint k = exact_log2_long(con+1); // Extract k | 1034 uint k = exact_log2_long(con+1); // Extract k |
1035 | 1035 |
1047 Node *divisor = in(2); // Also is mask | 1047 Node *divisor = in(2); // Also is mask |
1048 | 1048 |
1049 hook->init_req(0, x); // Add a use to x to prevent him from dying | 1049 hook->init_req(0, x); // Add a use to x to prevent him from dying |
1050 // Generate code to reduce X rapidly to nearly 2^k-1. | 1050 // Generate code to reduce X rapidly to nearly 2^k-1. |
1051 for( int i = 0; i < trip_count; i++ ) { | 1051 for( int i = 0; i < trip_count; i++ ) { |
1052 Node *xl = phase->transform( new (phase->C, 3) AndLNode(x,divisor) ); | 1052 Node *xl = phase->transform( new (phase->C) AndLNode(x,divisor) ); |
1053 Node *xh = phase->transform( new (phase->C, 3) RShiftLNode(x,phase->intcon(k)) ); // Must be signed | 1053 Node *xh = phase->transform( new (phase->C) RShiftLNode(x,phase->intcon(k)) ); // Must be signed |
1054 x = phase->transform( new (phase->C, 3) AddLNode(xh,xl) ); | 1054 x = phase->transform( new (phase->C) AddLNode(xh,xl) ); |
1055 hook->set_req(0, x); // Add a use to x to prevent him from dying | 1055 hook->set_req(0, x); // Add a use to x to prevent him from dying |
1056 } | 1056 } |
1057 | 1057 |
1058 // Generate sign-fixup code. Was original value positive? | 1058 // Generate sign-fixup code. Was original value positive? |
1059 // long hack_res = (i >= 0) ? divisor : CONST64(1); | 1059 // long hack_res = (i >= 0) ? divisor : CONST64(1); |
1060 Node *cmp1 = phase->transform( new (phase->C, 3) CmpLNode( in(1), phase->longcon(0) ) ); | 1060 Node *cmp1 = phase->transform( new (phase->C) CmpLNode( in(1), phase->longcon(0) ) ); |
1061 Node *bol1 = phase->transform( new (phase->C, 2) BoolNode( cmp1, BoolTest::ge ) ); | 1061 Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) ); |
1062 Node *cmov1= phase->transform( new (phase->C, 4) CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) ); | 1062 Node *cmov1= phase->transform( new (phase->C) CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) ); |
1063 // if( x >= hack_res ) x -= divisor; | 1063 // if( x >= hack_res ) x -= divisor; |
1064 Node *sub = phase->transform( new (phase->C, 3) SubLNode( x, divisor ) ); | 1064 Node *sub = phase->transform( new (phase->C) SubLNode( x, divisor ) ); |
1065 Node *cmp2 = phase->transform( new (phase->C, 3) CmpLNode( x, cmov1 ) ); | 1065 Node *cmp2 = phase->transform( new (phase->C) CmpLNode( x, cmov1 ) ); |
1066 Node *bol2 = phase->transform( new (phase->C, 2) BoolNode( cmp2, BoolTest::ge ) ); | 1066 Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) ); |
1067 // Convention is to not transform the return value of an Ideal | 1067 // Convention is to not transform the return value of an Ideal |
1068 // since Ideal is expected to return a modified 'this' or a new node. | 1068 // since Ideal is expected to return a modified 'this' or a new node. |
1069 Node *cmov2= new (phase->C, 4) CMoveLNode(bol2, x, sub, TypeLong::LONG); | 1069 Node *cmov2= new (phase->C) CMoveLNode(bol2, x, sub, TypeLong::LONG); |
1070 // cmov2 is now the mod | 1070 // cmov2 is now the mod |
1071 | 1071 |
1072 // Now remove the bogus extra edges used to keep things alive | 1072 // Now remove the bogus extra edges used to keep things alive |
1073 if (can_reshape) { | 1073 if (can_reshape) { |
1074 phase->is_IterGVN()->remove_dead_node(hook); | 1074 phase->is_IterGVN()->remove_dead_node(hook); |
1087 | 1087 |
1088 // Get the absolute value of the constant; at this point, we can use this | 1088 // Get the absolute value of the constant; at this point, we can use this |
1089 jlong pos_con = (con >= 0) ? con : -con; | 1089 jlong pos_con = (con >= 0) ? con : -con; |
1090 | 1090 |
1091 // integer Mod 1 is always 0 | 1091 // integer Mod 1 is always 0 |
1092 if( pos_con == 1 ) return new (phase->C, 1) ConLNode(TypeLong::ZERO); | 1092 if( pos_con == 1 ) return new (phase->C) ConLNode(TypeLong::ZERO); |
1093 | 1093 |
1094 int log2_con = -1; | 1094 int log2_con = -1; |
1095 | 1095 |
1096 // If this is a power of two, then maybe we can mask it | 1096 // If this is a power of two, then maybe we can mask it |
1097 if( is_power_of_2_long(pos_con) ) { | 1097 if( is_power_of_2_long(pos_con) ) { |
1100 const Type *dt = phase->type(in(1)); | 1100 const Type *dt = phase->type(in(1)); |
1101 const TypeLong *dtl = dt->isa_long(); | 1101 const TypeLong *dtl = dt->isa_long(); |
1102 | 1102 |
1103 // See if this can be masked, if the dividend is non-negative | 1103 // See if this can be masked, if the dividend is non-negative |
1104 if( dtl && dtl->_lo >= 0 ) | 1104 if( dtl && dtl->_lo >= 0 ) |
1105 return ( new (phase->C, 3) AndLNode( in(1), phase->longcon( pos_con-1 ) ) ); | 1105 return ( new (phase->C) AndLNode( in(1), phase->longcon( pos_con-1 ) ) ); |
1106 } | 1106 } |
1107 | 1107 |
1108 // Save in(1) so that it cannot be changed or deleted | 1108 // Save in(1) so that it cannot be changed or deleted |
1109 hook->init_req(0, in(1)); | 1109 hook->init_req(0, in(1)); |
1110 | 1110 |
1115 | 1115 |
1116 // Re-multiply, using a shift if this is a power of two | 1116 // Re-multiply, using a shift if this is a power of two |
1117 Node *mult = NULL; | 1117 Node *mult = NULL; |
1118 | 1118 |
1119 if( log2_con >= 0 ) | 1119 if( log2_con >= 0 ) |
1120 mult = phase->transform( new (phase->C, 3) LShiftLNode( divide, phase->intcon( log2_con ) ) ); | 1120 mult = phase->transform( new (phase->C) LShiftLNode( divide, phase->intcon( log2_con ) ) ); |
1121 else | 1121 else |
1122 mult = phase->transform( new (phase->C, 3) MulLNode( divide, phase->longcon( pos_con ) ) ); | 1122 mult = phase->transform( new (phase->C) MulLNode( divide, phase->longcon( pos_con ) ) ); |
1123 | 1123 |
1124 // Finally, subtract the multiplied divided value from the original | 1124 // Finally, subtract the multiplied divided value from the original |
1125 result = new (phase->C, 3) SubLNode( in(1), mult ); | 1125 result = new (phase->C) SubLNode( in(1), mult ); |
1126 } | 1126 } |
1127 | 1127 |
1128 // Now remove the bogus extra edges used to keep things alive | 1128 // Now remove the bogus extra edges used to keep things alive |
1129 if (can_reshape) { | 1129 if (can_reshape) { |
1130 phase->is_IterGVN()->remove_dead_node(hook); | 1130 phase->is_IterGVN()->remove_dead_node(hook); |
1275 DivModINode* DivModINode::make(Compile* C, Node* div_or_mod) { | 1275 DivModINode* DivModINode::make(Compile* C, Node* div_or_mod) { |
1276 Node* n = div_or_mod; | 1276 Node* n = div_or_mod; |
1277 assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI, | 1277 assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI, |
1278 "only div or mod input pattern accepted"); | 1278 "only div or mod input pattern accepted"); |
1279 | 1279 |
1280 DivModINode* divmod = new (C, 3) DivModINode(n->in(0), n->in(1), n->in(2)); | 1280 DivModINode* divmod = new (C) DivModINode(n->in(0), n->in(1), n->in(2)); |
1281 Node* dproj = new (C, 1) ProjNode(divmod, DivModNode::div_proj_num); | 1281 Node* dproj = new (C) ProjNode(divmod, DivModNode::div_proj_num); |
1282 Node* mproj = new (C, 1) ProjNode(divmod, DivModNode::mod_proj_num); | 1282 Node* mproj = new (C) ProjNode(divmod, DivModNode::mod_proj_num); |
1283 return divmod; | 1283 return divmod; |
1284 } | 1284 } |
1285 | 1285 |
1286 //------------------------------make------------------------------------------ | 1286 //------------------------------make------------------------------------------ |
1287 DivModLNode* DivModLNode::make(Compile* C, Node* div_or_mod) { | 1287 DivModLNode* DivModLNode::make(Compile* C, Node* div_or_mod) { |
1288 Node* n = div_or_mod; | 1288 Node* n = div_or_mod; |
1289 assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL, | 1289 assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL, |
1290 "only div or mod input pattern accepted"); | 1290 "only div or mod input pattern accepted"); |
1291 | 1291 |
1292 DivModLNode* divmod = new (C, 3) DivModLNode(n->in(0), n->in(1), n->in(2)); | 1292 DivModLNode* divmod = new (C) DivModLNode(n->in(0), n->in(1), n->in(2)); |
1293 Node* dproj = new (C, 1) ProjNode(divmod, DivModNode::div_proj_num); | 1293 Node* dproj = new (C) ProjNode(divmod, DivModNode::div_proj_num); |
1294 Node* mproj = new (C, 1) ProjNode(divmod, DivModNode::mod_proj_num); | 1294 Node* mproj = new (C) ProjNode(divmod, DivModNode::mod_proj_num); |
1295 return divmod; | 1295 return divmod; |
1296 } | 1296 } |
1297 | 1297 |
1298 //------------------------------match------------------------------------------ | 1298 //------------------------------match------------------------------------------ |
1299 // return result(s) along with their RegMask info | 1299 // return result(s) along with their RegMask info |
1304 rm = match->divI_proj_mask(); | 1304 rm = match->divI_proj_mask(); |
1305 } else { | 1305 } else { |
1306 assert(proj->_con == mod_proj_num, "must be div or mod projection"); | 1306 assert(proj->_con == mod_proj_num, "must be div or mod projection"); |
1307 rm = match->modI_proj_mask(); | 1307 rm = match->modI_proj_mask(); |
1308 } | 1308 } |
1309 return new (match->C, 1)MachProjNode(this, proj->_con, rm, ideal_reg); | 1309 return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg); |
1310 } | 1310 } |
1311 | 1311 |
1312 | 1312 |
1313 //------------------------------match------------------------------------------ | 1313 //------------------------------match------------------------------------------ |
1314 // return result(s) along with their RegMask info | 1314 // return result(s) along with their RegMask info |
1319 rm = match->divL_proj_mask(); | 1319 rm = match->divL_proj_mask(); |
1320 } else { | 1320 } else { |
1321 assert(proj->_con == mod_proj_num, "must be div or mod projection"); | 1321 assert(proj->_con == mod_proj_num, "must be div or mod projection"); |
1322 rm = match->modL_proj_mask(); | 1322 rm = match->modL_proj_mask(); |
1323 } | 1323 } |
1324 return new (match->C, 1)MachProjNode(this, proj->_con, rm, ideal_reg); | 1324 return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg); |
1325 } | 1325 } |