mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8375498: [VectorAPI] Dump primary vector IR details with -XX:+TraceNewVectors
Reviewed-by: epeter
This commit is contained in:
parent
5c7c2f093b
commit
983ae96f60
@ -74,6 +74,11 @@ static bool is_vector_mask(ciKlass* klass) {
|
||||
return klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass());
|
||||
}
|
||||
|
||||
static Node* trace_vector(Node* operation) {
|
||||
VectorNode::trace_new_vector(operation, "VectorAPI");
|
||||
return operation;
|
||||
}
|
||||
|
||||
bool LibraryCallKit::arch_supports_vector_rotate(int opc, int num_elem, BasicType elem_bt,
|
||||
VectorMaskUseType mask_use_type, bool has_scalar_args) {
|
||||
bool is_supported = true;
|
||||
@ -458,7 +463,7 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
|
||||
}
|
||||
default: fatal("unsupported arity: %d", n);
|
||||
}
|
||||
|
||||
trace_vector(operation);
|
||||
if (is_masked_op && mask != nullptr) {
|
||||
if (use_predicate) {
|
||||
operation->add_req(mask);
|
||||
@ -466,7 +471,7 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
|
||||
} else {
|
||||
operation->add_flag(Node::Flag_is_predicated_using_blend);
|
||||
operation = gvn().transform(operation);
|
||||
operation = new VectorBlendNode(opd1, operation, mask);
|
||||
operation = trace_vector(new VectorBlendNode(opd1, operation, mask));
|
||||
}
|
||||
}
|
||||
operation = gvn().transform(operation);
|
||||
@ -627,7 +632,7 @@ bool LibraryCallKit::inline_vector_mask_operation() {
|
||||
mask_vec = gvn().transform(VectorStoreMaskNode::make(gvn(), mask_vec, elem_bt, num_elem));
|
||||
}
|
||||
const Type* maskoper_ty = mopc == Op_VectorMaskToLong ? (const Type*)TypeLong::LONG : (const Type*)TypeInt::INT;
|
||||
Node* maskoper = gvn().transform(VectorMaskOpNode::make(mask_vec, maskoper_ty, mopc));
|
||||
Node* maskoper = gvn().transform(trace_vector(VectorMaskOpNode::make(mask_vec, maskoper_ty, mopc)));
|
||||
if (mopc != Op_VectorMaskToLong) {
|
||||
maskoper = ConvI2L(maskoper);
|
||||
}
|
||||
@ -710,10 +715,10 @@ bool LibraryCallKit::inline_vector_frombits_coerced() {
|
||||
if (opc == Op_VectorLongToMask) {
|
||||
const TypeVect* vt = TypeVect::makemask(elem_bt, num_elem);
|
||||
if (Matcher::mask_op_prefers_predicate(opc, vt)) {
|
||||
broadcast = gvn().transform(new VectorLongToMaskNode(elem, vt));
|
||||
broadcast = gvn().transform(trace_vector(new VectorLongToMaskNode(elem, vt)));
|
||||
} else {
|
||||
const TypeVect* mvt = TypeVect::make(T_BOOLEAN, num_elem);
|
||||
broadcast = gvn().transform(new VectorLongToMaskNode(elem, mvt));
|
||||
broadcast = gvn().transform(trace_vector(new VectorLongToMaskNode(elem, mvt)));
|
||||
broadcast = gvn().transform(new VectorLoadMaskNode(broadcast, vt));
|
||||
}
|
||||
} else {
|
||||
@ -741,7 +746,7 @@ bool LibraryCallKit::inline_vector_frombits_coerced() {
|
||||
}
|
||||
default: fatal("%s", type2name(elem_bt));
|
||||
}
|
||||
broadcast = VectorNode::scalar2vector(elem, num_elem, elem_bt, is_mask);
|
||||
broadcast = trace_vector(VectorNode::scalar2vector(elem, num_elem, elem_bt, is_mask));
|
||||
broadcast = gvn().transform(broadcast);
|
||||
}
|
||||
|
||||
@ -927,22 +932,22 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
|
||||
if (is_mask) {
|
||||
val = gvn().transform(VectorStoreMaskNode::make(gvn(), val, elem_bt, num_elem));
|
||||
}
|
||||
Node* vstore = gvn().transform(StoreVectorNode::make(0, control(), memory(addr), addr, addr_type, val, store_num_elem));
|
||||
Node* vstore = gvn().transform(trace_vector(StoreVectorNode::make(0, control(), memory(addr), addr, addr_type, val, store_num_elem)));
|
||||
set_memory(vstore, addr_type);
|
||||
} else {
|
||||
// When using byte array, we need to load as byte then reinterpret the value. Otherwise, do a simple vector load.
|
||||
Node* vload = nullptr;
|
||||
if (mismatched_ms) {
|
||||
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, mem_num_elem, mem_elem_bt));
|
||||
vload = gvn().transform(trace_vector(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, mem_num_elem, mem_elem_bt)));
|
||||
const TypeVect* to_vect_type = TypeVect::make(elem_bt, num_elem);
|
||||
vload = gvn().transform(new VectorReinterpretNode(vload, vload->bottom_type()->is_vect(), to_vect_type));
|
||||
} else {
|
||||
// Special handle for masks
|
||||
if (is_mask) {
|
||||
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, T_BOOLEAN));
|
||||
vload = gvn().transform(trace_vector(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, T_BOOLEAN)));
|
||||
vload = gvn().transform(new VectorLoadMaskNode(vload, TypeVect::makemask(elem_bt, num_elem)));
|
||||
} else {
|
||||
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, elem_bt));
|
||||
vload = gvn().transform(trace_vector(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, elem_bt)));
|
||||
}
|
||||
}
|
||||
Node* box = box_vector(vload, vbox_type, elem_bt, num_elem);
|
||||
@ -1140,7 +1145,7 @@ bool LibraryCallKit::inline_vector_mem_masked_operation(bool is_store) {
|
||||
const TypeVect* to_mask_type = TypeVect::makemask(mem_elem_bt, mem_num_elem);
|
||||
mask = gvn().transform(new VectorReinterpretNode(mask, from_mask_type, to_mask_type));
|
||||
}
|
||||
Node* vstore = gvn().transform(new StoreVectorMaskedNode(control(), memory(addr), addr, val, addr_type, mask));
|
||||
Node* vstore = gvn().transform(trace_vector(new StoreVectorMaskedNode(control(), memory(addr), addr, val, addr_type, mask)));
|
||||
set_memory(vstore, addr_type);
|
||||
} else {
|
||||
Node* vload = nullptr;
|
||||
@ -1155,13 +1160,13 @@ bool LibraryCallKit::inline_vector_mem_masked_operation(bool is_store) {
|
||||
if (supports_predicate) {
|
||||
// Generate masked load vector node if predicate feature is supported.
|
||||
const TypeVect* vt = TypeVect::make(mem_elem_bt, mem_num_elem);
|
||||
vload = gvn().transform(new LoadVectorMaskedNode(control(), memory(addr), addr, addr_type, vt, mask));
|
||||
vload = gvn().transform(trace_vector(new LoadVectorMaskedNode(control(), memory(addr), addr, addr_type, vt, mask)));
|
||||
} else {
|
||||
// Use the vector blend to implement the masked load vector. The biased elements are zeros.
|
||||
Node* zero = gvn().transform(gvn().zerocon(mem_elem_bt));
|
||||
zero = gvn().transform(VectorNode::scalar2vector(zero, mem_num_elem, mem_elem_bt));
|
||||
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, mem_num_elem, mem_elem_bt));
|
||||
vload = gvn().transform(new VectorBlendNode(zero, vload, mask));
|
||||
vload = gvn().transform(trace_vector(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, mem_num_elem, mem_elem_bt)));
|
||||
vload = gvn().transform(trace_vector(new VectorBlendNode(zero, vload, mask)));
|
||||
}
|
||||
|
||||
if (mismatched_ms) {
|
||||
@ -1365,17 +1370,17 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
|
||||
|
||||
Node* vstore = nullptr;
|
||||
if (mask != nullptr) {
|
||||
vstore = gvn().transform(new StoreVectorScatterMaskedNode(control(), memory(addr), addr, addr_type, val, indexes, mask));
|
||||
vstore = gvn().transform(trace_vector(new StoreVectorScatterMaskedNode(control(), memory(addr), addr, addr_type, val, indexes, mask)));
|
||||
} else {
|
||||
vstore = gvn().transform(new StoreVectorScatterNode(control(), memory(addr), addr, addr_type, val, indexes));
|
||||
vstore = gvn().transform(trace_vector(new StoreVectorScatterNode(control(), memory(addr), addr, addr_type, val, indexes)));
|
||||
}
|
||||
set_memory(vstore, addr_type);
|
||||
} else {
|
||||
Node* vload = nullptr;
|
||||
if (mask != nullptr) {
|
||||
vload = gvn().transform(new LoadVectorGatherMaskedNode(control(), memory(addr), addr, addr_type, vector_type, indexes, mask));
|
||||
vload = gvn().transform(trace_vector(new LoadVectorGatherMaskedNode(control(), memory(addr), addr, addr_type, vector_type, indexes, mask)));
|
||||
} else {
|
||||
vload = gvn().transform(new LoadVectorGatherNode(control(), memory(addr), addr, addr_type, vector_type, indexes));
|
||||
vload = gvn().transform(trace_vector(new LoadVectorGatherNode(control(), memory(addr), addr, addr_type, vector_type, indexes)));
|
||||
}
|
||||
Node* box = box_vector(vload, vbox_type, elem_bt, num_elem);
|
||||
set_result(box);
|
||||
@ -1493,7 +1498,7 @@ bool LibraryCallKit::inline_vector_reduction() {
|
||||
|
||||
// Make an unordered Reduction node. This affects only AddReductionVF/VD and MulReductionVF/VD,
|
||||
// as these operations are allowed to be associative (not requiring strict order) in VectorAPI.
|
||||
value = ReductionNode::make(opc, nullptr, init, value, elem_bt, /* requires_strict_order */ false);
|
||||
value = trace_vector(ReductionNode::make(opc, nullptr, init, value, elem_bt, /* requires_strict_order */ false));
|
||||
|
||||
if (mask != nullptr && use_predicate) {
|
||||
value->add_req(mask);
|
||||
@ -1585,7 +1590,7 @@ bool LibraryCallKit::inline_vector_test() {
|
||||
return false; // operand unboxing failed
|
||||
}
|
||||
|
||||
Node* cmp = gvn().transform(new VectorTestNode(opd1, opd2, booltest));
|
||||
Node* cmp = gvn().transform(trace_vector(new VectorTestNode(opd1, opd2, booltest)));
|
||||
BoolTest::mask test = Matcher::vectortest_mask(booltest == BoolTest::overflow,
|
||||
opd1->bottom_type()->isa_vectmask(), num_elem);
|
||||
Node* bol = gvn().transform(new BoolNode(cmp, test));
|
||||
@ -1653,7 +1658,7 @@ bool LibraryCallKit::inline_vector_blend() {
|
||||
return false; // operand unboxing failed
|
||||
}
|
||||
|
||||
Node* blend = gvn().transform(new VectorBlendNode(v1, v2, mask));
|
||||
Node* blend = gvn().transform(trace_vector(new VectorBlendNode(v1, v2, mask)));
|
||||
|
||||
Node* box = box_vector(blend, vbox_type, elem_bt, num_elem);
|
||||
set_result(box);
|
||||
@ -1748,6 +1753,7 @@ bool LibraryCallKit::inline_vector_compare() {
|
||||
|
||||
const TypeVect* vmask_type = TypeVect::makemask(mask_bt, num_elem);
|
||||
Node* operation = new VectorMaskCmpNode(pred, v1, v2, pred_node, vmask_type);
|
||||
trace_vector(operation);
|
||||
|
||||
if (is_masked_op) {
|
||||
if (use_predicate) {
|
||||
@ -1887,6 +1893,7 @@ bool LibraryCallKit::inline_vector_rearrange() {
|
||||
}
|
||||
|
||||
Node* rearrange = new VectorRearrangeNode(v1, shuffle);
|
||||
trace_vector(rearrange);
|
||||
if (is_masked_op) {
|
||||
if (use_predicate) {
|
||||
rearrange->add_req(mask);
|
||||
@ -2034,6 +2041,7 @@ bool LibraryCallKit::inline_vector_select_from() {
|
||||
|
||||
// and finally rearrange
|
||||
Node* rearrange = new VectorRearrangeNode(v2, shuffle);
|
||||
trace_vector(rearrange);
|
||||
if (is_masked_op) {
|
||||
if (use_predicate) {
|
||||
// masked rearrange is supported so use that directly
|
||||
@ -2193,6 +2201,7 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
|
||||
}
|
||||
|
||||
Node* operation = VectorNode::make(opc, opd1, opd2, num_elem, elem_bt);
|
||||
trace_vector(operation);
|
||||
if (is_masked_op && mask != nullptr) {
|
||||
if (use_predicate) {
|
||||
operation->add_req(mask);
|
||||
@ -2370,7 +2379,7 @@ bool LibraryCallKit::inline_vector_convert() {
|
||||
return false;
|
||||
}
|
||||
|
||||
op = gvn().transform(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_for_cast));
|
||||
op = gvn().transform(trace_vector(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_for_cast)));
|
||||
// Now ensure that the destination gets properly resized to needed size.
|
||||
op = gvn().transform(new VectorReinterpretNode(op, op->bottom_type()->is_vect(), dst_type));
|
||||
} else if (num_elem_from > num_elem_to) {
|
||||
@ -2391,7 +2400,7 @@ bool LibraryCallKit::inline_vector_convert() {
|
||||
|
||||
const TypeVect* resize_type = TypeVect::make(elem_bt_from, num_elem_for_resize);
|
||||
op = gvn().transform(new VectorReinterpretNode(op, src_type, resize_type));
|
||||
op = gvn().transform(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_to));
|
||||
op = gvn().transform(trace_vector(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_to)));
|
||||
} else { // num_elem_from == num_elem_to
|
||||
if (is_mask) {
|
||||
// Make sure that cast for vector mask is implemented to particular type/size combination.
|
||||
@ -2400,16 +2409,16 @@ bool LibraryCallKit::inline_vector_convert() {
|
||||
num_elem_to, type2name(elem_bt_to), is_mask);
|
||||
return false;
|
||||
}
|
||||
op = gvn().transform(new VectorMaskCastNode(op, dst_type));
|
||||
op = gvn().transform(trace_vector(new VectorMaskCastNode(op, dst_type)));
|
||||
} else {
|
||||
// Since input and output number of elements match, and since we know this vector size is
|
||||
// supported, simply do a cast with no resize needed.
|
||||
op = gvn().transform(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_to));
|
||||
op = gvn().transform(trace_vector(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_to)));
|
||||
}
|
||||
}
|
||||
} else if (!Type::equals(src_type, dst_type)) {
|
||||
assert(!is_cast, "must be reinterpret");
|
||||
op = gvn().transform(new VectorReinterpretNode(op, src_type, dst_type));
|
||||
op = gvn().transform(trace_vector(new VectorReinterpretNode(op, src_type, dst_type)));
|
||||
}
|
||||
|
||||
const TypeInstPtr* vbox_type_to = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass_to);
|
||||
@ -2494,7 +2503,7 @@ bool LibraryCallKit::inline_vector_insert() {
|
||||
default: fatal("%s", type2name(elem_bt)); break;
|
||||
}
|
||||
|
||||
Node* operation = gvn().transform(VectorInsertNode::make(opd, insert_val, idx->get_con(), gvn()));
|
||||
Node* operation = gvn().transform(trace_vector(VectorInsertNode::make(opd, insert_val, idx->get_con(), gvn())));
|
||||
|
||||
Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem);
|
||||
set_result(vbox);
|
||||
@ -2552,7 +2561,7 @@ bool LibraryCallKit::inline_vector_extract() {
|
||||
if (opd == nullptr) {
|
||||
return false;
|
||||
}
|
||||
opd = gvn().transform(VectorStoreMaskNode::make(gvn(), opd, elem_bt, num_elem));
|
||||
opd = gvn().transform(trace_vector(VectorStoreMaskNode::make(gvn(), opd, elem_bt, num_elem)));
|
||||
opd = gvn().transform(new ExtractUBNode(opd, pos));
|
||||
opd = gvn().transform(new ConvI2LNode(opd));
|
||||
} else if (arch_supports_vector(Op_VectorMaskToLong, num_elem, elem_bt, VecMaskUseLoad)) {
|
||||
@ -2562,7 +2571,7 @@ bool LibraryCallKit::inline_vector_extract() {
|
||||
}
|
||||
// VectorMaskToLongNode requires the input is either a mask or a vector with BOOLEAN type.
|
||||
if (!Matcher::mask_op_prefers_predicate(Op_VectorMaskToLong, opd->bottom_type()->is_vect())) {
|
||||
opd = gvn().transform(VectorStoreMaskNode::make(gvn(), opd, elem_bt, num_elem));
|
||||
opd = gvn().transform(trace_vector(VectorStoreMaskNode::make(gvn(), opd, elem_bt, num_elem)));
|
||||
}
|
||||
// ((toLong() >>> pos) & 1L
|
||||
opd = gvn().transform(new VectorMaskToLongNode(opd, TypeLong::LONG));
|
||||
@ -2680,8 +2689,8 @@ static Node* LowerSelectFromTwoVectorOperation(PhaseGVN& phase, Node* index_vec,
|
||||
vmask_type = TypeVect::makemask(elem_bt, num_elem);
|
||||
mask = phase.transform(new VectorMaskCastNode(mask, vmask_type));
|
||||
|
||||
Node* p1 = phase.transform(new VectorRearrangeNode(src1, wrapped_index_vec));
|
||||
Node* p2 = phase.transform(new VectorRearrangeNode(src2, wrapped_index_vec));
|
||||
Node* p1 = phase.transform(trace_vector(new VectorRearrangeNode(src1, wrapped_index_vec)));
|
||||
Node* p2 = phase.transform(trace_vector(new VectorRearrangeNode(src2, wrapped_index_vec)));
|
||||
|
||||
return new VectorBlendNode(p2, p1, mask);
|
||||
}
|
||||
@ -2799,7 +2808,7 @@ bool LibraryCallKit::inline_vector_select_from_two_vectors() {
|
||||
Node* wrap_mask = gvn().makecon(TypeInteger::make(indexRangeMask, indexRangeMask, Type::WidenMin, index_elem_bt != T_LONG ? T_INT : index_elem_bt));
|
||||
Node* wrap_mask_vec = gvn().transform(VectorNode::scalar2vector(wrap_mask, num_elem, index_elem_bt, false));
|
||||
opd1 = gvn().transform(VectorNode::make(Op_AndV, opd1, wrap_mask_vec, opd1->bottom_type()->is_vect()));
|
||||
operation = gvn().transform(VectorNode::make(Op_SelectFromTwoVector, opd1, opd2, opd3, vt));
|
||||
operation = gvn().transform(trace_vector(VectorNode::make(Op_SelectFromTwoVector, opd1, opd2, opd3, vt)));
|
||||
}
|
||||
|
||||
// Wrap it up in VectorBox to keep object type information.
|
||||
@ -2884,7 +2893,7 @@ bool LibraryCallKit::inline_vector_compress_expand() {
|
||||
}
|
||||
|
||||
const TypeVect* vt = TypeVect::make(elem_bt, num_elem, opc == Op_CompressM);
|
||||
Node* operation = gvn().transform(VectorNode::make(opc, opd1, mask, vt));
|
||||
Node* operation = gvn().transform(trace_vector(VectorNode::make(opc, opd1, mask, vt)));
|
||||
|
||||
// Wrap it up in VectorBox to keep object type information.
|
||||
const TypeInstPtr* box_type = opc == Op_CompressM ? mbox_type : vbox_type;
|
||||
@ -3017,12 +3026,12 @@ bool LibraryCallKit::inline_index_vector() {
|
||||
default: fatal("%s", type2name(elem_bt));
|
||||
}
|
||||
scale = gvn().transform(VectorNode::scalar2vector(scale, num_elem, elem_bt));
|
||||
index = gvn().transform(VectorNode::make(vmul_op, index, scale, vt));
|
||||
index = gvn().transform(trace_vector(VectorNode::make(vmul_op, index, scale, vt)));
|
||||
}
|
||||
|
||||
// Add "opd" if addition is needed.
|
||||
if (needs_add) {
|
||||
index = gvn().transform(VectorNode::make(vadd_op, opd, index, vt));
|
||||
index = gvn().transform(trace_vector(VectorNode::make(vadd_op, opd, index, vt)));
|
||||
}
|
||||
Node* vbox = box_vector(index, vbox_type, elem_bt, num_elem);
|
||||
set_result(vbox);
|
||||
@ -3139,7 +3148,7 @@ bool LibraryCallKit::inline_index_partially_in_upper_range() {
|
||||
// Compute the vector mask with "mask = iota < indexLimit".
|
||||
ConINode* pred_node = (ConINode*)gvn().makecon(TypeInt::make(BoolTest::lt));
|
||||
const TypeVect* vmask_type = TypeVect::makemask(elem_bt, num_elem);
|
||||
mask = gvn().transform(new VectorMaskCmpNode(BoolTest::lt, iota, indexLimit, pred_node, vmask_type));
|
||||
mask = gvn().transform(trace_vector(new VectorMaskCmpNode(BoolTest::lt, iota, indexLimit, pred_node, vmask_type)));
|
||||
}
|
||||
Node* vbox = box_vector(mask, box_type, elem_bt, num_elem);
|
||||
set_result(vbox);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user