< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page

        

*** 332,341 **** --- 332,343 ---- bool inline_isCompileConstant(); // Vector API support bool inline_vector_nary_operation(int n); bool inline_vector_broadcast_coerced(); + bool inline_vector_shuffle_to_vector(); + bool inline_vector_shuffle_iota(); bool inline_vector_mem_operation(bool is_store); bool inline_vector_gather_scatter(bool is_scatter); bool inline_vector_reduction(); bool inline_vector_test(); bool inline_vector_blend();
*** 908,917 **** --- 910,923 ---- return inline_vector_nary_operation(2); case vmIntrinsics::_VectorTernaryOp: return inline_vector_nary_operation(3); case vmIntrinsics::_VectorBroadcastCoerced: return inline_vector_broadcast_coerced(); + case vmIntrinsics::_VectorShuffleIota: + return inline_vector_shuffle_iota(); + case vmIntrinsics::_VectorShuffleToVector: + return inline_vector_shuffle_to_vector(); case vmIntrinsics::_VectorLoadOp: return inline_vector_mem_operation(/*is_store=*/false); case vmIntrinsics::_VectorStoreOp: return inline_vector_mem_operation(/*is_store=*/true); case vmIntrinsics::_VectorGatherOp:
*** 6987,6996 **** --- 6993,7093 ---- C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); return true; } + // <Sh extends VectorShuffle<E>, E> + // Sh ShuffleIota(Class<?> E, Class<?> ShuffleClass, Vector.Species<E> s, int length, + // int step, ShuffleIotaOperation<Sh, E> defaultImpl) + bool LibraryCallKit::inline_vector_shuffle_iota() { + const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->is_instptr(); + const TypeInt* vlen = gvn().type(argument(3))->is_int(); + Node* step = argument(4); + + if (!vlen->is_con() || shuffle_klass->const_oop() == NULL) { + return false; // not enough info for intrinsification + } + + int num_elem = vlen->get_con(); + BasicType elem_bt = T_BYTE; + + if (num_elem < 4) + return false; + + if (!arch_supports_vector(VectorNode::replicate_opcode(elem_bt), num_elem, elem_bt, VecMaskNotUsed)) { + return false; + } + if (!arch_supports_vector(Op_AddVB, num_elem, elem_bt, VecMaskNotUsed)) { + return false; + } + if (!arch_supports_vector(Op_AndV, num_elem, elem_bt, VecMaskNotUsed)) { + return false; + } + + const TypeVect * vt = TypeVect::make(Type::get_const_basic_type(elem_bt), num_elem); + + Node* iota = _gvn.transform(new VectorLoadConstNode(gvn().makecon(TypeInt::ZERO), vt)); + Node* bcast_step = _gvn.transform(VectorNode::scalar2vector(step, num_elem, Type::get_const_basic_type(elem_bt))); + + Node* bcast_mod = _gvn.transform(VectorNode::scalar2vector(gvn().makecon(TypeInt::make(num_elem-1)), + num_elem, Type::get_const_basic_type(elem_bt))); + Node* add = _gvn.transform(VectorNode::make(Op_AddI, iota, bcast_step, num_elem, elem_bt)); + Node* res = _gvn.transform(VectorNode::make(Op_AndI, add, bcast_mod, num_elem, elem_bt)); + + ciKlass* sbox_klass = shuffle_klass->const_oop()->as_instance()->java_lang_Class_klass(); + const TypeInstPtr* shuffle_box_type = TypeInstPtr::make_exact(TypePtr::NotNull, sbox_klass); + + // Wrap it up in VectorBox to keep object type information. + res = box_vector(res, shuffle_box_type, elem_bt, num_elem); + + set_vector_result(res); + C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); + return true; + } + + // <VM ,Sh extends VectorShuffle<E>, E> + // VM shuffleToVector(Class<VM> VecClass, Class<?>E , Class<?> ShuffleClass, Sh s, int length, + // ShuffleToVectorOperation<VM,Sh,E> defaultImpl) + bool LibraryCallKit::inline_vector_shuffle_to_vector() { + const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); + const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr(); + const TypeInstPtr* shuffle_klass = gvn().type(argument(2))->is_instptr(); + Node* shuffle = argument(3); + const TypeInt* vlen = gvn().type(argument(4))->is_int(); + + if (!vlen->is_con() || shuffle_klass->const_oop() == NULL) { + return false; // not enough info for intrinsification + } + + int num_elem = vlen->get_con(); + ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); + BasicType elem_bt = elem_type->basic_type(); + + if (num_elem < 4) { + return false; + } + + if (!arch_supports_vector(Op_VectorLoadShuffle, num_elem, elem_bt, VecMaskNotUsed)) { + return false; // not supported + } + + ciKlass* sbox_klass = shuffle_klass->const_oop()->as_instance()->java_lang_Class_klass(); + const TypeInstPtr* shuffle_box_type = TypeInstPtr::make_exact(TypePtr::NotNull, sbox_klass); + + // Unbox shuffle + Node* shuffle_vec = unbox_vector(shuffle, shuffle_box_type, elem_bt, num_elem); + + ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); + const TypeInstPtr* vec_box_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); + + // Box vector + Node* res = box_vector(shuffle_vec, vec_box_type, elem_bt, num_elem); + set_vector_result(res); + C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); + return true; + } + // <V extends Vector<?,?>> // V broadcastCoerced(Class<?> vectorClass, Class<?> elementType, int vlen, // long bits, // LongFunction<V> defaultImpl) bool LibraryCallKit::inline_vector_broadcast_coerced() {
< prev index next >