Skip to content

Commit e9278de

Browse files
author
Quan Anh Mai
committedFeb 8, 2025
8348411: C2: Remove the control input of LoadKlassNode and LoadNKlassNode
Reviewed-by: vlivanov, epeter
1 parent 5395ffa commit e9278de

10 files changed

+42
-55
lines changed
 

‎src/hotspot/share/opto/doCall.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
947947
Node* ex_klass_node = nullptr;
948948
if (has_exception_handler() && !ex_type->klass_is_exact()) {
949949
Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes());
950-
ex_klass_node = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT));
950+
ex_klass_node = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT));
951951

952952
// Compute the exception klass a little more cleverly.
953953
// Obvious solution is to simple do a LoadKlass from the 'ex_node'.
@@ -965,7 +965,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
965965
continue;
966966
}
967967
Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes());
968-
Node* k = _gvn.transform( LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT));
968+
Node* k = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT));
969969
ex_klass_node->init_req( i, k );
970970
}
971971
ex_klass_node = _gvn.transform(ex_klass_node);

‎src/hotspot/share/opto/graphKit.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,7 @@ Node* GraphKit::load_object_klass(Node* obj) {
12001200
Node* akls = AllocateNode::Ideal_klass(obj, &_gvn);
12011201
if (akls != nullptr) return akls;
12021202
Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
1203-
return _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), k_adr, TypeInstPtr::KLASS));
1203+
return _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), k_adr, TypeInstPtr::KLASS));
12041204
}
12051205

12061206
//-------------------------load_array_length-----------------------------------
@@ -2779,7 +2779,7 @@ Node* Phase::gen_subtype_check(Node* subklass, Node* superklass, Node** ctrl, No
27792779
if (might_be_cache && mem != nullptr) {
27802780
kmem = mem->is_MergeMem() ? mem->as_MergeMem()->memory_at(C->get_alias_index(gvn.type(p2)->is_ptr())) : mem;
27812781
}
2782-
Node *nkls = gvn.transform(LoadKlassNode::make(gvn, nullptr, kmem, p2, gvn.type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL));
2782+
Node* nkls = gvn.transform(LoadKlassNode::make(gvn, kmem, p2, gvn.type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL));
27832783

27842784
// Compile speed common case: ARE a subtype and we canNOT fail
27852785
if (superklass == nkls) {

‎src/hotspot/share/opto/library_call.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -3006,7 +3006,7 @@ bool LibraryCallKit::inline_native_classID() {
30063006
IdealKit ideal(this);
30073007
#define __ ideal.
30083008
IdealVariable result(ideal); __ declarations_done();
3009-
Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(),
3009+
Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(),
30103010
basic_plus_adr(cls, java_lang_Class::klass_offset()),
30113011
TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL));
30123012

@@ -3036,7 +3036,7 @@ bool LibraryCallKit::inline_native_classID() {
30363036

30373037
ideal.set(result, _gvn.transform(new URShiftLNode(kls_trace_id_raw, ideal.ConI(TRACE_ID_SHIFT))));
30383038
} __ else_(); {
3039-
Node* array_kls = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(),
3039+
Node* array_kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(),
30403040
basic_plus_adr(cls, java_lang_Class::array_klass_offset()),
30413041
TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL));
30423042
__ if_then(array_kls, BoolTest::ne, null()); {
@@ -3830,7 +3830,7 @@ Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror,
38303830
if (region == nullptr) never_see_null = true;
38313831
Node* p = basic_plus_adr(mirror, offset);
38323832
const TypeKlassPtr* kls_type = TypeInstKlassPtr::OBJECT_OR_NULL;
3833-
Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
3833+
Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
38343834
Node* null_ctl = top();
38353835
kls = null_check_oop(kls, &null_ctl, never_see_null);
38363836
if (region != nullptr) {
@@ -4026,7 +4026,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) {
40264026
phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror())));
40274027
// If we fall through, it's a plain class. Get its _super.
40284028
p = basic_plus_adr(kls, in_bytes(Klass::super_offset()));
4029-
kls = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL));
4029+
kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL));
40304030
null_ctl = top();
40314031
kls = null_check_oop(kls, &null_ctl);
40324032
if (null_ctl != top()) {
@@ -4180,7 +4180,7 @@ bool LibraryCallKit::inline_native_subtype_check() {
41804180
args[which_arg] = arg;
41814181

41824182
Node* p = basic_plus_adr(arg, class_klass_offset);
4183-
Node* kls = LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, adr_type, kls_type);
4183+
Node* kls = LoadKlassNode::make(_gvn, immutable_memory(), p, adr_type, kls_type);
41844184
klasses[which_arg] = _gvn.transform(kls);
41854185
}
41864186

