217 // R - Phi - Phi - Phi Rc - Phi - Phi - Phi Rx - Phi - Phi - Phi
218 // cmp - 2 cmp - 2 cmp - 2
219 // bool bool_c bool_x
220 // if if_c if_x
221 // T F T F T F
222 // ..s.. ..t .. ..s.. ..t.. ..s.. ..t..
223 //
224 // Split the paths coming into the merge point into 2 separate groups of
225 // merges. On the left will be all the paths feeding constants into the
226 // Cmp's Phi. On the right will be the remaining paths. The Cmp's Phi
227 // will fold up into a constant; this will let the Cmp fold up as well as
228 // all the control flow. Below the original IF we have 2 control
229 // dependent regions, 's' and 't'. Now we will merge the two paths
230 // just prior to 's' and 't' from the two IFs. At least 1 path (and quite
231 // likely 2 or more) will promptly constant fold away.
232 PhaseGVN *phase = igvn;
233
234 // Make a region merging constants and a region merging the rest
235 uint req_c = 0;
236 Node* predicate_proj = NULL;
237 for (uint ii = 1; ii < r->req(); ii++) {
238 if (phi->in(ii) == con1) {
239 req_c++;
240 }
241 Node* proj = PhaseIdealLoop::find_predicate(r->in(ii));
242 if (proj != NULL) {
243 assert(predicate_proj == NULL, "only one predicate entry expected");
244 predicate_proj = proj;
245 }
246 }
247 Node* predicate_c = NULL;
248 Node* predicate_x = NULL;
249 bool counted_loop = r->is_CountedLoop();
250
251 Node *region_c = new RegionNode(req_c + 1);
252 Node *phi_c = con1;
253 uint len = r->req();
254 Node *region_x = new RegionNode(len - req_c);
255 Node *phi_x = PhiNode::make_blank(region_x, phi);
256 for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) {
257 if (phi->in(i) == con1) {
258 region_c->init_req( i_c++, r ->in(i) );
259 if (r->in(i) == predicate_proj)
260 predicate_c = predicate_proj;
261 } else {
262 region_x->init_req( i_x, r ->in(i) );
263 phi_x ->init_req( i_x++, phi->in(i) );
264 if (r->in(i) == predicate_proj)
265 predicate_x = predicate_proj;
|
217 // R - Phi - Phi - Phi Rc - Phi - Phi - Phi Rx - Phi - Phi - Phi
218 // cmp - 2 cmp - 2 cmp - 2
219 // bool bool_c bool_x
220 // if if_c if_x
221 // T F T F T F
222 // ..s.. ..t .. ..s.. ..t.. ..s.. ..t..
223 //
224 // Split the paths coming into the merge point into 2 separate groups of
225 // merges. On the left will be all the paths feeding constants into the
226 // Cmp's Phi. On the right will be the remaining paths. The Cmp's Phi
227 // will fold up into a constant; this will let the Cmp fold up as well as
228 // all the control flow. Below the original IF we have 2 control
229 // dependent regions, 's' and 't'. Now we will merge the two paths
230 // just prior to 's' and 't' from the two IFs. At least 1 path (and quite
231 // likely 2 or more) will promptly constant fold away.
232 PhaseGVN *phase = igvn;
233
234 // Make a region merging constants and a region merging the rest
235 uint req_c = 0;
236 Node* predicate_proj = NULL;
237 int nb_predicate_proj = 0;
238 for (uint ii = 1; ii < r->req(); ii++) {
239 if (phi->in(ii) == con1) {
240 req_c++;
241 }
242 Node* proj = PhaseIdealLoop::find_predicate(r->in(ii));
243 if (proj != NULL) {
244 nb_predicate_proj++;
245 predicate_proj = proj;
246 }
247 }
248 if (nb_predicate_proj > 1) {
249 // Can happen in case of loop unswitching and when the loop is
250 // optimized out: it's not a loop anymore so we don't care about
251 // predicates.
252 assert(!r->is_Loop(), "this must not be a loop anymore");
253 predicate_proj = NULL;
254 }
255 Node* predicate_c = NULL;
256 Node* predicate_x = NULL;
257 bool counted_loop = r->is_CountedLoop();
258
259 Node *region_c = new RegionNode(req_c + 1);
260 Node *phi_c = con1;
261 uint len = r->req();
262 Node *region_x = new RegionNode(len - req_c);
263 Node *phi_x = PhiNode::make_blank(region_x, phi);
264 for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) {
265 if (phi->in(i) == con1) {
266 region_c->init_req( i_c++, r ->in(i) );
267 if (r->in(i) == predicate_proj)
268 predicate_c = predicate_proj;
269 } else {
270 region_x->init_req( i_x, r ->in(i) );
271 phi_x ->init_req( i_x++, phi->in(i) );
272 if (r->in(i) == predicate_proj)
273 predicate_x = predicate_proj;
|