< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page
rev 49509 : [vector] Intrinsic support for resize


 322   bool inline_hasNegatives();
 323   bool inline_squareToLen();
 324   bool inline_mulAdd();
 325   bool inline_montgomeryMultiply();
 326   bool inline_montgomerySquare();
 327   bool inline_vectorizedMismatch();
 328   bool inline_fma(vmIntrinsics::ID id);
 329 
 330   bool inline_profileBoolean();
 331   bool inline_isCompileConstant();
 332 
 333   // Vector API support
 334   bool inline_vector_nary_operation(int n);
 335   bool inline_vector_broadcast_coerced();
 336   bool inline_vector_mem_operation(bool is_store);
 337   bool inline_vector_reduction();
 338   bool inline_vector_test();
 339   bool inline_vector_blend();
 340   bool inline_vector_compare();
 341   bool inline_vector_broadcast_int();
 342   bool inline_vector_rebracket();
 343   Node* box_vector(Node* in, const TypeInstPtr* vbox_type, BasicType bt, int num_elem);
 344   Node* unbox_vector(Node* in, const TypeInstPtr* vbox_type, BasicType bt, int num_elem);
 345   Node* shift_count(Node* cnt, int shift_op, BasicType bt, int num_elem);

 346 
 347   void clear_upper_avx() {
 348 #ifdef X86
 349     if (UseAVX >= 2) {
 350       C->set_clear_upper_avx(true);
 351     }
 352 #endif
 353   }
 354 };
 355 
 356 //---------------------------make_vm_intrinsic----------------------------
 357 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
 358   vmIntrinsics::ID id = m->intrinsic_id();
 359   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 360 
 361   if (!m->is_loaded()) {
 362     // Do not attempt to inline unloaded methods.
 363     return NULL;
 364   }
 365 


 890     return inline_vector_nary_operation(2);
 891   case vmIntrinsics::_VectorTernaryOp:
 892     return inline_vector_nary_operation(3);
 893 
 894   case vmIntrinsics::_VectorBroadcastCoerced:
 895     return inline_vector_broadcast_coerced();
 896   case vmIntrinsics::_VectorLoadOp:
 897     return inline_vector_mem_operation(/*is_store=*/false);
 898   case vmIntrinsics::_VectorStoreOp:
 899     return inline_vector_mem_operation(/*is_store=*/true);
 900   case vmIntrinsics::_VectorReductionCoerced:
 901     return inline_vector_reduction();
 902   case vmIntrinsics::_VectorTest:
 903     return inline_vector_test();
 904   case vmIntrinsics::_VectorBlend:
 905     return inline_vector_blend();
 906   case vmIntrinsics::_VectorCompare:
 907     return inline_vector_compare();
 908   case vmIntrinsics::_VectorBroadcastInt:
 909     return inline_vector_broadcast_int();
 910   case vmIntrinsics::_VectorRebracket:
 911     return inline_vector_rebracket();
 912 
 913   default:
 914     // If you get here, it may be that someone has added a new intrinsic
 915     // to the list in vmSymbols.hpp without implementing it here.
 916 #ifndef PRODUCT
 917     if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
 918       tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
 919                     vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
 920     }
 921 #endif
 922     return false;
 923   }
 924 }
 925 
 926 Node* LibraryCallKit::try_to_predicate(int predicate) {
 927   if (!jvms()->has_method()) {
 928     // Root JVMState has a null method.
 929     assert(map()->memory()->Opcode() == Op_Parm, "");
 930     // Insert the memory aliasing node
 931     set_all_memory(reset_memory());


7170   set_all_memory(_gvn.transform( new ProjNode(alloc, TypeFunc::Memory) ));
7171   Node* ret = _gvn.transform(new ProjNode(alloc, TypeFunc::Parms));
7172 
7173   VectorBoxNode* vbox = new VectorBoxNode(C, ret, vector, vbox_type, vec_type);
7174   return _gvn.transform(vbox);
7175 }
7176 
7177 Node* LibraryCallKit::unbox_vector(Node* v, const TypeInstPtr* vbox_type, BasicType elem_bt, int num_elem) {
7178   const TypeInstPtr* vbox_type_v = gvn().type(v)->is_instptr();
7179   if (vbox_type->klass() != vbox_type_v->klass()) {
7180     return NULL; // arguments don't agree on vector shapes
7181   }
7182   if (vbox_type_v->maybe_null()) {
7183     return NULL; // no nulls are allowed
7184   }
7185   const TypeVect* vec_type = TypeVect::make(elem_bt, num_elem);
7186   Node* unbox = gvn().transform(new VectorUnboxNode(C, vec_type, v, merged_memory()));
7187   return unbox;
7188 }
7189 













7190 bool LibraryCallKit::inline_vector_nary_operation(int n) {
7191   const TypeInt* opr              = gvn().type(argument(0))->is_int();
7192   const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
7193   const TypeInstPtr* elem_klass   = gvn().type(argument(2))->is_instptr();
7194   const TypeInt* vlen             = gvn().type(argument(3))->is_int();
7195 
7196   if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
7197     return false; // not enough info for intrinsification
7198   }
7199   ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type();
7200   if (!elem_type->is_primitive_type()) {
7201     return false; // should be primitive type
7202   }
7203   BasicType elem_bt = elem_type->basic_type();
7204   int num_elem = vlen->get_con();
7205   int opc = get_opc(opr->get_con(), elem_bt);
7206   int sopc = VectorNode::opcode(opc, elem_bt); // get_node_id(opr->get_con(), elem_bt);
7207   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7208   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7209 


7236       break;
7237     }
7238     default: fatal("unsupported arity: %d", n);
7239   }
7240 
7241   Node* operation = NULL;
7242   switch (n) {
7243     case 1:
7244     case 2: {
7245       operation = _gvn.transform(VectorNode::make(sopc, opd1, opd2, num_elem, elem_bt));
7246       break;
7247     }
7248     case 3: {
7249       operation = _gvn.transform(VectorNode::make(sopc, opd1, opd2, opd3, num_elem, elem_bt));
7250       break;
7251     }
7252     default: fatal("unsupported arity: %d", n);
7253   }
7254   // Wrap it up in VectorBox to keep object type information.
7255   operation = box_vector(operation, vbox_type, elem_bt, num_elem);
7256   set_result(operation);
7257 
7258   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7259   return true;
7260 }
7261 
7262 // <V extends Vector<?,?>>
7263 // V broadcastCoerced(Class<?> vectorClass, Class<?> elementType, int vlen,
7264 //                    long bits,
7265 //                    LongFunction<V> defaultImpl)
7266 bool LibraryCallKit::inline_vector_broadcast_coerced() {
7267   const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
7268   const TypeInstPtr* elem_klass   = gvn().type(argument(1))->is_instptr();
7269   const TypeInt* vlen             = gvn().type(argument(2))->is_int();
7270 
7271   if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
7272     return false; // not enough info for intrinsification
7273   }
7274 
7275   ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type();
7276   if (!elem_type->is_primitive_type()) {


7301     }
7302     case T_DOUBLE: {
7303       elem = gvn().transform(new MoveL2DNode(bits));
7304       break;
7305     }
7306     case T_FLOAT: {
7307       bits = gvn().transform(new ConvL2INode(bits));
7308       elem = gvn().transform(new MoveI2FNode(bits));
7309       break;
7310     }
7311     case T_LONG: {
7312       elem = bits; // no conversion needed
7313       break;
7314     }
7315     default: fatal("%s", type2name(elem_bt));
7316   }
7317 
7318   Node* broadcast = VectorNode::scalar2vector(elem, num_elem, Type::get_const_basic_type(elem_bt));
7319   broadcast = gvn().transform(broadcast);
7320   Node* box = box_vector(broadcast, vbox_type, elem_bt, num_elem);
7321   set_result(box);
7322 
7323   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7324   return true;
7325 }
7326 
7327 //    <V extends Vector<?,?>>
7328 //    V load(Class<?> vectorClass, Class<?> elementType, int vlen,
7329 //           Object array, int index, /* Vector.Mask<E,S> m*/
7330 //           BiFunction<Object, Integer, V> defaultImpl) {
7331 //
7332 //    <V extends Vector<?,?>>
7333 //    void store(Class<?> vectorClass, Class<?> elementType, int vlen,
7334 //               Object array, int index, V v, /*Vector.Mask<E,S> m*/
7335 //               StoreVectorOperation<V> defaultImpl) {
7336 
7337 bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
7338   const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
7339   const TypeInstPtr* elem_klass   = gvn().type(argument(1))->is_instptr();
7340   const TypeInt* vlen             = gvn().type(argument(2))->is_int();
7341 