‎src/hotspot/share/opto/macro.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2338,7 +2338,7 @@ void PhaseMacroExpand::expand_subtypecheck_node(SubTypeCheckNode *check) {
23382338
subklass = obj_or_subklass;
23392339
} else {
23402340
Node* k_adr = basic_plus_adr(obj_or_subklass, oopDesc::klass_offset_in_bytes());
2341-
subklass = _igvn.transform(LoadKlassNode::make(_igvn, nullptr, C->immutable_memory(), k_adr, TypeInstPtr::KLASS));
2341+
subklass = _igvn.transform(LoadKlassNode::make(_igvn, C->immutable_memory(), k_adr, TypeInstPtr::KLASS));
23422342
}
23432343

23442344
Node* not_subtype_ctrl = Phase::gen_subtype_check(subklass, superklass, &ctrl, nullptr, _igvn, check->method(), check->bci());

‎src/hotspot/share/opto/macroArrayCopy.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
642642
// (At this point we can assume disjoint_bases, since types differ.)
643643
int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
644644
Node* p1 = basic_plus_adr(dest_klass, ek_offset);
645-
Node* n1 = LoadKlassNode::make(_igvn, nullptr, C->immutable_memory(), p1, TypeRawPtr::BOTTOM);
645+
Node* n1 = LoadKlassNode::make(_igvn, C->immutable_memory(), p1, TypeRawPtr::BOTTOM);
646646
Node* dest_elem_klass = transform_later(n1);
647647
Node* cv = generate_checkcast_arraycopy(&local_ctrl, &local_mem,
648648
adr_type,

‎src/hotspot/share/opto/memnode.cpp

+4-10
Original file line numberDiff line numberDiff line change
@@ -2398,32 +2398,26 @@ const Type* LoadSNode::Value(PhaseGVN* phase) const {
23982398
//=============================================================================
23992399
//----------------------------LoadKlassNode::make------------------------------
24002400
// Polymorphic factory method:
2401-
Node* LoadKlassNode::make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at, const TypeKlassPtr* tk) {
2401+
Node* LoadKlassNode::make(PhaseGVN& gvn, Node* mem, Node* adr, const TypePtr* at, const TypeKlassPtr* tk) {
24022402
// sanity check the alias category against the created node type
2403-
const TypePtr *adr_type = adr->bottom_type()->isa_ptr();
2403+
const TypePtr* adr_type = adr->bottom_type()->isa_ptr();
24042404
assert(adr_type != nullptr, "expecting TypeKlassPtr");
24052405
#ifdef _LP64
24062406
if (adr_type->is_ptr_to_narrowklass()) {
24072407
assert(UseCompressedClassPointers, "no compressed klasses");
2408-
Node* load_klass = gvn.transform(new LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass(), MemNode::unordered));
2408+
Node* load_klass = gvn.transform(new LoadNKlassNode(mem, adr, at, tk->make_narrowklass(), MemNode::unordered));
24092409
return new DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr());
24102410
}
24112411
#endif
24122412
assert(!adr_type->is_ptr_to_narrowklass() && !adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
2413-
return new LoadKlassNode(ctl, mem, adr, at, tk, MemNode::unordered);
2413+
return new LoadKlassNode(mem, adr, at, tk, MemNode::unordered);
24142414
}
24152415

24162416
//------------------------------Value------------------------------------------
24172417
const Type* LoadKlassNode::Value(PhaseGVN* phase) const {
24182418
return klass_value_common(phase);
24192419
}
24202420

2421-
// In most cases, LoadKlassNode does not have the control input set. If the control
2422-
// input is set, it must not be removed (by LoadNode::Ideal()).
2423-
bool LoadKlassNode::can_remove_control() const {
2424-
return false;
2425-
}
2426-
24272421
const Type* LoadNode::klass_value_common(PhaseGVN* phase) const {
24282422
// Either input is TOP ==> the result is TOP
24292423
const Type *t1 = phase->type( in(MemNode::Memory) );

‎src/hotspot/share/opto/memnode.hpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2024, Alibaba Group Holding Limited. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -522,20 +522,18 @@ class LoadNNode : public LoadNode {
522522
//------------------------------LoadKlassNode----------------------------------
523523
// Load a Klass from an object
524524
class LoadKlassNode : public LoadPNode {
525-
protected:
526-
// In most cases, LoadKlassNode does not have the control input set. If the control
527-
// input is set, it must not be removed (by LoadNode::Ideal()).
528-
virtual bool can_remove_control() const;
525+
private:
526+
LoadKlassNode(Node* mem, Node* adr, const TypePtr* at, const TypeKlassPtr* tk, MemOrd mo)
527+
: LoadPNode(nullptr, mem, adr, at, tk, mo) {}
528+
529529
public:
530-
LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo)
531-
: LoadPNode(c, mem, adr, at, tk, mo) {}
532530
virtual int Opcode() const;
533531
virtual const Type* Value(PhaseGVN* phase) const;
534532
virtual Node* Identity(PhaseGVN* phase);
535533
virtual bool depends_only_on_test() const { return true; }
536534

537535
// Polymorphic factory method:
538-
static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at,
536+
static Node* make(PhaseGVN& gvn, Node* mem, Node* adr, const TypePtr* at,
539537
const TypeKlassPtr* tk = TypeInstKlassPtr::OBJECT);
540538
};
541539

@@ -548,9 +546,12 @@ class LoadKlassNode : public LoadPNode {
548546
// extract the actual class pointer. C2's type system is agnostic on whether the
549547
// input address directly points into the class pointer.
550548
class LoadNKlassNode : public LoadNNode {
549+
private:
550+
friend Node* LoadKlassNode::make(PhaseGVN&, Node*, Node*, const TypePtr*, const TypeKlassPtr*);
551+
LoadNKlassNode(Node* mem, Node* adr, const TypePtr* at, const TypeNarrowKlass* tk, MemOrd mo)
552+
: LoadNNode(nullptr, mem, adr, at, tk, mo) {}
553+
551554
public:
552-
LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo)
553-
: LoadNNode(c, mem, adr, at, tk, mo) {}
554555
virtual int Opcode() const;
555556
virtual uint ideal_reg() const { return Op_RegN; }
556557
virtual int store_Opcode() const { return Op_StoreNKlass; }

‎src/hotspot/share/opto/parse1.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2120,7 +2120,7 @@ void Parse::call_register_finalizer() {
21202120
// finalization. In general this will fold up since the concrete
21212121
// class is often visible so the access flags are constant.
21222122
Node* klass_addr = basic_plus_adr( receiver, receiver, oopDesc::klass_offset_in_bytes() );
2123-
Node* klass = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), klass_addr, TypeInstPtr::KLASS));
2123+
Node* klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), klass_addr, TypeInstPtr::KLASS));
21242124

