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 "opto/castnode.hpp"
  27 #include "opto/graphKit.hpp"
  28 #include "opto/phaseX.hpp"
  29 #include "opto/rootnode.hpp"
  30 #include "opto/vector.hpp"
  31 #include "utilities/macros.hpp"
  32 
  33 void PhaseVector::optimize_vector_boxes() {
  34   Compile::TracePhase tp("vector_elimination", &timers[_t_vector_elimination]);
  35 
  36   assert(C->inlining_incrementally() == false, "sanity");
  37 
  38   C->set_inlining_incrementally(true); // FIXME another way to signal GraphKit it's post-parsing phase?
  39 
  40   C->for_igvn()->clear();
  41   C->initial_gvn()->replace_with(&_igvn);
  42 
  43   expand_vunbox_nodes();
  44   scalarize_vbox_nodes();
  45 
  46   C->inline_vector_reboxing_calls();
  47 
  48   expand_vbox_nodes();
  49   eliminate_vbox_alloc_nodes();
  50 
  51   C->set_inlining_incrementally(false); // FIXME another way to signal GraphKit it's post-parsing phase?
  52 
  53   do_cleanup();
  54 }
  55 
  56 void PhaseVector::do_cleanup() {
  57   if (C->failing())  return;
  58   {
  59     Compile::TracePhase tp("vector_pru", &timers[_t_vector_pru]);
  60     ResourceMark rm;
  61     PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
  62   }
  63 
  64   if (C->failing())  return;
  65 
  66   {
  67     Compile::TracePhase tp("incrementalInline_igvn", &timers[_t_vector_igvn]);
  68     _igvn = PhaseIterGVN(C->initial_gvn());
  69     _igvn.optimize();
  70   }
  71 }
  72 
  73 void PhaseVector::scalarize_vbox_nodes() {
  74   if (C->failing())  return;
  75 
  76   if (!EnableVectorReboxing) {
  77     return; // don't scalarize vector boxes
  78   }
  79 
  80   int macro_idx = C->macro_count() - 1;
  81   while (macro_idx >= 0) {
  82     Node * n = C->macro_node(macro_idx);
  83     assert(n->is_macro(), "only macro nodes expected here");
  84     if (n->Opcode() == Op_VectorBox) {
  85       VectorBoxNode* vbox = static_cast<VectorBoxNode*>(n);
  86       scalarize_vbox_node(vbox);
  87       if (C->failing())  return;
  88       C->print_method(PHASE_SCALARIZE_VBOX, vbox, 3);
  89     }
  90     if (C->failing())  return;
  91     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
  92   }
  93 }
  94 
  95 void PhaseVector::expand_vbox_nodes() {
  96   if (C->failing())  return;
  97 
  98   int macro_idx = C->macro_count() - 1;
  99   while (macro_idx >= 0) {
 100     Node * n = C->macro_node(macro_idx);
 101     assert(n->is_macro(), "only macro nodes expected here");
 102     if (n->Opcode() == Op_VectorBox) {
 103       VectorBoxNode* vbox = static_cast<VectorBoxNode*>(n);
 104       expand_vbox_node(vbox);
 105       if (C->failing())  return;
 106       C->print_method(PHASE_EXPAND_VBOX, vbox, 3);
 107     }
 108     if (C->failing())  return;
 109     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
 110   }
 111 }
 112 
 113 void PhaseVector::expand_vunbox_nodes() {
 114   if (C->failing())  return;
 115 
 116   int macro_idx = C->macro_count() - 1;
 117   while (macro_idx >= 0) {
 118     Node * n = C->macro_node(macro_idx);
 119     assert(n->is_macro(), "only macro nodes expected here");
 120     if (n->Opcode() == Op_VectorUnbox) {
 121       VectorUnboxNode* vec_unbox = static_cast<VectorUnboxNode*>(n);
 122       expand_vunbox_node(vec_unbox);
 123       if (C->failing())  return;
 124       C->print_method(PHASE_EXPAND_VUNBOX, vec_unbox, 3);
 125     }
 126     if (C->failing())  return;
 127     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
 128   }
 129 }
 130 
 131 void PhaseVector::eliminate_vbox_alloc_nodes() {
 132   if (C->failing())  return;
 133 
 134   int macro_idx = C->macro_count() - 1;
 135   while (macro_idx >= 0) {
 136     Node * n = C->macro_node(macro_idx);
 137     assert(n->is_macro(), "only macro nodes expected here");
 138     if (n->Opcode() == Op_VectorBoxAllocate) {
 139       VectorBoxAllocateNode* vbox_alloc = static_cast<VectorBoxAllocateNode*>(n);
 140       eliminate_vbox_alloc_node(vbox_alloc);
 141       if (C->failing())  return;
 142       C->print_method(PHASE_ELIMINATE_VBOX_ALLOC, vbox_alloc, 3);
 143     }
 144     if (C->failing())  return;
 145     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
 146   }
 147 }
 148 
 149 static JVMState* clone_jvms(Compile* C, SafePointNode* sfpt) {
 150   JVMState* new_jvms = sfpt->jvms()->clone_shallow(C);
 151   uint size = sfpt->req();
 152   SafePointNode* map = new SafePointNode(size, new_jvms);
 153   for (uint i = 0; i < size; i++) {
 154     map->init_req(i, sfpt->in(i));
 155   }
 156   new_jvms->set_map(map);
 157   return new_jvms;
 158 }
 159 
 160 void PhaseVector::scalarize_vbox_node(VectorBoxNode* vec_box) {
 161   Node* vec_value = vec_box->in(VectorBoxNode::Value);
 162   PhaseGVN& gvn = *C->initial_gvn();
 163 
 164   // Process merged VBAs
 165 
 166   if (EnableVectorAggressiveReboxing) {
 167     Unique_Node_List calls(C->comp_arena());
 168     for (DUIterator_Fast imax, i = vec_box->fast_outs(imax); i < imax; i++) {
 169       Node* use = vec_box->fast_out(i);
 170       if (use->is_CallJava()) {
 171         CallJavaNode* call = use->as_CallJava();
 172         if (call->has_non_debug_use(vec_box) && vec_box->in(VectorBoxNode::Box)->is_Phi()) {
 173           calls.push(call);
 174         }
 175       }
 176     }
 177 
 178     while (calls.size() > 0) {
 179       CallJavaNode* call = calls.pop()->as_CallJava();
 180       // Attach new VBA to the call and use it instead of Phi (VBA ... VBA).
 181 
 182       JVMState* jvms = clone_jvms(C, call);
 183       GraphKit kit(jvms);
 184       PhaseGVN& gvn = kit.gvn();
 185 
 186       // Adjust JVMS from post-call to pre-call state: put args on stack
 187       uint nargs = call->method()->arg_size();
 188       kit.ensure_stack(kit.sp() + nargs);
 189       for (uint i = TypeFunc::Parms; i < call->tf()->domain()->cnt(); i++) {
 190         kit.push(call->in(i));
 191       }
 192       jvms = kit.sync_jvms();
 193 
 194       Node* new_vbox = NULL;
 195       {
 196         PreserveReexecuteState prs(&kit);
 197 
 198         kit.jvms()->set_should_reexecute(true);
 199 
 200         const TypeInstPtr* vbox_type = vec_box->box_type();
 201         const TypeVect* vect_type = vec_box->vec_type();
 202         Node* vect = vec_box->in(VectorBoxNode::Value);
 203 
 204         VectorBoxAllocateNode* alloc = new VectorBoxAllocateNode(C, vbox_type);
 205         kit.set_edges_for_java_call(alloc, /*must_throw=*/false, /*separate_io_proj=*/true);
 206         kit.make_slow_call_ex(alloc, C->env()->Throwable_klass(), /*separate_io_proj=*/true, /*deoptimize=*/true);
 207         kit.set_i_o(gvn.transform( new ProjNode(alloc, TypeFunc::I_O) ));
 208         kit.set_all_memory(gvn.transform( new ProjNode(alloc, TypeFunc::Memory) ));
 209         Node* ret = gvn.transform(new ProjNode(alloc, TypeFunc::Parms));
 210 
 211         new_vbox = gvn.transform(new VectorBoxNode(C, ret, vect, vbox_type, vect_type));
 212 
 213         kit.replace_in_map(vec_box, new_vbox);
 214       }
 215 
 216       kit.dec_sp(nargs);
 217       jvms = kit.sync_jvms();
 218 
 219       call->set_req(TypeFunc::Control , kit.control());
 220       call->set_req(TypeFunc::I_O     , kit.i_o());
 221       call->set_req(TypeFunc::Memory  , kit.reset_memory());
 222       call->set_req(TypeFunc::FramePtr, kit.frameptr());
 223       call->replace_edge(vec_box, new_vbox);
 224 
 225       C->record_for_igvn(call);
 226     }
 227   }
 228 
 229   // Process debug uses at safepoints
 230   Unique_Node_List safepoints(C->comp_arena());
 231 
 232   for (DUIterator_Fast imax, i = vec_box->fast_outs(imax); i < imax; i++) {
 233     Node* use = vec_box->fast_out(i);
 234     if (use->is_SafePoint()) {
 235       SafePointNode* sfpt = use->as_SafePoint();
 236       if (!sfpt->is_Call() || !sfpt->as_Call()->has_non_debug_use(vec_box)) {
 237         safepoints.push(sfpt);
 238       }
 239     }
 240   }
 241 
 242   while (safepoints.size() > 0) {
 243     SafePointNode* sfpt = safepoints.pop()->as_SafePoint();
 244 
 245     uint first_ind = (sfpt->req() - sfpt->jvms()->scloff());
 246     Node* sobj = new SafePointScalarObjectNode(vec_box->box_type(),
 247 #ifdef ASSERT
 248                                                NULL,
 249 #endif // ASSERT
 250                                                first_ind, /*n_fields=*/1);
 251     sobj->init_req(0, C->root());
 252     sfpt->add_req(vec_value);
 253 
 254     sobj = gvn.transform(sobj);
 255 
 256     JVMState *jvms = sfpt->jvms();
 257 
 258     jvms->set_endoff(sfpt->req());
 259     // Now make a pass over the debug information replacing any references
 260     // to the allocated object with "sobj"
 261     int start = jvms->debug_start();
 262     int end   = jvms->debug_end();
 263     sfpt->replace_edges_in_range(vec_box, sobj, start, end);
 264 
 265     C->record_for_igvn(sfpt);
 266   }
 267 }
 268 
 269 void PhaseVector::expand_vbox_node(VectorBoxNode* vec_box) {
 270   if (vec_box->outcnt() > 0) {
 271     Node* vbox = vec_box->in(VectorBoxNode::Box);
 272     Node* vect = vec_box->in(VectorBoxNode::Value);
 273     Node* result = expand_vbox_node_helper(vbox, vect, vec_box->box_type(), vec_box->vec_type());
 274     C->gvn_replace_by(vec_box, result);
 275   }
 276   C->remove_macro_node(vec_box);
 277 }
 278 
 279 Node* PhaseVector::expand_vbox_node_helper(Node* vbox,
 280                                        Node* vect,
 281                                        const TypeInstPtr* box_type,
 282                                        const TypeVect* vect_type) {
 283   if (vbox->is_Phi() && vect->is_Phi()) {
 284     assert(vbox->as_Phi()->region() == vect->as_Phi()->region(), "");
 285     Node* new_phi = new PhiNode(vbox->as_Phi()->region(), box_type);
 286     for (uint i = 1; i < vbox->req(); i++) {
 287       Node* new_box = expand_vbox_node_helper(vbox->in(i), vect->in(i), box_type, vect_type);
 288       new_phi->set_req(i, new_box);
 289     }
 290     new_phi = C->initial_gvn()->transform(new_phi);
 291     return new_phi;
 292   } else if (vbox->is_Proj() && vbox->in(0)->Opcode() == Op_VectorBoxAllocate) {
 293     VectorBoxAllocateNode* vbox_alloc = static_cast<VectorBoxAllocateNode*>(vbox->in(0));
 294     return expand_vbox_alloc_node(vbox_alloc, vect, box_type, vect_type);
 295   } else {
 296     assert(!vbox->is_Phi(), "");
 297     // TODO: ensure that expanded vbox is initialized with the same value (vect).
 298     return vbox; // already expanded
 299   }
 300 }
 301 
 302 static bool is_vector_mask(ciKlass* klass) {
 303   return klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass());
 304 }
 305 
 306 static bool is_vector_shuffle(ciKlass* klass) {
 307   return klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass());
 308 }
 309 
 310 Node* PhaseVector::expand_vbox_alloc_node(VectorBoxAllocateNode* vbox_alloc,
 311                                           Node* value,
 312                                           const TypeInstPtr* box_type,
 313                                           const TypeVect* vect_type) {
 314   JVMState* jvms = clone_jvms(C, vbox_alloc);
 315   GraphKit kit(jvms);
 316   PhaseGVN& gvn = kit.gvn();
 317 
 318   ciInstanceKlass* box_klass = box_type->klass()->as_instance_klass();
 319   BasicType bt = vect_type->element_basic_type();
 320   int num_elem = vect_type->length();
 321 
 322   bool is_mask = is_vector_mask(box_klass);
 323   if (is_mask && bt != T_BOOLEAN) {
 324     value = gvn.transform(new VectorStoreMaskNode(value, bt, num_elem));
 325     // Although type of mask depends on its definition, in terms of storage everything is stored in boolean array.
 326     bt = T_BOOLEAN;
 327     assert(value->as_Vector()->bottom_type()->is_vect()->element_basic_type() == bt,
 328            "must be consistent with mask representation");
 329   }
 330 
 331   // Generate array allocation for the field which holds the values.
 332   const TypeKlassPtr* array_klass = TypeKlassPtr::make(ciTypeArrayKlass::make(bt));
 333   Node* arr = kit.new_array(kit.makecon(array_klass), kit.intcon(num_elem), 1);
 334 
 335   // Store the vector value into the array.
 336   // (The store should be captured by InitializeNode and turned into initialized store later.)
 337   Node* arr_adr = kit.array_element_address(arr, kit.intcon(0), bt);
 338   const TypePtr* arr_adr_type = arr_adr->bottom_type()->is_ptr();
 339   Node* arr_mem = kit.memory(arr_adr);
 340   Node* vstore = gvn.transform(StoreVectorNode::make(0,
 341                                                      kit.control(),
 342                                                      arr_mem,
 343                                                      arr_adr,
 344                                                      arr_adr_type,
 345                                                      value,
 346                                                      num_elem));
 347   kit.set_memory(vstore, arr_adr_type);
 348 
 349   C->set_max_vector_size(MAX2(C->max_vector_size(), vect_type->length_in_bytes()));
 350 
 351   // Generate the allocate for the Vector object.
 352   const TypeKlassPtr* klass_type = box_type->as_klass_type();
 353   Node* klass_node = kit.makecon(klass_type);
 354   Node* vec_obj = kit.new_instance(klass_node);
 355 
 356   // Store the allocated array into object.
 357   ciField* field = ciEnv::current()->vector_VectorPayload_klass()->get_field_by_name(ciSymbol::payload_name(),
 358                                                                                      ciSymbol::object_signature(),
 359                                                                                      false);
 360   assert(field != NULL, "");
 361   Node* vec_field = kit.basic_plus_adr(vec_obj, field->offset_in_bytes());
 362   const TypePtr* vec_adr_type = vec_field->bottom_type()->is_ptr();
 363 
 364   // The store should be captured by InitializeNode and turned into initialized store later.
 365   Node* field_store = gvn.transform(kit.access_store_at(vec_obj,
 366                                                             vec_field,
 367                                                             vec_adr_type,
 368                                                             arr,
 369                                                             TypeOopPtr::make_from_klass(field->type()->as_klass()),
 370                                                             T_OBJECT,
 371                                                             IN_HEAP));
 372   kit.set_memory(field_store, vec_adr_type);
 373 
 374   kit.replace_call(vbox_alloc, vec_obj, true);
 375   C->remove_macro_node(vbox_alloc);
 376   return vec_obj;
 377 }
 378 
 379 void PhaseVector::expand_vunbox_node(VectorUnboxNode* vec_unbox) {
 380   if (vec_unbox->outcnt() > 0) {
 381     GraphKit kit;
 382     PhaseGVN& gvn = kit.gvn();
 383 
 384     Node* obj = vec_unbox->obj();
 385     const TypeInstPtr* tinst = gvn.type(obj)->isa_instptr();
 386     ciInstanceKlass* from_kls = tinst->klass()->as_instance_klass();
 387     BasicType bt = vec_unbox->vect_type()->element_basic_type();
 388     BasicType masktype = bt;
 389     BasicType elem_bt;
 390 
 391     if (is_vector_mask(from_kls)) {
 392       bt = T_BOOLEAN;
 393     } else if (is_vector_shuffle(from_kls)) {
 394       if (vec_unbox->is_shuffle_to_vector() == true) {
 395         elem_bt = bt;
 396       }
 397       bt = T_BYTE;
 398     }
 399 
 400     ciField* field = ciEnv::current()->vector_VectorPayload_klass()->get_field_by_name(ciSymbol::payload_name(),
 401                                                                                        ciSymbol::object_signature(),
 402                                                                                        false);
 403     assert(field != NULL, "");
 404     int offset = field->offset_in_bytes();
 405     Node* vec_adr = kit.basic_plus_adr(obj, offset);
 406 
 407     Node* mem = vec_unbox->mem();
 408     Node* ctrl = vec_unbox->in(0);
 409     Node* vec_field_ld = LoadNode::make(gvn,
 410                                         ctrl,
 411                                         mem,
 412                                         vec_adr,
 413                                         vec_adr->bottom_type()->is_ptr(),
 414                                         TypeOopPtr::make_from_klass(field->type()->as_klass()),
 415                                         T_OBJECT,
 416                                         MemNode::unordered);
 417     vec_field_ld = gvn.transform(vec_field_ld);
 418 
 419     // For proper aliasing, attach concrete payload type.
 420     ciKlass* payload_klass = ciTypeArrayKlass::make(bt);
 421     const Type* payload_type = TypeAryPtr::make_from_klass(payload_klass)->cast_to_ptr_type(TypePtr::NotNull);
 422     vec_field_ld = gvn.transform(new CastPPNode(vec_field_ld, payload_type));
 423 
 424     Node* adr = kit.array_element_address(vec_field_ld, gvn.intcon(0), bt);
 425     const TypePtr* adr_type = adr->bottom_type()->is_ptr();
 426     const TypeVect* vt = vec_unbox->bottom_type()->is_vect();
 427     int num_elem = vt->length();
 428     Node* vec_val_load = LoadVectorNode::make(0,
 429                                               ctrl,
 430                                               mem,
 431                                               adr,
 432                                               adr_type,
 433                                               num_elem,
 434                                               bt);
 435     vec_val_load = gvn.transform(vec_val_load);
 436 
 437     C->set_max_vector_size(MAX2(C->max_vector_size(), vt->length_in_bytes()));
 438 
 439     if (is_vector_mask(from_kls) && masktype != T_BOOLEAN) {
 440       assert(vec_unbox->bottom_type()->is_vect()->element_basic_type() == masktype, "expect mask type consistency");
 441       vec_val_load = gvn.transform(new VectorLoadMaskNode(vec_val_load, TypeVect::make(masktype, num_elem)));
 442     } else if (is_vector_shuffle(from_kls)) {
 443       if (vec_unbox->is_shuffle_to_vector() == false) {
 444         assert(vec_unbox->bottom_type()->is_vect()->element_basic_type() == masktype, "expect shuffle type consistency");
 445         vec_val_load = gvn.transform(new VectorLoadShuffleNode(vec_val_load, TypeVect::make(masktype, num_elem)));
 446       } else if (elem_bt != T_BYTE) {
 447         vec_val_load = gvn.transform(VectorCastNode::make(Op_VectorCastB2X, vec_val_load, elem_bt, num_elem));
 448       }
 449     }
 450 
 451     gvn.hash_delete(vec_unbox);
 452     vec_unbox->disconnect_inputs(NULL, C);
 453     C->gvn_replace_by(vec_unbox, vec_val_load);
 454   }
 455   C->remove_macro_node(vec_unbox);
 456 }
 457 
 458 void PhaseVector::eliminate_vbox_alloc_node(VectorBoxAllocateNode* vbox_alloc) {
 459   JVMState* jvms = clone_jvms(C, vbox_alloc);
 460   GraphKit kit(jvms);
 461   // Remove VBA, but leave a safepoint behind.
 462   // Otherwise, it may end up with a loop without any safepoint polls.
 463   kit.replace_call(vbox_alloc, kit.map(), true);
 464   C->remove_macro_node(vbox_alloc);
 465 }