7362   if (arr_type == NULL) {
7363     return false; // should be an array
7364   }
7365   if (elem_bt != arr_type->elem()->array_element_basic_type()) {
7366     return false; // array & vector element types should be the same
7367   }
7368   Node* adr = array_element_address(arr, idx,  elem_bt);
7369   const TypePtr* adr_type = adr->bottom_type()->is_ptr();
7370 
7371   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7372   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7373 
7374   if (is_store) {
7375     Node* val = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
7376     if (val == NULL) {
7377       return false; // operand unboxing failed
7378     }
7379     set_all_memory(reset_memory());
7380     Node* vstore = gvn().transform(StoreVectorNode::make(0, control(), memory(adr), adr, adr_type, val, num_elem));
7381     set_memory(vstore, adr_type);

7382   } else {
7383     Node* vload = gvn().transform(LoadVectorNode::make(0, control(), memory(adr), adr, adr_type, num_elem, elem_bt));
7384     Node* box = box_vector(vload, vbox_type, elem_bt, num_elem);
7385     set_result(box);
7386   }
7387 
7388   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7389   return true;
7390 }
7391 
7392 // <V extends Vector<?,?>>
7393 // long reductionCoerced(int oprId, Class<?> vectorClass, Class<?> elementType, int vlen,
7394 //                       V v,
7395 //                       Function<V,Long> defaultImpl)
7396 
7397 bool LibraryCallKit::inline_vector_reduction() {
7398   const TypeInt* opr              = gvn().type(argument(0))->is_int();
7399   const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
7400   const TypeInstPtr* elem_klass   = gvn().type(argument(2))->is_instptr();
7401   const TypeInt* vlen             = gvn().type(argument(3))->is_int();
7402 
7403   if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
7404     return false; // not enough info for intrinsification
7405   }


