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();