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*/};