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