1 /*
2 * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
263 ciField* field = lf->field();
264 if (field->is_static_constant()) {
265 // Constant field loads are usually folded during parsing.
266 // But it doesn't happen with PatchALot, ScavengeRootsInCode < 2, or when
267 // holder class is being initialized during parsing (for static fields).
268 ciObject* c = field->constant_value().as_object();
269 if (!c->is_null_object()) {
270 set_constant(c->as_array()->length());
271 }
272 }
273 }
274 }
275
276 void Canonicalizer::do_LoadIndexed (LoadIndexed* x) {
277 StableArrayConstant* array = x->array()->type()->as_StableArrayConstant();
278 IntConstant* index = x->index()->type()->as_IntConstant();
279
280 assert(array == nullptr || FoldStableValues, "not enabled");
281
282 // Constant fold loads from stable arrays.
283 if (!x->mismatched() && array != nullptr && index != nullptr) {
284 jint idx = index->value();
285 if (idx < 0 || idx >= array->value()->length()) {
286 // Leave the load as is. The range check will handle it.
287 return;
288 }
289
290 ciConstant field_val = array->value()->element_value(idx);
291 if (!field_val.is_null_or_zero()) {
292 jint dimension = array->dimension();
293 assert(dimension <= array->value()->array_type()->dimension(), "inconsistent info");
294 ValueType* value = nullptr;
295 if (dimension > 1) {
296 // Preserve information about the dimension for the element.
297 assert(field_val.as_object()->is_array(), "not an array");
298 value = new StableArrayConstant(field_val.as_object()->as_array(), dimension - 1);
299 } else {
300 assert(dimension == 1, "sanity");
301 value = as_ValueType(field_val);
302 }
303 set_canonical(new Constant(value));
451 double vy = x->y()->type()->as_DoubleConstant()->value();
452 if (g_isnan(vx) || g_isnan(vy))
453 set_constant(x->op() == Bytecodes::_dcmpl ? -1 : 1);
454 else if (vx == vy)
455 set_constant(0);
456 else if (vx < vy)
457 set_constant(-1);
458 else
459 set_constant(1);
460 break;
461 }
462
463 default:
464 break;
465 }
466 }
467 }
468
469
470 void Canonicalizer::do_IfOp(IfOp* x) {
471 // Currently, Canonicalizer is only used by GraphBuilder,
472 // and IfOp is not created by GraphBuilder but only later
473 // when eliminating conditional expressions with CE_Eliminator,
474 // so this method will not be called.
475 ShouldNotReachHere();
476 }
477
478
479 void Canonicalizer::do_Intrinsic (Intrinsic* x) {
480 switch (x->id()) {
481 case vmIntrinsics::_floatToRawIntBits : {
482 FloatConstant* c = x->argument_at(0)->type()->as_FloatConstant();
483 if (c != nullptr) {
484 JavaValue v;
485 v.set_jfloat(c->value());
486 set_constant(v.get_jint());
487 }
488 break;
489 }
490 case vmIntrinsics::_intBitsToFloat : {
491 IntConstant* c = x->argument_at(0)->type()->as_IntConstant();
492 if (c != nullptr) {
493 JavaValue v;
494 v.set_jint(c->value());
495 set_constant(v.get_jfloat());
631 }
632
633 void Canonicalizer::do_TypeCast (TypeCast* x) {}
634 void Canonicalizer::do_Invoke (Invoke* x) {}
635 void Canonicalizer::do_NewInstance (NewInstance* x) {}
636 void Canonicalizer::do_NewTypeArray (NewTypeArray* x) {}
637 void Canonicalizer::do_NewObjectArray (NewObjectArray* x) {}
638 void Canonicalizer::do_NewMultiArray (NewMultiArray* x) {}
639 void Canonicalizer::do_CheckCast (CheckCast* x) {
640 if (x->klass()->is_loaded()) {
641 Value obj = x->obj();
642 ciType* klass = obj->exact_type();
643 if (klass == nullptr) {
644 klass = obj->declared_type();
645 }
646 if (klass != nullptr && klass->is_loaded()) {
647 bool is_interface = klass->is_instance_klass() &&
648 klass->as_instance_klass()->is_interface();
649 // Interface casts can't be statically optimized away since verifier doesn't
650 // enforce interface types in bytecode.
651 if (!is_interface && klass->is_subtype_of(x->klass())) {
652 set_canonical(obj);
653 return;
654 }
655 }
656 // checkcast of null returns null
657 if (obj->as_Constant() && obj->type()->as_ObjectType()->constant_value()->is_null_object()) {
658 set_canonical(obj);
659 }
660 }
661 }
662 void Canonicalizer::do_InstanceOf (InstanceOf* x) {
663 if (x->klass()->is_loaded()) {
664 Value obj = x->obj();
665 ciType* exact = obj->exact_type();
666 if (exact != nullptr && exact->is_loaded() && (obj->as_NewInstance() || obj->as_NewArray())) {
667 set_constant(exact->is_subtype_of(x->klass()) ? 1 : 0);
668 return;
669 }
670 // instanceof null returns false
671 if (obj->as_Constant() && obj->type()->as_ObjectType()->constant_value()->is_null_object()) {
672 set_constant(0);
673 }
674 }
675
676 }
677 void Canonicalizer::do_MonitorEnter (MonitorEnter* x) {}
678 void Canonicalizer::do_MonitorExit (MonitorExit* x) {}
679 void Canonicalizer::do_BlockBegin (BlockBegin* x) {}
680 void Canonicalizer::do_Goto (Goto* x) {}
681
682
683 static bool is_true(jlong x, If::Condition cond, jlong y) {
684 switch (cond) {
685 case If::eql: return x == y;
686 case If::neq: return x != y;
687 case If::lss: return x < y;
688 case If::leq: return x <= y;
689 case If::gtr: return x > y;
690 case If::geq: return x >= y;
691 default:
828 high = mid - 1;
829 } else {
830 low = mid + 1;
831 }
832 }
833 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
834 }
835 }
836
837
838 void Canonicalizer::do_Return (Return* x) {}
839 void Canonicalizer::do_Throw (Throw* x) {}
840 void Canonicalizer::do_Base (Base* x) {}
841 void Canonicalizer::do_OsrEntry (OsrEntry* x) {}
842 void Canonicalizer::do_ExceptionObject(ExceptionObject* x) {}
843 void Canonicalizer::do_UnsafeGet (UnsafeGet* x) {}
844 void Canonicalizer::do_UnsafePut (UnsafePut* x) {}
845 void Canonicalizer::do_UnsafeGetAndSet(UnsafeGetAndSet* x) {}
846 void Canonicalizer::do_ProfileCall (ProfileCall* x) {}
847 void Canonicalizer::do_ProfileReturnType(ProfileReturnType* x) {}
848 void Canonicalizer::do_ProfileInvoke (ProfileInvoke* x) {}
849 void Canonicalizer::do_RuntimeCall (RuntimeCall* x) {}
850 void Canonicalizer::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
851 #ifdef ASSERT
852 void Canonicalizer::do_Assert (Assert* x) {}
853 #endif
854 void Canonicalizer::do_MemBar (MemBar* x) {}
|
1 /*
2 * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
263 ciField* field = lf->field();
264 if (field->is_static_constant()) {
265 // Constant field loads are usually folded during parsing.
266 // But it doesn't happen with PatchALot, ScavengeRootsInCode < 2, or when
267 // holder class is being initialized during parsing (for static fields).
268 ciObject* c = field->constant_value().as_object();
269 if (!c->is_null_object()) {
270 set_constant(c->as_array()->length());
271 }
272 }
273 }
274 }
275
276 void Canonicalizer::do_LoadIndexed (LoadIndexed* x) {
277 StableArrayConstant* array = x->array()->type()->as_StableArrayConstant();
278 IntConstant* index = x->index()->type()->as_IntConstant();
279
280 assert(array == nullptr || FoldStableValues, "not enabled");
281
282 // Constant fold loads from stable arrays.
283 if (!x->should_profile() && !x->mismatched() && array != nullptr && index != nullptr) {
284 jint idx = index->value();
285 if (idx < 0 || idx >= array->value()->length()) {
286 // Leave the load as is. The range check will handle it.
287 return;
288 }
289
290 ciConstant field_val = array->value()->element_value(idx);
291 if (!field_val.is_null_or_zero()) {
292 jint dimension = array->dimension();
293 assert(dimension <= array->value()->array_type()->dimension(), "inconsistent info");
294 ValueType* value = nullptr;
295 if (dimension > 1) {
296 // Preserve information about the dimension for the element.
297 assert(field_val.as_object()->is_array(), "not an array");
298 value = new StableArrayConstant(field_val.as_object()->as_array(), dimension - 1);
299 } else {
300 assert(dimension == 1, "sanity");
301 value = as_ValueType(field_val);
302 }
303 set_canonical(new Constant(value));
451 double vy = x->y()->type()->as_DoubleConstant()->value();
452 if (g_isnan(vx) || g_isnan(vy))
453 set_constant(x->op() == Bytecodes::_dcmpl ? -1 : 1);
454 else if (vx == vy)
455 set_constant(0);
456 else if (vx < vy)
457 set_constant(-1);
458 else
459 set_constant(1);
460 break;
461 }
462
463 default:
464 break;
465 }
466 }
467 }
468
469
470 void Canonicalizer::do_IfOp(IfOp* x) {
471 // Currently, Canonicalizer is only used by GraphBuilder, and IfOp is only created by
472 // GraphBuilder when loading/storing flat fields, do nothing for now.
473 }
474
475
476 void Canonicalizer::do_Intrinsic (Intrinsic* x) {
477 switch (x->id()) {
478 case vmIntrinsics::_floatToRawIntBits : {
479 FloatConstant* c = x->argument_at(0)->type()->as_FloatConstant();
480 if (c != nullptr) {
481 JavaValue v;
482 v.set_jfloat(c->value());
483 set_constant(v.get_jint());
484 }
485 break;
486 }
487 case vmIntrinsics::_intBitsToFloat : {
488 IntConstant* c = x->argument_at(0)->type()->as_IntConstant();
489 if (c != nullptr) {
490 JavaValue v;
491 v.set_jint(c->value());
492 set_constant(v.get_jfloat());
628 }
629
630 void Canonicalizer::do_TypeCast (TypeCast* x) {}
631 void Canonicalizer::do_Invoke (Invoke* x) {}
632 void Canonicalizer::do_NewInstance (NewInstance* x) {}
633 void Canonicalizer::do_NewTypeArray (NewTypeArray* x) {}
634 void Canonicalizer::do_NewObjectArray (NewObjectArray* x) {}
635 void Canonicalizer::do_NewMultiArray (NewMultiArray* x) {}
636 void Canonicalizer::do_CheckCast (CheckCast* x) {
637 if (x->klass()->is_loaded()) {
638 Value obj = x->obj();
639 ciType* klass = obj->exact_type();
640 if (klass == nullptr) {
641 klass = obj->declared_type();
642 }
643 if (klass != nullptr && klass->is_loaded()) {
644 bool is_interface = klass->is_instance_klass() &&
645 klass->as_instance_klass()->is_interface();
646 // Interface casts can't be statically optimized away since verifier doesn't
647 // enforce interface types in bytecode.
648 if (!is_interface && klass->is_subtype_of(x->klass()) && (!x->is_null_free() || obj->is_null_free())) {
649 assert(!x->klass()->is_inlinetype() || x->klass() == klass, "Inline klasses can't have subtypes");
650 set_canonical(obj);
651 return;
652 }
653 }
654 // checkcast of null returns null for non null-free klasses
655 if (!x->is_null_free() && obj->is_null_obj()) {
656 set_canonical(obj);
657 }
658 }
659 }
660 void Canonicalizer::do_InstanceOf (InstanceOf* x) {
661 if (x->klass()->is_loaded()) {
662 Value obj = x->obj();
663 ciType* exact = obj->exact_type();
664 if (exact != nullptr && exact->is_loaded() && (obj->as_NewInstance() || obj->as_NewArray())) {
665 set_constant(exact->is_subtype_of(x->klass()) ? 1 : 0);
666 return;
667 }
668 // instanceof null returns false
669 if (obj->as_Constant() && obj->is_null_obj()) {
670 set_constant(0);
671 }
672 }
673
674 }
675 void Canonicalizer::do_MonitorEnter (MonitorEnter* x) {}
676 void Canonicalizer::do_MonitorExit (MonitorExit* x) {}
677 void Canonicalizer::do_BlockBegin (BlockBegin* x) {}
678 void Canonicalizer::do_Goto (Goto* x) {}
679
680
681 static bool is_true(jlong x, If::Condition cond, jlong y) {
682 switch (cond) {
683 case If::eql: return x == y;
684 case If::neq: return x != y;
685 case If::lss: return x < y;
686 case If::leq: return x <= y;
687 case If::gtr: return x > y;
688 case If::geq: return x >= y;
689 default:
826 high = mid - 1;
827 } else {
828 low = mid + 1;
829 }
830 }
831 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
832 }
833 }
834
835
836 void Canonicalizer::do_Return (Return* x) {}
837 void Canonicalizer::do_Throw (Throw* x) {}
838 void Canonicalizer::do_Base (Base* x) {}
839 void Canonicalizer::do_OsrEntry (OsrEntry* x) {}
840 void Canonicalizer::do_ExceptionObject(ExceptionObject* x) {}
841 void Canonicalizer::do_UnsafeGet (UnsafeGet* x) {}
842 void Canonicalizer::do_UnsafePut (UnsafePut* x) {}
843 void Canonicalizer::do_UnsafeGetAndSet(UnsafeGetAndSet* x) {}
844 void Canonicalizer::do_ProfileCall (ProfileCall* x) {}
845 void Canonicalizer::do_ProfileReturnType(ProfileReturnType* x) {}
846 void Canonicalizer::do_ProfileInvoke (ProfileInvoke* x) {}
847 void Canonicalizer::do_ProfileACmpTypes (ProfileACmpTypes* x) {}
848 void Canonicalizer::do_RuntimeCall (RuntimeCall* x) {}
849 void Canonicalizer::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
850 #ifdef ASSERT
851 void Canonicalizer::do_Assert (Assert* x) {}
852 #endif
853 void Canonicalizer::do_MemBar (MemBar* x) {}
|