hotspot/src/share/vm/opto/loopUnswitch.cpp
changeset 9124 f60dee480d49
parent 8921 14bfe81f2a9d
parent 9101 ff58f9a8e31c
child 9446 748a37b25d10
equal deleted inserted replaced
9093:62b8e328f8c8 9124:f60dee480d49
    30 
    30 
    31 //================= Loop Unswitching =====================
    31 //================= Loop Unswitching =====================
    32 //
    32 //
    33 // orig:                       transformed:
    33 // orig:                       transformed:
    34 //                               if (invariant-test) then
    34 //                               if (invariant-test) then
       
    35 //  predicate                      predicate
    35 //  loop                           loop
    36 //  loop                           loop
    36 //    stmt1                          stmt1
    37 //    stmt1                          stmt1
    37 //    if (invariant-test) then       stmt2
    38 //    if (invariant-test) then       stmt2
    38 //      stmt2                        stmt4
    39 //      stmt2                        stmt4
    39 //    else                         endloop
    40 //    else                         endloop
    40 //      stmt3                    else
    41 //      stmt3                    else
    41 //    endif                        loop [clone]
    42 //    endif                        predicate [clone]
    42 //    stmt4                          stmt1 [clone]
    43 //    stmt4                        loop [clone]
    43 //  endloop                          stmt3
    44 //  endloop                          stmt1 [clone]
       
    45 //                                   stmt3
    44 //                                   stmt4 [clone]
    46 //                                   stmt4 [clone]
    45 //                                 endloop
    47 //                                 endloop
    46 //                               endif
    48 //                               endif
    47 //
    49 //
    48 // Note: the "else" clause may be empty
    50 // Note: the "else" clause may be empty
   122     head->as_CountedLoop()->set_normal_loop();
   124     head->as_CountedLoop()->set_normal_loop();
   123   }
   125   }
   124 
   126 
   125   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
   127   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
   126 
   128 
   127   assert(proj_true->is_IfTrue() && proj_true->unique_ctrl_out() == head, "by construction");
   129 #ifdef ASSERT
   128 
   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
   129   // Increment unswitch count
   138   // Increment unswitch count
   130   LoopNode* head_clone = old_new[head->_idx]->as_Loop();
   139   LoopNode* head_clone = old_new[head->_idx]->as_Loop();
   131   int nct = head->unswitch_count() + 1;
   140   int nct = head->unswitch_count() + 1;
   132   head->set_unswitch_count(nct);
   141   head->set_unswitch_count(nct);
   133   head_clone->set_unswitch_count(nct);
   142   head_clone->set_unswitch_count(nct);
   225   register_node(iffast, outer_loop, iff, dom_depth(iff));
   234   register_node(iffast, outer_loop, iff, dom_depth(iff));
   226   ProjNode* ifslow = new (C, 1) IfFalseNode(iff);
   235   ProjNode* ifslow = new (C, 1) IfFalseNode(iff);
   227   register_node(ifslow, outer_loop, iff, dom_depth(iff));
   236   register_node(ifslow, outer_loop, iff, dom_depth(iff));
   228 
   237 
   229   // Clone the loop body.  The clone becomes the fast loop.  The
   238   // Clone the loop body.  The clone becomes the fast loop.  The
   230   // original pre-header will (illegally) have 2 control users (old & new loops).
   239   // original pre-header will (illegally) have 3 control users
       
   240   // (old & new loops & new if).
   231   clone_loop(loop, old_new, dom_depth(head), iff);
   241   clone_loop(loop, old_new, dom_depth(head), iff);
   232   assert(old_new[head->_idx]->is_Loop(), "" );
   242   assert(old_new[head->_idx]->is_Loop(), "" );
   233 
   243 
   234   // Fast (true) control
   244   // Fast (true) control
       
   245   Node* iffast_pred = clone_loop_predicates(entry, iffast);
   235   _igvn.hash_delete(head);
   246   _igvn.hash_delete(head);
   236   head->set_req(LoopNode::EntryControl, iffast);
   247   head->set_req(LoopNode::EntryControl, iffast_pred);
   237   set_idom(head, iffast, dom_depth(head));
   248   set_idom(head, iffast_pred, dom_depth(head));
   238   _igvn._worklist.push(head);
   249   _igvn._worklist.push(head);
   239 
   250 
   240   // Slow (false) control
   251   // Slow (false) control
       
   252   Node* ifslow_pred = move_loop_predicates(entry, ifslow);
   241   LoopNode* slow_head = old_new[head->_idx]->as_Loop();
   253   LoopNode* slow_head = old_new[head->_idx]->as_Loop();
   242   _igvn.hash_delete(slow_head);
   254   _igvn.hash_delete(slow_head);
   243   slow_head->set_req(LoopNode::EntryControl, ifslow);
   255   slow_head->set_req(LoopNode::EntryControl, ifslow_pred);
   244   set_idom(slow_head, ifslow, dom_depth(slow_head));
   256   set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
   245   _igvn._worklist.push(slow_head);
   257   _igvn._worklist.push(slow_head);
   246 
   258 
   247   recompute_dom_depth();
   259   recompute_dom_depth();
   248 
   260 
   249   return iffast;
   261   return iffast;