Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8307715: Integrate VectorMask/Shuffle with value/primitive classes #845

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/hotspot/share/classfile/classFileParser.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -4892,10 +4892,7 @@ bool ClassFileParser::is_jdk_internal_class(const Symbol* outer_class, const cha
inner_class &&
(vmSymbols::jdk_internal_vm_vector_VectorSupport() == outer_class ||
vmSymbols::jdk_internal_vm_vector_VectorPayloadMF() == outer_class)) {
if (strstr(inner_class, "VectorPayloadMF64") ||
strstr(inner_class, "VectorPayloadMF128") ||
strstr(inner_class, "VectorPayloadMF256") ||
strstr(inner_class, "VectorPayloadMF512")) {
if (strstr(inner_class, "VectorPayloadMF")) {
return true;
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/hotspot/share/classfile/vmClassMacros.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -193,6 +193,16 @@
\
/* support multi-field based vectors */ \
do_klass(vector_VectorPayloadMF_klass, jdk_internal_vm_vector_VectorPayloadMF ) \
do_klass(vector_VectorPayloadMF8Z_klass, jdk_internal_vm_vector_VectorPayloadMF8Z ) \
do_klass(vector_VectorPayloadMF16Z_klass, jdk_internal_vm_vector_VectorPayloadMF16Z ) \
do_klass(vector_VectorPayloadMF32Z_klass, jdk_internal_vm_vector_VectorPayloadMF32Z ) \
do_klass(vector_VectorPayloadMF64Z_klass, jdk_internal_vm_vector_VectorPayloadMF64Z ) \
do_klass(vector_VectorPayloadMF128Z_klass, jdk_internal_vm_vector_VectorPayloadMF128Z ) \
do_klass(vector_VectorPayloadMF256Z_klass, jdk_internal_vm_vector_VectorPayloadMF256Z ) \
do_klass(vector_VectorPayloadMF512Z_klass, jdk_internal_vm_vector_VectorPayloadMF512Z ) \
do_klass(vector_VectorPayloadMF8B_klass, jdk_internal_vm_vector_VectorPayloadMF8B ) \
do_klass(vector_VectorPayloadMF16B_klass, jdk_internal_vm_vector_VectorPayloadMF16B ) \
do_klass(vector_VectorPayloadMF32B_klass, jdk_internal_vm_vector_VectorPayloadMF32B ) \
do_klass(vector_VectorPayloadMF64B_klass, jdk_internal_vm_vector_VectorPayloadMF64B ) \
do_klass(vector_VectorPayloadMF128B_klass, jdk_internal_vm_vector_VectorPayloadMF128B ) \
do_klass(vector_VectorPayloadMF256B_klass, jdk_internal_vm_vector_VectorPayloadMF256B ) \
Expand Down
42 changes: 31 additions & 11 deletions src/hotspot/share/classfile/vmSymbols.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -88,12 +88,22 @@
template(java_lang_Long, "java/lang/Long") \
template(java_lang_Long_LongCache, "java/lang/Long$LongCache") \
\
template(jdk_internal_vm_vector_VectorSupport, "jdk/internal/vm/vector/VectorSupport") \
template(jdk_internal_vm_vector_VectorPayload, "jdk/internal/vm/vector/VectorSupport$VectorPayload") \
template(jdk_internal_vm_vector_Vector, "jdk/internal/vm/vector/VectorSupport$Vector") \
template(jdk_internal_vm_vector_VectorMask, "jdk/internal/vm/vector/VectorSupport$VectorMask") \
template(jdk_internal_vm_vector_VectorShuffle, "jdk/internal/vm/vector/VectorSupport$VectorShuffle") \
template(jdk_internal_vm_vector_VectorPayloadMF, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF") \
template(jdk_internal_vm_vector_VectorSupport, "jdk/internal/vm/vector/VectorSupport") \
template(jdk_internal_vm_vector_VectorPayload, "jdk/internal/vm/vector/VectorSupport$VectorPayload") \
template(jdk_internal_vm_vector_Vector, "jdk/internal/vm/vector/VectorSupport$Vector") \
template(jdk_internal_vm_vector_VectorMask, "jdk/internal/vm/vector/VectorSupport$VectorMask") \
template(jdk_internal_vm_vector_VectorShuffle, "jdk/internal/vm/vector/VectorSupport$VectorShuffle") \
template(jdk_internal_vm_vector_VectorPayloadMF, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF") \
template(jdk_internal_vm_vector_VectorPayloadMF8Z, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF8Z") \
template(jdk_internal_vm_vector_VectorPayloadMF16Z, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF16Z") \
template(jdk_internal_vm_vector_VectorPayloadMF32Z, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF32Z") \
template(jdk_internal_vm_vector_VectorPayloadMF64Z, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF64Z") \
template(jdk_internal_vm_vector_VectorPayloadMF128Z, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF128Z") \
template(jdk_internal_vm_vector_VectorPayloadMF256Z, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF256Z") \
template(jdk_internal_vm_vector_VectorPayloadMF512Z, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF512Z") \
template(jdk_internal_vm_vector_VectorPayloadMF8B, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF8B") \
template(jdk_internal_vm_vector_VectorPayloadMF16B, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF16B") \
template(jdk_internal_vm_vector_VectorPayloadMF32B, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF32B") \
template(jdk_internal_vm_vector_VectorPayloadMF64B, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF64B") \
template(jdk_internal_vm_vector_VectorPayloadMF128B, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF128B") \
template(jdk_internal_vm_vector_VectorPayloadMF256B, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF256B") \
Expand All @@ -118,10 +128,10 @@
template(jdk_internal_vm_vector_VectorPayloadMF128D, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF128D") \
template(jdk_internal_vm_vector_VectorPayloadMF256D, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF256D") \
template(jdk_internal_vm_vector_VectorPayloadMF512D, "jdk/internal/vm/vector/VectorSupport$VectorPayloadMF512D") \
template(payload_name, "payload") \
template(mfield_name, "mfield") \
template(ETYPE_name, "ETYPE") \
template(VLENGTH_name, "VLENGTH") \
template(payload_name, "payload") \
template(mfield_name, "mfield") \
template(ETYPE_name, "ETYPE") \
template(VLENGTH_name, "VLENGTH") \
\
template(jdk_internal_vm_FillerObject, "jdk/internal/vm/FillerObject") \
\
Expand Down Expand Up @@ -293,6 +303,16 @@
template(jdk_internal_ValueBased_signature, "Ljdk/internal/ValueBased;") \
\
/* VectorAPI support */ \
template(vector_VectorPayloadMF8Z_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF8Z;") \
template(vector_VectorPayloadMF16Z_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF16Z;") \
template(vector_VectorPayloadMF32Z_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF32Z;") \
template(vector_VectorPayloadMF64Z_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF64Z;") \
template(vector_VectorPayloadMF128Z_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF128Z;") \
template(vector_VectorPayloadMF256Z_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF256Z;") \
template(vector_VectorPayloadMF512Z_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF512Z;") \
template(vector_VectorPayloadMF8B_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF8B;") \
template(vector_VectorPayloadMF16B_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF16B;") \
template(vector_VectorPayloadMF32B_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF32B;") \
template(vector_VectorPayloadMF64B_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF64B;") \
template(vector_VectorPayloadMF128B_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF128B;") \
template(vector_VectorPayloadMF256B_signature, "Qjdk/internal/vm/vector/VectorSupport$VectorPayloadMF256B;") \
Expand Down
18 changes: 10 additions & 8 deletions src/hotspot/share/opto/castnode.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -87,13 +87,15 @@ Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}

// Push cast through InlineTypeNode
InlineTypeNode* vt = in(1)->isa_InlineType();
if (vt != NULL && phase->type(vt)->filter_speculative(_type) != Type::TOP) {
Node* cast = clone();
cast->set_req(1, vt->get_oop());
vt = vt->clone()->as_InlineType();
vt->set_oop(phase->transform(cast));
return vt;
if (in(1)->is_InlineType() && !in(1)->is_VectorBox()) {
InlineTypeNode* vt = in(1)->as_InlineType();
if (phase->type(vt)->filter_speculative(_type) != Type::TOP) {
Node* cast = clone();
cast->set_req(1, vt->get_oop());
vt = vt->clone()->as_InlineType();
vt->set_oop(phase->transform(cast));
return vt;
}
}
Comment on lines +90 to 99
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per JEP Value classes (primitve and value) are implicitly final. Also both oop and InlineTypeNode should always be of same type. Do you see a case where a cast should be applied to oop but InlineTypeNode remain sacrosanct ?
Only one I can think off is when InlineTypeNode was created using make_default / make_uninitialized and ciInstanceKlass was uninitialized

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the relative API is VectorMask.fromArray(), which the InlineTypeNode type is the concrete value class (e.g. Byte128Mask.class), while the receiver type is its super class (e.g. VectorMask.class). I think it is generated between VectorBox and its relative inline method call.


return NULL;
Expand Down
14 changes: 12 additions & 2 deletions src/hotspot/share/opto/cfgnode.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -2571,7 +2571,17 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
n = n->in(1);
}
const Type* t = phase->type(n);
if (n->is_InlineType() && (vk == NULL || vk == t->inline_klass())) {
// FIXME: Skipping pushing VectorBox across Phi
// since they are special type of InlineTypeNode
// carrying VBA as oop fields.
// We have a seperate handling for pushing VectorBoxes
// across PhiNodes in merge_through_phi.
// In long run we should eliminate VectorBox which is
// just a light weight wrapper of InlineTypeNode.
// Only reason to keep VectorBox was to defer buffering
// to a later stage and associate VBA which carry
// JVM state to reinitialize GraphKit before buffering.
if (n->is_InlineType() && !n->is_VectorBox() && (vk == NULL || vk == t->inline_klass())) {
XiaohongGong marked this conversation as resolved.
Show resolved Hide resolved
vk = (vk == NULL) ? t->inline_klass() : vk;
if (phase->find_int_con(n->as_InlineType()->get_is_init(), 0) != 1) {
is_init = false;
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/graphKit.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -916,7 +916,7 @@ class GraphKit : public Phase {

// Vector API support (implemented in vectorIntrinsics.cpp)
Node* box_vector(Node* in, const TypeInstPtr* vbox_type, BasicType elem_bt, int num_elem, bool deoptimize_on_exception = false);
Node* unbox_vector(Node* in, const TypeInstPtr* vbox_type, BasicType elem_bt, int num_elem, bool shuffle_to_vector = false);
Node* unbox_vector(Node* in, const TypeInstPtr* vbox_type, BasicType elem_bt, int num_elem);
Node* vector_shift_count(Node* cnt, int shift_op, BasicType bt, int num_elem);
};

Expand Down
16 changes: 8 additions & 8 deletions src/hotspot/share/opto/inlinetypenode.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -151,6 +151,7 @@ bool InlineTypeNode::has_phi_inputs(Node* region) {

// Merges 'this' with 'other' by updating the input PhiNodes added by 'clone_with_phis'
InlineTypeNode* InlineTypeNode::merge_with(PhaseGVN* gvn, const InlineTypeNode* other, int pnum, bool transform) {
assert(this->Opcode() == other->Opcode(), "");
_is_buffered = _is_buffered && other->_is_buffered;
// Merge oop inputs
PhiNode* phi = get_oop()->as_Phi();
Expand Down Expand Up @@ -408,6 +409,11 @@ const TypePtr* InlineTypeNode::field_adr_type(Node* base, int offset, ciInstance
}

void InlineTypeNode::load(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, DecoratorSet decorators) {
// FIXME: It is possible that "base" is a constant NULL_PTR, which is
// created by "gvn.zerocon(T_PRIMITIVE_OBJECT)". It has to do special
// handling for such cases.
assert(!kit->gvn().type(base)->maybe_null(), "the memory cannot be null");

// Initialize the inline type by loading its field values from
// memory and adding the values as input edges to the node.
for (uint i = 0; i < field_count(); ++i) {
Expand All @@ -425,7 +431,7 @@ void InlineTypeNode::load(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass*
const TypeOopPtr* oop_ptr = kit->gvn().type(base)->isa_oopptr();
bool is_array = (oop_ptr->isa_aryptr() != NULL);
bool mismatched = (decorators & C2_MISMATCHED) != 0;
if (base->is_Con() && !is_array && !mismatched) {
if (base->is_Con() && !is_array && !mismatched && ft->bundle_size() == 1) {
// If the oop to the inline type is constant (static final field), we can
// also treat the fields as constants because the inline type is immutable.
ciObject* constant_oop = oop_ptr->const_oop();
Expand All @@ -440,12 +446,6 @@ void InlineTypeNode::load(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass*
ft = con_type->inline_klass();
null_free = true;
}
BasicType bt = con_type->basic_type();
int vec_len = field->secondary_fields_count();
if (field->is_multifield_base() &&
Matcher::match_rule_supported_vector(VectorNode::replicate_opcode(bt), vec_len, bt)) {
value = kit->gvn().transform(VectorNode::scalar2vector(value, vec_len, Type::get_const_type(field->type()), false));
}
Comment on lines -443 to -448
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be needed for constant oops (gvn.zerocon(T_PRIMITIVE_OBJECT)) as created on following line.
Otherwise it may result into semantically incorrect IR which tries to load a vector from a constant.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason that I change this here is I met another issue when the constant oops is IOTA which saves the index values. For such cases, the scalar2vector will result into wrong result. Besides, for subtype vectors, the basic type from line-443 (i.e. BasicType bt = con_type->basic_type();) is promoted to int. I cannot see the issue if loading a vector from a constant oop. Could you please give an example? Alternatively, I was thinking about generating different IRs for the ZERO and IOTA constants. But we need to do more check about the actual values, which I think is not so urgent now.

Copy link
Member

@jatin-bhateja jatin-bhateja May 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will not be a problem with constant oops or even default values which are value_mirrors, but gvn.zerocon(T_PRIMITIVE_OBJECT) will create a ConP node representing a NULL_PTR, any address commutation w.r.t. base is will result into illegal address.

We should keep multi-field handling in both the control paths and add an extract check for ConP of TypePtr::NULL_PTR in if condition, it will handle all the cases.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense to me. But if the constant oop is gvn.zerocon(T_PRIMITIVE_OBJECT), it's more reasonable that accessing the multi-fields is invalid in runtime, right? I think compiler should exclude such cases before calling InlineTypeNode::load. WDYT?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a test when the constant oop's type is NULL_PTR? I can prepare a fixing and testing. Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phi is still carrying an abstract VectorMask type where as one of its input is concrete mask which is why C2 injects InlineTypeNode for it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, so do you know how this PhiNode is generated and what it is used for? From the log, I can see the two inputs of Phi are all from VectorBox. I guess the abstract VectorMask is from the return type of VectorMask.fromArray() ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also met several issues due to the VectorAPI abstract classes and its concrete vector classes. As I see, in compiler, sometimes the argument/return type is calculated from the sigunature type of the method, but sometimes it is calculated based on the speculative type which use the profiling info as a reference. Following is part of my fixing for such cases:

diff --git a/src/hotspot/share/opto/callGenerator.cpp b/src/hotspot/share/opto/callGenerator.cpp
index 985f7f1c8..b77aa11d9 100644
--- a/src/hotspot/share/opto/callGenerator.cpp
+++ b/src/hotspot/share/opto/callGenerator.cpp
@@ -1169,7 +1169,7 @@ static void cast_argument(int nargs, int arg_nb, ciType* t, GraphKit& kit, bool
     kit.set_argument(arg_nb, arg);
   }
   if (sig_type->is_inlinetypeptr()) {
-    arg = InlineTypeNode::make_from_oop(&kit, arg, t->as_inline_klass(), !kit.gvn().type(arg)->maybe_null());
+    arg = InlineTypeNode::make_from_oop(&kit, arg, sig_type->inline_klass(), !kit.gvn().type(arg)->maybe_null());
     kit.set_argument(arg_nb, arg);
   }
 }
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index bce8d7781..bab94b204 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -1914,20 +1914,25 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p
   }
 
   // Capture the return value, if any.
-  Node* ret;
   if (call->method() == NULL || call->method()->return_type()->basic_type() == T_VOID) {
-    ret = top();
+    return top();
   } else if (call->tf()->returns_inline_type_as_fields()) {
     // Return of multiple values (inline type fields): we create a
     // InlineType node, each field is a projection from the call.
     ciInlineKlass* vk = call->method()->return_type()->as_inline_klass();
     uint base_input = TypeFunc::Parms;
-    ret = InlineTypeNode::make_from_multi(this, call, vk, base_input, false, call->method()->signature()->returns_null_free_inline_type());
+    return InlineTypeNode::make_from_multi(this, call, vk, base_input, false, call->method()->signature()->returns_null_free_inline_type());
   } else {
-    ret = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
+    Node* ret = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
+    ciType* t = call->method()->return_type();
+    if (t->is_klass()) {
+      const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass());
+      if (sig_type->is_inlinetypeptr()) {
+        ret = InlineTypeNode::make_from_oop(this, ret, sig_type->inline_klass(), false);
+      }
+    }
+    return ret;
   }
-
-  return ret;
 }
 
 //--------------------set_predefined_input_for_runtime_call--------------------

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, so do you know how this PhiNode is generated and what it is used for? From the log, I can see the two inputs of Phi are all from VectorBox. I guess the abstract VectorMask is from the return type of VectorMask.fromArray() ?

Do not consider empty output list of the PhiNode, this dump was taken from debugger during a reverse debugging step, so it may appear its not getting used.

All the signatures of top level VectorAPIs methods always deal in abstract types, its only due to aggressive in-lining boxes (concrete vector/mask/shuffle) gets exposed.

We have currently disabled value scalarization for vectors, please also add mask/shuffle to that list

https://github.com/openjdk/valhalla/blob/lworld%2Bvector/src/hotspot/share/oops/inlineKlass.cpp#L341
https://github.com/openjdk/valhalla/blob/lworld%2Bvector/src/hotspot/share/oops/inlineKlass.cpp#L336

Copy link
Author

@XiaohongGong XiaohongGong May 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

} else {
// Load field value from memory
BasicType bt = type2field[ft->basic_type()];
Expand Down
10 changes: 8 additions & 2 deletions src/hotspot/share/opto/library_call.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -2317,8 +2317,14 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
return false;
}
base = vt->get_oop();
// FIXME: Larval bit check is needed to preserve the semantics of value
// objects which can be mutated only if its _larval bit is set. Since
// the oop is not always an AllocateNode, we have to find an utility way
// to check the larval state for all kind of oops.
AllocateNode* alloc = AllocateNode::Ideal_allocation(base, &_gvn);
assert(alloc->_larval, "InlineType instance must be in _larval state for unsafe put operation.\n");
if (alloc != NULL) {
assert(alloc->_larval, "InlineType instance must be in _larval state for unsafe put operation.\n");
}
XiaohongGong marked this conversation as resolved.
Show resolved Hide resolved
} else {
if (offset->is_Con()) {
long off = find_long_con(offset, 0);
Expand Down
Loading