172 ProjNode* invar_proj = invar_iff->proj_out(proj->_con)->as_Proj(); |
172 ProjNode* invar_proj = invar_iff->proj_out(proj->_con)->as_Proj(); |
173 while (worklist.size() > 0) { |
173 while (worklist.size() > 0) { |
174 Node* use = worklist.pop(); |
174 Node* use = worklist.pop(); |
175 Node* nuse = use->clone(); |
175 Node* nuse = use->clone(); |
176 nuse->set_req(0, invar_proj); |
176 nuse->set_req(0, invar_proj); |
177 _igvn.hash_delete(use); |
177 _igvn.replace_input_of(use, 1, nuse); |
178 use->set_req(1, nuse); |
|
179 _igvn._worklist.push(use); |
|
180 register_new_node(nuse, invar_proj); |
178 register_new_node(nuse, invar_proj); |
181 // Same for the clone |
179 // Same for the clone |
182 Node* use_clone = old_new[use->_idx]; |
180 Node* use_clone = old_new[use->_idx]; |
183 _igvn.hash_delete(use_clone); |
181 _igvn.replace_input_of(use_clone, 1, nuse); |
184 use_clone->set_req(1, nuse); |
|
185 _igvn._worklist.push(use_clone); |
|
186 } |
182 } |
187 } |
183 } |
188 |
184 |
189 // Hardwire the control paths in the loops into if(true) and if(false) |
185 // Hardwire the control paths in the loops into if(true) and if(false) |
190 _igvn.hash_delete(unswitch_iff); |
186 _igvn.rehash_node_delayed(unswitch_iff); |
191 short_circuit_if(unswitch_iff, proj_true); |
187 short_circuit_if(unswitch_iff, proj_true); |
192 _igvn._worklist.push(unswitch_iff); |
|
193 |
188 |
194 IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If(); |
189 IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If(); |
195 _igvn.hash_delete(unswitch_iff_clone); |
190 _igvn.rehash_node_delayed(unswitch_iff_clone); |
196 short_circuit_if(unswitch_iff_clone, proj_false); |
191 short_circuit_if(unswitch_iff_clone, proj_false); |
197 _igvn._worklist.push(unswitch_iff_clone); |
|
198 |
192 |
199 // Reoptimize loops |
193 // Reoptimize loops |
200 loop->record_for_igvn(); |
194 loop->record_for_igvn(); |
201 for(int i = loop->_body.size() - 1; i >= 0 ; i--) { |
195 for(int i = loop->_body.size() - 1; i >= 0 ; i--) { |
202 Node *n = loop->_body[i]; |
196 Node *n = loop->_body[i]; |
222 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop, |
216 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop, |
223 Node_List &old_new) { |
217 Node_List &old_new) { |
224 LoopNode* head = loop->_head->as_Loop(); |
218 LoopNode* head = loop->_head->as_Loop(); |
225 bool counted_loop = head->is_CountedLoop(); |
219 bool counted_loop = head->is_CountedLoop(); |
226 Node* entry = head->in(LoopNode::EntryControl); |
220 Node* entry = head->in(LoopNode::EntryControl); |
227 _igvn.hash_delete(entry); |
221 _igvn.rehash_node_delayed(entry); |
228 _igvn._worklist.push(entry); |
|
229 IdealLoopTree* outer_loop = loop->_parent; |
222 IdealLoopTree* outer_loop = loop->_parent; |
230 |
223 |
231 Node *cont = _igvn.intcon(1); |
224 Node *cont = _igvn.intcon(1); |
232 set_ctrl(cont, C->root()); |
225 set_ctrl(cont, C->root()); |
233 Node* opq = new (C, 2) Opaque1Node(C, cont); |
226 Node* opq = new (C, 2) Opaque1Node(C, cont); |
247 clone_loop(loop, old_new, dom_depth(head), iff); |
240 clone_loop(loop, old_new, dom_depth(head), iff); |
248 assert(old_new[head->_idx]->is_Loop(), "" ); |
241 assert(old_new[head->_idx]->is_Loop(), "" ); |
249 |
242 |
250 // Fast (true) control |
243 // Fast (true) control |
251 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop); |
244 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop); |
252 _igvn.hash_delete(head); |
245 _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred); |
253 head->set_req(LoopNode::EntryControl, iffast_pred); |
|
254 set_idom(head, iffast_pred, dom_depth(head)); |
246 set_idom(head, iffast_pred, dom_depth(head)); |
255 _igvn._worklist.push(head); |
|
256 |
247 |
257 // Slow (false) control |
248 // Slow (false) control |
258 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop); |
249 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop); |
259 LoopNode* slow_head = old_new[head->_idx]->as_Loop(); |
250 LoopNode* slow_head = old_new[head->_idx]->as_Loop(); |
260 _igvn.hash_delete(slow_head); |
251 _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow_pred); |
261 slow_head->set_req(LoopNode::EntryControl, ifslow_pred); |
|
262 set_idom(slow_head, ifslow_pred, dom_depth(slow_head)); |
252 set_idom(slow_head, ifslow_pred, dom_depth(slow_head)); |
263 _igvn._worklist.push(slow_head); |
|
264 |
253 |
265 recompute_dom_depth(); |
254 recompute_dom_depth(); |
266 |
255 |
267 return iffast; |
256 return iffast; |
268 } |
257 } |