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;