7433   switch (elem_bt) {
7434     case T_INT: {
7435       bits = gvn().transform(new ConvI2LNode(rn));
7436       break;
7437     }
7438     case T_FLOAT: {
7439       rn   = gvn().transform(new MoveF2INode(rn));
7440       bits = gvn().transform(new ConvI2LNode(rn));
7441       break;
7442     }
7443     case T_DOUBLE: {
7444       bits = gvn().transform(new MoveD2LNode(rn));
7445       break;
7446     }
7447     case T_LONG: {
7448       bits = rn; // no conversion needed
7449       break;
7450     }
7451     default: fatal("%s", type2name(elem_bt));
7452   }
7453   set_result(bits);
7454   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7455   return true;
7456 }
7457 
7458 // static <V> boolean test(int cond, Class<?> vectorClass, Class<?> elementType, int vlen,
7459 //                         V v1, V v2,
7460 //                         BiFunction<V, V, Boolean> defaultImpl) {
7461 
7462 bool LibraryCallKit::inline_vector_test() {
7463   const TypeInt* cond             = gvn().type(argument(0))->is_int();
7464   const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
7465   const TypeInstPtr* elem_klass   = gvn().type(argument(2))->is_instptr();
7466   const TypeInt* vlen             = gvn().type(argument(3))->is_int();
7467 
7468   if (!cond->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
7469     return false; // not enough info for intrinsification
7470   }
7471   ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type();
7472   if (!elem_type->is_primitive_type()) {
7473     return false; // should be primitive type
7474   }
7475   BasicType elem_bt = elem_type->basic_type();
7476   int num_elem = vlen->get_con();
7477   Assembler::Condition booltest = (Assembler::Condition)cond->get_con();
7478   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7479   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7480 
7481   if (!arch_supports_vector(Op_VectorTest, num_elem, elem_bt, vbox_klass->is_vectormask() ? VecMaskUseLoad : VecMaskNotUsed)) {
7482     return false;
7483   }
7484 
7485   Node* opd1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem);
7486   Node* opd2 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
7487   if (opd1 == NULL || opd2 == NULL) {
7488     return false; // operand unboxing failed
7489   }
7490   Node* test = new VectorTestNode(opd1, opd2, booltest);
7491   test = _gvn.transform(test);
7492   set_result(test);
7493   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7494   return true;
7495 }
7496 
7497 // static
7498 // <V extends Vector, M extends Mask>
7499 // V blend(Class<V> vectorClass, Class<M> maskClass, Class<?> elementType, int vlen,
7500 //         V v1, V v2, M m,
7501 //         VectorBlendOp<V,M> defaultImpl) { ...
7502 //
7503 bool LibraryCallKit::inline_vector_blend() {
7504   const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
7505   const TypeInstPtr* mask_klass   = gvn().type(argument(1))->is_instptr();
7506   const TypeInstPtr* elem_klass   = gvn().type(argument(2))->is_instptr();
7507   const TypeInt*     vlen         = gvn().type(argument(3))->is_int();
7508 
7509   if (mask_klass->const_oop() == NULL || vector_klass->const_oop() == NULL ||
7510       elem_klass->const_oop() == NULL || !vlen->is_con()) {
7511     return false; // not enough info for intrinsification
7512   }


7520 
7521   if (!arch_supports_vector(Op_VectorBlend, num_elem, elem_bt, VecMaskUseLoad)) {
7522     return false; // not supported
7523   }
7524   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7525   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7526 
7527   ciKlass* mbox_klass = mask_klass->const_oop()->as_instance()->java_lang_Class_klass();
7528   const TypeInstPtr* mbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, mbox_klass);
7529 
7530   Node* v1   = unbox_vector(argument(4), vbox_type, elem_bt, num_elem);
7531   Node* v2   = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
7532   Node* mask = unbox_vector(argument(6), mbox_type, mask_bt, num_elem);
7533 
7534   if (v1 == NULL || v2 == NULL || mask == NULL) {
7535     return false; // operand unboxing failed
7536   }
7537 
7538   Node* blend = _gvn.transform(new VectorBlendNode(v1, v2, mask));
7539   Node* box = box_vector(blend, vbox_type, elem_bt, num_elem);
7540   set_result(box);
7541 
7542   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7543   return true;
7544 }
7545 
7546 //  static <V extends Vector<E,S>,
7547 //          M extends Vector.Mask<E,S>,
7548 //          S extends Vector.Shape, E>
7549 //  M compare(int cond, Class<V> vectorClass, Class<M> maskClass, Class<?> elementType, int vlen,
7550 //            V v1, V v2,
7551 //            VectorCompareOp<V,M> defaultImpl) { ...
7552 //
7553 bool LibraryCallKit::inline_vector_compare() {
7554   const TypeInt*     cond         = gvn().type(argument(0))->is_int();
7555   const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
7556   const TypeInstPtr* mask_klass   = gvn().type(argument(2))->is_instptr();
7557   const TypeInstPtr* elem_klass   = gvn().type(argument(3))->is_instptr();
7558   const TypeInt*     vlen         = gvn().type(argument(4))->is_int();
7559 
7560   if (!cond->is_con() || vector_klass->const_oop() == NULL || mask_klass->const_oop() == NULL ||


7574     return false;
7575   }
7576 
7577   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7578   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7579 
7580   ciKlass* mbox_klass = mask_klass->const_oop()->as_instance()->java_lang_Class_klass();
7581   const TypeInstPtr* mbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, mbox_klass);
7582 
7583   Node* v1 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
7584   Node* v2 = unbox_vector(argument(6), vbox_type, elem_bt, num_elem);
7585 
7586   if (v1 == NULL || v2 == NULL) {
7587     return false; // operand unboxing failed
7588   }
7589   BoolTest::mask pred = (BoolTest::mask)cond->get_con();
7590   const TypeVect* vt = TypeVect::make(mask_bt, num_elem);
7591   Node* operation = _gvn.transform(new VectorMaskCmpNode(pred, v1, v2, vt));
7592 
7593   Node* box = box_vector(operation, mbox_type, mask_bt, num_elem);
7594   set_result(box);
7595 
7596   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7597   return true;
7598 }
7599 
7600 Node* LibraryCallKit::shift_count(Node* cnt, int shift_op, BasicType bt, int num_elem) {
7601   assert(bt == T_INT || bt == T_LONG, "Only long and int are supported");
7602   juint mask = (bt == T_INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
7603   const TypeInt* t = cnt->find_int_type();
7604   if (t != NULL && t->is_con()) {
7605     juint shift = t->get_con();
7606     if (shift > mask) {
7607       return _gvn.transform(ConNode::make(TypeInt::make(shift & mask)));
7608     } else {
7609       return cnt;
7610     }
7611   } else {
7612     Node* maskedcnt = cnt;
7613     if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) {
7614       Node* nmask = _gvn.transform(ConNode::make(TypeInt::make(mask)));


7638     return false; // should be primitive type
7639   }
7640   BasicType elem_bt = elem_type->basic_type();
7641   int num_elem = vlen->get_con();
7642   int opc = get_opc(opr->get_con(), elem_bt);
7643   int sopc = VectorNode::opcode(opc, elem_bt); // get_node_id(opr->get_con(), elem_bt);
7644   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7645   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7646 
7647   if (!arch_supports_vector(sopc, num_elem, elem_bt, VecMaskNotUsed)) {
7648     return false; // not supported
7649   }
7650   Node* opd1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem);
7651   Node* opd2 = shift_count(argument(5), opc, elem_bt, num_elem);
7652   if (opd1 == NULL || opd2 == NULL) {
7653     return false;
7654   }
7655   Node* operation = _gvn.transform(VectorNode::make(sopc, opd1, opd2, num_elem, elem_bt));
7656 
7657   Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem);
7658   set_result(vbox);
7659   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7660   return true;
7661 }
7662 
7663 static BasicType extract_bt_from_box_class(ciType* t) {
7664   if (t->basic_type() == T_OBJECT) {
7665     switch(t->as_klass()->name()->sid()) {
7666       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Boolean):   return T_BOOLEAN;
7667       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Byte):      return T_BYTE;
7668       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Short):     return T_SHORT;
7669       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Character): return T_CHAR;
7670       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Integer):   return T_INT;
7671       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Long):      return T_LONG;
7672       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Float):     return T_FLOAT;
7673       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Double):    return T_DOUBLE;
7674       default: fatal("unknown type: %s", t->as_klass()->name()->as_utf8());
7675     }
7676   }
7677   return T_ILLEGAL;
7678 }
7679 
7680 bool LibraryCallKit::inline_vector_rebracket() {
7681   const TypeInstPtr* vector_klass_from = gvn().type(argument(0))->is_instptr();
7682   const TypeInstPtr* elem_klass_from   = gvn().type(argument(1))->is_instptr();
7683   const TypeInt*     vlen_from         = gvn().type(argument(2))->is_int();
7684 
7685   const TypeInstPtr* elem_klass_to     = gvn().type(argument(3))->is_instptr();

7686 
7687   if (vector_klass_from->const_oop() == NULL || elem_klass_from->const_oop() == NULL || !vlen_from->is_con() ||
7688       elem_klass_to->const_oop() == NULL ) {
7689     return false; // not enough info for intrinsification
7690   }
7691 
7692   ciKlass* vbox_klass_from = vector_klass_from->const_oop()->as_instance()->java_lang_Class_klass();
7693   if (!vbox_klass_from->is_vectorapi_vector()) {
7694     return false; // only vector & mask are supported
7695   }
7696   bool is_mask = vbox_klass_from->is_vectormask();
7697 
7698   ciType* elem_type_from = elem_klass_from->const_oop()->as_instance()->java_mirror_type();
7699   if (!elem_type_from->is_primitive_type()) {
7700     return false; // should be primitive type
7701   }
7702   BasicType elem_bt_from = elem_type_from->basic_type();
7703   if (is_mask) {
7704     elem_bt_from = getMaskBasicType(elem_bt_from);
7705   }
7706   ciType* elem_type_to = elem_klass_to->const_oop()->as_instance()->java_mirror_type();
7707   BasicType elem_bt_to = extract_bt_from_box_class(elem_type_to);
7708   if (elem_bt_to == T_ILLEGAL) {
7709     return false;
7710   }
7711   if (is_mask) {
7712     elem_bt_to = getMaskBasicType(elem_bt_to);
7713   }
7714   if (is_mask && elem_bt_from != elem_bt_to) {
7715     return false; // type mismatch
7716   }
7717   int num_elem_from = vlen_from->get_con();




7718 
7719   int num_elem_to = (type2aelembytes(elem_bt_from) * num_elem_from) / type2aelembytes(elem_bt_to);
7720   if (num_elem_to == 0) {



7721     return false;
7722   }
7723   if (is_mask) {
7724     elem_bt_to = getMaskBasicType(elem_bt_to);





7725   }
7726 
7727   const TypeInstPtr* vbox_type_from = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass_from);
7728 
7729   Node* opd1 = unbox_vector(argument(4), vbox_type_from, elem_bt_from, num_elem_from);
7730   if (opd1 == NULL) {
7731     return false;
7732   }
7733 
7734   // Can assert when Phi merges vectors of different types:
7735   // #  Internal Error (/Users/vlivanov/ws/jdk/panama-dev/open/src/hotspot/share/opto/type.cpp:2291), pid=67536, tid=14083
7736   // #  Error: assert(length() == v->length()) failed
7737   const TypeVect* src_type = TypeVect::make(elem_bt_from, num_elem_from);
7738   const TypeVect* dst_type = TypeVect::make(elem_bt_to,   num_elem_to);
7739   Node* op = opd1;
7740   if (src_type != dst_type) {
7741     op = _gvn.transform(new VectorReinterpretNode(op, src_type, dst_type));
7742   }
7743   ciKlass* vbox_klass_to = get_exact_klass_for_vector_box(vbox_klass_from, extract_bt_from_box_class(elem_type_to),
7744                                                           num_elem_to, is_mask ? VECAPI_MASK : VECAPI_VECTOR);
7745   const TypeInstPtr* vbox_type_to = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass_to);
7746   Node* vbox = box_vector(op, vbox_type_to, elem_bt_to, num_elem_to);
7747   set_result(vbox);
7748   return true;
7749 }
7750 
7751 //------------------------------get_state_from_sha_object-----------------------
7752 Node * LibraryCallKit::get_state_from_sha_object(Node *sha_object) {
7753   Node* sha_state = load_field_from_object(sha_object, "state", "[I", /*is_exact*/ false);
7754   assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2");
7755   if (sha_state == NULL) return (Node *) NULL;
7756 
7757   // now have the array, need to get the start address of the state array
7758   Node* state = array_element_address(sha_state, intcon(0), T_INT);
7759   return state;
7760 }
7761 
7762 //------------------------------get_state_from_sha5_object-----------------------
7763 Node * LibraryCallKit::get_state_from_sha5_object(Node *sha_object) {
7764   Node* sha_state = load_field_from_object(sha_object, "state", "[J", /*is_exact*/ false);
7765   assert (sha_state != NULL, "wrong version of sun.security.provider.SHA5");
7766   if (sha_state == NULL) return (Node *) NULL;
7767 




 322   bool inline_hasNegatives();
 323   bool inline_squareToLen();
 324   bool inline_mulAdd();
 325   bool inline_montgomeryMultiply();
 326   bool inline_montgomerySquare();
 327   bool inline_vectorizedMismatch();
 328   bool inline_fma(vmIntrinsics::ID id);
 329 
 330   bool inline_profileBoolean();
 331   bool inline_isCompileConstant();
 332 
 333   // Vector API support
 334   bool inline_vector_nary_operation(int n);
 335   bool inline_vector_broadcast_coerced();
 336   bool inline_vector_mem_operation(bool is_store);
 337   bool inline_vector_reduction();
 338   bool inline_vector_test();
 339   bool inline_vector_blend();
 340   bool inline_vector_compare();
 341   bool inline_vector_broadcast_int();
 342   bool inline_vector_reinterpret();
 343   Node* box_vector(Node* in, const TypeInstPtr* vbox_type, BasicType bt, int num_elem);
 344   Node* unbox_vector(Node* in, const TypeInstPtr* vbox_type, BasicType bt, int num_elem);
 345   Node* shift_count(Node* cnt, int shift_op, BasicType bt, int num_elem);
 346   void set_vector_result(Node* result, bool set_res = true);
 347 
 348   void clear_upper_avx() {
 349 #ifdef X86
 350     if (UseAVX >= 2) {
 351       C->set_clear_upper_avx(true);
 352     }
 353 #endif
 354   }
 355 };
 356 
 357 //---------------------------make_vm_intrinsic----------------------------
 358 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
 359   vmIntrinsics::ID id = m->intrinsic_id();
 360   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 361 
 362   if (!m->is_loaded()) {
 363     // Do not attempt to inline unloaded methods.
 364     return NULL;
 365   }
 366 


 891     return inline_vector_nary_operation(2);
 892   case vmIntrinsics::_VectorTernaryOp:
 893     return inline_vector_nary_operation(3);
 894 
 895   case vmIntrinsics::_VectorBroadcastCoerced:
 896     return inline_vector_broadcast_coerced();
 897   case vmIntrinsics::_VectorLoadOp:
 898     return inline_vector_mem_operation(/*is_store=*/false);
 899   case vmIntrinsics::_VectorStoreOp:
 900     return inline_vector_mem_operation(/*is_store=*/true);
 901   case vmIntrinsics::_VectorReductionCoerced:
 902     return inline_vector_reduction();
 903   case vmIntrinsics::_VectorTest:
 904     return inline_vector_test();
 905   case vmIntrinsics::_VectorBlend:
 906     return inline_vector_blend();
 907   case vmIntrinsics::_VectorCompare:
 908     return inline_vector_compare();
 909   case vmIntrinsics::_VectorBroadcastInt:
 910     return inline_vector_broadcast_int();
 911   case vmIntrinsics::_VectorReinterpret:
 912     return inline_vector_reinterpret();
 913 
 914   default:
 915     // If you get here, it may be that someone has added a new intrinsic
 916     // to the list in vmSymbols.hpp without implementing it here.
 917 #ifndef PRODUCT
 918     if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
 919       tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
 920                     vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
 921     }
 922 #endif
 923     return false;
 924   }
 925 }
 926 
 927 Node* LibraryCallKit::try_to_predicate(int predicate) {
 928   if (!jvms()->has_method()) {
 929     // Root JVMState has a null method.
 930     assert(map()->memory()->Opcode() == Op_Parm, "");
 931     // Insert the memory aliasing node
 932     set_all_memory(reset_memory());


7171   set_all_memory(_gvn.transform( new ProjNode(alloc, TypeFunc::Memory) ));
7172   Node* ret = _gvn.transform(new ProjNode(alloc, TypeFunc::Parms));
7173 
7174   VectorBoxNode* vbox = new VectorBoxNode(C, ret, vector, vbox_type, vec_type);
7175   return _gvn.transform(vbox);
7176 }
7177 
7178 Node* LibraryCallKit::unbox_vector(Node* v, const TypeInstPtr* vbox_type, BasicType elem_bt, int num_elem) {
7179   const TypeInstPtr* vbox_type_v = gvn().type(v)->is_instptr();
7180   if (vbox_type->klass() != vbox_type_v->klass()) {
7181     return NULL; // arguments don't agree on vector shapes
7182   }
7183   if (vbox_type_v->maybe_null()) {
7184     return NULL; // no nulls are allowed
7185   }
7186   const TypeVect* vec_type = TypeVect::make(elem_bt, num_elem);
7187   Node* unbox = gvn().transform(new VectorUnboxNode(C, vec_type, v, merged_memory()));
7188   return unbox;
7189 }
7190 
7191 void LibraryCallKit::set_vector_result(Node* result, bool set_res) {
7192   if (DebugVectorApi) {
7193     tty->print("============ ");
7194     callee()->print();
7195     tty->print_cr(" ============");
7196     result->dump(5);
7197     tty->print_cr("----------------------------------------------------");
7198   }
7199   if (set_res) {
7200     set_result(result);
7201   }
7202 }
7203 
7204 bool LibraryCallKit::inline_vector_nary_operation(int n) {
7205   const TypeInt* opr              = gvn().type(argument(0))->is_int();
7206   const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
7207   const TypeInstPtr* elem_klass   = gvn().type(argument(2))->is_instptr();
7208   const TypeInt* vlen             = gvn().type(argument(3))->is_int();
7209 
7210   if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
7211     return false; // not enough info for intrinsification
7212   }
7213   ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type();
7214   if (!elem_type->is_primitive_type()) {
7215     return false; // should be primitive type
7216   }
7217   BasicType elem_bt = elem_type->basic_type();
7218   int num_elem = vlen->get_con();
7219   int opc = get_opc(opr->get_con(), elem_bt);
7220   int sopc = VectorNode::opcode(opc, elem_bt); // get_node_id(opr->get_con(), elem_bt);
7221   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7222   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7223 


7250       break;
7251     }
7252     default: fatal("unsupported arity: %d", n);
7253   }
7254 
7255   Node* operation = NULL;
7256   switch (n) {
7257     case 1:
7258     case 2: {
7259       operation = _gvn.transform(VectorNode::make(sopc, opd1, opd2, num_elem, elem_bt));
7260       break;
7261     }
7262     case 3: {
7263       operation = _gvn.transform(VectorNode::make(sopc, opd1, opd2, opd3, num_elem, elem_bt));
7264       break;
7265     }
7266     default: fatal("unsupported arity: %d", n);
7267   }
7268   // Wrap it up in VectorBox to keep object type information.
7269   operation = box_vector(operation, vbox_type, elem_bt, num_elem);
7270   set_vector_result(operation);
7271 
7272   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7273   return true;
7274 }
7275 
7276 // <V extends Vector<?,?>>
7277 // V broadcastCoerced(Class<?> vectorClass, Class<?> elementType, int vlen,
7278 //                    long bits,
7279 //                    LongFunction<V> defaultImpl)
7280 bool LibraryCallKit::inline_vector_broadcast_coerced() {
7281   const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
7282   const TypeInstPtr* elem_klass   = gvn().type(argument(1))->is_instptr();
7283   const TypeInt* vlen             = gvn().type(argument(2))->is_int();
7284 
7285   if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
7286     return false; // not enough info for intrinsification
7287   }
7288 
7289   ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type();
7290   if (!elem_type->is_primitive_type()) {


7315     }
7316     case T_DOUBLE: {
7317       elem = gvn().transform(new MoveL2DNode(bits));
7318       break;
7319     }
7320     case T_FLOAT: {
7321       bits = gvn().transform(new ConvL2INode(bits));
7322       elem = gvn().transform(new MoveI2FNode(bits));
7323       break;
7324     }
7325     case T_LONG: {
7326       elem = bits; // no conversion needed
7327       break;
7328     }
7329     default: fatal("%s", type2name(elem_bt));
7330   }
7331 
7332   Node* broadcast = VectorNode::scalar2vector(elem, num_elem, Type::get_const_basic_type(elem_bt));
7333   broadcast = gvn().transform(broadcast);
7334   Node* box = box_vector(broadcast, vbox_type, elem_bt, num_elem);
7335   set_vector_result(box);
7336 
7337   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7338   return true;
7339 }
7340 
7341 //    <V extends Vector<?,?>>
7342 //    V load(Class<?> vectorClass, Class<?> elementType, int vlen,
7343 //           Object array, int index, /* Vector.Mask<E,S> m*/
7344 //           BiFunction<Object, Integer, V> defaultImpl) {
7345 //
7346 //    <V extends Vector<?,?>>
7347 //    void store(Class<?> vectorClass, Class<?> elementType, int vlen,
7348 //               Object array, int index, V v, /*Vector.Mask<E,S> m*/
7349 //               StoreVectorOperation<V> defaultImpl) {
7350 
7351 bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
7352   const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
7353   const TypeInstPtr* elem_klass   = gvn().type(argument(1))->is_instptr();
7354   const TypeInt* vlen             = gvn().type(argument(2))->is_int();
7355 


