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

src/share/vm/opto/loopUnswitch.cpp

Print this page




 113   assert(unswitch_iff != NULL, "should be at least one");
 114 
 115 #ifndef PRODUCT
 116   if (TraceLoopOpts) {
 117     tty->print("Unswitch   %d ", head->unswitch_count()+1);
 118     loop->dump_head();
 119   }
 120 #endif
 121 
 122   // Need to revert back to normal loop
 123   if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
 124     head->as_CountedLoop()->set_normal_loop();
 125   }
 126 
 127   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
 128 
 129 #ifdef ASSERT
 130   Node* uniqc = proj_true->unique_ctrl_out();
 131   Node* entry = head->in(LoopNode::EntryControl);
 132   Node* predicate = find_predicate(entry);





 133   if (predicate != NULL) predicate = predicate->in(0);
 134   assert(proj_true->is_IfTrue() &&
 135          (predicate == NULL && uniqc == head ||
 136           predicate != NULL && uniqc == predicate), "by construction");
 137 #endif
 138   // Increment unswitch count
 139   LoopNode* head_clone = old_new[head->_idx]->as_Loop();
 140   int nct = head->unswitch_count() + 1;
 141   head->set_unswitch_count(nct);
 142   head_clone->set_unswitch_count(nct);
 143 
 144   // Add test to new "if" outside of loop
 145   IfNode* invar_iff   = proj_true->in(0)->as_If();
 146   Node* invar_iff_c   = invar_iff->in(0);
 147   BoolNode* bol       = unswitch_iff->in(1)->as_Bool();
 148   invar_iff->set_req(1, bol);
 149   invar_iff->_prob    = unswitch_iff->_prob;
 150 
 151   ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
 152 


 200   }
 201 
 202 #ifndef PRODUCT
 203   if (TraceLoopUnswitching) {
 204     tty->print_cr("Loop unswitching orig: %d @ %d  new: %d @ %d",
 205                   head->_idx,                unswitch_iff->_idx,
 206                   old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
 207   }
 208 #endif
 209 
 210   C->set_major_progress();
 211 }
 212 
 213 //-------------------------create_slow_version_of_loop------------------------
 214 // Create a slow version of the loop by cloning the loop
 215 // and inserting an if to select fast-slow versions.
 216 // Return control projection of the entry to the fast version.
 217 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
 218                                                       Node_List &old_new) {
 219   LoopNode* head  = loop->_head->as_Loop();

 220   Node*     entry = head->in(LoopNode::EntryControl);
 221   _igvn.hash_delete(entry);
 222   _igvn._worklist.push(entry);
 223   IdealLoopTree* outer_loop = loop->_parent;
 224 
 225   Node *cont      = _igvn.intcon(1);
 226   set_ctrl(cont, C->root());
 227   Node* opq       = new (C, 2) Opaque1Node(C, cont);
 228   register_node(opq, outer_loop, entry, dom_depth(entry));
 229   Node *bol       = new (C, 2) Conv2BNode(opq);
 230   register_node(bol, outer_loop, entry, dom_depth(entry));
 231   IfNode* iff = new (C, 2) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
 232   register_node(iff, outer_loop, entry, dom_depth(entry));
 233   ProjNode* iffast = new (C, 1) IfTrueNode(iff);
 234   register_node(iffast, outer_loop, iff, dom_depth(iff));
 235   ProjNode* ifslow = new (C, 1) IfFalseNode(iff);
 236   register_node(ifslow, outer_loop, iff, dom_depth(iff));
 237 
 238   // Clone the loop body.  The clone becomes the fast loop.  The
 239   // original pre-header will (illegally) have 3 control users
 240   // (old & new loops & new if).
 241   clone_loop(loop, old_new, dom_depth(head), iff);
 242   assert(old_new[head->_idx]->is_Loop(), "" );
 243 
 244   // Fast (true) control
 245   Node* iffast_pred = clone_loop_predicates(entry, iffast);
 246   _igvn.hash_delete(head);
 247   head->set_req(LoopNode::EntryControl, iffast_pred);
 248   set_idom(head, iffast_pred, dom_depth(head));
 249   _igvn._worklist.push(head);
 250 
 251   // Slow (false) control
 252   Node* ifslow_pred = move_loop_predicates(entry, ifslow);
 253   LoopNode* slow_head = old_new[head->_idx]->as_Loop();
 254   _igvn.hash_delete(slow_head);
 255   slow_head->set_req(LoopNode::EntryControl, ifslow_pred);
 256   set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
 257   _igvn._worklist.push(slow_head);
 258 
 259   recompute_dom_depth();
 260 
 261   return iffast;
 262 }


 113   assert(unswitch_iff != NULL, "should be at least one");
 114 
 115 #ifndef PRODUCT
 116   if (TraceLoopOpts) {
 117     tty->print("Unswitch   %d ", head->unswitch_count()+1);
 118     loop->dump_head();
 119   }
 120 #endif
 121 
 122   // Need to revert back to normal loop
 123   if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
 124     head->as_CountedLoop()->set_normal_loop();
 125   }
 126 
 127   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
 128 
 129 #ifdef ASSERT
 130   Node* uniqc = proj_true->unique_ctrl_out();
 131   Node* entry = head->in(LoopNode::EntryControl);
 132   Node* predicate = find_predicate(entry);
 133   if (predicate != NULL && LoopLimitCheck && UseLoopPredicate) {
 134     // We may have two predicates, find first.
 135     entry = find_predicate(entry->in(0)->in(0));
 136     if (entry != NULL) predicate = entry;
 137   }
 138   if (predicate != NULL) predicate = predicate->in(0);
 139   assert(proj_true->is_IfTrue() &&
 140          (predicate == NULL && uniqc == head ||
 141           predicate != NULL && uniqc == predicate), "by construction");
 142 #endif
 143   // Increment unswitch count
 144   LoopNode* head_clone = old_new[head->_idx]->as_Loop();
 145   int nct = head->unswitch_count() + 1;
 146   head->set_unswitch_count(nct);
 147   head_clone->set_unswitch_count(nct);
 148 
 149   // Add test to new "if" outside of loop
 150   IfNode* invar_iff   = proj_true->in(0)->as_If();
 151   Node* invar_iff_c   = invar_iff->in(0);
 152   BoolNode* bol       = unswitch_iff->in(1)->as_Bool();
 153   invar_iff->set_req(1, bol);
 154   invar_iff->_prob    = unswitch_iff->_prob;
 155 
 156   ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
 157 


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