Skip to content

Commit f71be8b

Browse files
author
Jatin Bhateja
committedApr 12, 2021
8264954: unified handling for VectorMask object re-materialization during de-optimization
Reviewed-by: vlivanov
1 parent 3c9858d commit f71be8b

File tree

3 files changed

+44
-44
lines changed

3 files changed

+44
-44
lines changed
 

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

+20-8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@
3232
#include "opto/vector.hpp"
3333
#include "utilities/macros.hpp"
3434

35+
static bool is_vector_mask(ciKlass* klass) {
36+
return klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass());
37+
}
38+
39+
static bool is_vector_shuffle(ciKlass* klass) {
40+
return klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass());
41+
}
42+
43+
3544
void PhaseVector::optimize_vector_boxes() {
3645
Compile::TracePhase tp("vector_elimination", &timers[_t_vector_elimination]);
3746

@@ -252,6 +261,17 @@ void PhaseVector::scalarize_vbox_node(VectorBoxNode* vec_box) {
252261
#endif // ASSERT
253262
first_ind, n_fields);
254263
sobj->init_req(0, C->root());
264+
265+
// If a mask is feeding into a safepoint, then its value should be
266+
// packed into a boolean/byte vector first, this will simplify the
267+
// re-materialization logic for both predicated and non-predicated
268+
// targets.
269+
bool is_mask = is_vector_mask(iklass);
270+
if (is_mask && vec_value->Opcode() != Op_VectorStoreMask) {
271+
const TypeVect* vt = vec_value->bottom_type()->is_vect();
272+
BasicType bt = vt->element_basic_type();
273+
vec_value = gvn.transform(VectorStoreMaskNode::make(gvn, vec_value, bt, vt->length()));
274+
}
255275
sfpt->add_req(vec_value);
256276

257277
sobj = gvn.transform(sobj);
@@ -305,14 +325,6 @@ Node* PhaseVector::expand_vbox_node_helper(Node* vbox,
305325
}
306326
}
307327