7376   if (arr_type == NULL) {
7377     return false; // should be an array
7378   }
7379   if (elem_bt != arr_type->elem()->array_element_basic_type()) {
7380     return false; // array & vector element types should be the same
7381   }
7382   Node* adr = array_element_address(arr, idx,  elem_bt);
7383   const TypePtr* adr_type = adr->bottom_type()->is_ptr();
7384 
7385   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7386   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7387 
7388   if (is_store) {
7389     Node* val = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
7390     if (val == NULL) {
7391       return false; // operand unboxing failed
7392     }
7393     set_all_memory(reset_memory());
7394     Node* vstore = gvn().transform(StoreVectorNode::make(0, control(), memory(adr), adr, adr_type, val, num_elem));
7395     set_memory(vstore, adr_type);
7396     set_vector_result(vstore, false);
7397   } else {
7398     Node* vload = gvn().transform(LoadVectorNode::make(0, control(), memory(adr), adr, adr_type, num_elem, elem_bt));
7399     Node* box = box_vector(vload, vbox_type, elem_bt, num_elem);
7400     set_vector_result(box);
7401   }
7402 
7403   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7404   return true;
7405 }
7406 
7407 // <V extends Vector<?,?>>
7408 // long reductionCoerced(int oprId, Class<?> vectorClass, Class<?> elementType, int vlen,
7409 //                       V v,
7410 //                       Function<V,Long> defaultImpl)
7411 
7412 bool LibraryCallKit::inline_vector_reduction() {
7413   const TypeInt* opr              = gvn().type(argument(0))->is_int();
7414   const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
7415   const TypeInstPtr* elem_klass   = gvn().type(argument(2))->is_instptr();
7416   const TypeInt* vlen             = gvn().type(argument(3))->is_int();
7417 
7418   if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
7419     return false; // not enough info for intrinsification
7420   }