21252125
Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::misc_flags_offset()));
21262126
Node* access_flags = make_load(nullptr, access_flags_addr, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered);

‎src/hotspot/share/opto/parseHelper.cpp

+13-21
Original file line numberDiff line numberDiff line change
@@ -156,19 +156,18 @@ void Parse::array_store_check() {
156156
int klass_offset = oopDesc::klass_offset_in_bytes();
157157
Node* p = basic_plus_adr( ary, ary, klass_offset );
158158
// p's type is array-of-OOPS plus klass_offset
159-
Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeInstPtr::KLASS));
159+
Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS));
160160
// Get the array klass
161161
const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr();
162162

163163
// The type of array_klass is usually INexact array-of-oop. Heroically
164164
// cast array_klass to EXACT array and uncommon-trap if the cast fails.
165165
// Make constant out of the inexact array klass, but use it only if the cast
166166
// succeeds.
167-
bool always_see_exact_class = false;
168-
if (MonomorphicArrayCheck
169-
&& !too_many_traps(Deoptimization::Reason_array_check)
170-
&& !tak->klass_is_exact()
171-
&& tak != TypeInstKlassPtr::OBJECT) {
167+
if (MonomorphicArrayCheck &&
168+
!too_many_traps(Deoptimization::Reason_array_check) &&
169+
!tak->klass_is_exact() &&
170+
tak->isa_aryklassptr()) {
172171
// Regarding the fourth condition in the if-statement from above:
173172
//
174173
// If the compiler has determined that the type of array 'ary' (represented
@@ -190,16 +189,12 @@ void Parse::array_store_check() {
190189
//
191190
// See issue JDK-8057622 for details.
192191

193-
always_see_exact_class = true;
194-
// (If no MDO at all, hope for the best, until a trap actually occurs.)
195-
196-
// Make a constant out of the inexact array klass
197-
const TypeKlassPtr *extak = tak->cast_to_exactness(true);
198-
192+
// Make a constant out of the exact array klass
193+
const TypeAryKlassPtr* extak = tak->cast_to_exactness(true)->is_aryklassptr();
199194
if (extak->exact_klass(true) != nullptr) {
200195
Node* con = makecon(extak);
201-
Node* cmp = _gvn.transform(new CmpPNode( array_klass, con ));
202-
Node* bol = _gvn.transform(new BoolNode( cmp, BoolTest::eq ));
196+
Node* cmp = _gvn.transform(new CmpPNode(array_klass, con));
197+
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
203198
Node* ctrl= control();
204199
{ BuildCutout unless(this, bol, PROB_MAX);
205200
uncommon_trap(Deoptimization::Reason_array_check,
@@ -210,7 +205,7 @@ void Parse::array_store_check() {
210205
set_control(ctrl); // Then Don't Do It, just fall into the normal checking
211206
} else { // Cast array klass to exactness:
212207
// Use the exact constant value we know it is.
213-
replace_in_map(array_klass,con);
208+
replace_in_map(array_klass, con);
214209
CompileLog* log = C->log();
215210
if (log != nullptr) {
216211
log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'",
@@ -225,12 +220,9 @@ void Parse::array_store_check() {
225220

226221
// Extract the array element class
227222
int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset());
228-
Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
229-
// We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true,
230-
// we must set a control edge from the IfTrue node created by the uncommon_trap above to the
231-
// LoadKlassNode.
232-
Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : nullptr,
233-
immutable_memory(), p2, tak));
223+
Node* p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
224+
Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p2, tak));
225+
assert(array_klass->is_Con() == a_e_klass->is_Con() || StressReflectiveCode, "a constant array type must come with a constant element type");
234226

235227
// Check (the hard way) and throw if not a subklass.
236228
// Result is ignored, we just need the CFG effects.

‎src/hotspot/share/opto/subtypenode.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ bool SubTypeCheckNode::verify(PhaseGVN* phase) {
195195
chk_off_X = phase->transform(new ConvI2LNode(chk_off_X));
196196
#endif
197197
Node* p2 = phase->transform(new AddPNode(subklass, subklass, chk_off_X));
198-
Node* nkls = phase->transform(LoadKlassNode::make(*phase, nullptr, C->immutable_memory(), p2, phase->type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL));
198+
Node* nkls = phase->transform(LoadKlassNode::make(*phase, C->immutable_memory(), p2, phase->type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL));
199199

200200
return verify_helper(phase, nkls, cached_t);
201201
}
@@ -218,7 +218,7 @@ Node* SubTypeCheckNode::load_klass(PhaseGVN* phase) const {
218218
Node* subklass = nullptr;
219219
if (sub_t->isa_oopptr()) {
220220
Node* adr = phase->transform(new AddPNode(obj_or_subklass, obj_or_subklass, phase->MakeConX(oopDesc::klass_offset_in_bytes())));
221-
subklass = phase->transform(LoadKlassNode::make(*phase, nullptr, phase->C->immutable_memory(), adr, TypeInstPtr::KLASS));
221+
subklass = phase->transform(LoadKlassNode::make(*phase, phase->C->immutable_memory(), adr, TypeInstPtr::KLASS));
222222
record_for_cleanup(subklass, phase);
223223
} else {
224224
subklass = obj_or_subklass;

0 commit comments

Comments
 (0)
Failed to load comments.