src/share/vm/opto/loopUnswitch.cpp

changeset 2727
08eb13460b3a
parent 2665
9dc311b8473e
child 2750
6c97c830fb6f
     1.1 --- a/src/share/vm/opto/loopUnswitch.cpp	Sat Apr 02 09:49:27 2011 -0700
     1.2 +++ b/src/share/vm/opto/loopUnswitch.cpp	Sat Apr 02 10:54:15 2011 -0700
     1.3 @@ -32,15 +32,17 @@
     1.4  //
     1.5  // orig:                       transformed:
     1.6  //                               if (invariant-test) then
     1.7 +//  predicate                      predicate
     1.8  //  loop                           loop
     1.9  //    stmt1                          stmt1
    1.10  //    if (invariant-test) then       stmt2
    1.11  //      stmt2                        stmt4
    1.12  //    else                         endloop
    1.13  //      stmt3                    else
    1.14 -//    endif                        loop [clone]
    1.15 -//    stmt4                          stmt1 [clone]
    1.16 -//  endloop                          stmt3
    1.17 +//    endif                        predicate [clone]
    1.18 +//    stmt4                        loop [clone]
    1.19 +//  endloop                          stmt1 [clone]
    1.20 +//                                   stmt3
    1.21  //                                   stmt4 [clone]
    1.22  //                                 endloop
    1.23  //                               endif
    1.24 @@ -124,8 +126,15 @@
    1.25  
    1.26    ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
    1.27  
    1.28 -  assert(proj_true->is_IfTrue() && proj_true->unique_ctrl_out() == head, "by construction");
    1.29 -
    1.30 +#ifdef ASSERT
    1.31 +  Node* uniqc = proj_true->unique_ctrl_out();
    1.32 +  Node* entry = head->in(LoopNode::EntryControl);
    1.33 +  Node* predicate = find_predicate(entry);
    1.34 +  if (predicate != NULL) predicate = predicate->in(0);
    1.35 +  assert(proj_true->is_IfTrue() &&
    1.36 +         (predicate == NULL && uniqc == head ||
    1.37 +          predicate != NULL && uniqc == predicate), "by construction");
    1.38 +#endif
    1.39    // Increment unswitch count
    1.40    LoopNode* head_clone = old_new[head->_idx]->as_Loop();
    1.41    int nct = head->unswitch_count() + 1;
    1.42 @@ -227,21 +236,24 @@
    1.43    register_node(ifslow, outer_loop, iff, dom_depth(iff));
    1.44  
    1.45    // Clone the loop body.  The clone becomes the fast loop.  The
    1.46 -  // original pre-header will (illegally) have 2 control users (old & new loops).
    1.47 +  // original pre-header will (illegally) have 3 control users
    1.48 +  // (old & new loops & new if).
    1.49    clone_loop(loop, old_new, dom_depth(head), iff);
    1.50    assert(old_new[head->_idx]->is_Loop(), "" );
    1.51  
    1.52    // Fast (true) control
    1.53 +  Node* iffast_pred = clone_loop_predicates(entry, iffast);
    1.54    _igvn.hash_delete(head);
    1.55 -  head->set_req(LoopNode::EntryControl, iffast);
    1.56 -  set_idom(head, iffast, dom_depth(head));
    1.57 +  head->set_req(LoopNode::EntryControl, iffast_pred);
    1.58 +  set_idom(head, iffast_pred, dom_depth(head));
    1.59    _igvn._worklist.push(head);
    1.60  
    1.61    // Slow (false) control
    1.62 +  Node* ifslow_pred = move_loop_predicates(entry, ifslow);
    1.63    LoopNode* slow_head = old_new[head->_idx]->as_Loop();
    1.64    _igvn.hash_delete(slow_head);
    1.65 -  slow_head->set_req(LoopNode::EntryControl, ifslow);
    1.66 -  set_idom(slow_head, ifslow, dom_depth(slow_head));
    1.67 +  slow_head->set_req(LoopNode::EntryControl, ifslow_pred);
    1.68 +  set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
    1.69    _igvn._worklist.push(slow_head);
    1.70  
    1.71    recompute_dom_depth();

mercurial