--- old/src/hotspot/share/opto/vectorIntrinsics.cpp 2020-08-07 00:36:32.000000000 +0300 +++ new/src/hotspot/share/opto/vectorIntrinsics.cpp 2020-08-07 00:36:32.000000000 +0300 @@ -29,9 +29,9 @@ #include "opto/vectornode.hpp" #include "prims/vectorSupport.hpp" -bool LibraryCallKit::arch_supports_vector(int op, int num_elem, BasicType type, VectorMaskUseType mask_use_type) { +bool LibraryCallKit::arch_supports_vector(int sopc, int num_elem, BasicType type, VectorMaskUseType mask_use_type, bool has_scalar_args) { // Check that the operation is valid. - if (op <= 0) { + if (sopc <= 0) { #ifndef PRODUCT if (C->print_intrinsics()) { tty->print_cr(" ** Rejected intrinsification because no valid vector op could be extracted"); @@ -41,16 +41,25 @@ } // Check that architecture supports this op-size-type combination. - if (!Matcher::match_rule_supported_vector(op, num_elem, type)) { + if (!Matcher::match_rule_supported_vector(sopc, num_elem, type)) { #ifndef PRODUCT if (C->print_intrinsics()) { tty->print_cr(" ** Rejected vector op (%s,%s,%d) because architecture does not support it", - NodeClassNames[op], type2name(type), num_elem); + NodeClassNames[sopc], type2name(type), num_elem); } #endif return false; } else { - assert(Matcher::match_rule_supported(op), "must be supported"); + assert(Matcher::match_rule_supported(sopc), "must be supported"); + } + + if (!has_scalar_args && VectorNode::is_vector_shift(sopc) && + Matcher::supports_vector_variable_shifts() == false) { + if (C->print_intrinsics()) { + tty->print_cr(" ** Rejected vector op (%s,%s,%d) because architecture does not support variable vector shifts", + NodeClassNames[sopc], type2name(type), num_elem); + } + return false; } // Check whether mask unboxing is supported. @@ -82,30 +91,6 @@ return true; } -static int get_sopc(int opc, BasicType elem_bt, int arity) { -#ifdef X86 - // Variable shift handling - if (arity == 2) { - switch (opc) { - case Op_LShiftI: - case Op_LShiftL: - return Op_VLShiftV; - case Op_RShiftI: - case Op_RShiftL: - return Op_VRShiftV; - case Op_URShiftB: - case Op_URShiftS: - case Op_URShiftI: - case Op_URShiftL: - return Op_VURShiftV; - - default: break; - } - } -#endif - return VectorNode::opcode(opc, elem_bt); -} - static bool is_vector_mask(ciKlass* klass) { return klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass()); } @@ -114,6 +99,12 @@ return klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass()); } +static bool is_klass_initialized(const TypeInstPtr* vec_klass) { + assert(vec_klass->const_oop()->as_instance()->java_lang_Class_klass(), "klass instance expected"); + ciInstanceKlass* klass = vec_klass->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass(); + return klass->is_initialized(); +} + #ifdef ASSERT static bool is_vector(ciKlass* klass) { return klass->is_subclass_of(ciEnv::current()->vector_VectorPayload_klass()); @@ -215,10 +206,16 @@ } return false; // should be primitive type } + if (!is_klass_initialized(vector_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } BasicType elem_bt = elem_type->basic_type(); int num_elem = vlen->get_con(); int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt); - int sopc = get_sopc(opc, elem_bt, n); + int sopc = VectorNode::opcode(opc, elem_bt); ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); @@ -307,6 +304,12 @@ shuffle_klass->const_oop() == NULL || !wrap->is_con()) { return false; // not enough info for intrinsification } + if (!is_klass_initialized(shuffle_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } int do_wrap = wrap->get_con(); int num_elem = vlen->get_con(); @@ -386,9 +389,15 @@ Node* shuffle = argument(3); const TypeInt* vlen = gvn().type(argument(4))->is_int(); - if (!vlen->is_con() || shuffle_klass->const_oop() == NULL) { + if (!vlen->is_con() || vector_klass->const_oop() == NULL || shuffle_klass->const_oop() == NULL) { return false; // not enough info for intrinsification } + if (!is_klass_initialized(shuffle_klass) || !is_klass_initialized(vector_klass) ) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } int num_elem = vlen->get_con(); ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); @@ -443,6 +452,12 @@ return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) { @@ -457,7 +472,7 @@ // TODO When mask usage is supported, VecMaskNotUsed needs to be VecMaskUseLoad. if (!arch_supports_vector(VectorNode::replicate_opcode(elem_bt), num_elem, elem_bt, - is_vector_mask(vbox_klass) ? VecMaskUseStore : VecMaskNotUsed)) { + (is_vector_mask(vbox_klass) ? VecMaskUseStore : VecMaskNotUsed), true /*has_scalar_args*/)) { if (C->print_intrinsics()) { tty->print_cr(" ** not supported: arity=0 op=broadcast vlen=%d etype=%s ismask=%d", num_elem, type2name(elem_bt), @@ -531,6 +546,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { @@ -689,6 +710,12 @@ return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass) || !is_klass_initialized(vector_idx_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) { @@ -786,6 +813,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) { @@ -867,6 +900,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) { @@ -925,6 +964,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass) || !is_klass_initialized(mask_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) { @@ -991,6 +1036,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass) || !is_klass_initialized(mask_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) { @@ -1049,7 +1100,6 @@ if (shuffle_klass->const_oop() == NULL || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) { - return false; // not enough info for intrinsification if (C->print_intrinsics()) { tty->print_cr(" ** missing constant: vclass=%s sclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], @@ -1057,6 +1107,13 @@ NodeClassNames[argument(2)->Opcode()], NodeClassNames[argument(3)->Opcode()]); } + return false; // not enough info for intrinsification + } + if (!is_klass_initialized(vector_klass) || !is_klass_initialized(shuffle_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { @@ -1134,6 +1191,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) { @@ -1144,11 +1207,11 @@ BasicType elem_bt = elem_type->basic_type(); int num_elem = vlen->get_con(); int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt); - int sopc = get_sopc(opc, elem_bt, 1); // get_node_id(opr->get_con(), elem_bt); + int sopc = VectorNode::opcode(opc, elem_bt); ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); - if (!arch_supports_vector(sopc, num_elem, elem_bt, VecMaskNotUsed)) { + if (!arch_supports_vector(sopc, num_elem, elem_bt, VecMaskNotUsed, true /*has_scalar_args*/)) { if (C->print_intrinsics()) { tty->print_cr(" ** not supported: arity=0 op=int/%d vlen=%d etype=%s ismask=no", sopc, num_elem, type2name(elem_bt)); @@ -1203,6 +1266,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass_from) || !is_klass_initialized(vector_klass_to)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } assert(opr->get_con() == VectorSupport::VECTOR_OP_CAST || opr->get_con() == VectorSupport::VECTOR_OP_REINTERPRET, "wrong opcode"); @@ -1349,11 +1418,11 @@ return true; } -// public static -// > -// V insert(Class vectorClass, Class elementType, int vlen, -// V vec, int ix, long val, -// VecInsertOp defaultImpl) { +// public static +// > +// V insert(Class vectorClass, Class elementType, int vlen, +// V vec, int ix, long val, +// VecInsertOp defaultImpl) { // bool LibraryCallKit::inline_vector_insert() { const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); @@ -1371,6 +1440,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) { @@ -1455,6 +1530,12 @@ } return false; // not enough info for intrinsification } + if (!is_klass_initialized(vector_klass)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** klass argument not initialized"); + } + return false; + } ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); if (!elem_type->is_primitive_type()) { if (C->print_intrinsics()) {