Mercurial > hg > truffle
comparison src/share/vm/opto/loopUnswitch.cpp @ 2445:08eb13460b3a
7004535: Clone loop predicate during loop unswitch
Summary: Clone loop predicate for clonned loops
Reviewed-by: never
author | kvn |
---|---|
date | Sat, 02 Apr 2011 10:54:15 -0700 |
parents | 9dc311b8473e |
children | 6c97c830fb6f |
comparison
equal
deleted
inserted
replaced
2444:07acc51c1d2a | 2445:08eb13460b3a |
---|---|
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; |