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 "ci/ciSymbols.hpp"
27 #include "gc/shared/barrierSet.hpp"
28 #include "opto/castnode.hpp"
29 #include "opto/graphKit.hpp"
30 #include "opto/phaseX.hpp"
31 #include "opto/rootnode.hpp"
32 #include "opto/vector.hpp"
33 #include "utilities/macros.hpp"
34 
is_vector_mask(ciKlass * klass)35 static bool is_vector_mask(ciKlass* klass) {
36   return klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass());
37 }
38 
is_vector_shuffle(ciKlass * klass)39 static bool is_vector_shuffle(ciKlass* klass) {
40   return klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass());
41 }
42 
43 
optimize_vector_boxes()44 void PhaseVector::optimize_vector_boxes() {
45   Compile::TracePhase tp("vector_elimination", &timers[_t_vector_elimination]);
46 
47   // Signal GraphKit it's post-parse phase.
48   assert(C->inlining_incrementally() == false, "sanity");
49   C->set_inlining_incrementally(true);
50 
51   C->for_igvn()->clear();
52   C->initial_gvn()->replace_with(&_igvn);
53 
54   expand_vunbox_nodes();
55   scalarize_vbox_nodes();
56 
57   C->inline_vector_reboxing_calls();
58 
59   expand_vbox_nodes();
60   eliminate_vbox_alloc_nodes();
61 
62   C->set_inlining_incrementally(false);
63 
64   do_cleanup();
65 }
66 
do_cleanup()67 void PhaseVector::do_cleanup() {
68   if (C->failing())  return;
69   {
70     Compile::TracePhase tp("vector_pru", &timers[_t_vector_pru]);
71     ResourceMark rm;
72     PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
73     if (C->failing())  return;
74   }
75   {
76     Compile::TracePhase tp("incrementalInline_igvn", &timers[_t_vector_igvn]);
77     _igvn = PhaseIterGVN(C->initial_gvn());
78     _igvn.optimize();
79     if (C->failing())  return;
80   }
81   C->print_method(PHASE_ITER_GVN_BEFORE_EA, 3);
82 }
83 
scalarize_vbox_nodes()84 void PhaseVector::scalarize_vbox_nodes() {
85   if (C->failing())  return;
86 
87   if (!EnableVectorReboxing) {
88     return; // don't scalarize vector boxes
89   }
90 
91   int macro_idx = C->macro_count() - 1;
92   while (macro_idx >= 0) {
93     Node * n = C->macro_node(macro_idx);
94     assert(n->is_macro(), "only macro nodes expected here");
95     if (n->Opcode() == Op_VectorBox) {
96       VectorBoxNode* vbox = static_cast<VectorBoxNode*>(n);
97       scalarize_vbox_node(vbox);
98       if (C->failing())  return;
99       C->print_method(PHASE_SCALARIZE_VBOX, vbox, 3);
100     }
101     if (C->failing())  return;
102     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
103   }
104 }
105 
expand_vbox_nodes()106 void PhaseVector::expand_vbox_nodes() {
107   if (C->failing())  return;
108 
109   int macro_idx = C->macro_count() - 1;
110   while (macro_idx >= 0) {
111     Node * n = C->macro_node(macro_idx);
112     assert(n->is_macro(), "only macro nodes expected here");
113     if (n->Opcode() == Op_VectorBox) {
114       VectorBoxNode* vbox = static_cast<VectorBoxNode*>(n);
115       expand_vbox_node(vbox);
116       if (C->failing())  return;
117     }
118     if (C->failing())  return;
119     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
120   }
121 }
122 
expand_vunbox_nodes()123 void PhaseVector::expand_vunbox_nodes() {
124   if (C->failing())  return;
125 
126   int macro_idx = C->macro_count() - 1;
127   while (macro_idx >= 0) {
128     Node * n = C->macro_node(macro_idx);
129     assert(n->is_macro(), "only macro nodes expected here");
130     if (n->Opcode() == Op_VectorUnbox) {
131       VectorUnboxNode* vec_unbox = static_cast<VectorUnboxNode*>(n);
132       expand_vunbox_node(vec_unbox);
133       if (C->failing())  return;
134       C->print_method(PHASE_EXPAND_VUNBOX, vec_unbox, 3);
135     }
136     if (C->failing())  return;
137     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
138   }
139 }
140 
eliminate_vbox_alloc_nodes()141 void PhaseVector::eliminate_vbox_alloc_nodes() {
142   if (C->failing())  return;
143 
144   int macro_idx = C->macro_count() - 1;
145   while (macro_idx >= 0) {
146     Node * n = C->macro_node(macro_idx);
147     assert(n->is_macro(), "only macro nodes expected here");
148     if (n->Opcode() == Op_VectorBoxAllocate) {
149       VectorBoxAllocateNode* vbox_alloc = static_cast<VectorBoxAllocateNode*>(n);
150       eliminate_vbox_alloc_node(vbox_alloc);
151       if (C->failing())  return;
152       C->print_method(PHASE_ELIMINATE_VBOX_ALLOC, vbox_alloc, 3);
153     }
154     if (C->failing())  return;
155     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
156   }
157 }
158 
clone_jvms(Compile * C,SafePointNode * sfpt)159 static JVMState* clone_jvms(Compile* C, SafePointNode* sfpt) {
160   JVMState* new_jvms = sfpt->jvms()->clone_shallow(C);
161   uint size = sfpt->req();
162   SafePointNode* map = new SafePointNode(size, new_jvms);
163   for (uint i = 0; i < size; i++) {
164     map->init_req(i, sfpt->in(i));
165   }
166   new_jvms->set_map(map);
167   return new_jvms;
168 }
169 
scalarize_vbox_node(VectorBoxNode * vec_box)170 void PhaseVector::scalarize_vbox_node(VectorBoxNode* vec_box) {
171   Node* vec_value = vec_box->in(VectorBoxNode::Value);
172   PhaseGVN& gvn = *C->initial_gvn();
173 
174   // Process merged VBAs
175 
176   if (EnableVectorAggressiveReboxing) {
177     Unique_Node_List calls(C->comp_arena());
178     for (DUIterator_Fast imax, i = vec_box->fast_outs(imax); i < imax; i++) {
179       Node* use = vec_box->fast_out(i);
180       if (use->is_CallJava()) {
181         CallJavaNode* call = use->as_CallJava();
182         if (call->has_non_debug_use(vec_box) && vec_box->in(VectorBoxNode::Box)->is_Phi()) {
183           calls.push(call);
184         }
185       }
186     }
187 
188     while (calls.size() > 0) {
189       CallJavaNode* call = calls.pop()->as_CallJava();
190       // Attach new VBA to the call and use it instead of Phi (VBA ... VBA).
191 
192       JVMState* jvms = clone_jvms(C, call);
193       GraphKit kit(jvms);
194       PhaseGVN& gvn = kit.gvn();
195 
196       // Adjust JVMS from post-call to pre-call state: put args on stack
197       uint nargs = call->method()->arg_size();
198       kit.ensure_stack(kit.sp() + nargs);
199       for (uint i = TypeFunc::Parms; i < call->tf()->domain()->cnt(); i++) {
200         kit.push(call->in(i));
201       }
202       jvms = kit.sync_jvms();
203 
204       Node* new_vbox = NULL;
205       {
206         Node* vect = vec_box->in(VectorBoxNode::Value);
207         const TypeInstPtr* vbox_type = vec_box->box_type();
208         const TypeVect* vt = vec_box->vec_type();
209         BasicType elem_bt = vt->element_basic_type();
210         int num_elem = vt->length();
211 
212         new_vbox = kit.box_vector(vect, vbox_type, elem_bt, num_elem, /*deoptimize=*/true);
213 
214         kit.replace_in_map(vec_box, new_vbox);
215       }
216 
217       kit.dec_sp(nargs);
218       jvms = kit.sync_jvms();
219 
220       call->set_req(TypeFunc::Control , kit.control());
221       call->set_req(TypeFunc::I_O     , kit.i_o());
222       call->set_req(TypeFunc::Memory  , kit.reset_memory());
223       call->set_req(TypeFunc::FramePtr, kit.frameptr());
224       call->replace_edge(vec_box, new_vbox);
225 
226       C->record_for_igvn(call);
227     }
228   }
229 
230   // Process debug uses at safepoints
231   Unique_Node_List safepoints(C->comp_arena());
232 
233   Unique_Node_List worklist(C->comp_arena());
234   worklist.push(vec_box);
235   while (worklist.size() > 0) {
236     Node* n = worklist.pop();
237     for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
238       Node* use = n->fast_out(i);
239       if (use->is_SafePoint()) {
240         SafePointNode* sfpt = use->as_SafePoint();
241         if (!sfpt->is_Call() || !sfpt->as_Call()->has_non_debug_use(n)) {
242           safepoints.push(sfpt);
243         }
244       } else if (use->is_ConstraintCast()) {
245         worklist.push(use); // reversed version of Node::uncast()
246       }
247     }
248   }
249 
250   ciInstanceKlass* iklass = vec_box->box_type()->klass()->as_instance_klass();
251   int n_fields = iklass->nof_nonstatic_fields();
252   assert(n_fields == 1, "sanity");
253 
254   // If a mask is feeding into safepoint[s], then its value should be
255   // packed into a boolean/byte vector first, this will simplify the
256   // re-materialization logic for both predicated and non-predicated
257   // targets.
258   bool is_mask = is_vector_mask(iklass);
259   if (is_mask && vec_value->Opcode() != Op_VectorStoreMask) {
260     const TypeVect* vt = vec_value->bottom_type()->is_vect();
261     BasicType bt = vt->element_basic_type();
262     vec_value = gvn.transform(VectorStoreMaskNode::make(gvn, vec_value, bt, vt->length()));
263   }
264 
265   while (safepoints.size() > 0) {
266     SafePointNode* sfpt = safepoints.pop()->as_SafePoint();
267 
268     uint first_ind = (sfpt->req() - sfpt->jvms()->scloff());
269     Node* sobj = new SafePointScalarObjectNode(vec_box->box_type(),
270 #ifdef ASSERT
271                                                vec_box,
272 #endif // ASSERT
273                                                first_ind, n_fields);
274     sobj->init_req(0, C->root());
275     sfpt->add_req(vec_value);
276 
277     sobj = gvn.transform(sobj);
278 
279     JVMState *jvms = sfpt->jvms();
280 
281     jvms->set_endoff(sfpt->req());
282     // Now make a pass over the debug information replacing any references
283     // to the allocated object with vector value.
284     for (uint i = jvms->debug_start(); i < jvms->debug_end(); i++) {
285       Node* debug = sfpt->in(i);
286       if (debug != NULL && debug->uncast(/*keep_deps*/false) == vec_box) {
287         sfpt->set_req(i, sobj);
288       }
289     }
290     C->record_for_igvn(sfpt);
291   }
292 }
293 
expand_vbox_node(VectorBoxNode * vec_box)294 void PhaseVector::expand_vbox_node(VectorBoxNode* vec_box) {
295   if (vec_box->outcnt() > 0) {
296     Node* vbox = vec_box->in(VectorBoxNode::Box);
297     Node* vect = vec_box->in(VectorBoxNode::Value);
298     Node* result = expand_vbox_node_helper(vbox, vect, vec_box->box_type(), vec_box->vec_type());
299     C->gvn_replace_by(vec_box, result);
300     C->print_method(PHASE_EXPAND_VBOX, vec_box, 3);
301   }
302   C->remove_macro_node(vec_box);
303 }
304 
expand_vbox_node_helper(Node * vbox,Node * vect,const TypeInstPtr * box_type,const TypeVect * vect_type)305 Node* PhaseVector::expand_vbox_node_helper(Node* vbox,
306                                            Node* vect,
307                                            const TypeInstPtr* box_type,
308                                            const TypeVect* vect_type) {
309   if (vbox->is_Phi() && vect->is_Phi()) {
310     assert(vbox->as_Phi()->region() == vect->as_Phi()->region(), "");
311     Node* new_phi = new PhiNode(vbox->as_Phi()->region(), box_type);
312     for (uint i = 1; i < vbox->req(); i++) {
313       Node* new_box = expand_vbox_node_helper(vbox->in(i), vect->in(i), box_type, vect_type);
314       new_phi->set_req(i, new_box);
315     }
316     new_phi = C->initial_gvn()->transform(new_phi);
317     return new_phi;
318   } else if (vbox->is_Proj() && vbox->in(0)->Opcode() == Op_VectorBoxAllocate) {
319     VectorBoxAllocateNode* vbox_alloc = static_cast<VectorBoxAllocateNode*>(vbox->in(0));
320     return expand_vbox_alloc_node(vbox_alloc, vect, box_type, vect_type);
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 
expand_vbox_alloc_node(VectorBoxAllocateNode * vbox_alloc,Node * value,const TypeInstPtr * box_type,const TypeVect * vect_type)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,
362                                                      arr_adr_type,
363                                                      value,
364                                                      num_elem));
365   kit.set_memory(vstore, arr_adr_type);
366 
367   C->set_max_vector_size(MAX2(C->max_vector_size(), vect_type->length_in_bytes()));
368 
369   // Generate the allocate for the Vector object.
370   const TypeKlassPtr* klass_type = box_type->as_klass_type();
371   Node* klass_node = kit.makecon(klass_type);
372   Node* vec_obj = kit.new_instance(klass_node);
373 
374   // Store the allocated array into object.
375   ciField* field = ciEnv::current()->vector_VectorPayload_klass()->get_field_by_name(ciSymbols::payload_name(),
376                                                                                      ciSymbols::object_signature(),
377                                                                                      false);
378   assert(field != NULL, "");
379   Node* vec_field = kit.basic_plus_adr(vec_obj, field->offset_in_bytes());
380   const TypePtr* vec_adr_type = vec_field->bottom_type()->is_ptr();
381 
382   // The store should be captured by InitializeNode and turned into initialized store later.
383   Node* field_store = gvn.transform(kit.access_store_at(vec_obj,
384                                                         vec_field,
385                                                         vec_adr_type,
386                                                         arr,
387                                                         TypeOopPtr::make_from_klass(field->type()->as_klass()),
388                                                         T_OBJECT,
389                                                         IN_HEAP));
390   kit.set_memory(field_store, vec_adr_type);
391 
392   kit.replace_call(vbox_alloc, vec_obj, true);
393   C->remove_macro_node(vbox_alloc);
394 
395   return vec_obj;
396 }
397 
expand_vunbox_node(VectorUnboxNode * vec_unbox)398 void PhaseVector::expand_vunbox_node(VectorUnboxNode* vec_unbox) {
399   if (vec_unbox->outcnt() > 0) {
400     GraphKit kit;
401     PhaseGVN& gvn = kit.gvn();
402 
403     Node* obj = vec_unbox->obj();
404     const TypeInstPtr* tinst = gvn.type(obj)->isa_instptr();
405     ciInstanceKlass* from_kls = tinst->klass()->as_instance_klass();
406     const TypeVect* vt = vec_unbox->bottom_type()->is_vect();
407     BasicType bt = vt->element_basic_type();
408     BasicType masktype = bt;
409 
410     if (is_vector_mask(from_kls)) {
411       bt = T_BOOLEAN;
412     } else if (is_vector_shuffle(from_kls)) {
413       bt = T_BYTE;
414     }
415 
416     ciField* field = ciEnv::current()->vector_VectorPayload_klass()->get_field_by_name(ciSymbols::payload_name(),
417                                                                                        ciSymbols::object_signature(),
418                                                                                        false);
419     assert(field != NULL, "");
420     int offset = field->offset_in_bytes();
421     Node* vec_adr = kit.basic_plus_adr(obj, offset);
422 
423     Node* mem = vec_unbox->mem();
424     Node* ctrl = vec_unbox->in(0);
425     Node* vec_field_ld;
426     {
427       DecoratorSet decorators = MO_UNORDERED | IN_HEAP;
428       C2AccessValuePtr addr(vec_adr, vec_adr->bottom_type()->is_ptr());
429       MergeMemNode* local_mem = MergeMemNode::make(mem);
430       gvn.record_for_igvn(local_mem);
431       BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
432       C2OptAccess access(gvn, ctrl, local_mem, decorators, T_OBJECT, obj, addr);
433       const Type* type = TypeOopPtr::make_from_klass(field->type()->as_klass());
434       vec_field_ld = bs->load_at(access, type);
435     }
436 
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 
eliminate_vbox_alloc_node(VectorBoxAllocateNode * vbox_alloc)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 }
478