308-
static bool is_vector_mask(ciKlass* klass) {
309-
return klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass());
310-
}
311-
312-
static bool is_vector_shuffle(ciKlass* klass) {
313-
return klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass());
314-
}
315-
316328
Node* PhaseVector::expand_vbox_alloc_node(VectorBoxAllocateNode* vbox_alloc,
317329
Node* value,
318330
const TypeInstPtr* box_type,

‎src/hotspot/share/prims/vectorSupport.cpp

+23-35
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ BasicType VectorSupport::klass2bt(InstanceKlass* ik) {
6565

6666
if (is_vector_shuffle(ik)) {
6767
return T_BYTE;
68+
} else if (is_vector_mask(ik)) {
69+
return T_BOOLEAN;
6870
} else { // vector and mask
6971
oop value = ik->java_mirror()->obj_field(fd.offset());
7072
BasicType elem_bt = java_lang_Class::as_BasicType(value);
@@ -86,48 +88,34 @@ jint VectorSupport::klass2length(InstanceKlass* ik) {
8688
return vlen;
8789
}
8890

89-
void VectorSupport::init_payload_element(typeArrayOop arr, bool is_mask, BasicType elem_bt, int index, address addr) {
90-
if (is_mask) {
91-
// Masks require special handling: when boxed they are packed and stored in boolean
92-
// arrays, but in scalarized form they have the same size as corresponding vectors.
93-
// For example, Int512Mask is represented in memory as boolean[16], but
94-
// occupies the whole 512-bit vector register when scalarized.
95-
// (In generated code, the conversion is performed by VectorStoreMask.)
96-
//
97-
// TODO: revisit when predicate registers are fully supported.
98-
switch (elem_bt) {
99-
case T_BYTE: arr->bool_at_put(index, (*(jbyte*)addr) != 0); break;
100-
case T_SHORT: arr->bool_at_put(index, (*(jshort*)addr) != 0); break;
101-
case T_INT: // fall-through
102-
case T_FLOAT: arr->bool_at_put(index, (*(jint*)addr) != 0); break;
103-
case T_LONG: // fall-through
104-
case T_DOUBLE: arr->bool_at_put(index, (*(jlong*)addr) != 0); break;
105-
106-
default: fatal("unsupported: %s", type2name(elem_bt));
107-
}
108-
} else {
109-
switch (elem_bt) {
110-
case T_BYTE: arr-> byte_at_put(index, *(jbyte*)addr); break;
111-
case T_SHORT: arr-> short_at_put(index, *(jshort*)addr); break;
112-
case T_INT: arr-> int_at_put(index, *(jint*)addr); break;
113-
case T_FLOAT: arr-> float_at_put(index, *(jfloat*)addr); break;
114-
case T_LONG: arr-> long_at_put(index, *(jlong*)addr); break;
115-
case T_DOUBLE: arr->double_at_put(index, *(jdouble*)addr); break;
116-
117-
default: fatal("unsupported: %s", type2name(elem_bt));
118-
}
91+
// Masks require special handling: when boxed they are packed and stored in boolean
92+
// arrays, but in scalarized form they have the same size as corresponding vectors.
93+
// For example, Int512Mask is represented in memory as boolean[16], but
94+
// occupies the whole 512-bit vector register when scalarized.
95+
// During scalarization inserting a VectorStoreMask node between mask
96+
// and safepoint node always ensures the existence of masks in a boolean array.
97+
98+
void VectorSupport::init_payload_element(typeArrayOop arr, BasicType elem_bt, int index, address addr) {
99+
switch (elem_bt) {
100+
case T_BOOLEAN: arr-> byte_at_put(index, *(jboolean*)addr); break;
101+
case T_BYTE: arr-> byte_at_put(index, *(jbyte*)addr); break;
102+
case T_SHORT: arr-> short_at_put(index, *(jshort*)addr); break;
103+
case T_INT: arr-> int_at_put(index, *(jint*)addr); break;
104+
case T_FLOAT: arr-> float_at_put(index, *(jfloat*)addr); break;
105+
case T_LONG: arr-> long_at_put(index, *(jlong*)addr); break;
106+
case T_DOUBLE: arr->double_at_put(index, *(jdouble*)addr); break;
107+
108+
default: fatal("unsupported: %s", type2name(elem_bt));
119109
}
120110
}
121111

122112
Handle VectorSupport::allocate_vector_payload_helper(InstanceKlass* ik, frame* fr, RegisterMap* reg_map, Location location, TRAPS) {
123-
bool is_mask = is_vector_mask(ik);
124-
125113
int num_elem = klass2length(ik);
126114
BasicType elem_bt = klass2bt(ik);
127115
int elem_size = type2aelembytes(elem_bt);
128116

129117
// On-heap vector values are represented as primitive arrays.
130-
TypeArrayKlass* tak = TypeArrayKlass::cast(Universe::typeArrayKlassObj(is_mask ? T_BOOLEAN : elem_bt));
118+
TypeArrayKlass* tak = TypeArrayKlass::cast(Universe::typeArrayKlassObj(elem_bt));
131119

132120
typeArrayOop arr = tak->allocate(num_elem, CHECK_NH); // safepoint
133121

@@ -140,13 +128,13 @@ Handle VectorSupport::allocate_vector_payload_helper(InstanceKlass* ik, frame* f
140128
int off = (i * elem_size) % VMRegImpl::stack_slot_size;
141129

142130
address elem_addr = reg_map->location(vreg, vslot) + off; // assumes little endian element order
143-
init_payload_element(arr, is_mask, elem_bt, i, elem_addr);
131+
init_payload_element(arr, elem_bt, i, elem_addr);
144132
}
145133
} else {
146134
// Value was directly saved on the stack.
147135
address base_addr = ((address)fr->unextended_sp()) + location.stack_offset();
148136
for (int i = 0; i < num_elem; i++) {
149-
init_payload_element(arr, is_mask, elem_bt, i, base_addr + i * elem_size);
137+
init_payload_element(arr, elem_bt, i, base_addr + i * elem_size);
150138
}
151139
}
152140
return Handle(THREAD, arr);

‎src/hotspot/share/prims/vectorSupport.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class VectorSupport : AllStatic {
4242
static Handle allocate_vector_payload(InstanceKlass* ik, frame* fr, RegisterMap* reg_map, ScopeValue* payload, TRAPS);
4343
static Handle allocate_vector_payload_helper(InstanceKlass* ik, frame* fr, RegisterMap* reg_map, Location location, TRAPS);
4444

45-
static void init_payload_element(typeArrayOop arr, bool is_mask, BasicType elem_bt, int index, address addr);
45+
static void init_payload_element(typeArrayOop arr, BasicType elem_bt, int index, address addr);
4646

4747
static BasicType klass2bt(InstanceKlass* ik);
4848
static jint klass2length(InstanceKlass* ik);

0 commit comments

Comments
 (0)
Please sign in to comment.