1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/vmSymbols.hpp" 27 #include "opto/library_call.hpp" 28 #include "opto/runtime.hpp" 29 #include "opto/vectornode.hpp" 30 #include "prims/vectorSupport.hpp" 31 32 bool LibraryCallKit::arch_supports_vector(int op, int num_elem, BasicType type, VectorMaskUseType mask_use_type) { 33 // Check that the operation is valid. 34 if (op <= 0) { 35 #ifndef PRODUCT 36 if (C->print_intrinsics()) { 37 tty->print_cr(" ** Rejected intrinsification because no valid vector op could be extracted"); 38 } 39 #endif 40 return false; 41 } 42 43 // Check that architecture supports this op-size-type combination. 44 if (!Matcher::match_rule_supported_vector(op, num_elem, type)) { 45 #ifndef PRODUCT 46 if (C->print_intrinsics()) { 47 tty->print_cr(" ** Rejected vector op (%s,%s,%d) because architecture does not support it", 48 NodeClassNames[op], type2name(type), num_elem); 49 } 50 #endif 51 return false; 52 } else { 53 assert(Matcher::match_rule_supported(op), "must be supported"); 54 } 55 56 // Check whether mask unboxing is supported. 57 if (mask_use_type == VecMaskUseAll || mask_use_type == VecMaskUseLoad) { 58 if (!Matcher::match_rule_supported_vector(Op_VectorLoadMask, num_elem, type)) { 59 #ifndef PRODUCT 60 if (C->print_intrinsics()) { 61 tty->print_cr(" ** Rejected vector mask loading (%s,%s,%d) because architecture does not support it", 62 NodeClassNames[Op_VectorLoadMask], type2name(type), num_elem); 63 } 64 #endif 65 return false; 66 } 67 } 68 69 // Check whether mask boxing is supported. 70 if (mask_use_type == VecMaskUseAll || mask_use_type == VecMaskUseStore) { 71 if (!Matcher::match_rule_supported_vector(Op_VectorStoreMask, num_elem, type)) { 72 #ifndef PRODUCT 73 if (C->print_intrinsics()) { 74 tty->print_cr("Rejected vector mask storing (%s,%s,%d) because architecture does not support it", 75 NodeClassNames[Op_VectorStoreMask], type2name(type), num_elem); 76 } 77 #endif 78 return false; 79 } 80 } 81 82 return true; 83 } 84 85 static int get_sopc(int opc, BasicType elem_bt, int arity) { 86 #ifdef X86 87 // Variable shift handling 88 if (arity == 2) { 89 switch (opc) { 90 case Op_LShiftI: 91 case Op_LShiftL: 92 return Op_VLShiftV; 93 case Op_RShiftI: 94 case Op_RShiftL: 95 return Op_VRShiftV; 96 case Op_URShiftB: 97 case Op_URShiftS: 98 case Op_URShiftI: 99 case Op_URShiftL: 100 return Op_VURShiftV; 101 102 default: break; 103 } 104 } 105 #endif 106 return VectorNode::opcode(opc, elem_bt); 107 } 108 109 static bool is_vector_mask(ciKlass* klass) { 110 return klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass()); 111 } 112 113 static bool is_vector_shuffle(ciKlass* klass) { 114 return klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass()); 115 } 116 117 #ifdef ASSERT 118 static bool is_vector(ciKlass* klass) { 119 return klass->is_subclass_of(ciEnv::current()->vector_VectorPayload_klass()); 120 } 121 122 static bool check_vbox(const TypeInstPtr* vbox_type) { 123 assert(vbox_type->klass_is_exact(), ""); 124 125 ciInstanceKlass* ik = vbox_type->klass()->as_instance_klass(); 126 assert(is_vector(ik), "not a vector"); 127 128 ciField* fd1 = ik->get_field_by_name(ciSymbol::ETYPE_name(), ciSymbol::class_signature(), /* is_static */ true); 129 assert(fd1 != NULL, "element type info is missing"); 130 131 ciConstant val1 = fd1->constant_value(); 132 BasicType elem_bt = val1.as_object()->as_instance()->java_mirror_type()->basic_type(); 133 assert(is_java_primitive(elem_bt), "element type info is missing"); 134 135 ciField* fd2 = ik->get_field_by_name(ciSymbol::VLENGTH_name(), ciSymbol::int_signature(), /* is_static */ true); 136 assert(fd2 != NULL, "vector length info is missing"); 137 138 ciConstant val2 = fd2->constant_value(); 139 assert(val2.as_int() > 0, "vector length info is missing"); 140 141 return true; 142 } 143 #endif 144 145 Node* LibraryCallKit::box_vector(Node* vector, const TypeInstPtr* vbox_type, 146 BasicType elem_bt, int num_elem) { 147 assert(EnableVectorSupport, ""); 148 const TypeVect* vec_type = TypeVect::make(elem_bt, num_elem); 149 150 VectorBoxAllocateNode* alloc = new VectorBoxAllocateNode(C, vbox_type); 151 set_edges_for_java_call(alloc, /*must_throw=*/false, /*separate_io_proj=*/true); 152 make_slow_call_ex(alloc, env()->Throwable_klass(), /*separate_io_proj=*/true); 153 set_i_o(gvn().transform( new ProjNode(alloc, TypeFunc::I_O) )); 154 set_all_memory(gvn().transform( new ProjNode(alloc, TypeFunc::Memory) )); 155 Node* ret = gvn().transform(new ProjNode(alloc, TypeFunc::Parms)); 156 157 assert(check_vbox(vbox_type), ""); 158 VectorBoxNode* vbox = new VectorBoxNode(C, ret, vector, vbox_type, vec_type); 159 return gvn().transform(vbox); 160 } 161 162 Node* LibraryCallKit::unbox_vector(Node* v, const TypeInstPtr* vbox_type, BasicType elem_bt, int num_elem, bool shuffle_to_vector) { 163 assert(EnableVectorSupport, ""); 164 const TypeInstPtr* vbox_type_v = gvn().type(v)->is_instptr(); 165 if (vbox_type->klass() != vbox_type_v->klass()) { 166 return NULL; // arguments don't agree on vector shapes 167 } 168 if (vbox_type_v->maybe_null()) { 169 return NULL; // no nulls are allowed 170 } 171 assert(check_vbox(vbox_type), ""); 172 const TypeVect* vec_type = TypeVect::make(elem_bt, num_elem); 173 Node* unbox = gvn().transform(new VectorUnboxNode(C, vec_type, v, merged_memory(), shuffle_to_vector)); 174 return unbox; 175 } 176 177 // public static 178 // <VM> 179 // VM unaryOp(int oprId, Class<? extends VM> vmClass, Class<?> elementType, int length, 180 // VM vm, 181 // Function<VM, VM> defaultImpl) { 182 // 183 // public static 184 // <VM> 185 // VM binaryOp(int oprId, Class<? extends VM> vmClass, Class<?> elementType, int length, 186 // VM vm1, VM vm2, 187 // BiFunction<VM, VM, VM> defaultImpl) { 188 // 189 // public static 190 // <VM> 191 // VM ternaryOp(int oprId, Class<? extends VM> vmClass, Class<?> elementType, int length, 192 // VM vm1, VM vm2, VM vm3, 193 // TernaryOperation<VM> defaultImpl) { 194 // 195 bool LibraryCallKit::inline_vector_nary_operation(int n) { 196 const TypeInt* opr = gvn().type(argument(0))->is_int(); 197 const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr(); 198 const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr(); 199 const TypeInt* vlen = gvn().type(argument(3))->is_int(); 200 201 if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) { 202 if (C->print_intrinsics()) { 203 tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s", 204 NodeClassNames[argument(0)->Opcode()], 205 NodeClassNames[argument(1)->Opcode()], 206 NodeClassNames[argument(2)->Opcode()], 207 NodeClassNames[argument(3)->Opcode()]); 208 } 209 return false; // not enough info for intrinsification 210 } 211 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 212 if (!elem_type->is_primitive_type()) { 213 if (C->print_intrinsics()) { 214 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 215 } 216 return false; // should be primitive type 217 } 218 BasicType elem_bt = elem_type->basic_type(); 219 int num_elem = vlen->get_con(); 220 int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt); 221 int sopc = get_sopc(opc, elem_bt, n); 222 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 223 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 224 225 // TODO When mask usage is supported, VecMaskNotUsed needs to be VecMaskUseLoad. 226 if (!arch_supports_vector(sopc, num_elem, elem_bt, is_vector_mask(vbox_klass) ? VecMaskUseAll : VecMaskNotUsed)) { 227 if (C->print_intrinsics()) { 228 tty->print_cr(" ** not supported: arity=%d opc=%d vlen=%d etype=%s ismask=%d", 229 n, sopc, num_elem, type2name(elem_bt), 230 is_vector_mask(vbox_klass) ? 1 : 0); 231 } 232 return false; // not supported 233 } 234 235 Node* opd1 = NULL; Node* opd2 = NULL; Node* opd3 = NULL; 236 switch (n) { 237 case 3: { 238 opd3 = unbox_vector(argument(6), vbox_type, elem_bt, num_elem); 239 if (opd3 == NULL) { 240 if (C->print_intrinsics()) { 241 tty->print_cr(" ** unbox failed v3=%s", 242 NodeClassNames[argument(6)->Opcode()]); 243 } 244 return false; 245 } 246 // fall-through 247 } 248 case 2: { 249 opd2 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem); 250 if (opd2 == NULL) { 251 if (C->print_intrinsics()) { 252 tty->print_cr(" ** unbox failed v2=%s", 253 NodeClassNames[argument(5)->Opcode()]); 254 } 255 return false; 256 } 257 // fall-through 258 } 259 case 1: { 260 opd1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem); 261 if (opd1 == NULL) { 262 if (C->print_intrinsics()) { 263 tty->print_cr(" ** unbox failed v1=%s", 264 NodeClassNames[argument(4)->Opcode()]); 265 } 266 return false; 267 } 268 break; 269 } 270 default: fatal("unsupported arity: %d", n); 271 } 272 273 Node* operation = NULL; 274 const TypeVect* vt = TypeVect::make(elem_bt, num_elem); 275 switch (n) { 276 case 1: 277 case 2: { 278 operation = gvn().transform(VectorNode::make(sopc, opd1, opd2, vt)); 279 break; 280 } 281 case 3: { 282 operation = gvn().transform(VectorNode::make(sopc, opd1, opd2, opd3, vt)); 283 break; 284 } 285 default: fatal("unsupported arity: %d", n); 286 } 287 // Wrap it up in VectorBox to keep object type information. 288 Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem); 289 set_result(vbox); 290 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 291 return true; 292 } 293 294 // <Sh extends VectorShuffle<E>, E> 295 // Sh ShuffleIota(Class<?> E, Class<?> ShuffleClass, Vector.Species<E> s, int length, 296 // int start, int step, int wrap, ShuffleIotaOperation<Sh, E> defaultImpl) 297 bool LibraryCallKit::inline_vector_shuffle_iota() { 298 const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->is_instptr(); 299 const TypeInt* vlen = gvn().type(argument(3))->is_int(); 300 Node* start = argument(4); 301 const TypeInt* start_val = gvn().type(start)->is_int(); 302 Node* step = argument(5); 303 const TypeInt* step_val = gvn().type(step)->is_int(); 304 const TypeInt* wrap = gvn().type(argument(6))->is_int(); 305 306 if (!vlen->is_con() || !is_power_of_2(vlen->get_con()) || 307 shuffle_klass->const_oop() == NULL || !wrap->is_con()) { 308 return false; // not enough info for intrinsification 309 } 310 311 int do_wrap = wrap->get_con(); 312 int num_elem = vlen->get_con(); 313 BasicType elem_bt = T_BYTE; 314 315 if (num_elem < 4) 316 return false; 317 318 if (!arch_supports_vector(VectorNode::replicate_opcode(elem_bt), num_elem, elem_bt, VecMaskNotUsed)) { 319 return false; 320 } 321 if (!arch_supports_vector(Op_AddVB, num_elem, elem_bt, VecMaskNotUsed)) { 322 return false; 323 } 324 if (!arch_supports_vector(Op_AndV, num_elem, elem_bt, VecMaskNotUsed)) { 325 return false; 326 } 327 if (!arch_supports_vector(Op_VectorBlend, num_elem, elem_bt, VecMaskUseLoad)) { 328 return false; 329 } 330 if (!arch_supports_vector(Op_VectorMaskCmp, num_elem, elem_bt, VecMaskUseStore)) { 331 return false; 332 } 333 334 const Type * type_bt = Type::get_const_basic_type(elem_bt); 335 const TypeVect * vt = TypeVect::make(type_bt, num_elem); 336 337 Node* res = gvn().transform(new VectorLoadConstNode(gvn().makecon(TypeInt::ZERO), vt)); 338 339 if(!step_val->is_con() || !is_power_of_2(step_val->get_con())) { 340 Node* bcast_step = gvn().transform(VectorNode::scalar2vector(step, num_elem, type_bt)); 341 res = gvn().transform(VectorNode::make(Op_MulI, res, bcast_step, num_elem, elem_bt)); 342 } else if (step_val->get_con() > 1) { 343 Node* cnt = gvn().makecon(TypeInt::make(log2_int(step_val->get_con()))); 344 res = gvn().transform(VectorNode::make(Op_LShiftVB, res, cnt, vt)); 345 } 346 347 if (!start_val->is_con() || start_val->get_con() != 0) { 348 Node* bcast_start = gvn().transform(VectorNode::scalar2vector(start, num_elem, type_bt)); 349 res = gvn().transform(VectorNode::make(Op_AddI, res, bcast_start, num_elem, elem_bt)); 350 } 351 352 Node * mod_val = gvn().makecon(TypeInt::make(num_elem-1)); 353 Node * bcast_mod = gvn().transform(VectorNode::scalar2vector(mod_val, num_elem, type_bt)); 354 if(do_wrap) { 355 // Wrap the indices greater than lane count. 356 res = gvn().transform(VectorNode::make(Op_AndI, res, bcast_mod, num_elem, elem_bt)); 357 } else { 358 ConINode* pred_node = (ConINode*)gvn().makecon(TypeInt::make(1)); 359 Node * lane_cnt = gvn().makecon(TypeInt::make(num_elem)); 360 Node * bcast_lane_cnt = gvn().transform(VectorNode::scalar2vector(lane_cnt, num_elem, type_bt)); 361 Node* mask = gvn().transform(new VectorMaskCmpNode(BoolTest::ge, bcast_lane_cnt, res, pred_node, vt)); 362 363 // Make the indices greater than lane count as -ve values. This matches the java side implementation. 364 res = gvn().transform(VectorNode::make(Op_AndI, res, bcast_mod, num_elem, elem_bt)); 365 Node * biased_val = gvn().transform(VectorNode::make(Op_SubI, res, bcast_lane_cnt, num_elem, elem_bt)); 366 res = gvn().transform(new VectorBlendNode(biased_val, res, mask)); 367 } 368 369 ciKlass* sbox_klass = shuffle_klass->const_oop()->as_instance()->java_lang_Class_klass(); 370 const TypeInstPtr* shuffle_box_type = TypeInstPtr::make_exact(TypePtr::NotNull, sbox_klass); 371 372 // Wrap it up in VectorBox to keep object type information. 373 res = box_vector(res, shuffle_box_type, elem_bt, num_elem); 374 set_result(res); 375 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 376 return true; 377 } 378 379 // <VM ,Sh extends VectorShuffle<E>, E> 380 // VM shuffleToVector(Class<VM> VecClass, Class<?>E , Class<?> ShuffleClass, Sh s, int length, 381 // ShuffleToVectorOperation<VM,Sh,E> defaultImpl) 382 bool LibraryCallKit::inline_vector_shuffle_to_vector() { 383 const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); 384 const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr(); 385 const TypeInstPtr* shuffle_klass = gvn().type(argument(2))->is_instptr(); 386 Node* shuffle = argument(3); 387 const TypeInt* vlen = gvn().type(argument(4))->is_int(); 388 389 if (!vlen->is_con() || shuffle_klass->const_oop() == NULL) { 390 return false; // not enough info for intrinsification 391 } 392 393 int num_elem = vlen->get_con(); 394 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 395 BasicType elem_bt = elem_type->basic_type(); 396 397 if (num_elem < 4) { 398 return false; 399 } 400 401 int cast_vopc = VectorCastNode::opcode(T_BYTE); // from shuffle of type T_BYTE 402 // Make sure that cast is implemented to particular type/size combination. 403 if (!arch_supports_vector(cast_vopc, num_elem, elem_bt, VecMaskNotUsed)) { 404 if (C->print_intrinsics()) { 405 tty->print_cr(" ** not supported: arity=1 op=cast#%d/3 vlen2=%d etype2=%s", 406 cast_vopc, num_elem, type2name(elem_bt)); 407 } 408 return false; 409 } 410 411 ciKlass* sbox_klass = shuffle_klass->const_oop()->as_instance()->java_lang_Class_klass(); 412 const TypeInstPtr* shuffle_box_type = TypeInstPtr::make_exact(TypePtr::NotNull, sbox_klass); 413 414 // Unbox shuffle with true flag to indicate its load shuffle to vector 415 Node* shuffle_vec = unbox_vector(shuffle, shuffle_box_type, elem_bt, num_elem, true); 416 417 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 418 const TypeInstPtr* vec_box_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 419 420 // Box vector 421 Node* res = box_vector(shuffle_vec, vec_box_type, elem_bt, num_elem); 422 set_result(res); 423 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 424 return true; 425 } 426 427 // <V extends Vector<?,?>> 428 // V broadcastCoerced(Class<?> vectorClass, Class<?> elementType, int vlen, 429 // long bits, 430 // LongFunction<V> defaultImpl) 431 bool LibraryCallKit::inline_vector_broadcast_coerced() { 432 const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); 433 const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr(); 434 const TypeInt* vlen = gvn().type(argument(2))->is_int(); 435 436 if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) { 437 if (C->print_intrinsics()) { 438 tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s", 439 NodeClassNames[argument(0)->Opcode()], 440 NodeClassNames[argument(1)->Opcode()], 441 NodeClassNames[argument(2)->Opcode()]); 442 } 443 return false; // not enough info for intrinsification 444 } 445 446 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 447 if (!elem_type->is_primitive_type()) { 448 if (C->print_intrinsics()) { 449 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 450 } 451 return false; // should be primitive type 452 } 453 BasicType elem_bt = elem_type->basic_type(); 454 int num_elem = vlen->get_con(); 455 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 456 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 457 458 // TODO When mask usage is supported, VecMaskNotUsed needs to be VecMaskUseLoad. 459 if (!arch_supports_vector(VectorNode::replicate_opcode(elem_bt), num_elem, elem_bt, 460 is_vector_mask(vbox_klass) ? VecMaskUseStore : VecMaskNotUsed)) { 461 if (C->print_intrinsics()) { 462 tty->print_cr(" ** not supported: arity=0 op=broadcast vlen=%d etype=%s ismask=%d", 463 num_elem, type2name(elem_bt), 464 is_vector_mask(vbox_klass) ? 1 : 0); 465 } 466 return false; // not supported 467 } 468 469 Node* bits = argument(3); // long 470 471 Node* elem = NULL; 472 switch (elem_bt) { 473 case T_BOOLEAN: // fall-through 474 case T_BYTE: // fall-through 475 case T_SHORT: // fall-through 476 case T_CHAR: // fall-through 477 case T_INT: { 478 elem = gvn().transform(new ConvL2INode(bits)); 479 break; 480 } 481 case T_DOUBLE: { 482 elem = gvn().transform(new MoveL2DNode(bits)); 483 break; 484 } 485 case T_FLOAT: { 486 bits = gvn().transform(new ConvL2INode(bits)); 487 elem = gvn().transform(new MoveI2FNode(bits)); 488 break; 489 } 490 case T_LONG: { 491 elem = bits; // no conversion needed 492 break; 493 } 494 default: fatal("%s", type2name(elem_bt)); 495 } 496 497 Node* broadcast = VectorNode::scalar2vector(elem, num_elem, Type::get_const_basic_type(elem_bt)); 498 broadcast = gvn().transform(broadcast); 499 500 Node* box = box_vector(broadcast, vbox_type, elem_bt, num_elem); 501 set_result(box); 502 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 503 return true; 504 } 505 506 // <C, V extends Vector<?,?>> 507 // V load(Class<?> vectorClass, Class<?> elementType, int vlen, 508 // Object base, long offset, 509 // /* Vector.Mask<E,S> m*/ 510 // Object container, int index, 511 // LoadOperation<C, VM> defaultImpl) { 512 // 513 // <C, V extends Vector<?,?>> 514 // void store(Class<?> vectorClass, Class<?> elementType, int vlen, 515 // Object base, long offset, 516 // V v, /*Vector.Mask<E,S> m*/ 517 // Object container, int index, 518 // StoreVectorOperation<C, V> defaultImpl) { 519 520 bool LibraryCallKit::inline_vector_mem_operation(bool is_store) { 521 const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); 522 const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr(); 523 const TypeInt* vlen = gvn().type(argument(2))->is_int(); 524 525 if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) { 526 if (C->print_intrinsics()) { 527 tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s", 528 NodeClassNames[argument(0)->Opcode()], 529 NodeClassNames[argument(1)->Opcode()], 530 NodeClassNames[argument(2)->Opcode()]); 531 } 532 return false; // not enough info for intrinsification 533 } 534 535 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 536 if (!elem_type->is_primitive_type()) { 537 if (C->print_intrinsics()) { 538 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 539 } 540 return false; // should be primitive type 541 } 542 BasicType elem_bt = elem_type->basic_type(); 543 int num_elem = vlen->get_con(); 544 545 // TODO When mask usage is supported, VecMaskNotUsed needs to be VecMaskUseLoad. 546 if (!arch_supports_vector(is_store ? Op_StoreVector : Op_LoadVector, num_elem, elem_bt, VecMaskNotUsed)) { 547 if (C->print_intrinsics()) { 548 tty->print_cr(" ** not supported: arity=%d op=%s vlen=%d etype=%s ismask=no", 549 is_store, is_store ? "store" : "load", 550 num_elem, type2name(elem_bt)); 551 } 552 return false; // not supported 553 } 554 555 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 556 bool is_mask = is_vector_mask(vbox_klass); 557 558 Node* base = argument(3); 559 Node* offset = ConvL2X(argument(4)); 560 DecoratorSet decorators = C2_UNSAFE_ACCESS; 561 Node* addr = make_unsafe_address(base, offset, decorators, (is_mask ? T_BOOLEAN : elem_bt), true); 562 563 // Can base be NULL? Otherwise, always on-heap access. 564 bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(gvn().type(base)); 565 566 const TypePtr *addr_type = gvn().type(addr)->isa_ptr(); 567 const TypeAryPtr* arr_type = addr_type->isa_aryptr(); 568 569 // Now handle special case where load/store happens from/to byte array but element type is not byte. 570 bool using_byte_array = arr_type != NULL && arr_type->elem()->array_element_basic_type() == T_BYTE && elem_bt != T_BYTE; 571 // Handle loading masks. 572 // If there is no consistency between array and vector element types, it must be special byte array case or loading masks 573 if (arr_type != NULL && !using_byte_array && elem_bt != arr_type->elem()->array_element_basic_type() && !is_mask) { 574 return false; 575 } 576 // Since we are using byte array, we need to double check that the byte operations are supported by backend. 577 if (using_byte_array) { 578 int byte_num_elem = num_elem * type2aelembytes(elem_bt); 579 if (!arch_supports_vector(is_store ? Op_StoreVector : Op_LoadVector, byte_num_elem, T_BYTE, VecMaskNotUsed)) { 580 if (C->print_intrinsics()) { 581 tty->print_cr(" ** not supported: arity=%d op=%s vlen=%d*8 etype=%s/8 ismask=no", 582 is_store, is_store ? "store" : "load", 583 byte_num_elem, type2name(elem_bt)); 584 } 585 return false; // not supported 586 } 587 } 588 if (is_mask) { 589 if (!arch_supports_vector(Op_LoadVector, num_elem, T_BOOLEAN, VecMaskNotUsed)) { 590 if (C->print_intrinsics()) { 591 tty->print_cr(" ** not supported: arity=%d op=%s/mask vlen=%d etype=bit ismask=no", 592 is_store, is_store ? "store" : "load", 593 num_elem); 594 } 595 return false; // not supported 596 } 597 if (!is_store) { 598 if (!arch_supports_vector(Op_LoadVector, num_elem, elem_bt, VecMaskUseLoad)) { 599 return false; // not supported 600 } 601 } else { 602 if (!arch_supports_vector(Op_StoreVector, num_elem, elem_bt, VecMaskUseStore)) { 603 return false; // not supported 604 } 605 } 606 } 607 608 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 609 610 if (can_access_non_heap) { 611 insert_mem_bar(Op_MemBarCPUOrder); 612 } 613 614 if (is_store) { 615 Node* val = unbox_vector(argument(6), vbox_type, elem_bt, num_elem); 616 if (val == NULL) { 617 return false; // operand unboxing failed 618 } 619 set_all_memory(reset_memory()); 620 621 // In case the store needs to happen to byte array, reinterpret the incoming vector to byte vector. 622 int store_num_elem = num_elem; 623 if (using_byte_array) { 624 store_num_elem = num_elem * type2aelembytes(elem_bt); 625 const TypeVect* to_vect_type = TypeVect::make(T_BYTE, store_num_elem); 626 val = gvn().transform(new VectorReinterpretNode(val, val->bottom_type()->is_vect(), to_vect_type)); 627 } 628 629 Node* vstore = gvn().transform(StoreVectorNode::make(0, control(), memory(addr), addr, addr_type, val, store_num_elem)); 630 set_memory(vstore, addr_type); 631 } else { 632 // When using byte array, we need to load as byte then reinterpret the value. Otherwise, do a simple vector load. 633 Node* vload = NULL; 634 if (using_byte_array) { 635 int load_num_elem = num_elem * type2aelembytes(elem_bt); 636 vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, load_num_elem, T_BYTE)); 637 const TypeVect* to_vect_type = TypeVect::make(elem_bt, num_elem); 638 vload = gvn().transform(new VectorReinterpretNode(vload, vload->bottom_type()->is_vect(), to_vect_type)); 639 } else { 640 // Special handle for masks 641 if (is_mask) { 642 vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, T_BOOLEAN)); 643 const TypeVect* to_vect_type = TypeVect::make(elem_bt, num_elem); 644 vload = gvn().transform(new VectorLoadMaskNode(vload, to_vect_type)); 645 } else { 646 vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, elem_bt)); 647 } 648 } 649 Node* box = box_vector(vload, vbox_type, elem_bt, num_elem); 650 set_result(box); 651 } 652 653 if (can_access_non_heap) { 654 insert_mem_bar(Op_MemBarCPUOrder); 655 } 656 657 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 658 return true; 659 } 660 661 // <C, V extends Vector<?>, W extends IntVector, E, S extends VectorSpecies<E>> 662 // void loadWithMap(Class<?> vectorClass, Class<E> E, int length, Class<?> vectorIndexClass, 663 // Object base, long offset, // Unsafe addressing 664 // W index_vector, 665 // C container, int index, int[] indexMap, int indexM, S s, // Arguments for default implementation 666 // LoadVectorOperationWithMap<C, V, E, S> defaultImpl) 667 // 668 // <C, V extends Vector<?>, W extends IntVector> 669 // void storeWithMap(Class<?> vectorClass, Class<?> elementType, int length, Class<?> vectorIndexClass, 670 // Object base, long offset, // Unsafe addressing 671 // W index_vector, V v, 672 // C container, int index, int[] indexMap, int indexM, // Arguments for default implementation 673 // StoreVectorOperationWithMap<C, V> defaultImpl) { 674 // 675 bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) { 676 const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); 677 const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr(); 678 const TypeInt* vlen = gvn().type(argument(2))->is_int(); 679 const TypeInstPtr* vector_idx_klass = gvn().type(argument(3))->is_instptr(); 680 681 if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || vector_idx_klass->const_oop() == NULL || !vlen->is_con()) { 682 if (C->print_intrinsics()) { 683 tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s viclass=%s", 684 NodeClassNames[argument(0)->Opcode()], 685 NodeClassNames[argument(1)->Opcode()], 686 NodeClassNames[argument(2)->Opcode()], 687 NodeClassNames[argument(3)->Opcode()]); 688 } 689 return false; // not enough info for intrinsification 690 } 691 692 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 693 if (!elem_type->is_primitive_type()) { 694 if (C->print_intrinsics()) { 695 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 696 } 697 return false; // should be primitive type 698 } 699 BasicType elem_bt = elem_type->basic_type(); 700 int num_elem = vlen->get_con(); 701 702 if (!arch_supports_vector(is_scatter ? Op_StoreVectorScatter : Op_LoadVectorGather, num_elem, elem_bt, VecMaskNotUsed)) { 703 if (C->print_intrinsics()) { 704 tty->print_cr(" ** not supported: arity=%d op=%s vlen=%d etype=%s ismask=no", 705 is_scatter, is_scatter ? "scatter" : "gather", 706 num_elem, type2name(elem_bt)); 707 } 708 return false; // not supported 709 } 710 711 // Check that the vector holding indices is supported by architecture 712 if (!arch_supports_vector(Op_LoadVector, num_elem, T_INT, VecMaskNotUsed)) { 713 if (C->print_intrinsics()) { 714 tty->print_cr(" ** not supported: arity=%d op=%s/loadindex vlen=%d etype=int ismask=no", 715 is_scatter, is_scatter ? "scatter" : "gather", 716 num_elem); 717 } 718 return false; // not supported 719 } 720 721 Node* base = argument(4); 722 Node* offset = ConvL2X(argument(5)); 723 Node* addr = make_unsafe_address(base, offset, C2_UNSAFE_ACCESS, elem_bt, true); 724 725 const TypePtr *addr_type = gvn().type(addr)->isa_ptr(); 726 const TypeAryPtr* arr_type = addr_type->isa_aryptr(); 727 728 // The array must be consistent with vector type 729 if (arr_type == NULL || (arr_type != NULL && elem_bt != arr_type->elem()->array_element_basic_type())) { 730 return false; 731 } 732 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 733 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 734 735 ciKlass* vbox_idx_klass = vector_idx_klass->const_oop()->as_instance()->java_lang_Class_klass(); 736 737 if (vbox_idx_klass == NULL) { 738 return false; 739 } 740 741 const TypeInstPtr* vbox_idx_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_idx_klass); 742 743 Node* index_vect = unbox_vector(argument(7), vbox_idx_type, T_INT, num_elem); 744 if (index_vect == NULL) { 745 return false; 746 } 747 const TypeVect* vector_type = TypeVect::make(elem_bt, num_elem); 748 if (is_scatter) { 749 Node* val = unbox_vector(argument(8), vbox_type, elem_bt, num_elem); 750 if (val == NULL) { 751 return false; // operand unboxing failed 752 } 753 set_all_memory(reset_memory()); 754 755 Node* vstore = gvn().transform(new StoreVectorScatterNode(control(), memory(addr), addr, addr_type, val, index_vect)); 756 set_memory(vstore, addr_type); 757 } else { 758 Node* vload = gvn().transform(new LoadVectorGatherNode(control(), memory(addr), addr, addr_type, vector_type, index_vect)); 759 760 Node* box = box_vector(vload, vbox_type, elem_bt, num_elem); 761 set_result(box); 762 } 763 764 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 765 return true; 766 } 767 768 // <V extends Vector<?,?>> 769 // long reductionCoerced(int oprId, Class<?> vectorClass, Class<?> elementType, int vlen, 770 // V v, 771 // Function<V,Long> defaultImpl) 772 773 bool LibraryCallKit::inline_vector_reduction() { 774 const TypeInt* opr = gvn().type(argument(0))->is_int(); 775 const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr(); 776 const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr(); 777 const TypeInt* vlen = gvn().type(argument(3))->is_int(); 778 779 if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) { 780 if (C->print_intrinsics()) { 781 tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s", 782 NodeClassNames[argument(0)->Opcode()], 783 NodeClassNames[argument(1)->Opcode()], 784 NodeClassNames[argument(2)->Opcode()], 785 NodeClassNames[argument(3)->Opcode()]); 786 } 787 return false; // not enough info for intrinsification 788 } 789 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 790 if (!elem_type->is_primitive_type()) { 791 if (C->print_intrinsics()) { 792 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 793 } 794 return false; // should be primitive type 795 } 796 BasicType elem_bt = elem_type->basic_type(); 797 int num_elem = vlen->get_con(); 798 799 int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt); 800 int sopc = ReductionNode::opcode(opc, elem_bt); 801 802 // TODO When mask usage is supported, VecMaskNotUsed needs to be VecMaskUseLoad. 803 if (!arch_supports_vector(sopc, num_elem, elem_bt, VecMaskNotUsed)) { 804 if (C->print_intrinsics()) { 805 tty->print_cr(" ** not supported: arity=1 op=%d/reduce vlen=%d etype=%s ismask=no", 806 sopc, num_elem, type2name(elem_bt)); 807 } 808 return false; 809 } 810 811 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 812 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 813 814 Node* opd = unbox_vector(argument(4), vbox_type, elem_bt, num_elem); 815 if (opd == NULL) { 816 return false; // operand unboxing failed 817 } 818 819 Node* init = ReductionNode::make_reduction_input(gvn(), opc, elem_bt); 820 Node* rn = gvn().transform(ReductionNode::make(opc, NULL, init, opd, elem_bt)); 821 822 Node* bits = NULL; 823 switch (elem_bt) { 824 case T_BYTE: 825 case T_SHORT: 826 case T_INT: { 827 bits = gvn().transform(new ConvI2LNode(rn)); 828 break; 829 } 830 case T_FLOAT: { 831 rn = gvn().transform(new MoveF2INode(rn)); 832 bits = gvn().transform(new ConvI2LNode(rn)); 833 break; 834 } 835 case T_DOUBLE: { 836 bits = gvn().transform(new MoveD2LNode(rn)); 837 break; 838 } 839 case T_LONG: { 840 bits = rn; // no conversion needed 841 break; 842 } 843 default: fatal("%s", type2name(elem_bt)); 844 } 845 set_result(bits); 846 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 847 return true; 848 } 849 850 // public static <V> boolean test(int cond, Class<?> vectorClass, Class<?> elementType, int vlen, 851 // V v1, V v2, 852 // BiFunction<V, V, Boolean> defaultImpl) { 853 // 854 bool LibraryCallKit::inline_vector_test() { 855 const TypeInt* cond = gvn().type(argument(0))->is_int(); 856 const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr(); 857 const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr(); 858 const TypeInt* vlen = gvn().type(argument(3))->is_int(); 859 860 if (!cond->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) { 861 if (C->print_intrinsics()) { 862 tty->print_cr(" ** missing constant: cond=%s vclass=%s etype=%s vlen=%s", 863 NodeClassNames[argument(0)->Opcode()], 864 NodeClassNames[argument(1)->Opcode()], 865 NodeClassNames[argument(2)->Opcode()], 866 NodeClassNames[argument(3)->Opcode()]); 867 } 868 return false; // not enough info for intrinsification 869 } 870 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 871 if (!elem_type->is_primitive_type()) { 872 if (C->print_intrinsics()) { 873 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 874 } 875 return false; // should be primitive type 876 } 877 BasicType elem_bt = elem_type->basic_type(); 878 int num_elem = vlen->get_con(); 879 BoolTest::mask booltest = (BoolTest::mask)cond->get_con(); 880 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 881 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 882 883 if (!arch_supports_vector(Op_VectorTest, num_elem, elem_bt, is_vector_mask(vbox_klass) ? VecMaskUseLoad : VecMaskNotUsed)) { 884 if (C->print_intrinsics()) { 885 tty->print_cr(" ** not supported: arity=2 op=test/%d vlen=%d etype=%s ismask=%d", 886 cond->get_con(), num_elem, type2name(elem_bt), 887 is_vector_mask(vbox_klass)); 888 } 889 return false; 890 } 891 892 Node* opd1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem); 893 Node* opd2 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem); 894 if (opd1 == NULL || opd2 == NULL) { 895 return false; // operand unboxing failed 896 } 897 Node* test = new VectorTestNode(opd1, opd2, booltest); 898 test = gvn().transform(test); 899 900 set_result(test); 901 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 902 return true; 903 } 904 905 // public static 906 // <V extends Vector, M extends Mask> 907 // V blend(Class<V> vectorClass, Class<M> maskClass, Class<?> elementType, int vlen, 908 // V v1, V v2, M m, 909 // VectorBlendOp<V,M> defaultImpl) { ... 910 // 911 bool LibraryCallKit::inline_vector_blend() { 912 const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); 913 const TypeInstPtr* mask_klass = gvn().type(argument(1))->is_instptr(); 914 const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr(); 915 const TypeInt* vlen = gvn().type(argument(3))->is_int(); 916 917 if (mask_klass->const_oop() == NULL || vector_klass->const_oop() == NULL || 918 elem_klass->const_oop() == NULL || !vlen->is_con()) { 919 if (C->print_intrinsics()) { 920 tty->print_cr(" ** missing constant: vclass=%s mclass=%s etype=%s vlen=%s", 921 NodeClassNames[argument(0)->Opcode()], 922 NodeClassNames[argument(1)->Opcode()], 923 NodeClassNames[argument(2)->Opcode()], 924 NodeClassNames[argument(3)->Opcode()]); 925 } 926 return false; // not enough info for intrinsification 927 } 928 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 929 if (!elem_type->is_primitive_type()) { 930 if (C->print_intrinsics()) { 931 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 932 } 933 return false; // should be primitive type 934 } 935 BasicType elem_bt = elem_type->basic_type(); 936 BasicType mask_bt = elem_bt; 937 int num_elem = vlen->get_con(); 938 939 if (!arch_supports_vector(Op_VectorBlend, num_elem, elem_bt, VecMaskUseLoad)) { 940 if (C->print_intrinsics()) { 941 tty->print_cr(" ** not supported: arity=2 op=blend vlen=%d etype=%s ismask=useload", 942 num_elem, type2name(elem_bt)); 943 } 944 return false; // not supported 945 } 946 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 947 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 948 949 ciKlass* mbox_klass = mask_klass->const_oop()->as_instance()->java_lang_Class_klass(); 950 const TypeInstPtr* mbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, mbox_klass); 951 952 Node* v1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem); 953 Node* v2 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem); 954 Node* mask = unbox_vector(argument(6), mbox_type, mask_bt, num_elem); 955 956 if (v1 == NULL || v2 == NULL || mask == NULL) { 957 return false; // operand unboxing failed 958 } 959 960 Node* blend = gvn().transform(new VectorBlendNode(v1, v2, mask)); 961 962 Node* box = box_vector(blend, vbox_type, elem_bt, num_elem); 963 set_result(box); 964 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 965 return true; 966 } 967 968 // public static <V extends Vector<E,S>, 969 // M extends Vector.Mask<E,S>, 970 // S extends Vector.Shape, E> 971 // M compare(int cond, Class<V> vectorClass, Class<M> maskClass, Class<?> elementType, int vlen, 972 // V v1, V v2, 973 // VectorCompareOp<V,M> defaultImpl) { ... 974 // 975 bool LibraryCallKit::inline_vector_compare() { 976 const TypeInt* cond = gvn().type(argument(0))->is_int(); 977 const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr(); 978 const TypeInstPtr* mask_klass = gvn().type(argument(2))->is_instptr(); 979 const TypeInstPtr* elem_klass = gvn().type(argument(3))->is_instptr(); 980 const TypeInt* vlen = gvn().type(argument(4))->is_int(); 981 982 if (!cond->is_con() || vector_klass->const_oop() == NULL || mask_klass->const_oop() == NULL || 983 elem_klass->const_oop() == NULL || !vlen->is_con()) { 984 if (C->print_intrinsics()) { 985 tty->print_cr(" ** missing constant: cond=%s vclass=%s mclass=%s etype=%s vlen=%s", 986 NodeClassNames[argument(0)->Opcode()], 987 NodeClassNames[argument(1)->Opcode()], 988 NodeClassNames[argument(2)->Opcode()], 989 NodeClassNames[argument(3)->Opcode()], 990 NodeClassNames[argument(4)->Opcode()]); 991 } 992 return false; // not enough info for intrinsification 993 } 994 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 995 if (!elem_type->is_primitive_type()) { 996 if (C->print_intrinsics()) { 997 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 998 } 999 return false; // should be primitive type 1000 } 1001 1002 int num_elem = vlen->get_con(); 1003 BasicType elem_bt = elem_type->basic_type(); 1004 BasicType mask_bt = elem_bt; 1005 1006 if (!arch_supports_vector(Op_VectorMaskCmp, num_elem, elem_bt, VecMaskUseStore)) { 1007 if (C->print_intrinsics()) { 1008 tty->print_cr(" ** not supported: arity=2 op=comp/%d vlen=%d etype=%s ismask=usestore", 1009 cond->get_con(), num_elem, type2name(elem_bt)); 1010 } 1011 return false; 1012 } 1013 1014 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 1015 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 1016 1017 ciKlass* mbox_klass = mask_klass->const_oop()->as_instance()->java_lang_Class_klass(); 1018 const TypeInstPtr* mbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, mbox_klass); 1019 1020 Node* v1 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem); 1021 Node* v2 = unbox_vector(argument(6), vbox_type, elem_bt, num_elem); 1022 1023 if (v1 == NULL || v2 == NULL) { 1024 return false; // operand unboxing failed 1025 } 1026 BoolTest::mask pred = (BoolTest::mask)cond->get_con(); 1027 ConINode* pred_node = (ConINode*)gvn().makecon(cond); 1028 1029 const TypeVect* vt = TypeVect::make(mask_bt, num_elem); 1030 Node* operation = gvn().transform(new VectorMaskCmpNode(pred, v1, v2, pred_node, vt)); 1031 1032 Node* box = box_vector(operation, mbox_type, mask_bt, num_elem); 1033 set_result(box); 1034 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 1035 return true; 1036 } 1037 1038 // public static 1039 // <V extends Vector, Sh extends Shuffle> 1040 // V rearrangeOp(Class<V> vectorClass, Class<Sh> shuffleClass, Class< ? > elementType, int vlen, 1041 // V v1, Sh sh, 1042 // VectorSwizzleOp<V, Sh, S, E> defaultImpl) { ... 1043 1044 bool LibraryCallKit::inline_vector_rearrange() { 1045 const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); 1046 const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->is_instptr(); 1047 const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr(); 1048 const TypeInt* vlen = gvn().type(argument(3))->is_int(); 1049 1050 if (shuffle_klass->const_oop() == NULL || vector_klass->const_oop() == NULL || 1051 elem_klass->const_oop() == NULL || !vlen->is_con()) { 1052 return false; // not enough info for intrinsification 1053 if (C->print_intrinsics()) { 1054 tty->print_cr(" ** missing constant: vclass=%s sclass=%s etype=%s vlen=%s", 1055 NodeClassNames[argument(0)->Opcode()], 1056 NodeClassNames[argument(1)->Opcode()], 1057 NodeClassNames[argument(2)->Opcode()], 1058 NodeClassNames[argument(3)->Opcode()]); 1059 } 1060 } 1061 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 1062 if (!elem_type->is_primitive_type()) { 1063 if (C->print_intrinsics()) { 1064 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 1065 } 1066 return false; // should be primitive type 1067 } 1068 BasicType elem_bt = elem_type->basic_type(); 1069 BasicType shuffle_bt = elem_bt; 1070 int num_elem = vlen->get_con(); 1071 1072 if (!arch_supports_vector(Op_VectorLoadShuffle, num_elem, elem_bt, VecMaskNotUsed)) { 1073 if (C->print_intrinsics()) { 1074 tty->print_cr(" ** not supported: arity=0 op=load/shuffle vlen=%d etype=%s ismask=no", 1075 num_elem, type2name(elem_bt)); 1076 } 1077 return false; // not supported 1078 } 1079 if (!arch_supports_vector(Op_VectorRearrange, num_elem, elem_bt, VecMaskNotUsed)) { 1080 if (C->print_intrinsics()) { 1081 tty->print_cr(" ** not supported: arity=2 op=shuffle/rearrange vlen=%d etype=%s ismask=no", 1082 num_elem, type2name(elem_bt)); 1083 } 1084 return false; // not supported 1085 } 1086 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 1087 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 1088 1089 ciKlass* shbox_klass = shuffle_klass->const_oop()->as_instance()->java_lang_Class_klass(); 1090 const TypeInstPtr* shbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, shbox_klass); 1091 1092 Node* v1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem); 1093 Node* shuffle = unbox_vector(argument(5), shbox_type, shuffle_bt, num_elem); 1094 1095 if (v1 == NULL || shuffle == NULL) { 1096 return false; // operand unboxing failed 1097 } 1098 1099 Node* rearrange = gvn().transform(new VectorRearrangeNode(v1, shuffle)); 1100 1101 Node* box = box_vector(rearrange, vbox_type, elem_bt, num_elem); 1102 set_result(box); 1103 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 1104 return true; 1105 } 1106 1107 Node* LibraryCallKit::shift_count(Node* cnt, int shift_op, BasicType bt, int num_elem) { 1108 assert(bt == T_INT || bt == T_LONG || bt == T_SHORT || bt == T_BYTE, "byte, short, long and int are supported"); 1109 juint mask = (type2aelembytes(bt) * BitsPerByte - 1); 1110 Node* nmask = gvn().transform(ConNode::make(TypeInt::make(mask))); 1111 Node* mcnt = gvn().transform(new AndINode(cnt, nmask)); 1112 return gvn().transform(VectorNode::shift_count(shift_op, mcnt, num_elem, bt)); 1113 } 1114 1115 // public static 1116 // <V extends Vector<?,?>> 1117 // V broadcastInt(int opr, Class<V> vectorClass, Class<?> elementType, int vlen, 1118 // V v, int i, 1119 // VectorBroadcastIntOp<V> defaultImpl) { 1120 // 1121 bool LibraryCallKit::inline_vector_broadcast_int() { 1122 const TypeInt* opr = gvn().type(argument(0))->is_int(); 1123 const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr(); 1124 const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr(); 1125 const TypeInt* vlen = gvn().type(argument(3))->is_int(); 1126 1127 if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) { 1128 if (C->print_intrinsics()) { 1129 tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s", 1130 NodeClassNames[argument(0)->Opcode()], 1131 NodeClassNames[argument(1)->Opcode()], 1132 NodeClassNames[argument(2)->Opcode()], 1133 NodeClassNames[argument(3)->Opcode()]); 1134 } 1135 return false; // not enough info for intrinsification 1136 } 1137 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 1138 if (!elem_type->is_primitive_type()) { 1139 if (C->print_intrinsics()) { 1140 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 1141 } 1142 return false; // should be primitive type 1143 } 1144 BasicType elem_bt = elem_type->basic_type(); 1145 int num_elem = vlen->get_con(); 1146 int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt); 1147 int sopc = get_sopc(opc, elem_bt, 1); // get_node_id(opr->get_con(), elem_bt); 1148 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 1149 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 1150 1151 if (!arch_supports_vector(sopc, num_elem, elem_bt, VecMaskNotUsed)) { 1152 if (C->print_intrinsics()) { 1153 tty->print_cr(" ** not supported: arity=0 op=int/%d vlen=%d etype=%s ismask=no", 1154 sopc, num_elem, type2name(elem_bt)); 1155 } 1156 return false; // not supported 1157 } 1158 Node* opd1 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem); 1159 Node* opd2 = shift_count(argument(5), opc, elem_bt, num_elem); 1160 if (opd1 == NULL || opd2 == NULL) { 1161 return false; 1162 } 1163 Node* operation = gvn().transform(VectorNode::make(opc, opd1, opd2, num_elem, elem_bt)); 1164 1165 Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem); 1166 set_result(vbox); 1167 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 1168 return true; 1169 } 1170 1171 // public static <VOUT extends VectorPayload, 1172 // VIN extends VectorPayload, 1173 // S extends VectorSpecies> 1174 // VOUT convert(int oprId, 1175 // Class<?> fromVectorClass, Class<?> fromElementType, int fromVLen, 1176 // Class<?> toVectorClass, Class<?> toElementType, int toVLen, 1177 // VIN v, S s, 1178 // VectorConvertOp<VOUT, VIN, S> defaultImpl) { 1179 // 1180 bool LibraryCallKit::inline_vector_convert() { 1181 const TypeInt* opr = gvn().type(argument(0))->is_int(); 1182 1183 const TypeInstPtr* vector_klass_from = gvn().type(argument(1))->is_instptr(); 1184 const TypeInstPtr* elem_klass_from = gvn().type(argument(2))->is_instptr(); 1185 const TypeInt* vlen_from = gvn().type(argument(3))->is_int(); 1186 1187 const TypeInstPtr* vector_klass_to = gvn().type(argument(4))->is_instptr(); 1188 const TypeInstPtr* elem_klass_to = gvn().type(argument(5))->is_instptr(); 1189 const TypeInt* vlen_to = gvn().type(argument(6))->is_int(); 1190 1191 if (!opr->is_con() || 1192 vector_klass_from->const_oop() == NULL || elem_klass_from->const_oop() == NULL || !vlen_from->is_con() || 1193 vector_klass_to->const_oop() == NULL || elem_klass_to->const_oop() == NULL || !vlen_to->is_con()) { 1194 if (C->print_intrinsics()) { 1195 tty->print_cr(" ** missing constant: opr=%s vclass_from=%s etype_from=%s vlen_from=%s vclass_to=%s etype_to=%s vlen_to=%s", 1196 NodeClassNames[argument(0)->Opcode()], 1197 NodeClassNames[argument(1)->Opcode()], 1198 NodeClassNames[argument(2)->Opcode()], 1199 NodeClassNames[argument(3)->Opcode()], 1200 NodeClassNames[argument(4)->Opcode()], 1201 NodeClassNames[argument(5)->Opcode()], 1202 NodeClassNames[argument(6)->Opcode()]); 1203 } 1204 return false; // not enough info for intrinsification 1205 } 1206 1207 assert(opr->get_con() == VectorSupport::VECTOR_OP_CAST || 1208 opr->get_con() == VectorSupport::VECTOR_OP_REINTERPRET, "wrong opcode"); 1209 bool is_cast = (opr->get_con() == VectorSupport::VECTOR_OP_CAST); 1210 1211 ciKlass* vbox_klass_from = vector_klass_from->const_oop()->as_instance()->java_lang_Class_klass(); 1212 ciKlass* vbox_klass_to = vector_klass_to->const_oop()->as_instance()->java_lang_Class_klass(); 1213 if (is_vector_shuffle(vbox_klass_from) || is_vector_shuffle(vbox_klass_to)) { 1214 return false; // vector shuffles aren't supported 1215 } 1216 bool is_mask = is_vector_mask(vbox_klass_from); 1217 1218 ciType* elem_type_from = elem_klass_from->const_oop()->as_instance()->java_mirror_type(); 1219 if (!elem_type_from->is_primitive_type()) { 1220 return false; // should be primitive type 1221 } 1222 BasicType elem_bt_from = elem_type_from->basic_type(); 1223 ciType* elem_type_to = elem_klass_to->const_oop()->as_instance()->java_mirror_type(); 1224 if (!elem_type_to->is_primitive_type()) { 1225 return false; // should be primitive type 1226 } 1227 BasicType elem_bt_to = elem_type_to->basic_type(); 1228 if (is_mask && elem_bt_from != elem_bt_to) { 1229 return false; // type mismatch 1230 } 1231 int num_elem_from = vlen_from->get_con(); 1232 int num_elem_to = vlen_to->get_con(); 1233 1234 // Check whether we can unbox to appropriate size. Even with casting, checking for reinterpret is needed 1235 // since we may need to change size. 1236 if (!arch_supports_vector(Op_VectorReinterpret, 1237 num_elem_from, 1238 elem_bt_from, 1239 is_mask ? VecMaskUseAll : VecMaskNotUsed)) { 1240 if (C->print_intrinsics()) { 1241 tty->print_cr(" ** not supported: arity=1 op=%s/1 vlen1=%d etype1=%s ismask=%d", 1242 is_cast ? "cast" : "reinterpret", 1243 num_elem_from, type2name(elem_bt_from), is_mask); 1244 } 1245 return false; 1246 } 1247 1248 // Check whether we can support resizing/reinterpreting to the new size. 1249 if (!arch_supports_vector(Op_VectorReinterpret, 1250 num_elem_to, 1251 elem_bt_to, 1252 is_mask ? VecMaskUseAll : VecMaskNotUsed)) { 1253 if (C->print_intrinsics()) { 1254 tty->print_cr(" ** not supported: arity=1 op=%s/2 vlen2=%d etype2=%s ismask=%d", 1255 is_cast ? "cast" : "reinterpret", 1256 num_elem_to, type2name(elem_bt_to), is_mask); 1257 } 1258 return false; 1259 } 1260 1261 // At this point, we know that both input and output vector registers are supported 1262 // by the architecture. Next check if the casted type is simply to same type - which means 1263 // that it is actually a resize and not a cast. 1264 if (is_cast && elem_bt_from == elem_bt_to) { 1265 is_cast = false; 1266 } 1267 1268 const TypeInstPtr* vbox_type_from = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass_from); 1269 1270 Node* opd1 = unbox_vector(argument(7), vbox_type_from, elem_bt_from, num_elem_from); 1271 if (opd1 == NULL) { 1272 return false; 1273 } 1274 1275 const TypeVect* src_type = TypeVect::make(elem_bt_from, num_elem_from); 1276 const TypeVect* dst_type = TypeVect::make(elem_bt_to, num_elem_to); 1277 1278 Node* op = opd1; 1279 if (is_cast) { 1280 assert(!is_mask, "masks cannot be casted"); 1281 int cast_vopc = VectorCastNode::opcode(elem_bt_from); 1282 // Make sure that cast is implemented to particular type/size combination. 1283 if (!arch_supports_vector(cast_vopc, num_elem_to, elem_bt_to, VecMaskNotUsed)) { 1284 if (C->print_intrinsics()) { 1285 tty->print_cr(" ** not supported: arity=1 op=cast#%d/3 vlen2=%d etype2=%s ismask=%d", 1286 cast_vopc, 1287 num_elem_to, type2name(elem_bt_to), is_mask); 1288 } 1289 return false; 1290 } 1291 1292 if (num_elem_from < num_elem_to) { 1293 // Since input and output number of elements are not consistent, we need to make sure we 1294 // properly size. Thus, first make a cast that retains the number of elements from source. 1295 // In case the size exceeds the arch size, we do the minimum. 1296 int num_elem_for_cast = MIN2(num_elem_from, Matcher::max_vector_size(elem_bt_to)); 1297 1298 // It is possible that arch does not support this intermediate vector size 1299 // TODO More complex logic required here to handle this corner case for the sizes. 1300 if (!arch_supports_vector(cast_vopc, num_elem_for_cast, elem_bt_to, VecMaskNotUsed)) { 1301 if (C->print_intrinsics()) { 1302 tty->print_cr(" ** not supported: arity=1 op=cast#%d/4 vlen1=%d etype2=%s ismask=%d", 1303 cast_vopc, 1304 num_elem_for_cast, type2name(elem_bt_to), is_mask); 1305 } 1306 return false; 1307 } 1308 1309 op = gvn().transform(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_for_cast)); 1310 // Now ensure that the destination gets properly resized to needed size. 1311 op = gvn().transform(new VectorReinterpretNode(op, op->bottom_type()->is_vect(), dst_type)); 1312 } else if (num_elem_from > num_elem_to) { 1313 // Since number elements from input is larger than output, simply reduce size of input (we are supposed to 1314 // drop top elements anyway). 1315 int num_elem_for_resize = MAX2(num_elem_to, Matcher::min_vector_size(elem_bt_to)); 1316 1317 // It is possible that arch does not support this intermediate vector size 1318 // TODO More complex logic required here to handle this corner case for the sizes. 1319 if (!arch_supports_vector(Op_VectorReinterpret, 1320 num_elem_for_resize, 1321 elem_bt_from, 1322 VecMaskNotUsed)) { 1323 if (C->print_intrinsics()) { 1324 tty->print_cr(" ** not supported: arity=1 op=cast/5 vlen2=%d etype1=%s ismask=%d", 1325 num_elem_for_resize, type2name(elem_bt_from), is_mask); 1326 } 1327 return false; 1328 } 1329 1330 op = gvn().transform(new VectorReinterpretNode(op, 1331 src_type, 1332 TypeVect::make(elem_bt_from, 1333 num_elem_for_resize))); 1334 op = gvn().transform(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_to)); 1335 } else { 1336 // Since input and output number of elements match, and since we know this vector size is 1337 // supported, simply do a cast with no resize needed. 1338 op = gvn().transform(VectorCastNode::make(cast_vopc, op, elem_bt_to, num_elem_to)); 1339 } 1340 } else if (Type::cmp(src_type, dst_type) != 0) { 1341 assert(!is_cast, "must be reinterpret"); 1342 op = gvn().transform(new VectorReinterpretNode(op, src_type, dst_type)); 1343 } 1344 1345 const TypeInstPtr* vbox_type_to = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass_to); 1346 Node* vbox = box_vector(op, vbox_type_to, elem_bt_to, num_elem_to); 1347 set_result(vbox); 1348 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem_to * type2aelembytes(elem_bt_to)))); 1349 return true; 1350 } 1351 1352 // public static 1353 // <V extends Vector<?>> 1354 // V insert(Class<? extends V> vectorClass, Class<?> elementType, int vlen, 1355 // V vec, int ix, long val, 1356 // VecInsertOp<V> defaultImpl) { 1357 // 1358 bool LibraryCallKit::inline_vector_insert() { 1359 const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); 1360 const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr(); 1361 const TypeInt* vlen = gvn().type(argument(2))->is_int(); 1362 const TypeInt* idx = gvn().type(argument(4))->is_int(); 1363 1364 if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con() || !idx->is_con()) { 1365 if (C->print_intrinsics()) { 1366 tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s idx=%s", 1367 NodeClassNames[argument(0)->Opcode()], 1368 NodeClassNames[argument(1)->Opcode()], 1369 NodeClassNames[argument(2)->Opcode()], 1370 NodeClassNames[argument(4)->Opcode()]); 1371 } 1372 return false; // not enough info for intrinsification 1373 } 1374 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 1375 if (!elem_type->is_primitive_type()) { 1376 if (C->print_intrinsics()) { 1377 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 1378 } 1379 return false; // should be primitive type 1380 } 1381 BasicType elem_bt = elem_type->basic_type(); 1382 int num_elem = vlen->get_con(); 1383 if (!arch_supports_vector(Op_VectorInsert, num_elem, elem_bt, VecMaskNotUsed)) { 1384 if (C->print_intrinsics()) { 1385 tty->print_cr(" ** not supported: arity=1 op=insert vlen=%d etype=%s ismask=no", 1386 num_elem, type2name(elem_bt)); 1387 } 1388 return false; // not supported 1389 } 1390 1391 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 1392 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 1393 1394 Node* opd = unbox_vector(argument(3), vbox_type, elem_bt, num_elem); 1395 if (opd == NULL) { 1396 return false; 1397 } 1398 1399 Node* insert_val = argument(5); 1400 assert(gvn().type(insert_val)->isa_long() != NULL, "expected to be long"); 1401 1402 // Convert insert value back to its appropriate type. 1403 switch (elem_bt) { 1404 case T_BYTE: 1405 insert_val = gvn().transform(new ConvL2INode(insert_val)); 1406 insert_val = gvn().transform(new CastIINode(insert_val, TypeInt::BYTE)); 1407 break; 1408 case T_SHORT: 1409 insert_val = gvn().transform(new ConvL2INode(insert_val)); 1410 insert_val = gvn().transform(new CastIINode(insert_val, TypeInt::SHORT)); 1411 break; 1412 case T_INT: 1413 insert_val = gvn().transform(new ConvL2INode(insert_val)); 1414 break; 1415 case T_FLOAT: 1416 insert_val = gvn().transform(new ConvL2INode(insert_val)); 1417 insert_val = gvn().transform(new MoveI2FNode(insert_val)); 1418 break; 1419 case T_DOUBLE: 1420 insert_val = gvn().transform(new MoveL2DNode(insert_val)); 1421 break; 1422 case T_LONG: 1423 // no conversion needed 1424 break; 1425 default: fatal("%s", type2name(elem_bt)); break; 1426 } 1427 1428 Node* operation = gvn().transform(VectorInsertNode::make(opd, insert_val, idx->get_con())); 1429 1430 Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem); 1431 set_result(vbox); 1432 C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); 1433 return true; 1434 } 1435 1436 // public static 1437 // <V extends Vector<?>> 1438 // long extract(Class<?> vectorClass, Class<?> elementType, int vlen, 1439 // V vec, int ix, 1440 // VecExtractOp<V> defaultImpl) { 1441 // 1442 bool LibraryCallKit::inline_vector_extract() { 1443 const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr(); 1444 const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr(); 1445 const TypeInt* vlen = gvn().type(argument(2))->is_int(); 1446 const TypeInt* idx = gvn().type(argument(4))->is_int(); 1447 1448 if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con() || !idx->is_con()) { 1449 if (C->print_intrinsics()) { 1450 tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s idx=%s", 1451 NodeClassNames[argument(0)->Opcode()], 1452 NodeClassNames[argument(1)->Opcode()], 1453 NodeClassNames[argument(2)->Opcode()], 1454 NodeClassNames[argument(4)->Opcode()]); 1455 } 1456 return false; // not enough info for intrinsification 1457 } 1458 ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); 1459 if (!elem_type->is_primitive_type()) { 1460 if (C->print_intrinsics()) { 1461 tty->print_cr(" ** not a primitive bt=%d", elem_type->basic_type()); 1462 } 1463 return false; // should be primitive type 1464 } 1465 BasicType elem_bt = elem_type->basic_type(); 1466 int num_elem = vlen->get_con(); 1467 int vopc = ExtractNode::opcode(elem_bt); 1468 if (!arch_supports_vector(vopc, num_elem, elem_bt, VecMaskNotUsed)) { 1469 if (C->print_intrinsics()) { 1470 tty->print_cr(" ** not supported: arity=1 op=extract vlen=%d etype=%s ismask=no", 1471 num_elem, type2name(elem_bt)); 1472 } 1473 return false; // not supported 1474 } 1475 1476 ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); 1477 const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); 1478 1479 Node* opd = unbox_vector(argument(3), vbox_type, elem_bt, num_elem); 1480 if (opd == NULL) { 1481 return false; 1482 } 1483 1484 Node* operation = gvn().transform(ExtractNode::make(opd, idx->get_con(), elem_bt)); 1485 1486 Node* bits = NULL; 1487 switch (elem_bt) { 1488 case T_BYTE: 1489 case T_SHORT: 1490 case T_INT: { 1491 bits = gvn().transform(new ConvI2LNode(operation)); 1492 break; 1493 } 1494 case T_FLOAT: { 1495 bits = gvn().transform(new MoveF2INode(operation)); 1496 bits = gvn().transform(new ConvI2LNode(bits)); 1497 break; 1498 } 1499 case T_DOUBLE: { 1500 bits = gvn().transform(new MoveD2LNode(operation)); 1501 break; 1502 } 1503 case T_LONG: { 1504 bits = operation; // no conversion needed 1505 break; 1506 } 1507 default: fatal("%s", type2name(elem_bt)); 1508 } 1509 1510 set_result(bits); 1511 return true; 1512 } 1513