Mercurial > hg > truffle
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); |