< prev index next >

src/hotspot/share/opto/vector.cpp

Print this page




  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 
  45   C->inline_vector_reboxing_calls();
  46 
  47   expand_vbox_nodes();
  48   eliminate_vbox_alloc_nodes();
  49 
  50   C->set_inlining_incrementally(false); // FIXME another way to signal GraphKit it's post-parsing phase?
  51 
  52   do_cleanup();
  53 }
  54 
  55 void PhaseVector::do_cleanup() {
  56   if (C->failing())  return;
  57   {
  58     Compile::TracePhase tp("vector_pru", &timers[_t_vector_pru]);
  59     ResourceMark rm;
  60     PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
  61   }
  62 
  63   if (C->failing())  return;
  64 
  65   {
  66     Compile::TracePhase tp("incrementalInline_igvn", &timers[_t_vector_igvn]);
  67     _igvn = PhaseIterGVN(C->initial_gvn());
  68     _igvn.optimize();
  69   }
  70 }
  71 






















  72 void PhaseVector::expand_vbox_nodes() {
  73   if (C->failing())  return;
  74 
  75   int macro_idx = C->macro_count() - 1;
  76   while (macro_idx >= 0) {
  77     Node * n = C->macro_node(macro_idx);
  78     assert(n->is_macro(), "only macro nodes expected here");
  79     if (n->Opcode() == Op_VectorBox) {
  80       VectorBoxNode* vbox = static_cast<VectorBoxNode*>(n);
  81       expand_vbox_node(vbox);
  82       if (C->failing())  return;
  83       C->print_method(PHASE_EXPAND_VBOX, vbox, 3);
  84     }
  85     if (C->failing())  return;
  86     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
  87   }
  88 }
  89 
  90 void PhaseVector::expand_vunbox_nodes() {
  91   if (C->failing())  return;


 117       eliminate_vbox_alloc_node(vbox_alloc);
 118       if (C->failing())  return;
 119       C->print_method(PHASE_ELIMINATE_VBOX_ALLOC, vbox_alloc, 3);
 120     }
 121     if (C->failing())  return;
 122     macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1);
 123   }
 124 }
 125 
 126 static JVMState* clone_jvms(Compile* C, SafePointNode* sfpt) {
 127   JVMState* new_jvms = sfpt->jvms()->clone_shallow(C);
 128   uint size = sfpt->req();
 129   SafePointNode* map = new SafePointNode(size, new_jvms);
 130   for (uint i = 0; i < size; i++) {
 131     map->init_req(i, sfpt->in(i));
 132   }
 133   new_jvms->set_map(map);
 134   return new_jvms;
 135 }
 136 













































































































 137 void PhaseVector::expand_vbox_node(VectorBoxNode* vec_box) {
 138   if (vec_box->outcnt() > 0) {
 139     Node* vbox = vec_box->in(VectorBoxNode::Box);
 140     Node* vect = vec_box->in(VectorBoxNode::Value);
 141     Node* result = expand_vbox_node_helper(vbox, vect, vec_box->box_type(), vec_box->vec_type());
 142     C->gvn_replace_by(vec_box, result);
 143   }
 144   C->remove_macro_node(vec_box);
 145 }
 146 
 147 Node* PhaseVector::expand_vbox_node_helper(Node* vbox,
 148                                        Node* vect,
 149                                        const TypeInstPtr* box_type,
 150                                        const TypeVect* vect_type) {
 151   if (vbox->is_Phi() && vect->is_Phi()) {
 152     assert(vbox->as_Phi()->region() == vect->as_Phi()->region(), "");
 153     Node* new_phi = new PhiNode(vbox->as_Phi()->region(), box_type);
 154     for (uint i = 1; i < vbox->req(); i++) {
 155       Node* new_box = expand_vbox_node_helper(vbox->in(i), vect->in(i), box_type, vect_type);
 156       new_phi->set_req(i, new_box);




  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;


 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);


< prev index next >