< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page

        

@@ -334,10 +334,11 @@
   bool inline_vector_broadcast_coerced();
   bool inline_vector_mem_operation(bool is_store);
   bool inline_vector_reduction();
   bool inline_vector_test();
   bool inline_vector_blend();
+  bool inline_vector_rearrange();
   bool inline_vector_compare();
   bool inline_vector_broadcast_int();
   bool inline_vector_cast_reinterpret(bool is_cast);
   bool inline_vector_extract();
   bool inline_vector_insert();

@@ -906,10 +907,12 @@
     return inline_vector_reduction();
   case vmIntrinsics::_VectorTest:
     return inline_vector_test();
   case vmIntrinsics::_VectorBlend:
     return inline_vector_blend();
+  case vmIntrinsics::_VectorRearrange:
+    return inline_vector_rearrange();
   case vmIntrinsics::_VectorCompare:
     return inline_vector_compare();
   case vmIntrinsics::_VectorBroadcastInt:
     return inline_vector_broadcast_int();
   case vmIntrinsics::_VectorReinterpret:

@@ -7283,10 +7286,61 @@
 
   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
   return true;
 }
 
+// static
+// <V extends Vector, Sh extends Shuffle>
+//  V rearrangeOp(Class<V> vectorClass, Class<Sh> shuffleClass, Class< ? > elementType, int vlen,
+//    V v1, Sh sh,
+//    VectorSwizzleOp<V, Sh, S, E> defaultImpl) { ...
+
+bool LibraryCallKit::inline_vector_rearrange() {
+  const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
+  const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->is_instptr();
+  const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
+  const TypeInt*     vlen = gvn().type(argument(3))->is_int();
+
+  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
+  }
+  ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type();
+  if (!elem_type->is_primitive_type()) {
+    return false; // should be primitive type
+  }
+  BasicType elem_bt = elem_type->basic_type();
+  BasicType shuffle_bt = elem_bt;
+  int num_elem = vlen->get_con();
+
+  if (!arch_supports_vector(Op_VectorLoadShuffle, num_elem, elem_bt, VecMaskNotUsed)) {
+    return false; // not supported
+  }
+  if (!arch_supports_vector(Op_VectorRearrange, num_elem, elem_bt, VecMaskNotUsed)) {
+    return false; // not supported
+  }
+  ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
+  const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
+
+  ciKlass* shbox_klass = shuffle_klass->const_oop()->as_instance()->java_lang_Class_klass();
+  const TypeInstPtr* shbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, shbox_klass);
+
+  Node* v1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem);
+  Node* shuffle = unbox_vector(argument(5), shbox_type, shuffle_bt, num_elem);
+
+  if (v1 == NULL || shuffle == NULL) {
+    return false; // operand unboxing failed
+  }
+
+  Node* rearrange = _gvn.transform(new VectorRearrangeNode(v1, shuffle));
+  Node* box = box_vector(rearrange, vbox_type, elem_bt, num_elem);
+  set_result(box);
+
+  C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
+  return true;
+}
+
 Node* LibraryCallKit::shift_count(Node* cnt, int shift_op, BasicType bt, int num_elem) {
   assert(bt == T_INT || bt == T_LONG, "Only long and int are supported");
   juint mask = (bt == T_INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
   const TypeInt* t = cnt->find_int_type();
   if (t != NULL && t->is_con()) {
< prev index next >