7448   switch (elem_bt) {
7449     case T_INT: {
7450       bits = gvn().transform(new ConvI2LNode(rn));
7451       break;
7452     }
7453     case T_FLOAT: {
7454       rn   = gvn().transform(new MoveF2INode(rn));
7455       bits = gvn().transform(new ConvI2LNode(rn));
7456       break;
7457     }
7458     case T_DOUBLE: {
7459       bits = gvn().transform(new MoveD2LNode(rn));
7460       break;
7461     }
7462     case T_LONG: {
7463       bits = rn; // no conversion needed
7464       break;
7465     }
7466     default: fatal("%s", type2name(elem_bt));
7467   }
7468   set_vector_result(bits);
7469   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7470   return true;
7471 }
7472 
7473 // static <V> boolean test(int cond, Class<?> vectorClass, Class<?> elementType, int vlen,
7474 //                         V v1, V v2,
7475 //                         BiFunction<V, V, Boolean> defaultImpl) {
7476 
7477 bool LibraryCallKit::inline_vector_test() {
7478   const TypeInt* cond             = gvn().type(argument(0))->is_int();
7479   const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
7480   const TypeInstPtr* elem_klass   = gvn().type(argument(2))->is_instptr();
7481   const TypeInt* vlen             = gvn().type(argument(3))->is_int();
7482 
7483   if (!cond->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
7484     return false; // not enough info for intrinsification
7485   }
7486   ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type();
7487   if (!elem_type->is_primitive_type()) {
7488     return false; // should be primitive type
7489   }
7490   BasicType elem_bt = elem_type->basic_type();
7491   int num_elem = vlen->get_con();
7492   Assembler::Condition booltest = (Assembler::Condition)cond->get_con();
7493   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7494   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7495 
7496   if (!arch_supports_vector(Op_VectorTest, num_elem, elem_bt, vbox_klass->is_vectormask() ? VecMaskUseLoad : VecMaskNotUsed)) {
7497     return false;
7498   }
7499 
7500   Node* opd1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem);
7501   Node* opd2 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
7502   if (opd1 == NULL || opd2 == NULL) {
7503     return false; // operand unboxing failed
7504   }
7505   Node* test = new VectorTestNode(opd1, opd2, booltest);
7506   test = _gvn.transform(test);
7507   set_vector_result(test);
7508   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7509   return true;
7510 }
7511 
7512 // static
7513 // <V extends Vector, M extends Mask>
7514 // V blend(Class<V> vectorClass, Class<M> maskClass, Class<?> elementType, int vlen,
7515 //         V v1, V v2, M m,
7516 //         VectorBlendOp<V,M> defaultImpl) { ...
7517 //
7518 bool LibraryCallKit::inline_vector_blend() {
7519   const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
7520   const TypeInstPtr* mask_klass   = gvn().type(argument(1))->is_instptr();
7521   const TypeInstPtr* elem_klass   = gvn().type(argument(2))->is_instptr();
7522   const TypeInt*     vlen         = gvn().type(argument(3))->is_int();
7523 
7524   if (mask_klass->const_oop() == NULL || vector_klass->const_oop() == NULL ||
7525       elem_klass->const_oop() == NULL || !vlen->is_con()) {
7526     return false; // not enough info for intrinsification
7527   }


7535 
7536   if (!arch_supports_vector(Op_VectorBlend, num_elem, elem_bt, VecMaskUseLoad)) {
7537     return false; // not supported
7538   }
7539   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7540   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7541 
7542   ciKlass* mbox_klass = mask_klass->const_oop()->as_instance()->java_lang_Class_klass();
7543   const TypeInstPtr* mbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, mbox_klass);
7544 
7545   Node* v1   = unbox_vector(argument(4), vbox_type, elem_bt, num_elem);
7546   Node* v2   = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
7547   Node* mask = unbox_vector(argument(6), mbox_type, mask_bt, num_elem);
7548 
7549   if (v1 == NULL || v2 == NULL || mask == NULL) {
7550     return false; // operand unboxing failed
7551   }
7552 
7553   Node* blend = _gvn.transform(new VectorBlendNode(v1, v2, mask));
7554   Node* box = box_vector(blend, vbox_type, elem_bt, num_elem);
7555   set_vector_result(box);
7556 
7557   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7558   return true;
7559 }
7560 
7561 //  static <V extends Vector<E,S>,
7562 //          M extends Vector.Mask<E,S>,
7563 //          S extends Vector.Shape, E>
7564 //  M compare(int cond, Class<V> vectorClass, Class<M> maskClass, Class<?> elementType, int vlen,
7565 //            V v1, V v2,
7566 //            VectorCompareOp<V,M> defaultImpl) { ...
7567 //
7568 bool LibraryCallKit::inline_vector_compare() {
7569   const TypeInt*     cond         = gvn().type(argument(0))->is_int();
7570   const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
7571   const TypeInstPtr* mask_klass   = gvn().type(argument(2))->is_instptr();
7572   const TypeInstPtr* elem_klass   = gvn().type(argument(3))->is_instptr();
7573   const TypeInt*     vlen         = gvn().type(argument(4))->is_int();
7574 
7575   if (!cond->is_con() || vector_klass->const_oop() == NULL || mask_klass->const_oop() == NULL ||


7589     return false;
7590   }
7591 
7592   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7593   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7594 
7595   ciKlass* mbox_klass = mask_klass->const_oop()->as_instance()->java_lang_Class_klass();
7596   const TypeInstPtr* mbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, mbox_klass);
7597 
7598   Node* v1 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
7599   Node* v2 = unbox_vector(argument(6), vbox_type, elem_bt, num_elem);
7600 
7601   if (v1 == NULL || v2 == NULL) {
7602     return false; // operand unboxing failed
7603   }
7604   BoolTest::mask pred = (BoolTest::mask)cond->get_con();
7605   const TypeVect* vt = TypeVect::make(mask_bt, num_elem);
7606   Node* operation = _gvn.transform(new VectorMaskCmpNode(pred, v1, v2, vt));
7607 
7608   Node* box = box_vector(operation, mbox_type, mask_bt, num_elem);
7609   set_vector_result(box);
7610 
7611   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7612   return true;
7613 }
7614 
7615 Node* LibraryCallKit::shift_count(Node* cnt, int shift_op, BasicType bt, int num_elem) {
7616   assert(bt == T_INT || bt == T_LONG, "Only long and int are supported");
7617   juint mask = (bt == T_INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
7618   const TypeInt* t = cnt->find_int_type();
7619   if (t != NULL && t->is_con()) {
7620     juint shift = t->get_con();
7621     if (shift > mask) {
7622       return _gvn.transform(ConNode::make(TypeInt::make(shift & mask)));
7623     } else {
7624       return cnt;
7625     }
7626   } else {
7627     Node* maskedcnt = cnt;
7628     if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) {
7629       Node* nmask = _gvn.transform(ConNode::make(TypeInt::make(mask)));


7653     return false; // should be primitive type
7654   }
7655   BasicType elem_bt = elem_type->basic_type();
7656   int num_elem = vlen->get_con();
7657   int opc = get_opc(opr->get_con(), elem_bt);
7658   int sopc = VectorNode::opcode(opc, elem_bt); // get_node_id(opr->get_con(), elem_bt);
7659   ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
7660   const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
7661 
7662   if (!arch_supports_vector(sopc, num_elem, elem_bt, VecMaskNotUsed)) {
7663     return false; // not supported
7664   }
7665   Node* opd1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem);
7666   Node* opd2 = shift_count(argument(5), opc, elem_bt, num_elem);
7667   if (opd1 == NULL || opd2 == NULL) {
7668     return false;
7669   }
7670   Node* operation = _gvn.transform(VectorNode::make(sopc, opd1, opd2, num_elem, elem_bt));
7671 
7672   Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem);
7673   set_vector_result(vbox);
7674   C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
7675   return true;
7676 }
7677 
7678 static BasicType extract_bt_from_box_class(ciType* t) {
7679   if (t->basic_type() == T_OBJECT) {
7680     switch(t->as_klass()->name()->sid()) {
7681       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Boolean):   return T_BOOLEAN;
7682       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Byte):      return T_BYTE;
7683       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Short):     return T_SHORT;
7684       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Character): return T_CHAR;
7685       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Integer):   return T_INT;
7686       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Long):      return T_LONG;
7687       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Float):     return T_FLOAT;
7688       case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Double):    return T_DOUBLE;
7689       default: fatal("unknown type: %s", t->as_klass()->name()->as_utf8());
7690     }
7691   }
7692   return T_ILLEGAL;
7693 }
7694 
7695 bool LibraryCallKit::inline_vector_reinterpret() {
7696   const TypeInstPtr* vector_klass_from = gvn().type(argument(0))->is_instptr();
7697   const TypeInstPtr* elem_klass_from   = gvn().type(argument(1))->is_instptr();
7698   const TypeInt*     vlen_from         = gvn().type(argument(2))->is_int();
7699 
7700   const TypeInstPtr* elem_klass_to     = gvn().type(argument(3))->is_instptr();
7701   const TypeInt*     vlen_to           = gvn().type(argument(4))->is_int();
7702 
7703   if (vector_klass_from->const_oop() == NULL || elem_klass_from->const_oop() == NULL || !vlen_from->is_con() ||
7704       elem_klass_to->const_oop() == NULL || !vlen_to->is_con()) {
7705     return false; // not enough info for intrinsification
7706   }
7707 
7708   ciKlass* vbox_klass_from = vector_klass_from->const_oop()->as_instance()->java_lang_Class_klass();
7709   if (!vbox_klass_from->is_vectorapi_vector()) {
7710     return false; // only vector & mask are supported
7711   }
7712   bool is_mask = vbox_klass_from->is_vectormask();
7713 
7714   ciType* elem_type_from = elem_klass_from->const_oop()->as_instance()->java_mirror_type();
7715   if (!elem_type_from->is_primitive_type()) {
7716     return false; // should be primitive type
7717   }
7718   BasicType elem_bt_from = elem_type_from->basic_type();
7719   if (is_mask) {
7720     elem_bt_from = getMaskBasicType(elem_bt_from);
7721   }
7722   ciType* elem_type_to = elem_klass_to->const_oop()->as_instance()->java_mirror_type();
7723   BasicType elem_bt_to = extract_bt_from_box_class(elem_type_to);
7724   if (elem_bt_to == T_ILLEGAL) {
7725     return false;
7726   }
7727   if (is_mask) {
7728     elem_bt_to = getMaskBasicType(elem_bt_to);
7729   }
7730   if (is_mask && elem_bt_from != elem_bt_to) {
7731     return false; // type mismatch
7732   }
7733   int num_elem_from = vlen_from->get_con();
7734   int num_elem_to = vlen_to->get_con();
7735   if (is_mask) {
7736     elem_bt_to = getMaskBasicType(elem_bt_to);
7737   }
7738 
7739   // Check whether we can unbox to appropriate size.
7740   if (!arch_supports_vector(Op_VectorReinterpret,
7741                             num_elem_from,
7742                             elem_bt_from,
7743                             is_mask ? VecMaskUseAll : VecMaskNotUsed)) {
7744     return false;
7745   }
7746 
7747   // Check whether we can support resizing/reinterpreting to the new size.
7748   if (!arch_supports_vector(Op_VectorReinterpret,
7749                             num_elem_to,
7750                             elem_bt_to,
7751                             is_mask ? VecMaskUseAll : VecMaskNotUsed)) {
7752     return false;
7753   }
7754 
7755   const TypeInstPtr* vbox_type_from = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass_from);
7756 
7757   Node* opd1 = unbox_vector(argument(5), vbox_type_from, elem_bt_from, num_elem_from);
7758   if (opd1 == NULL) {
7759     return false;
7760   }
7761 
7762   // Can assert when Phi merges vectors of different types:
7763   // #  Internal Error (/Users/vlivanov/ws/jdk/panama-dev/open/src/hotspot/share/opto/type.cpp:2291), pid=67536, tid=14083
7764   // #  Error: assert(length() == v->length()) failed
7765   const TypeVect* src_type = TypeVect::make(elem_bt_from, num_elem_from);
7766   const TypeVect* dst_type = TypeVect::make(elem_bt_to,   num_elem_to);
7767   Node* op = opd1;
7768   if (src_type != dst_type) {
7769     op = _gvn.transform(new VectorReinterpretNode(op, src_type, dst_type));
7770   }
7771   ciKlass* vbox_klass_to = get_exact_klass_for_vector_box(vbox_klass_from, extract_bt_from_box_class(elem_type_to),
7772                                                           num_elem_to, is_mask ? VECAPI_MASK : VECAPI_VECTOR);
7773   const TypeInstPtr* vbox_type_to = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass_to);
7774   Node* vbox = box_vector(op, vbox_type_to, elem_bt_to, num_elem_to);
7775   set_vector_result(vbox);
7776   return true;
7777 }
7778 
7779 //------------------------------get_state_from_sha_object-----------------------
7780 Node * LibraryCallKit::get_state_from_sha_object(Node *sha_object) {
7781   Node* sha_state = load_field_from_object(sha_object, "state", "[I", /*is_exact*/ false);
7782   assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2");
7783   if (sha_state == NULL) return (Node *) NULL;
7784 
7785   // now have the array, need to get the start address of the state array
7786   Node* state = array_element_address(sha_state, intcon(0), T_INT);
7787   return state;
7788 }
7789 
7790 //------------------------------get_state_from_sha5_object-----------------------
7791 Node * LibraryCallKit::get_state_from_sha5_object(Node *sha_object) {
7792   Node* sha_state = load_field_from_object(sha_object, "state", "[J", /*is_exact*/ false);
7793   assert (sha_state != NULL, "wrong version of sun.security.provider.SHA5");
7794   if (sha_state == NULL) return (Node *) NULL;
7795 


< prev index next >