< prev index next >

src/share/vm/opto/split_if.cpp

Print this page




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "memory/allocation.inline.hpp"
  27 #include "opto/callnode.hpp"
  28 #include "opto/loopnode.hpp"
  29 #include "opto/movenode.hpp"
  30 
  31 
  32 //------------------------------split_thru_region------------------------------
  33 // Split Node 'n' through merge point.
  34 Node *PhaseIdealLoop::split_thru_region( Node *n, Node *region ) {

  35   uint wins = 0;
  36   assert( n->is_CFG(), "" );
  37   assert( region->is_Region(), "" );
  38   Node *r = new RegionNode( region->req() );
  39   IdealLoopTree *loop = get_loop( n );
  40   for( uint i = 1; i < region->req(); i++ ) {
  41     Node *x = n->clone();
  42     Node *in0 = n->in(0);
  43     if( in0->in(0) == region ) x->set_req( 0, in0->in(i) );
  44     for( uint j = 1; j < n->req(); j++ ) {
  45       Node *in = n->in(j);
  46       if( get_ctrl(in) == region )
  47         x->set_req( j, in->in(i) );
  48     }
  49     _igvn.register_new_node_with_optimizer(x);
  50     set_loop(x, loop);
  51     set_idom(x, x->in(0), dom_depth(x->in(0))+1);
  52     r->init_req(i, x);
  53   }
  54 


  56   r->set_req(0,region);         // Not a TRUE RegionNode
  57   _igvn.register_new_node_with_optimizer(r);
  58   set_loop(r, loop);
  59   if( !loop->_child )
  60     loop->_body.push(r);
  61   return r;
  62 }
  63 
  64 //------------------------------split_up---------------------------------------
  65 // Split block-local op up through the phis to empty the current block
  66 bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) {
  67   if( n->is_CFG() ) {
  68     assert( n->in(0) != blk1, "Lousy candidate for split-if" );
  69     return false;
  70   }
  71   if( get_ctrl(n) != blk1 && get_ctrl(n) != blk2 )
  72     return false;               // Not block local
  73   if( n->is_Phi() ) return false; // Local PHIs are expected
  74 
  75   // Recursively split-up inputs
  76   for (uint i = 1; i < n->req(); i++) {

  77     if( split_up( n->in(i), blk1, blk2 ) ) {
  78       // Got split recursively and self went dead?
  79       if (n->outcnt() == 0)
  80         _igvn.remove_dead_node(n);
  81       return true;
  82     }
  83   }
  84 
  85   // Check for needing to clone-up a compare.  Can't do that, it forces
  86   // another (nested) split-if transform.  Instead, clone it "down".
  87   if( n->is_Cmp() ) {
  88     assert(get_ctrl(n) == blk2 || get_ctrl(n) == blk1, "must be in block with IF");
  89     // Check for simple Cmp/Bool/CMove which we can clone-up.  Cmp/Bool/CMove
  90     // sequence can have no other users and it must all reside in the split-if
  91     // block.  Non-simple Cmp/Bool/CMove sequences are 'cloned-down' below -
  92     // private, per-use versions of the Cmp and Bool are made.  These sink to
  93     // the CMove block.  If the CMove is in the split-if block, then in the
  94     // next iteration this will become a simple Cmp/Bool/CMove set to clone-up.
  95     Node *bol, *cmov;
  96     if( !(n->outcnt() == 1 && n->unique_out()->is_Bool() &&


 199   for( uint j = 1; j < blk1->req(); j++ ) {
 200     Node *x = n->clone();
 201     // Widen the type of the ConvI2L when pushing up.
 202     if (rtype != NULL) x->as_Type()->set_type(rtype);
 203     if( n->in(0) && n->in(0) == blk1 )
 204       x->set_req( 0, blk1->in(j) );
 205     for( uint i = 1; i < n->req(); i++ ) {
 206       Node *m = n->in(i);
 207       if( get_ctrl(m) == blk1 ) {
 208         assert( m->in(0) == blk1, "" );
 209         x->set_req( i, m->in(j) );
 210       }
 211     }
 212     register_new_node( x, blk1->in(j) );
 213     phi->init_req( j, x );
 214   }
 215   // Announce phi to optimizer
 216   register_new_node(phi, blk1);
 217 
 218   // Remove cloned-up value from optimizer; use phi instead

 219   _igvn.replace_node( n, phi );
 220 
 221   // (There used to be a self-recursive call to split_up() here,
 222   // but it is not needed.  All necessary forward walking is done
 223   // by do_split_if() below.)
 224 
 225   return true;
 226 }
 227 
 228 //------------------------------register_new_node------------------------------
 229 void PhaseIdealLoop::register_new_node( Node *n, Node *blk ) {
 230   assert(!n->is_CFG(), "must be data node");
 231   _igvn.register_new_node_with_optimizer(n);
 232   set_ctrl(n, blk);
 233   IdealLoopTree *loop = get_loop(blk);
 234   if( !loop->_child )
 235     loop->_body.push(n);
 236 }
 237 
 238 //------------------------------small_cache------------------------------------




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "memory/allocation.inline.hpp"
  27 #include "opto/callnode.hpp"
  28 #include "opto/loopnode.hpp"
  29 #include "opto/movenode.hpp"
  30 
  31 
  32 //------------------------------split_thru_region------------------------------
  33 // Split Node 'n' through merge point.
  34 Node *PhaseIdealLoop::split_thru_region( Node *n, Node *region ) {
  35   assert(n->Opcode() != Op_ShenandoahWriteBarrier, "not with write barriers");
  36   uint wins = 0;
  37   assert( n->is_CFG(), "" );
  38   assert( region->is_Region(), "" );
  39   Node *r = new RegionNode( region->req() );
  40   IdealLoopTree *loop = get_loop( n );
  41   for( uint i = 1; i < region->req(); i++ ) {
  42     Node *x = n->clone();
  43     Node *in0 = n->in(0);
  44     if( in0->in(0) == region ) x->set_req( 0, in0->in(i) );
  45     for( uint j = 1; j < n->req(); j++ ) {
  46       Node *in = n->in(j);
  47       if( get_ctrl(in) == region )
  48         x->set_req( j, in->in(i) );
  49     }
  50     _igvn.register_new_node_with_optimizer(x);
  51     set_loop(x, loop);
  52     set_idom(x, x->in(0), dom_depth(x->in(0))+1);
  53     r->init_req(i, x);
  54   }
  55 


  57   r->set_req(0,region);         // Not a TRUE RegionNode
  58   _igvn.register_new_node_with_optimizer(r);
  59   set_loop(r, loop);
  60   if( !loop->_child )
  61     loop->_body.push(r);
  62   return r;
  63 }
  64 
  65 //------------------------------split_up---------------------------------------
  66 // Split block-local op up through the phis to empty the current block
  67 bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) {
  68   if( n->is_CFG() ) {
  69     assert( n->in(0) != blk1, "Lousy candidate for split-if" );
  70     return false;
  71   }
  72   if( get_ctrl(n) != blk1 && get_ctrl(n) != blk2 )
  73     return false;               // Not block local
  74   if( n->is_Phi() ) return false; // Local PHIs are expected
  75 
  76   // Recursively split-up inputs
  77   uint first_input = n->Opcode() == Op_ShenandoahWBMemProj ? 0 : 1;
  78   for (uint i = first_input; i < n->req(); i++) {
  79     if( split_up( n->in(i), blk1, blk2 ) ) {
  80       // Got split recursively and self went dead?
  81       if (n->outcnt() == 0)
  82         _igvn.remove_dead_node(n);
  83       return true;
  84     }
  85   }
  86 
  87   // Check for needing to clone-up a compare.  Can't do that, it forces
  88   // another (nested) split-if transform.  Instead, clone it "down".
  89   if( n->is_Cmp() ) {
  90     assert(get_ctrl(n) == blk2 || get_ctrl(n) == blk1, "must be in block with IF");
  91     // Check for simple Cmp/Bool/CMove which we can clone-up.  Cmp/Bool/CMove
  92     // sequence can have no other users and it must all reside in the split-if
  93     // block.  Non-simple Cmp/Bool/CMove sequences are 'cloned-down' below -
  94     // private, per-use versions of the Cmp and Bool are made.  These sink to
  95     // the CMove block.  If the CMove is in the split-if block, then in the
  96     // next iteration this will become a simple Cmp/Bool/CMove set to clone-up.
  97     Node *bol, *cmov;
  98     if( !(n->outcnt() == 1 && n->unique_out()->is_Bool() &&


 201   for( uint j = 1; j < blk1->req(); j++ ) {
 202     Node *x = n->clone();
 203     // Widen the type of the ConvI2L when pushing up.
 204     if (rtype != NULL) x->as_Type()->set_type(rtype);
 205     if( n->in(0) && n->in(0) == blk1 )
 206       x->set_req( 0, blk1->in(j) );
 207     for( uint i = 1; i < n->req(); i++ ) {
 208       Node *m = n->in(i);
 209       if( get_ctrl(m) == blk1 ) {
 210         assert( m->in(0) == blk1, "" );
 211         x->set_req( i, m->in(j) );
 212       }
 213     }
 214     register_new_node( x, blk1->in(j) );
 215     phi->init_req( j, x );
 216   }
 217   // Announce phi to optimizer
 218   register_new_node(phi, blk1);
 219 
 220   // Remove cloned-up value from optimizer; use phi instead
 221   split_mem_thru_phi(n, blk1, phi);
 222   _igvn.replace_node( n, phi );
 223 
 224   // (There used to be a self-recursive call to split_up() here,
 225   // but it is not needed.  All necessary forward walking is done
 226   // by do_split_if() below.)
 227 
 228   return true;
 229 }
 230 
 231 //------------------------------register_new_node------------------------------
 232 void PhaseIdealLoop::register_new_node( Node *n, Node *blk ) {
 233   assert(!n->is_CFG(), "must be data node");
 234   _igvn.register_new_node_with_optimizer(n);
 235   set_ctrl(n, blk);
 236   IdealLoopTree *loop = get_loop(blk);
 237   if( !loop->_child )
 238     loop->_body.push(n);
 239 }
 240 
 241 //------------------------------small_cache------------------------------------


< prev index next >