Mercurial > hg > truffle
comparison src/share/vm/opto/divnode.cpp @ 570:dca06e7f503d
Merge
author | kvn |
---|---|
date | Tue, 17 Feb 2009 14:30:24 -0800 |
parents | 30663ca5e8f4 |
children | 98cb887364d3 |
comparison
equal
deleted
inserted
replaced
549:fe3d7c11b4b7 | 570:dca06e7f503d |
---|---|
1 /* | 1 /* |
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright 1997-2009 Sun Microsystems, Inc. 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. |
242 return true; | 242 return true; |
243 } | 243 } |
244 | 244 |
245 //---------------------long_by_long_mulhi-------------------------------------- | 245 //---------------------long_by_long_mulhi-------------------------------------- |
246 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication | 246 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication |
247 static Node *long_by_long_mulhi( PhaseGVN *phase, Node *dividend, jlong magic_const) { | 247 static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) { |
248 // If the architecture supports a 64x64 mulhi, there is | 248 // If the architecture supports a 64x64 mulhi, there is |
249 // no need to synthesize it in ideal nodes. | 249 // no need to synthesize it in ideal nodes. |
250 if (Matcher::has_match_rule(Op_MulHiL)) { | 250 if (Matcher::has_match_rule(Op_MulHiL)) { |
251 Node *v = phase->longcon(magic_const); | 251 Node* v = phase->longcon(magic_const); |
252 return new (phase->C, 3) MulHiLNode(dividend, v); | 252 return new (phase->C, 3) MulHiLNode(dividend, v); |
253 } | 253 } |
254 | 254 |
255 // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. | |
256 // (http://www.hackersdelight.org/HDcode/mulhs.c) | |
257 // | |
258 // int mulhs(int u, int v) { | |
259 // unsigned u0, v0, w0; | |
260 // int u1, v1, w1, w2, t; | |
261 // | |
262 // u0 = u & 0xFFFF; u1 = u >> 16; | |
263 // v0 = v & 0xFFFF; v1 = v >> 16; | |
264 // w0 = u0*v0; | |
265 // t = u1*v0 + (w0 >> 16); | |
266 // w1 = t & 0xFFFF; | |
267 // w2 = t >> 16; | |
268 // w1 = u0*v1 + w1; | |
269 // return u1*v1 + w2 + (w1 >> 16); | |
270 // } | |
271 // | |
272 // Note: The version above is for 32x32 multiplications, while the | |
273 // following inline comments are adapted to 64x64. | |
274 | |
255 const int N = 64; | 275 const int N = 64; |
256 | 276 |
257 Node *u_hi = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2))); | 277 // u0 = u & 0xFFFFFFFF; u1 = u >> 32; |
258 Node *u_lo = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); | 278 Node* u0 = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); |
259 | 279 Node* u1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2))); |
260 Node *v_hi = phase->longcon(magic_const >> N/2); | 280 |
261 Node *v_lo = phase->longcon(magic_const & 0XFFFFFFFF); | 281 // v0 = v & 0xFFFFFFFF; v1 = v >> 32; |
262 | 282 Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF); |
263 Node *hihi_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_hi)); | 283 Node* v1 = phase->longcon(magic_const >> (N / 2)); |
264 Node *hilo_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_lo)); | 284 |
265 Node *lohi_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_hi)); | 285 // w0 = u0*v0; |
266 Node *lolo_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_lo)); | 286 Node* w0 = phase->transform(new (phase->C, 3) MulLNode(u0, v0)); |
267 | 287 |
268 Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2))); | 288 // t = u1*v0 + (w0 >> 32); |
269 Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1)); | 289 Node* u1v0 = phase->transform(new (phase->C, 3) MulLNode(u1, v0)); |
270 | 290 Node* temp = phase->transform(new (phase->C, 3) URShiftLNode(w0, phase->intcon(N / 2))); |
271 // Construct both t3 and t4 before transforming so t2 doesn't go dead | 291 Node* t = phase->transform(new (phase->C, 3) AddLNode(u1v0, temp)); |
272 // prematurely. | 292 |
273 Node *t3 = new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2)); | 293 // w1 = t & 0xFFFFFFFF; |
274 Node *t4 = new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF)); | 294 Node* w1 = new (phase->C, 3) AndLNode(t, phase->longcon(0xFFFFFFFF)); |
275 t3 = phase->transform(t3); | 295 |
276 t4 = phase->transform(t4); | 296 // w2 = t >> 32; |
277 | 297 Node* w2 = new (phase->C, 3) RShiftLNode(t, phase->intcon(N / 2)); |
278 Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product)); | 298 |
279 Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2))); | 299 // 6732154: Construct both w1 and w2 before transforming, so t |
280 Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product)); | 300 // doesn't go dead prematurely. |
281 | 301 w1 = phase->transform(w1); |
282 return new (phase->C, 3) AddLNode(t7, t6); | 302 w2 = phase->transform(w2); |
303 | |
304 // w1 = u0*v1 + w1; | |
305 Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1)); | |
306 w1 = phase->transform(new (phase->C, 3) AddLNode(u0v1, w1)); | |
307 | |
308 // return u1*v1 + w2 + (w1 >> 32); | |
309 Node* u1v1 = phase->transform(new (phase->C, 3) MulLNode(u1, v1)); | |
310 Node* temp1 = phase->transform(new (phase->C, 3) AddLNode(u1v1, w2)); | |
311 Node* temp2 = phase->transform(new (phase->C, 3) RShiftLNode(w1, phase->intcon(N / 2))); | |
312 | |
313 return new (phase->C, 3) AddLNode(temp1, temp2); | |
283 } | 314 } |
284 | 315 |
285 | 316 |
286 //--------------------------transform_long_divide------------------------------ | 317 //--------------------------transform_long_divide------------------------------ |
287 // Convert a division by constant divisor into an alternate Ideal graph. | 318 // Convert a division by constant divisor into an alternate Ideal graph. |
974 | 1005 |
975 Node *hook = new (phase->C, 1) Node(1); | 1006 Node *hook = new (phase->C, 1) Node(1); |
976 | 1007 |
977 // Expand mod | 1008 // Expand mod |
978 if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { | 1009 if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { |
979 uint k = log2_long(con); // Extract k | 1010 uint k = exact_log2_long(con+1); // Extract k |
980 | 1011 |
981 // Basic algorithm by David Detlefs. See fastmod_long.java for gory details. | 1012 // Basic algorithm by David Detlefs. See fastmod_long.java for gory details. |
982 // Used to help a popular random number generator which does a long-mod | 1013 // Used to help a popular random number generator which does a long-mod |
983 // of 2^31-1 and shows up in SpecJBB and SciMark. | 1014 // of 2^31-1 and shows up in SpecJBB and SciMark. |
984 static int unroll_factor[] = { 999, 999, 61, 30, 20, 15, 12, 10, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 /*past here we assume 1 forever*/}; | 1015 static int unroll_factor[] = { 999, 999, 61, 30, 20, 15, 12, 10, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 /*past here we assume 1 forever*/}; |