src/share/vm/opto/loopUnswitch.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/loopUnswitch.cpp

Print this page
rev 9106 : 8137168: Replace IfNode with a new RangeCheckNode for range checks
Summary: new RangeCheckNode to enable optimization of explicit library level range checks
Reviewed-by:


 115 void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
 116 
 117   // Find first invariant test that doesn't exit the loop
 118   LoopNode *head = loop->_head->as_Loop();
 119 
 120   IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
 121   assert(unswitch_iff != NULL, "should be at least one");
 122 
 123 #ifndef PRODUCT
 124   if (TraceLoopOpts) {
 125     tty->print("Unswitch   %d ", head->unswitch_count()+1);
 126     loop->dump_head();
 127   }
 128 #endif
 129 
 130   // Need to revert back to normal loop
 131   if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
 132     head->as_CountedLoop()->set_normal_loop();
 133   }
 134 
 135   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
 136 
 137 #ifdef ASSERT
 138   Node* uniqc = proj_true->unique_ctrl_out();
 139   Node* entry = head->in(LoopNode::EntryControl);
 140   Node* predicate = find_predicate(entry);
 141   if (predicate != NULL && LoopLimitCheck && UseLoopPredicate) {
 142     // We may have two predicates, find first.
 143     entry = find_predicate(entry->in(0)->in(0));
 144     if (entry != NULL) predicate = entry;
 145   }
 146   if (predicate != NULL) predicate = predicate->in(0);
 147   assert(proj_true->is_IfTrue() &&
 148          (predicate == NULL && uniqc == head ||
 149           predicate != NULL && uniqc == predicate), "by construction");
 150 #endif
 151   // Increment unswitch count
 152   LoopNode* head_clone = old_new[head->_idx]->as_Loop();
 153   int nct = head->unswitch_count() + 1;
 154   head->set_unswitch_count(nct);
 155   head_clone->set_unswitch_count(nct);


 205     Node *n_clone = old_new[n->_idx];
 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   LoopNode* head  = loop->_head->as_Loop();
 227   bool counted_loop = head->is_CountedLoop();
 228   Node*     entry = head->in(LoopNode::EntryControl);
 229   _igvn.rehash_node_delayed(entry);
 230   IdealLoopTree* outer_loop = loop->_parent;
 231 
 232   Node *cont      = _igvn.intcon(1);
 233   set_ctrl(cont, C->root());
 234   Node* opq       = new Opaque1Node(C, cont);
 235   register_node(opq, outer_loop, entry, dom_depth(entry));
 236   Node *bol       = new Conv2BNode(opq);
 237   register_node(bol, outer_loop, entry, dom_depth(entry));
 238   IfNode* iff = new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);

 239   register_node(iff, outer_loop, entry, dom_depth(entry));
 240   ProjNode* iffast = new IfTrueNode(iff);
 241   register_node(iffast, outer_loop, iff, dom_depth(iff));
 242   ProjNode* ifslow = new IfFalseNode(iff);
 243   register_node(ifslow, outer_loop, iff, dom_depth(iff));
 244 
 245   // Clone the loop body.  The clone becomes the fast loop.  The
 246   // original pre-header will (illegally) have 3 control users
 247   // (old & new loops & new if).
 248   clone_loop(loop, old_new, dom_depth(head), iff);
 249   assert(old_new[head->_idx]->is_Loop(), "" );
 250 
 251   // Fast (true) control
 252   Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
 253   _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
 254   set_idom(head, iffast_pred, dom_depth(head));
 255 
 256   // Slow (false) control
 257   Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
 258   LoopNode* slow_head = old_new[head->_idx]->as_Loop();


 115 void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
 116 
 117   // Find first invariant test that doesn't exit the loop
 118   LoopNode *head = loop->_head->as_Loop();
 119 
 120   IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
 121   assert(unswitch_iff != NULL, "should be at least one");
 122 
 123 #ifndef PRODUCT
 124   if (TraceLoopOpts) {
 125     tty->print("Unswitch   %d ", head->unswitch_count()+1);
 126     loop->dump_head();
 127   }
 128 #endif
 129 
 130   // Need to revert back to normal loop
 131   if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
 132     head->as_CountedLoop()->set_normal_loop();
 133   }
 134 
 135   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new, unswitch_iff->Opcode());
 136 
 137 #ifdef ASSERT
 138   Node* uniqc = proj_true->unique_ctrl_out();
 139   Node* entry = head->in(LoopNode::EntryControl);
 140   Node* predicate = find_predicate(entry);
 141   if (predicate != NULL && LoopLimitCheck && UseLoopPredicate) {
 142     // We may have two predicates, find first.
 143     entry = find_predicate(entry->in(0)->in(0));
 144     if (entry != NULL) predicate = entry;
 145   }
 146   if (predicate != NULL) predicate = predicate->in(0);
 147   assert(proj_true->is_IfTrue() &&
 148          (predicate == NULL && uniqc == head ||
 149           predicate != NULL && uniqc == predicate), "by construction");
 150 #endif
 151   // Increment unswitch count
 152   LoopNode* head_clone = old_new[head->_idx]->as_Loop();
 153   int nct = head->unswitch_count() + 1;
 154   head->set_unswitch_count(nct);
 155   head_clone->set_unswitch_count(nct);


 205     Node *n_clone = old_new[n->_idx];
 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);
 260   LoopNode* slow_head = old_new[head->_idx]->as_Loop();
src/share/vm/opto/loopUnswitch.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File