Mercurial > hg > truffle
annotate src/share/vm/c1/c1_Canonicalizer.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | b812ff5abc73 |
children | d5d065957597 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_c1_Canonicalizer.cpp.incl" | |
27 | |
28 | |
1584 | 29 class PrintValueVisitor: public ValueVisitor { |
30 void visit(Value* vp) { | |
31 (*vp)->print_line(); | |
32 } | |
33 }; | |
0 | 34 |
35 void Canonicalizer::set_canonical(Value x) { | |
36 assert(x != NULL, "value must exist"); | |
37 // Note: we can not currently substitute root nodes which show up in | |
38 // the instruction stream (because the instruction list is embedded | |
39 // in the instructions). | |
40 if (canonical() != x) { | |
41 if (PrintCanonicalization) { | |
1584 | 42 PrintValueVisitor do_print_value; |
43 canonical()->input_values_do(&do_print_value); | |
0 | 44 canonical()->print_line(); |
45 tty->print_cr("canonicalized to:"); | |
1584 | 46 x->input_values_do(&do_print_value); |
0 | 47 x->print_line(); |
48 tty->cr(); | |
49 } | |
50 assert(_canonical->type()->tag() == x->type()->tag(), "types must match"); | |
51 _canonical = x; | |
52 } | |
53 } | |
54 | |
55 | |
56 void Canonicalizer::move_const_to_right(Op2* x) { | |
57 if (x->x()->type()->is_constant() && x->is_commutative()) x->swap_operands(); | |
58 } | |
59 | |
60 | |
61 void Canonicalizer::do_Op2(Op2* x) { | |
62 if (x->x() == x->y()) { | |
63 switch (x->op()) { | |
64 case Bytecodes::_isub: set_constant(0); return; | |
65 case Bytecodes::_lsub: set_constant(jlong_cast(0)); return; | |
66 case Bytecodes::_iand: // fall through | |
67 case Bytecodes::_land: // fall through | |
68 case Bytecodes::_ior: // fall through | |
69 case Bytecodes::_lor : set_canonical(x->x()); return; | |
70 case Bytecodes::_ixor: set_constant(0); return; | |
71 case Bytecodes::_lxor: set_constant(jlong_cast(0)); return; | |
72 } | |
73 } | |
74 | |
75 if (x->x()->type()->is_constant() && x->y()->type()->is_constant()) { | |
76 // do constant folding for selected operations | |
77 switch (x->type()->tag()) { | |
78 case intTag: | |
79 { jint a = x->x()->type()->as_IntConstant()->value(); | |
80 jint b = x->y()->type()->as_IntConstant()->value(); | |
81 switch (x->op()) { | |
82 case Bytecodes::_iadd: set_constant(a + b); return; | |
83 case Bytecodes::_isub: set_constant(a - b); return; | |
84 case Bytecodes::_imul: set_constant(a * b); return; | |
85 case Bytecodes::_idiv: | |
86 if (b != 0) { | |
87 if (a == min_jint && b == -1) { | |
88 set_constant(min_jint); | |
89 } else { | |
90 set_constant(a / b); | |
91 } | |
92 return; | |
93 } | |
94 break; | |
95 case Bytecodes::_irem: | |
96 if (b != 0) { | |
97 if (a == min_jint && b == -1) { | |
98 set_constant(0); | |
99 } else { | |
100 set_constant(a % b); | |
101 } | |
102 return; | |
103 } | |
104 break; | |
105 case Bytecodes::_iand: set_constant(a & b); return; | |
106 case Bytecodes::_ior : set_constant(a | b); return; | |
107 case Bytecodes::_ixor: set_constant(a ^ b); return; | |
108 } | |
109 } | |
110 break; | |
111 case longTag: | |
112 { jlong a = x->x()->type()->as_LongConstant()->value(); | |
113 jlong b = x->y()->type()->as_LongConstant()->value(); | |
114 switch (x->op()) { | |
115 case Bytecodes::_ladd: set_constant(a + b); return; | |
116 case Bytecodes::_lsub: set_constant(a - b); return; | |
117 case Bytecodes::_lmul: set_constant(a * b); return; | |
118 case Bytecodes::_ldiv: | |
119 if (b != 0) { | |
120 set_constant(SharedRuntime::ldiv(b, a)); | |
121 return; | |
122 } | |
123 break; | |
124 case Bytecodes::_lrem: | |
125 if (b != 0) { | |
126 set_constant(SharedRuntime::lrem(b, a)); | |
127 return; | |
128 } | |
129 break; | |
130 case Bytecodes::_land: set_constant(a & b); return; | |
131 case Bytecodes::_lor : set_constant(a | b); return; | |
132 case Bytecodes::_lxor: set_constant(a ^ b); return; | |
133 } | |
134 } | |
135 break; | |
136 // other cases not implemented (must be extremely careful with floats & doubles!) | |
137 } | |
138 } | |
139 // make sure constant is on the right side, if any | |
140 move_const_to_right(x); | |
141 | |
142 if (x->y()->type()->is_constant()) { | |
143 // do constant folding for selected operations | |
144 switch (x->type()->tag()) { | |
145 case intTag: | |
146 if (x->y()->type()->as_IntConstant()->value() == 0) { | |
147 switch (x->op()) { | |
148 case Bytecodes::_iadd: set_canonical(x->x()); return; | |
149 case Bytecodes::_isub: set_canonical(x->x()); return; | |
150 case Bytecodes::_imul: set_constant(0); return; | |
151 // Note: for div and rem, make sure that C semantics | |
152 // corresponds to Java semantics! | |
153 case Bytecodes::_iand: set_constant(0); return; | |
154 case Bytecodes::_ior : set_canonical(x->x()); return; | |
155 } | |
156 } | |
157 break; | |
158 case longTag: | |
159 if (x->y()->type()->as_LongConstant()->value() == (jlong)0) { | |
160 switch (x->op()) { | |
161 case Bytecodes::_ladd: set_canonical(x->x()); return; | |
162 case Bytecodes::_lsub: set_canonical(x->x()); return; | |
163 case Bytecodes::_lmul: set_constant((jlong)0); return; | |
164 // Note: for div and rem, make sure that C semantics | |
165 // corresponds to Java semantics! | |
166 case Bytecodes::_land: set_constant((jlong)0); return; | |
167 case Bytecodes::_lor : set_canonical(x->x()); return; | |
168 } | |
169 } | |
170 break; | |
171 } | |
172 } | |
173 } | |
174 | |
175 | |
176 void Canonicalizer::do_Phi (Phi* x) {} | |
177 void Canonicalizer::do_Constant (Constant* x) {} | |
178 void Canonicalizer::do_Local (Local* x) {} | |
179 void Canonicalizer::do_LoadField (LoadField* x) {} | |
180 | |
181 // checks if v is in the block that is currently processed by | |
182 // GraphBuilder. This is the only block that has not BlockEnd yet. | |
183 static bool in_current_block(Value v) { | |
184 int max_distance = 4; | |
185 while (max_distance > 0 && v != NULL && v->as_BlockEnd() == NULL) { | |
186 v = v->next(); | |
187 max_distance--; | |
188 } | |
189 return v == NULL; | |
190 } | |
191 | |
192 void Canonicalizer::do_StoreField (StoreField* x) { | |
193 // If a value is going to be stored into a field or array some of | |
194 // the conversions emitted by javac are unneeded because the fields | |
195 // are packed to their natural size. | |
196 Convert* conv = x->value()->as_Convert(); | |
197 if (conv) { | |
198 Value value = NULL; | |
199 BasicType type = x->field()->type()->basic_type(); | |
200 switch (conv->op()) { | |
201 case Bytecodes::_i2b: if (type == T_BYTE) value = conv->value(); break; | |
202 case Bytecodes::_i2s: if (type == T_SHORT || type == T_BYTE) value = conv->value(); break; | |
203 case Bytecodes::_i2c: if (type == T_CHAR || type == T_BYTE) value = conv->value(); break; | |
204 } | |
205 // limit this optimization to current block | |
206 if (value != NULL && in_current_block(conv)) { | |
207 set_canonical(new StoreField(x->obj(), x->offset(), x->field(), value, x->is_static(), | |
1584 | 208 x->lock_stack(), x->state_before(), x->is_loaded(), x->is_initialized())); |
0 | 209 return; |
210 } | |
211 } | |
212 | |
213 } | |
214 | |
215 void Canonicalizer::do_ArrayLength (ArrayLength* x) { | |
216 NewArray* array = x->array()->as_NewArray(); | |
217 if (array != NULL && array->length() != NULL) { | |
218 Constant* length = array->length()->as_Constant(); | |
219 if (length != NULL) { | |
220 // do not use the Constant itself, but create a new Constant | |
221 // with same value Otherwise a Constant is live over multiple | |
222 // blocks without being registered in a state array. | |
223 assert(length->type()->as_IntConstant() != NULL, "array length must be integer"); | |
224 set_constant(length->type()->as_IntConstant()->value()); | |
225 } | |
226 } else { | |
227 LoadField* lf = x->array()->as_LoadField(); | |
1295 | 228 if (lf != NULL) { |
229 ciField* field = lf->field(); | |
230 if (field->is_constant() && field->is_static()) { | |
231 // final static field | |
232 ciObject* c = field->constant_value().as_object(); | |
233 if (c->is_array()) { | |
234 ciArray* array = (ciArray*) c; | |
235 set_constant(array->length()); | |
236 } | |
0 | 237 } |
238 } | |
239 } | |
240 } | |
241 | |
242 void Canonicalizer::do_LoadIndexed (LoadIndexed* x) {} | |
243 void Canonicalizer::do_StoreIndexed (StoreIndexed* x) { | |
244 // If a value is going to be stored into a field or array some of | |
245 // the conversions emitted by javac are unneeded because the fields | |
246 // are packed to their natural size. | |
247 Convert* conv = x->value()->as_Convert(); | |
248 if (conv) { | |
249 Value value = NULL; | |
250 BasicType type = x->elt_type(); | |
251 switch (conv->op()) { | |
252 case Bytecodes::_i2b: if (type == T_BYTE) value = conv->value(); break; | |
253 case Bytecodes::_i2s: if (type == T_SHORT || type == T_BYTE) value = conv->value(); break; | |
254 case Bytecodes::_i2c: if (type == T_CHAR || type == T_BYTE) value = conv->value(); break; | |
255 } | |
256 // limit this optimization to current block | |
257 if (value != NULL && in_current_block(conv)) { | |
258 set_canonical(new StoreIndexed(x->array(), x->index(), x->length(), | |
259 x->elt_type(), value, x->lock_stack())); | |
260 return; | |
261 } | |
262 } | |
263 | |
264 | |
265 } | |
266 | |
267 | |
268 void Canonicalizer::do_NegateOp(NegateOp* x) { | |
269 ValueType* t = x->x()->type(); | |
270 if (t->is_constant()) { | |
271 switch (t->tag()) { | |
272 case intTag : set_constant(-t->as_IntConstant ()->value()); return; | |
273 case longTag : set_constant(-t->as_LongConstant ()->value()); return; | |
274 case floatTag : set_constant(-t->as_FloatConstant ()->value()); return; | |
275 case doubleTag: set_constant(-t->as_DoubleConstant()->value()); return; | |
276 default : ShouldNotReachHere(); | |
277 } | |
278 } | |
279 } | |
280 | |
281 | |
282 void Canonicalizer::do_ArithmeticOp (ArithmeticOp* x) { do_Op2(x); } | |
283 | |
284 | |
285 void Canonicalizer::do_ShiftOp (ShiftOp* x) { | |
286 ValueType* t = x->x()->type(); | |
287 ValueType* t2 = x->y()->type(); | |
288 if (t->is_constant()) { | |
289 switch (t->tag()) { | |
290 case intTag : if (t->as_IntConstant()->value() == 0) { set_constant(0); return; } break; | |
291 case longTag : if (t->as_LongConstant()->value() == (jlong)0) { set_constant(jlong_cast(0)); return; } break; | |
292 default : ShouldNotReachHere(); | |
293 } | |
294 if (t2->is_constant()) { | |
295 if (t->tag() == intTag) { | |
296 int value = t->as_IntConstant()->value(); | |
297 int shift = t2->as_IntConstant()->value() & 31; | |
298 jint mask = ~(~0 << (32 - shift)); | |
299 if (shift == 0) mask = ~0; | |
300 switch (x->op()) { | |
301 case Bytecodes::_ishl: set_constant(value << shift); return; | |
302 case Bytecodes::_ishr: set_constant(value >> shift); return; | |
303 case Bytecodes::_iushr: set_constant((value >> shift) & mask); return; | |
304 } | |
305 } else if (t->tag() == longTag) { | |
306 jlong value = t->as_LongConstant()->value(); | |
307 int shift = t2->as_IntConstant()->value() & 63; | |
308 jlong mask = ~(~jlong_cast(0) << (64 - shift)); | |
309 if (shift == 0) mask = ~jlong_cast(0); | |
310 switch (x->op()) { | |
311 case Bytecodes::_lshl: set_constant(value << shift); return; | |
312 case Bytecodes::_lshr: set_constant(value >> shift); return; | |
313 case Bytecodes::_lushr: set_constant((value >> shift) & mask); return; | |
314 } | |
315 } | |
316 } | |
317 } | |
318 if (t2->is_constant()) { | |
319 switch (t2->tag()) { | |
320 case intTag : if (t2->as_IntConstant()->value() == 0) set_canonical(x->x()); return; | |
321 case longTag : if (t2->as_IntConstant()->value() == 0) set_canonical(x->x()); return; | |
322 default : ShouldNotReachHere(); | |
323 } | |
324 } | |
325 } | |
326 | |
327 | |
328 void Canonicalizer::do_LogicOp (LogicOp* x) { do_Op2(x); } | |
329 void Canonicalizer::do_CompareOp (CompareOp* x) { | |
330 if (x->x() == x->y()) { | |
331 switch (x->x()->type()->tag()) { | |
332 case longTag: set_constant(0); break; | |
333 case floatTag: { | |
334 FloatConstant* fc = x->x()->type()->as_FloatConstant(); | |
335 if (fc) { | |
336 if (g_isnan(fc->value())) { | |
337 set_constant(x->op() == Bytecodes::_fcmpl ? -1 : 1); | |
338 } else { | |
339 set_constant(0); | |
340 } | |
341 } | |
342 break; | |
343 } | |
344 case doubleTag: { | |
345 DoubleConstant* dc = x->x()->type()->as_DoubleConstant(); | |
346 if (dc) { | |
347 if (g_isnan(dc->value())) { | |
348 set_constant(x->op() == Bytecodes::_dcmpl ? -1 : 1); | |
349 } else { | |
350 set_constant(0); | |
351 } | |
352 } | |
353 break; | |
354 } | |
355 } | |
356 } else if (x->x()->type()->is_constant() && x->y()->type()->is_constant()) { | |
357 switch (x->x()->type()->tag()) { | |
358 case longTag: { | |
359 jlong vx = x->x()->type()->as_LongConstant()->value(); | |
360 jlong vy = x->y()->type()->as_LongConstant()->value(); | |
361 if (vx == vy) | |
362 set_constant(0); | |
363 else if (vx < vy) | |
364 set_constant(-1); | |
365 else | |
366 set_constant(1); | |
367 break; | |
368 } | |
369 | |
370 case floatTag: { | |
371 float vx = x->x()->type()->as_FloatConstant()->value(); | |
372 float vy = x->y()->type()->as_FloatConstant()->value(); | |
373 if (g_isnan(vx) || g_isnan(vy)) | |
374 set_constant(x->op() == Bytecodes::_fcmpl ? -1 : 1); | |
375 else if (vx == vy) | |
376 set_constant(0); | |
377 else if (vx < vy) | |
378 set_constant(-1); | |
379 else | |
380 set_constant(1); | |
381 break; | |
382 } | |
383 | |
384 case doubleTag: { | |
385 double vx = x->x()->type()->as_DoubleConstant()->value(); | |
386 double vy = x->y()->type()->as_DoubleConstant()->value(); | |
387 if (g_isnan(vx) || g_isnan(vy)) | |
388 set_constant(x->op() == Bytecodes::_dcmpl ? -1 : 1); | |
389 else if (vx == vy) | |
390 set_constant(0); | |
391 else if (vx < vy) | |
392 set_constant(-1); | |
393 else | |
394 set_constant(1); | |
395 break; | |
396 } | |
397 } | |
398 | |
399 } | |
400 } | |
401 | |
402 | |
403 void Canonicalizer::do_IfInstanceOf(IfInstanceOf* x) {} | |
404 | |
405 void Canonicalizer::do_IfOp(IfOp* x) { | |
406 // Caution: do not use do_Op2(x) here for now since | |
407 // we map the condition to the op for now! | |
408 move_const_to_right(x); | |
409 } | |
410 | |
411 | |
412 void Canonicalizer::do_Intrinsic (Intrinsic* x) { | |
413 switch (x->id()) { | |
414 case vmIntrinsics::_floatToRawIntBits : { | |
415 FloatConstant* c = x->argument_at(0)->type()->as_FloatConstant(); | |
416 if (c != NULL) { | |
417 JavaValue v; | |
418 v.set_jfloat(c->value()); | |
419 set_constant(v.get_jint()); | |
420 } | |
421 break; | |
422 } | |
423 case vmIntrinsics::_intBitsToFloat : { | |
424 IntConstant* c = x->argument_at(0)->type()->as_IntConstant(); | |
425 if (c != NULL) { | |
426 JavaValue v; | |
427 v.set_jint(c->value()); | |
428 set_constant(v.get_jfloat()); | |
429 } | |
430 break; | |
431 } | |
432 case vmIntrinsics::_doubleToRawLongBits : { | |
433 DoubleConstant* c = x->argument_at(0)->type()->as_DoubleConstant(); | |
434 if (c != NULL) { | |
435 JavaValue v; | |
436 v.set_jdouble(c->value()); | |
437 set_constant(v.get_jlong()); | |
438 } | |
439 break; | |
440 } | |
441 case vmIntrinsics::_longBitsToDouble : { | |
442 LongConstant* c = x->argument_at(0)->type()->as_LongConstant(); | |
443 if (c != NULL) { | |
444 JavaValue v; | |
445 v.set_jlong(c->value()); | |
446 set_constant(v.get_jdouble()); | |
447 } | |
448 break; | |
449 } | |
450 } | |
451 } | |
452 | |
453 void Canonicalizer::do_Convert (Convert* x) { | |
454 if (x->value()->type()->is_constant()) { | |
455 switch (x->op()) { | |
456 case Bytecodes::_i2b: set_constant((int)((x->value()->type()->as_IntConstant()->value() << 24) >> 24)); break; | |
457 case Bytecodes::_i2s: set_constant((int)((x->value()->type()->as_IntConstant()->value() << 16) >> 16)); break; | |
458 case Bytecodes::_i2c: set_constant((int)(x->value()->type()->as_IntConstant()->value() & ((1<<16)-1))); break; | |
459 case Bytecodes::_i2l: set_constant((jlong)(x->value()->type()->as_IntConstant()->value())); break; | |
460 case Bytecodes::_i2f: set_constant((float)(x->value()->type()->as_IntConstant()->value())); break; | |
461 case Bytecodes::_i2d: set_constant((double)(x->value()->type()->as_IntConstant()->value())); break; | |
462 case Bytecodes::_l2i: set_constant((int)(x->value()->type()->as_LongConstant()->value())); break; | |
463 case Bytecodes::_l2f: set_constant(SharedRuntime::l2f(x->value()->type()->as_LongConstant()->value())); break; | |
464 case Bytecodes::_l2d: set_constant(SharedRuntime::l2d(x->value()->type()->as_LongConstant()->value())); break; | |
465 case Bytecodes::_f2d: set_constant((double)(x->value()->type()->as_FloatConstant()->value())); break; | |
466 case Bytecodes::_f2i: set_constant(SharedRuntime::f2i(x->value()->type()->as_FloatConstant()->value())); break; | |
467 case Bytecodes::_f2l: set_constant(SharedRuntime::f2l(x->value()->type()->as_FloatConstant()->value())); break; | |
468 case Bytecodes::_d2f: set_constant((float)(x->value()->type()->as_DoubleConstant()->value())); break; | |
469 case Bytecodes::_d2i: set_constant(SharedRuntime::d2i(x->value()->type()->as_DoubleConstant()->value())); break; | |
470 case Bytecodes::_d2l: set_constant(SharedRuntime::d2l(x->value()->type()->as_DoubleConstant()->value())); break; | |
471 default: | |
472 ShouldNotReachHere(); | |
473 } | |
474 } | |
475 | |
476 Value value = x->value(); | |
477 BasicType type = T_ILLEGAL; | |
478 LoadField* lf = value->as_LoadField(); | |
479 if (lf) { | |
480 type = lf->field_type(); | |
481 } else { | |
482 LoadIndexed* li = value->as_LoadIndexed(); | |
483 if (li) { | |
484 type = li->elt_type(); | |
485 } else { | |
486 Convert* conv = value->as_Convert(); | |
487 if (conv) { | |
488 switch (conv->op()) { | |
489 case Bytecodes::_i2b: type = T_BYTE; break; | |
490 case Bytecodes::_i2s: type = T_SHORT; break; | |
491 case Bytecodes::_i2c: type = T_CHAR; break; | |
492 } | |
493 } | |
494 } | |
495 } | |
496 if (type != T_ILLEGAL) { | |
497 switch (x->op()) { | |
498 case Bytecodes::_i2b: if (type == T_BYTE) set_canonical(x->value()); break; | |
499 case Bytecodes::_i2s: if (type == T_SHORT || type == T_BYTE) set_canonical(x->value()); break; | |
500 case Bytecodes::_i2c: if (type == T_CHAR) set_canonical(x->value()); break; | |
501 } | |
502 } else { | |
503 Op2* op2 = x->value()->as_Op2(); | |
504 if (op2 && op2->op() == Bytecodes::_iand && op2->y()->type()->is_constant()) { | |
505 jint safebits = 0; | |
506 jint mask = op2->y()->type()->as_IntConstant()->value(); | |
507 switch (x->op()) { | |
508 case Bytecodes::_i2b: safebits = 0x7f; break; | |
509 case Bytecodes::_i2s: safebits = 0x7fff; break; | |
510 case Bytecodes::_i2c: safebits = 0xffff; break; | |
511 } | |
512 // When casting a masked integer to a smaller signed type, if | |
513 // the mask doesn't include the sign bit the cast isn't needed. | |
514 if (safebits && (mask & ~safebits) == 0) { | |
515 set_canonical(x->value()); | |
516 } | |
517 } | |
518 } | |
519 | |
520 } | |
521 | |
522 void Canonicalizer::do_NullCheck (NullCheck* x) { | |
523 if (x->obj()->as_NewArray() != NULL || x->obj()->as_NewInstance() != NULL) { | |
524 set_canonical(x->obj()); | |
525 } else { | |
526 Constant* con = x->obj()->as_Constant(); | |
527 if (con) { | |
528 ObjectType* c = con->type()->as_ObjectType(); | |
529 if (c && c->is_loaded()) { | |
530 ObjectConstant* oc = c->as_ObjectConstant(); | |
531 if (!oc || !oc->value()->is_null_object()) { | |
532 set_canonical(con); | |
533 } | |
534 } | |
535 } | |
536 } | |
537 } | |
538 | |
539 void Canonicalizer::do_Invoke (Invoke* x) {} | |
540 void Canonicalizer::do_NewInstance (NewInstance* x) {} | |
541 void Canonicalizer::do_NewTypeArray (NewTypeArray* x) {} | |
542 void Canonicalizer::do_NewObjectArray (NewObjectArray* x) {} | |
543 void Canonicalizer::do_NewMultiArray (NewMultiArray* x) {} | |
544 void Canonicalizer::do_CheckCast (CheckCast* x) { | |
545 if (x->klass()->is_loaded()) { | |
546 Value obj = x->obj(); | |
547 ciType* klass = obj->exact_type(); | |
548 if (klass == NULL) klass = obj->declared_type(); | |
549 if (klass != NULL && klass->is_loaded() && klass->is_subtype_of(x->klass())) { | |
550 set_canonical(obj); | |
551 return; | |
552 } | |
553 // checkcast of null returns null | |
554 if (obj->as_Constant() && obj->type()->as_ObjectType()->constant_value()->is_null_object()) { | |
555 set_canonical(obj); | |
556 } | |
557 } | |
558 } | |
559 void Canonicalizer::do_InstanceOf (InstanceOf* x) { | |
560 if (x->klass()->is_loaded()) { | |
561 Value obj = x->obj(); | |
562 ciType* exact = obj->exact_type(); | |
563 if (exact != NULL && exact->is_loaded() && (obj->as_NewInstance() || obj->as_NewArray())) { | |
564 set_constant(exact->is_subtype_of(x->klass()) ? 1 : 0); | |
565 return; | |
566 } | |
567 // instanceof null returns false | |
568 if (obj->as_Constant() && obj->type()->as_ObjectType()->constant_value()->is_null_object()) { | |
569 set_constant(0); | |
570 } | |
571 } | |
572 | |
573 } | |
574 void Canonicalizer::do_MonitorEnter (MonitorEnter* x) {} | |
575 void Canonicalizer::do_MonitorExit (MonitorExit* x) {} | |
576 void Canonicalizer::do_BlockBegin (BlockBegin* x) {} | |
577 void Canonicalizer::do_Goto (Goto* x) {} | |
578 | |
579 | |
580 static bool is_true(jlong x, If::Condition cond, jlong y) { | |
581 switch (cond) { | |
582 case If::eql: return x == y; | |
583 case If::neq: return x != y; | |
584 case If::lss: return x < y; | |
585 case If::leq: return x <= y; | |
586 case If::gtr: return x > y; | |
587 case If::geq: return x >= y; | |
588 } | |
589 ShouldNotReachHere(); | |
590 return false; | |
591 } | |
592 | |
593 | |
594 void Canonicalizer::do_If(If* x) { | |
595 // move const to right | |
596 if (x->x()->type()->is_constant()) x->swap_operands(); | |
597 // simplify | |
598 const Value l = x->x(); ValueType* lt = l->type(); | |
599 const Value r = x->y(); ValueType* rt = r->type(); | |
600 | |
601 if (l == r && !lt->is_float_kind()) { | |
602 // pattern: If (a cond a) => simplify to Goto | |
603 BlockBegin* sux; | |
604 switch (x->cond()) { | |
605 case If::eql: sux = x->sux_for(true); break; | |
606 case If::neq: sux = x->sux_for(false); break; | |
607 case If::lss: sux = x->sux_for(false); break; | |
608 case If::leq: sux = x->sux_for(true); break; | |
609 case If::gtr: sux = x->sux_for(false); break; | |
610 case If::geq: sux = x->sux_for(true); break; | |
611 } | |
612 // If is a safepoint then the debug information should come from the state_before of the If. | |
613 set_canonical(new Goto(sux, x->state_before(), x->is_safepoint())); | |
614 return; | |
615 } | |
616 | |
617 if (lt->is_constant() && rt->is_constant()) { | |
618 if (x->x()->as_Constant() != NULL) { | |
619 // pattern: If (lc cond rc) => simplify to: Goto | |
620 BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(), | |
621 x->sux_for(true), | |
622 x->sux_for(false)); | |
623 if (sux != NULL) { | |
624 // If is a safepoint then the debug information should come from the state_before of the If. | |
625 set_canonical(new Goto(sux, x->state_before(), x->is_safepoint())); | |
626 } | |
627 } | |
628 } else if (rt->as_IntConstant() != NULL) { | |
629 // pattern: If (l cond rc) => investigate further | |
630 const jint rc = rt->as_IntConstant()->value(); | |
631 if (l->as_CompareOp() != NULL) { | |
632 // pattern: If ((a cmp b) cond rc) => simplify to: If (x cond y) or: Goto | |
633 CompareOp* cmp = l->as_CompareOp(); | |
634 bool unordered_is_less = cmp->op() == Bytecodes::_fcmpl || cmp->op() == Bytecodes::_dcmpl; | |
635 BlockBegin* lss_sux = x->sux_for(is_true(-1, x->cond(), rc)); // successor for a < b | |
636 BlockBegin* eql_sux = x->sux_for(is_true( 0, x->cond(), rc)); // successor for a = b | |
637 BlockBegin* gtr_sux = x->sux_for(is_true(+1, x->cond(), rc)); // successor for a > b | |
638 BlockBegin* nan_sux = unordered_is_less ? lss_sux : gtr_sux ; // successor for unordered | |
639 // Note: At this point all successors (lss_sux, eql_sux, gtr_sux, nan_sux) are | |
640 // equal to x->tsux() or x->fsux(). Furthermore, nan_sux equals either | |
641 // lss_sux or gtr_sux. | |
642 if (lss_sux == eql_sux && eql_sux == gtr_sux) { | |
643 // all successors identical => simplify to: Goto | |
644 set_canonical(new Goto(lss_sux, x->state_before(), x->is_safepoint())); | |
645 } else { | |
646 // two successors differ and two successors are the same => simplify to: If (x cmp y) | |
647 // determine new condition & successors | |
648 If::Condition cond; | |
649 BlockBegin* tsux = NULL; | |
650 BlockBegin* fsux = NULL; | |
651 if (lss_sux == eql_sux) { cond = If::leq; tsux = lss_sux; fsux = gtr_sux; } | |
652 else if (lss_sux == gtr_sux) { cond = If::neq; tsux = lss_sux; fsux = eql_sux; } | |
653 else if (eql_sux == gtr_sux) { cond = If::geq; tsux = eql_sux; fsux = lss_sux; } | |
654 else { ShouldNotReachHere(); } | |
655 If* canon = new If(cmp->x(), cond, nan_sux == tsux, cmp->y(), tsux, fsux, cmp->state_before(), x->is_safepoint()); | |
656 if (cmp->x() == cmp->y()) { | |
657 do_If(canon); | |
658 } else { | |
659 set_canonical(canon); | |
660 set_bci(cmp->bci()); | |
661 } | |
662 } | |
663 } else if (l->as_InstanceOf() != NULL) { | |
664 // NOTE: Code permanently disabled for now since it leaves the old InstanceOf | |
665 // instruction in the graph (it is pinned). Need to fix this at some point. | |
666 return; | |
667 // pattern: If ((obj instanceof klass) cond rc) => simplify to: IfInstanceOf or: Goto | |
668 InstanceOf* inst = l->as_InstanceOf(); | |
669 BlockBegin* is_inst_sux = x->sux_for(is_true(1, x->cond(), rc)); // successor for instanceof == 1 | |
670 BlockBegin* no_inst_sux = x->sux_for(is_true(0, x->cond(), rc)); // successor for instanceof == 0 | |
671 if (is_inst_sux == no_inst_sux && inst->is_loaded()) { | |
672 // both successors identical and klass is loaded => simplify to: Goto | |
673 set_canonical(new Goto(is_inst_sux, x->state_before(), x->is_safepoint())); | |
674 } else { | |
675 // successors differ => simplify to: IfInstanceOf | |
676 set_canonical(new IfInstanceOf(inst->klass(), inst->obj(), true, inst->bci(), is_inst_sux, no_inst_sux)); | |
677 } | |
678 } | |
679 } else if (rt == objectNull && (l->as_NewInstance() || l->as_NewArray())) { | |
680 if (x->cond() == Instruction::eql) { | |
681 set_canonical(new Goto(x->fsux(), x->state_before(), x->is_safepoint())); | |
682 } else { | |
683 assert(x->cond() == Instruction::neq, "only other valid case"); | |
684 set_canonical(new Goto(x->tsux(), x->state_before(), x->is_safepoint())); | |
685 } | |
686 } | |
687 } | |
688 | |
689 | |
690 void Canonicalizer::do_TableSwitch(TableSwitch* x) { | |
691 if (x->tag()->type()->is_constant()) { | |
692 int v = x->tag()->type()->as_IntConstant()->value(); | |
693 BlockBegin* sux = x->default_sux(); | |
694 if (v >= x->lo_key() && v <= x->hi_key()) { | |
695 sux = x->sux_at(v - x->lo_key()); | |
696 } | |
697 set_canonical(new Goto(sux, x->state_before(), x->is_safepoint())); | |
698 } else if (x->number_of_sux() == 1) { | |
699 // NOTE: Code permanently disabled for now since the switch statement's | |
700 // tag expression may produce side-effects in which case it must | |
701 // be executed. | |
702 return; | |
703 // simplify to Goto | |
704 set_canonical(new Goto(x->default_sux(), x->state_before(), x->is_safepoint())); | |
705 } else if (x->number_of_sux() == 2) { | |
706 // NOTE: Code permanently disabled for now since it produces two new nodes | |
707 // (Constant & If) and the Canonicalizer cannot return them correctly | |
708 // yet. For now we copied the corresponding code directly into the | |
709 // GraphBuilder (i.e., we should never reach here). | |
710 return; | |
711 // simplify to If | |
712 assert(x->lo_key() == x->hi_key(), "keys must be the same"); | |
713 Constant* key = new Constant(new IntConstant(x->lo_key())); | |
714 set_canonical(new If(x->tag(), If::eql, true, key, x->sux_at(0), x->default_sux(), x->state_before(), x->is_safepoint())); | |
715 } | |
716 } | |
717 | |
718 | |
719 void Canonicalizer::do_LookupSwitch(LookupSwitch* x) { | |
720 if (x->tag()->type()->is_constant()) { | |
721 int v = x->tag()->type()->as_IntConstant()->value(); | |
722 BlockBegin* sux = x->default_sux(); | |
723 for (int i = 0; i < x->length(); i++) { | |
724 if (v == x->key_at(i)) { | |
725 sux = x->sux_at(i); | |
726 } | |
727 } | |
728 set_canonical(new Goto(sux, x->state_before(), x->is_safepoint())); | |
729 } else if (x->number_of_sux() == 1) { | |
730 // NOTE: Code permanently disabled for now since the switch statement's | |
731 // tag expression may produce side-effects in which case it must | |
732 // be executed. | |
733 return; | |
734 // simplify to Goto | |
735 set_canonical(new Goto(x->default_sux(), x->state_before(), x->is_safepoint())); | |
736 } else if (x->number_of_sux() == 2) { | |
737 // NOTE: Code permanently disabled for now since it produces two new nodes | |
738 // (Constant & If) and the Canonicalizer cannot return them correctly | |
739 // yet. For now we copied the corresponding code directly into the | |
740 // GraphBuilder (i.e., we should never reach here). | |
741 return; | |
742 // simplify to If | |
743 assert(x->length() == 1, "length must be the same"); | |
744 Constant* key = new Constant(new IntConstant(x->key_at(0))); | |
745 set_canonical(new If(x->tag(), If::eql, true, key, x->sux_at(0), x->default_sux(), x->state_before(), x->is_safepoint())); | |
746 } | |
747 } | |
748 | |
749 | |
750 void Canonicalizer::do_Return (Return* x) {} | |
751 void Canonicalizer::do_Throw (Throw* x) {} | |
752 void Canonicalizer::do_Base (Base* x) {} | |
753 void Canonicalizer::do_OsrEntry (OsrEntry* x) {} | |
754 void Canonicalizer::do_ExceptionObject(ExceptionObject* x) {} | |
755 | |
756 static bool match_index_and_scale(Instruction* instr, | |
757 Instruction** index, | |
758 int* log2_scale, | |
759 Instruction** instr_to_unpin) { | |
760 *instr_to_unpin = NULL; | |
761 | |
762 // Skip conversion ops | |
763 Convert* convert = instr->as_Convert(); | |
764 if (convert != NULL) { | |
765 instr = convert->value(); | |
766 } | |
767 | |
768 ShiftOp* shift = instr->as_ShiftOp(); | |
769 if (shift != NULL) { | |
770 if (shift->is_pinned()) { | |
771 *instr_to_unpin = shift; | |
772 } | |
773 // Constant shift value? | |
774 Constant* con = shift->y()->as_Constant(); | |
775 if (con == NULL) return false; | |
776 // Well-known type and value? | |
777 IntConstant* val = con->type()->as_IntConstant(); | |
778 if (val == NULL) return false; | |
779 if (shift->x()->type() != intType) return false; | |
780 *index = shift->x(); | |
781 int tmp_scale = val->value(); | |
782 if (tmp_scale >= 0 && tmp_scale < 4) { | |
783 *log2_scale = tmp_scale; | |
784 return true; | |
785 } else { | |
786 return false; | |
787 } | |
788 } | |
789 | |
790 ArithmeticOp* arith = instr->as_ArithmeticOp(); | |
791 if (arith != NULL) { | |
792 if (arith->is_pinned()) { | |
793 *instr_to_unpin = arith; | |
794 } | |
795 // Check for integer multiply | |
796 if (arith->op() == Bytecodes::_imul) { | |
797 // See if either arg is a known constant | |
798 Constant* con = arith->x()->as_Constant(); | |
799 if (con != NULL) { | |
800 *index = arith->y(); | |
801 } else { | |
802 con = arith->y()->as_Constant(); | |
803 if (con == NULL) return false; | |
804 *index = arith->x(); | |
805 } | |
806 if ((*index)->type() != intType) return false; | |
807 // Well-known type and value? | |
808 IntConstant* val = con->type()->as_IntConstant(); | |
809 if (val == NULL) return false; | |
810 switch (val->value()) { | |
811 case 1: *log2_scale = 0; return true; | |
812 case 2: *log2_scale = 1; return true; | |
813 case 4: *log2_scale = 2; return true; | |
814 case 8: *log2_scale = 3; return true; | |
815 default: return false; | |
816 } | |
817 } | |
818 } | |
819 | |
820 // Unknown instruction sequence; don't touch it | |
821 return false; | |
822 } | |
823 | |
824 | |
825 static bool match(UnsafeRawOp* x, | |
826 Instruction** base, | |
827 Instruction** index, | |
828 int* log2_scale) { | |
829 Instruction* instr_to_unpin = NULL; | |
830 ArithmeticOp* root = x->base()->as_ArithmeticOp(); | |
831 if (root == NULL) return false; | |
832 // Limit ourselves to addition for now | |
833 if (root->op() != Bytecodes::_ladd) return false; | |
834 // Try to find shift or scale op | |
835 if (match_index_and_scale(root->y(), index, log2_scale, &instr_to_unpin)) { | |
836 *base = root->x(); | |
837 } else if (match_index_and_scale(root->x(), index, log2_scale, &instr_to_unpin)) { | |
838 *base = root->y(); | |
839 } else if (root->y()->as_Convert() != NULL) { | |
840 Convert* convert = root->y()->as_Convert(); | |
841 if (convert->op() == Bytecodes::_i2l && convert->value()->type() == intType) { | |
842 // pick base and index, setting scale at 1 | |
843 *base = root->x(); | |
844 *index = convert->value(); | |
845 *log2_scale = 0; | |
846 } else { | |
847 return false; | |
848 } | |
849 } else { | |
850 // doesn't match any expected sequences | |
851 return false; | |
852 } | |
853 | |
854 // If the value is pinned then it will be always be computed so | |
855 // there's no profit to reshaping the expression. | |
856 return !root->is_pinned(); | |
857 } | |
858 | |
859 | |
860 void Canonicalizer::do_UnsafeRawOp(UnsafeRawOp* x) { | |
861 Instruction* base = NULL; | |
862 Instruction* index = NULL; | |
863 int log2_scale; | |
864 | |
865 if (match(x, &base, &index, &log2_scale)) { | |
866 x->set_base(base); | |
867 x->set_index(index); | |
868 x->set_log2_scale(log2_scale); | |
869 if (PrintUnsafeOptimization) { | |
870 tty->print_cr("Canonicalizer: UnsafeRawOp id %d: base = id %d, index = id %d, log2_scale = %d", | |
871 x->id(), x->base()->id(), x->index()->id(), x->log2_scale()); | |
872 } | |
873 } | |
874 } | |
875 | |
876 void Canonicalizer::do_RoundFP(RoundFP* x) {} | |
877 void Canonicalizer::do_UnsafeGetRaw(UnsafeGetRaw* x) { if (OptimizeUnsafes) do_UnsafeRawOp(x); } | |
878 void Canonicalizer::do_UnsafePutRaw(UnsafePutRaw* x) { if (OptimizeUnsafes) do_UnsafeRawOp(x); } | |
879 void Canonicalizer::do_UnsafeGetObject(UnsafeGetObject* x) {} | |
880 void Canonicalizer::do_UnsafePutObject(UnsafePutObject* x) {} | |
881 void Canonicalizer::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} | |
882 void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} | |
883 void Canonicalizer::do_ProfileCall(ProfileCall* x) {} | |
884 void Canonicalizer::do_ProfileCounter(ProfileCounter* x) {} |