src/share/vm/opto/ifnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/ifnode.cpp

Print this page
rev 8172 : 8078426: mb/jvm/compiler/InterfaceCalls/testAC2 - assert(predicate_proj == 0L) failed: only one predicate entry expected
Summary: split if finds predicates on several incoming paths when unswitched's loops are optimized out
Reviewed-by:


 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;


src/share/vm/opto/ifnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File