< prev index next >

src/share/vm/opto/loopUnswitch.cpp

Print this page




 156 
 157   // Add test to new "if" outside of loop
 158   IfNode* invar_iff   = proj_true->in(0)->as_If();
 159   Node* invar_iff_c   = invar_iff->in(0);
 160   BoolNode* bol       = unswitch_iff->in(1)->as_Bool();
 161   invar_iff->set_req(1, bol);
 162   invar_iff->_prob    = unswitch_iff->_prob;
 163 
 164   ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
 165 
 166   // Hoist invariant casts out of each loop to the appropriate
 167   // control projection.
 168 
 169   Node_List worklist;
 170 
 171   for (DUIterator_Fast imax, i = unswitch_iff->fast_outs(imax); i < imax; i++) {
 172     ProjNode* proj= unswitch_iff->fast_out(i)->as_Proj();
 173     // Copy to a worklist for easier manipulation
 174     for (DUIterator_Fast jmax, j = proj->fast_outs(jmax); j < jmax; j++) {
 175       Node* use = proj->fast_out(j);
 176       if (use->Opcode() == Op_CheckCastPP && loop->is_invariant(use->in(1))) {
 177         worklist.push(use);
 178       }
 179     }
 180     ProjNode* invar_proj = invar_iff->proj_out(proj->_con)->as_Proj();
 181     while (worklist.size() > 0) {
 182       Node* use = worklist.pop();
 183       Node* nuse = use->clone();
 184       nuse->set_req(0, invar_proj);
 185       _igvn.replace_input_of(use, 1, nuse);
 186       register_new_node(nuse, invar_proj);
 187       // Same for the clone
 188       Node* use_clone = old_new[use->_idx];
 189       _igvn.replace_input_of(use_clone, 1, nuse);
 190     }
 191   }
 192 
 193   // Hardwire the control paths in the loops into if(true) and if(false)
 194   _igvn.rehash_node_delayed(unswitch_iff);
 195   short_circuit_if(unswitch_iff, proj_true);
 196 


 206     _igvn._worklist.push(n_clone);
 207   }
 208 
 209 #ifndef PRODUCT
 210   if (TraceLoopUnswitching) {
 211     tty->print_cr("Loop unswitching orig: %d @ %d  new: %d @ %d",
 212                   head->_idx,                unswitch_iff->_idx,
 213                   old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
 214   }
 215 #endif
 216 
 217   C->set_major_progress();
 218 }
 219 
 220 //-------------------------create_slow_version_of_loop------------------------
 221 // Create a slow version of the loop by cloning the loop
 222 // and inserting an if to select fast-slow versions.
 223 // Return control projection of the entry to the fast version.
 224 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
 225                                                       Node_List &old_new,
 226                                                       int opcode) {
 227   LoopNode* head  = loop->_head->as_Loop();
 228   bool counted_loop = head->is_CountedLoop();
 229   Node*     entry = head->in(LoopNode::EntryControl);
 230   _igvn.rehash_node_delayed(entry);
 231   IdealLoopTree* outer_loop = loop->_parent;
 232 
 233   Node *cont      = _igvn.intcon(1);
 234   set_ctrl(cont, C->root());
 235   Node* opq       = new Opaque1Node(C, cont);
 236   register_node(opq, outer_loop, entry, dom_depth(entry));
 237   Node *bol       = new Conv2BNode(opq);
 238   register_node(bol, outer_loop, entry, dom_depth(entry));
 239   IfNode* iff = (opcode == Op_RangeCheck) ? new RangeCheckNode(entry, bol, PROB_MAX, COUNT_UNKNOWN) :
 240     new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
 241   register_node(iff, outer_loop, entry, dom_depth(entry));
 242   ProjNode* iffast = new IfTrueNode(iff);
 243   register_node(iffast, outer_loop, iff, dom_depth(iff));
 244   ProjNode* ifslow = new IfFalseNode(iff);
 245   register_node(ifslow, outer_loop, iff, dom_depth(iff));
 246 
 247   // Clone the loop body.  The clone becomes the fast loop.  The
 248   // original pre-header will (illegally) have 3 control users
 249   // (old & new loops & new if).
 250   clone_loop(loop, old_new, dom_depth(head), iff);
 251   assert(old_new[head->_idx]->is_Loop(), "" );
 252 
 253   // Fast (true) control
 254   Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
 255   _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
 256   set_idom(head, iffast_pred, dom_depth(head));
 257 
 258   // Slow (false) control
 259   Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);


 388   }
 389 
 390   _lp = _lpt->_head->as_Loop();
 391   _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this);
 392 
 393   if (!_lp_reserved->is_CountedLoop()) {
 394     return false;
 395   }
 396 
 397   Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl);
 398 
 399   if (!ifslow_pred->is_IfFalse()) {
 400     return false;
 401   }
 402 
 403   Node* iff = ifslow_pred->in(0);
 404   if (!iff->is_If() || iff != _iff) {
 405     return false;
 406   }
 407 
 408   if (iff->in(1)->Opcode() != Op_ConI) {
 409     return false;
 410   }
 411 
 412   return _has_reserved = true;
 413 }


 156 
 157   // Add test to new "if" outside of loop
 158   IfNode* invar_iff   = proj_true->in(0)->as_If();
 159   Node* invar_iff_c   = invar_iff->in(0);
 160   BoolNode* bol       = unswitch_iff->in(1)->as_Bool();
 161   invar_iff->set_req(1, bol);
 162   invar_iff->_prob    = unswitch_iff->_prob;
 163 
 164   ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
 165 
 166   // Hoist invariant casts out of each loop to the appropriate
 167   // control projection.
 168 
 169   Node_List worklist;
 170 
 171   for (DUIterator_Fast imax, i = unswitch_iff->fast_outs(imax); i < imax; i++) {
 172     ProjNode* proj= unswitch_iff->fast_out(i)->as_Proj();
 173     // Copy to a worklist for easier manipulation
 174     for (DUIterator_Fast jmax, j = proj->fast_outs(jmax); j < jmax; j++) {
 175       Node* use = proj->fast_out(j);
 176       if (use->Opcode() == Opcodes::Op_CheckCastPP && loop->is_invariant(use->in(1))) {
 177         worklist.push(use);
 178       }
 179     }
 180     ProjNode* invar_proj = invar_iff->proj_out(proj->_con)->as_Proj();
 181     while (worklist.size() > 0) {
 182       Node* use = worklist.pop();
 183       Node* nuse = use->clone();
 184       nuse->set_req(0, invar_proj);
 185       _igvn.replace_input_of(use, 1, nuse);
 186       register_new_node(nuse, invar_proj);
 187       // Same for the clone
 188       Node* use_clone = old_new[use->_idx];
 189       _igvn.replace_input_of(use_clone, 1, nuse);
 190     }
 191   }
 192 
 193   // Hardwire the control paths in the loops into if(true) and if(false)
 194   _igvn.rehash_node_delayed(unswitch_iff);
 195   short_circuit_if(unswitch_iff, proj_true);
 196 


 206     _igvn._worklist.push(n_clone);
 207   }
 208 
 209 #ifndef PRODUCT
 210   if (TraceLoopUnswitching) {
 211     tty->print_cr("Loop unswitching orig: %d @ %d  new: %d @ %d",
 212                   head->_idx,                unswitch_iff->_idx,
 213                   old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
 214   }
 215 #endif
 216 
 217   C->set_major_progress();
 218 }
 219 
 220 //-------------------------create_slow_version_of_loop------------------------
 221 // Create a slow version of the loop by cloning the loop
 222 // and inserting an if to select fast-slow versions.
 223 // Return control projection of the entry to the fast version.
 224 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
 225                                                       Node_List &old_new,
 226                                                       Opcodes opcode) {
 227   LoopNode* head  = loop->_head->as_Loop();
 228   bool counted_loop = head->is_CountedLoop();
 229   Node*     entry = head->in(LoopNode::EntryControl);
 230   _igvn.rehash_node_delayed(entry);
 231   IdealLoopTree* outer_loop = loop->_parent;
 232 
 233   Node *cont      = _igvn.intcon(1);
 234   set_ctrl(cont, C->root());
 235   Node* opq       = new Opaque1Node(C, cont);
 236   register_node(opq, outer_loop, entry, dom_depth(entry));
 237   Node *bol       = new Conv2BNode(opq);
 238   register_node(bol, outer_loop, entry, dom_depth(entry));
 239   IfNode* iff = (opcode == Opcodes::Op_RangeCheck) ? new RangeCheckNode(entry, bol, PROB_MAX, COUNT_UNKNOWN) :
 240     new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
 241   register_node(iff, outer_loop, entry, dom_depth(entry));
 242   ProjNode* iffast = new IfTrueNode(iff);
 243   register_node(iffast, outer_loop, iff, dom_depth(iff));
 244   ProjNode* ifslow = new IfFalseNode(iff);
 245   register_node(ifslow, outer_loop, iff, dom_depth(iff));
 246 
 247   // Clone the loop body.  The clone becomes the fast loop.  The
 248   // original pre-header will (illegally) have 3 control users
 249   // (old & new loops & new if).
 250   clone_loop(loop, old_new, dom_depth(head), iff);
 251   assert(old_new[head->_idx]->is_Loop(), "" );
 252 
 253   // Fast (true) control
 254   Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
 255   _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
 256   set_idom(head, iffast_pred, dom_depth(head));
 257 
 258   // Slow (false) control
 259   Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);


 388   }
 389 
 390   _lp = _lpt->_head->as_Loop();
 391   _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this);
 392 
 393   if (!_lp_reserved->is_CountedLoop()) {
 394     return false;
 395   }
 396 
 397   Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl);
 398 
 399   if (!ifslow_pred->is_IfFalse()) {
 400     return false;
 401   }
 402 
 403   Node* iff = ifslow_pred->in(0);
 404   if (!iff->is_If() || iff != _iff) {
 405     return false;
 406   }
 407 
 408   if (iff->in(1)->Opcode() != Opcodes::Op_ConI) {
 409     return false;
 410   }
 411 
 412   return _has_reserved = true;
 413 }
< prev index next >