< prev index next >

src/hotspot/share/opto/vector.cpp

Print this page

  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  *

321   } else {
322     assert(!vbox->is_Phi(), "");
323     // TODO: assert that expanded vbox is initialized with the same value (vect).
324     return vbox; // already expanded
325   }
326 }
327 
328 Node* PhaseVector::expand_vbox_alloc_node(VectorBoxAllocateNode* vbox_alloc,
329                                           Node* value,
330                                           const TypeInstPtr* box_type,
331                                           const TypeVect* vect_type) {
332   JVMState* jvms = clone_jvms(C, vbox_alloc);
333   GraphKit kit(jvms);
334   PhaseGVN& gvn = kit.gvn();
335 
336   ciInstanceKlass* box_klass = box_type->klass()->as_instance_klass();
337   BasicType bt = vect_type->element_basic_type();
338   int num_elem = vect_type->length();
339 
340   bool is_mask = is_vector_mask(box_klass);
341   if (is_mask && bt != T_BOOLEAN) {



342     value = gvn.transform(VectorStoreMaskNode::make(gvn, value, bt, num_elem));
343     // Although type of mask depends on its definition, in terms of storage everything is stored in boolean array.
344     bt = T_BOOLEAN;
345     assert(value->bottom_type()->is_vect()->element_basic_type() == bt,
346            "must be consistent with mask representation");
347   }
348 
349   // Generate array allocation for the field which holds the values.
350   const TypeKlassPtr* array_klass = TypeKlassPtr::make(ciTypeArrayKlass::make(bt));
351   Node* arr = kit.new_array(kit.makecon(array_klass), kit.intcon(num_elem), 1);
352 
353   // Store the vector value into the array.
354   // (The store should be captured by InitializeNode and turned into initialized store later.)
355   Node* arr_adr = kit.array_element_address(arr, kit.intcon(0), bt);
356   const TypePtr* arr_adr_type = arr_adr->bottom_type()->is_ptr();
357   Node* arr_mem = kit.memory(arr_adr);
358   Node* vstore = gvn.transform(StoreVectorNode::make(0,
359                                                      kit.control(),
360                                                      arr_mem,
361                                                      arr_adr,

437     // For proper aliasing, attach concrete payload type.
438     ciKlass* payload_klass = ciTypeArrayKlass::make(bt);
439     const Type* payload_type = TypeAryPtr::make_from_klass(payload_klass)->cast_to_ptr_type(TypePtr::NotNull);
440     vec_field_ld = gvn.transform(new CastPPNode(vec_field_ld, payload_type));
441 
442     Node* adr = kit.array_element_address(vec_field_ld, gvn.intcon(0), bt);
443     const TypePtr* adr_type = adr->bottom_type()->is_ptr();
444     int num_elem = vt->length();
445     Node* vec_val_load = LoadVectorNode::make(0,
446                                               ctrl,
447                                               mem,
448                                               adr,
449                                               adr_type,
450                                               num_elem,
451                                               bt);
452     vec_val_load = gvn.transform(vec_val_load);
453 
454     C->set_max_vector_size(MAX2(C->max_vector_size(), vt->length_in_bytes()));
455 
456     if (is_vector_mask(from_kls)) {
457       vec_val_load = gvn.transform(new VectorLoadMaskNode(vec_val_load, TypeVect::make(masktype, num_elem)));
458     } else if (is_vector_shuffle(from_kls) && !vec_unbox->is_shuffle_to_vector()) {
459       assert(vec_unbox->bottom_type()->is_vect()->element_basic_type() == masktype, "expect shuffle type consistency");
460       vec_val_load = gvn.transform(new VectorLoadShuffleNode(vec_val_load, TypeVect::make(masktype, num_elem)));
461     }
462 
463     gvn.hash_delete(vec_unbox);
464     vec_unbox->disconnect_inputs(C);
465     C->gvn_replace_by(vec_unbox, vec_val_load);
466   }
467   C->remove_macro_node(vec_unbox);
468 }
469 
470 void PhaseVector::eliminate_vbox_alloc_node(VectorBoxAllocateNode* vbox_alloc) {
471   JVMState* jvms = clone_jvms(C, vbox_alloc);
472   GraphKit kit(jvms);
473   // Remove VBA, but leave a safepoint behind.
474   // Otherwise, it may end up with a loop without any safepoint polls.
475   kit.replace_call(vbox_alloc, kit.map(), true);
476   C->remove_macro_node(vbox_alloc);
477 }

  1 /*
  2  * Copyright (c) 2020, 2021, 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  *

321   } else {
322     assert(!vbox->is_Phi(), "");
323     // TODO: assert that expanded vbox is initialized with the same value (vect).
324     return vbox; // already expanded
325   }
326 }
327 
328 Node* PhaseVector::expand_vbox_alloc_node(VectorBoxAllocateNode* vbox_alloc,
329                                           Node* value,
330                                           const TypeInstPtr* box_type,
331                                           const TypeVect* vect_type) {
332   JVMState* jvms = clone_jvms(C, vbox_alloc);
333   GraphKit kit(jvms);
334   PhaseGVN& gvn = kit.gvn();
335 
336   ciInstanceKlass* box_klass = box_type->klass()->as_instance_klass();
337   BasicType bt = vect_type->element_basic_type();
338   int num_elem = vect_type->length();
339 
340   bool is_mask = is_vector_mask(box_klass);
341   // If boxed mask value is present in a predicate register, it must be
342   // spilled to a vector though a VectorStoreMaskOperation before actual StoreVector
343   // operation to vector payload field.
344   if (is_mask && (value->bottom_type()->isa_vectmask() || bt != T_BOOLEAN)) {
345     value = gvn.transform(VectorStoreMaskNode::make(gvn, value, bt, num_elem));
346     // Although type of mask depends on its definition, in terms of storage everything is stored in boolean array.
347     bt = T_BOOLEAN;
348     assert(value->bottom_type()->is_vect()->element_basic_type() == bt,
349            "must be consistent with mask representation");
350   }
351 
352   // Generate array allocation for the field which holds the values.
353   const TypeKlassPtr* array_klass = TypeKlassPtr::make(ciTypeArrayKlass::make(bt));
354   Node* arr = kit.new_array(kit.makecon(array_klass), kit.intcon(num_elem), 1);
355 
356   // Store the vector value into the array.
357   // (The store should be captured by InitializeNode and turned into initialized store later.)
358   Node* arr_adr = kit.array_element_address(arr, kit.intcon(0), bt);
359   const TypePtr* arr_adr_type = arr_adr->bottom_type()->is_ptr();
360   Node* arr_mem = kit.memory(arr_adr);
361   Node* vstore = gvn.transform(StoreVectorNode::make(0,
362                                                      kit.control(),
363                                                      arr_mem,
364                                                      arr_adr,

440     // For proper aliasing, attach concrete payload type.
441     ciKlass* payload_klass = ciTypeArrayKlass::make(bt);
442     const Type* payload_type = TypeAryPtr::make_from_klass(payload_klass)->cast_to_ptr_type(TypePtr::NotNull);
443     vec_field_ld = gvn.transform(new CastPPNode(vec_field_ld, payload_type));
444 
445     Node* adr = kit.array_element_address(vec_field_ld, gvn.intcon(0), bt);
446     const TypePtr* adr_type = adr->bottom_type()->is_ptr();
447     int num_elem = vt->length();
448     Node* vec_val_load = LoadVectorNode::make(0,
449                                               ctrl,
450                                               mem,
451                                               adr,
452                                               adr_type,
453                                               num_elem,
454                                               bt);
455     vec_val_load = gvn.transform(vec_val_load);
456 
457     C->set_max_vector_size(MAX2(C->max_vector_size(), vt->length_in_bytes()));
458 
459     if (is_vector_mask(from_kls)) {
460       vec_val_load = gvn.transform(new VectorLoadMaskNode(vec_val_load, TypeVect::makemask(masktype, num_elem)));
461     } else if (is_vector_shuffle(from_kls) && !vec_unbox->is_shuffle_to_vector()) {
462       assert(vec_unbox->bottom_type()->is_vect()->element_basic_type() == masktype, "expect shuffle type consistency");
463       vec_val_load = gvn.transform(new VectorLoadShuffleNode(vec_val_load, TypeVect::make(masktype, num_elem)));
464     }
465 
466     gvn.hash_delete(vec_unbox);
467     vec_unbox->disconnect_inputs(C);
468     C->gvn_replace_by(vec_unbox, vec_val_load);
469   }
470   C->remove_macro_node(vec_unbox);
471 }
472 
473 void PhaseVector::eliminate_vbox_alloc_node(VectorBoxAllocateNode* vbox_alloc) {
474   JVMState* jvms = clone_jvms(C, vbox_alloc);
475   GraphKit kit(jvms);
476   // Remove VBA, but leave a safepoint behind.
477   // Otherwise, it may end up with a loop without any safepoint polls.
478   kit.replace_call(vbox_alloc, kit.map(), true);
479   C->remove_macro_node(vbox_alloc);
480 }
< prev index next >