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