comparison src/share/vm/opto/ifnode.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 f95d63e2154a
children bad7ecd0b6ed
comparison
equal deleted inserted replaced
2444:07acc51c1d2a 2445:08eb13460b3a
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "memory/allocation.inline.hpp" 26 #include "memory/allocation.inline.hpp"
27 #include "opto/addnode.hpp" 27 #include "opto/addnode.hpp"
28 #include "opto/cfgnode.hpp" 28 #include "opto/cfgnode.hpp"
29 #include "opto/connode.hpp" 29 #include "opto/connode.hpp"
30 #include "opto/loopnode.hpp"
30 #include "opto/phaseX.hpp" 31 #include "opto/phaseX.hpp"
31 #include "opto/runtime.hpp" 32 #include "opto/runtime.hpp"
32 #include "opto/subnode.hpp" 33 #include "opto/subnode.hpp"
33 34
34 // Portions of code courtesy of Clifford Click 35 // Portions of code courtesy of Clifford Click
220 // likely 2 or more) will promptly constant fold away. 221 // likely 2 or more) will promptly constant fold away.
221 PhaseGVN *phase = igvn; 222 PhaseGVN *phase = igvn;
222 223
223 // Make a region merging constants and a region merging the rest 224 // Make a region merging constants and a region merging the rest
224 uint req_c = 0; 225 uint req_c = 0;
226 Node* predicate_proj = NULL;
225 for (uint ii = 1; ii < r->req(); ii++) { 227 for (uint ii = 1; ii < r->req(); ii++) {
226 if( phi->in(ii) == con1 ) { 228 if (phi->in(ii) == con1) {
227 req_c++; 229 req_c++;
228 } 230 }
229 } 231 Node* proj = PhaseIdealLoop::find_predicate(r->in(ii));
232 if (proj != NULL) {
233 assert(predicate_proj == NULL, "only one predicate entry expected");
234 predicate_proj = proj;
235 }
236 }
237 Node* predicate_c = NULL;
238 Node* predicate_x = NULL;
239
230 Node *region_c = new (igvn->C, req_c + 1) RegionNode(req_c + 1); 240 Node *region_c = new (igvn->C, req_c + 1) RegionNode(req_c + 1);
231 Node *phi_c = con1; 241 Node *phi_c = con1;
232 uint len = r->req(); 242 uint len = r->req();
233 Node *region_x = new (igvn->C, len - req_c + 1) RegionNode(len - req_c + 1); 243 Node *region_x = new (igvn->C, len - req_c) RegionNode(len - req_c);
234 Node *phi_x = PhiNode::make_blank(region_x, phi); 244 Node *phi_x = PhiNode::make_blank(region_x, phi);
235 for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) { 245 for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) {
236 if( phi->in(i) == con1 ) { 246 if (phi->in(i) == con1) {
237 region_c->init_req( i_c++, r ->in(i) ); 247 region_c->init_req( i_c++, r ->in(i) );
248 if (r->in(i) == predicate_proj)
249 predicate_c = predicate_proj;
238 } else { 250 } else {
239 region_x->init_req( i_x, r ->in(i) ); 251 region_x->init_req( i_x, r ->in(i) );
240 phi_x ->init_req( i_x++, phi->in(i) ); 252 phi_x ->init_req( i_x++, phi->in(i) );
253 if (r->in(i) == predicate_proj)
254 predicate_x = predicate_proj;
241 } 255 }
242 } 256 }
243 257
244 // Register the new RegionNodes but do not transform them. Cannot 258 // Register the new RegionNodes but do not transform them. Cannot
245 // transform until the entire Region/Phi conglomerate has been hacked 259 // transform until the entire Region/Phi conglomerate has been hacked
275 hook->init_req(3, iff_x); 289 hook->init_req(3, iff_x);
276 290
277 // Make the true/false arms 291 // Make the true/false arms
278 Node *iff_c_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_c)); 292 Node *iff_c_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_c));
279 Node *iff_c_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_c)); 293 Node *iff_c_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_c));
294 if (predicate_c != NULL) {
295 assert(predicate_x == NULL, "only one predicate entry expected");
296 // Clone loop predicates to each path
297 iff_c_t = igvn->clone_loop_predicates(predicate_c, iff_c_t);
298 iff_c_f = igvn->clone_loop_predicates(predicate_c, iff_c_f);
299 }
280 Node *iff_x_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_x)); 300 Node *iff_x_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_x));
281 Node *iff_x_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_x)); 301 Node *iff_x_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_x));
302 if (predicate_x != NULL) {
303 assert(predicate_c == NULL, "only one predicate entry expected");
304 // Clone loop predicates to each path
305 iff_x_t = igvn->clone_loop_predicates(predicate_x, iff_x_t);
306 iff_x_f = igvn->clone_loop_predicates(predicate_x, iff_x_f);
307 }
282 308
283 // Merge the TRUE paths 309 // Merge the TRUE paths
284 Node *region_s = new (igvn->C, 3) RegionNode(3); 310 Node *region_s = new (igvn->C, 3) RegionNode(3);
285 igvn->_worklist.push(region_s); 311 igvn->_worklist.push(region_s);
286 region_s->init_req(1, iff_c_t); 312 region_s->init_req(1, iff_c_t);