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

src/share/vm/opto/loopTransform.cpp

Print this page
rev 9106 : 8137168: Replace IfNode with a new RangeCheckNode for range checks
Summary: new RangeCheckNode to enable optimization of explicit library level range checks
Reviewed-by:


 273 // Return TRUE or FALSE if the loop should be peeled or not.  Peel if we can
 274 // make some loop-invariant test (usually a null-check) happen before the loop.
 275 bool IdealLoopTree::policy_peeling( PhaseIdealLoop *phase ) const {
 276   Node *test = ((IdealLoopTree*)this)->tail();
 277   int  body_size = ((IdealLoopTree*)this)->_body.size();
 278   // Peeling does loop cloning which can result in O(N^2) node construction
 279   if( body_size > 255 /* Prevent overflow for large body_size */
 280       || (body_size * body_size + phase->C->live_nodes()) > phase->C->max_node_limit() ) {
 281     return false;           // too large to safely clone
 282   }
 283 
 284   // check for vectorized loops, any peeling done was already applied
 285   if (_head->is_CountedLoop() && _head->as_CountedLoop()->do_unroll_only()) return false;
 286 
 287   while( test != _head ) {      // Scan till run off top of loop
 288     if( test->is_If() ) {       // Test?
 289       Node *ctrl = phase->get_ctrl(test->in(1));
 290       if (ctrl->is_top())
 291         return false;           // Found dead test on live IF?  No peeling!
 292       // Standard IF only has one input value to check for loop invariance
 293       assert( test->Opcode() == Op_If || test->Opcode() == Op_CountedLoopEnd, "Check this code when new subtype is added");
 294       // Condition is not a member of this loop?
 295       if( !is_member(phase->get_loop(ctrl)) &&
 296           is_loop_exit(test) )
 297         return true;            // Found reason to peel!
 298     }
 299     // Walk up dominators to loop _head looking for test which is
 300     // executed on every path thru loop.
 301     test = phase->idom(test);
 302   }
 303   return false;
 304 }
 305 
 306 //------------------------------peeled_dom_test_elim---------------------------
 307 // If we got the effect of peeling, either by actually peeling or by making
 308 // a pre-loop which must execute at least once, we can remove all
 309 // loop-invariant dominated tests in the main body.
 310 void PhaseIdealLoop::peeled_dom_test_elim( IdealLoopTree *loop, Node_List &old_new ) {
 311   bool progress = true;
 312   while( progress ) {
 313     progress = false;           // Reset for next iteration


 835 //------------------------------policy_range_check-----------------------------
 836 // Return TRUE or FALSE if the loop should be range-check-eliminated.
 837 // Actually we do iteration-splitting, a more powerful form of RCE.
 838 bool IdealLoopTree::policy_range_check( PhaseIdealLoop *phase ) const {
 839   if (!RangeCheckElimination) return false;
 840 
 841   CountedLoopNode *cl = _head->as_CountedLoop();
 842   // If we unrolled with no intention of doing RCE and we later
 843   // changed our minds, we got no pre-loop.  Either we need to
 844   // make a new pre-loop, or we gotta disallow RCE.
 845   if (cl->is_main_no_pre_loop()) return false; // Disallowed for now.
 846   Node *trip_counter = cl->phi();
 847 
 848   // check for vectorized loops, some opts are no longer needed
 849   if (cl->do_unroll_only()) return false;
 850 
 851   // Check loop body for tests of trip-counter plus loop-invariant vs
 852   // loop-invariant.
 853   for (uint i = 0; i < _body.size(); i++) {
 854     Node *iff = _body[i];
 855     if (iff->Opcode() == Op_If) { // Test?

 856 
 857       // Comparing trip+off vs limit
 858       Node *bol = iff->in(1);
 859       if (bol->req() != 2) continue; // dead constant test
 860       if (!bol->is_Bool()) {
 861         assert(UseLoopPredicate && bol->Opcode() == Op_Conv2B, "predicate check only");
 862         continue;
 863       }
 864       if (bol->as_Bool()->_test._test == BoolTest::ne)
 865         continue; // not RC
 866 
 867       Node *cmp = bol->in(1);
 868       Node *rc_exp = cmp->in(1);
 869       Node *limit = cmp->in(2);
 870 
 871       Node *limit_c = phase->get_ctrl(limit);
 872       if( limit_c == phase->C->top() )
 873         return false;           // Found dead test on live IF?  No RCE!
 874       if( is_member(phase->get_loop(limit_c) ) ) {
 875         // Compare might have operands swapped; commute them


2014   Node *zero = _igvn.intcon(0);
2015   Node *one  = _igvn.intcon(1);
2016   // Use symmetrical int range [-max_jint,max_jint]
2017   Node *mini = _igvn.intcon(-max_jint);
2018   set_ctrl(zero, C->root());
2019   set_ctrl(one,  C->root());
2020   set_ctrl(mini, C->root());
2021 
2022   // Range checks that do not dominate the loop backedge (ie.
2023   // conditionally executed) can lengthen the pre loop limit beyond
2024   // the original loop limit. To prevent this, the pre limit is
2025   // (for stride > 0) MINed with the original loop limit (MAXed
2026   // stride < 0) when some range_check (rc) is conditionally
2027   // executed.
2028   bool conditional_rc = false;
2029 
2030   // Check loop body for tests of trip-counter plus loop-invariant vs
2031   // loop-invariant.
2032   for( uint i = 0; i < loop->_body.size(); i++ ) {
2033     Node *iff = loop->_body[i];
2034     if( iff->Opcode() == Op_If ) { // Test?

2035 
2036       // Test is an IfNode, has 2 projections.  If BOTH are in the loop
2037       // we need loop unswitching instead of iteration splitting.
2038       Node *exit = loop->is_loop_exit(iff);
2039       if( !exit ) continue;
2040       int flip = (exit->Opcode() == Op_IfTrue) ? 1 : 0;
2041 
2042       // Get boolean condition to test
2043       Node *i1 = iff->in(1);
2044       if( !i1->is_Bool() ) continue;
2045       BoolNode *bol = i1->as_Bool();
2046       BoolTest b_test = bol->_test;
2047       // Flip sense of test if exit condition is flipped
2048       if( flip )
2049         b_test = b_test.negate();
2050 
2051       // Get compare
2052       Node *cmp = bol->in(1);
2053 
2054       // Look for trip_counter + offset vs limit




 273 // Return TRUE or FALSE if the loop should be peeled or not.  Peel if we can
 274 // make some loop-invariant test (usually a null-check) happen before the loop.
 275 bool IdealLoopTree::policy_peeling( PhaseIdealLoop *phase ) const {
 276   Node *test = ((IdealLoopTree*)this)->tail();
 277   int  body_size = ((IdealLoopTree*)this)->_body.size();
 278   // Peeling does loop cloning which can result in O(N^2) node construction
 279   if( body_size > 255 /* Prevent overflow for large body_size */
 280       || (body_size * body_size + phase->C->live_nodes()) > phase->C->max_node_limit() ) {
 281     return false;           // too large to safely clone
 282   }
 283 
 284   // check for vectorized loops, any peeling done was already applied
 285   if (_head->is_CountedLoop() && _head->as_CountedLoop()->do_unroll_only()) return false;
 286 
 287   while( test != _head ) {      // Scan till run off top of loop
 288     if( test->is_If() ) {       // Test?
 289       Node *ctrl = phase->get_ctrl(test->in(1));
 290       if (ctrl->is_top())
 291         return false;           // Found dead test on live IF?  No peeling!
 292       // Standard IF only has one input value to check for loop invariance
 293       assert(test->Opcode() == Op_If || test->Opcode() == Op_CountedLoopEnd || test->Opcode() == Op_RangeCheck, "Check this code when new subtype is added");
 294       // Condition is not a member of this loop?
 295       if( !is_member(phase->get_loop(ctrl)) &&
 296           is_loop_exit(test) )
 297         return true;            // Found reason to peel!
 298     }
 299     // Walk up dominators to loop _head looking for test which is
 300     // executed on every path thru loop.
 301     test = phase->idom(test);
 302   }
 303   return false;
 304 }
 305 
 306 //------------------------------peeled_dom_test_elim---------------------------
 307 // If we got the effect of peeling, either by actually peeling or by making
 308 // a pre-loop which must execute at least once, we can remove all
 309 // loop-invariant dominated tests in the main body.
 310 void PhaseIdealLoop::peeled_dom_test_elim( IdealLoopTree *loop, Node_List &old_new ) {
 311   bool progress = true;
 312   while( progress ) {
 313     progress = false;           // Reset for next iteration


 835 //------------------------------policy_range_check-----------------------------
 836 // Return TRUE or FALSE if the loop should be range-check-eliminated.
 837 // Actually we do iteration-splitting, a more powerful form of RCE.
 838 bool IdealLoopTree::policy_range_check( PhaseIdealLoop *phase ) const {
 839   if (!RangeCheckElimination) return false;
 840 
 841   CountedLoopNode *cl = _head->as_CountedLoop();
 842   // If we unrolled with no intention of doing RCE and we later
 843   // changed our minds, we got no pre-loop.  Either we need to
 844   // make a new pre-loop, or we gotta disallow RCE.
 845   if (cl->is_main_no_pre_loop()) return false; // Disallowed for now.
 846   Node *trip_counter = cl->phi();
 847 
 848   // check for vectorized loops, some opts are no longer needed
 849   if (cl->do_unroll_only()) return false;
 850 
 851   // Check loop body for tests of trip-counter plus loop-invariant vs
 852   // loop-invariant.
 853   for (uint i = 0; i < _body.size(); i++) {
 854     Node *iff = _body[i];
 855     if (iff->Opcode() == Op_If ||
 856         iff->Opcode() == Op_RangeCheck) { // Test?
 857 
 858       // Comparing trip+off vs limit
 859       Node *bol = iff->in(1);
 860       if (bol->req() != 2) continue; // dead constant test
 861       if (!bol->is_Bool()) {
 862         assert(UseLoopPredicate && bol->Opcode() == Op_Conv2B, "predicate check only");
 863         continue;
 864       }
 865       if (bol->as_Bool()->_test._test == BoolTest::ne)
 866         continue; // not RC
 867 
 868       Node *cmp = bol->in(1);
 869       Node *rc_exp = cmp->in(1);
 870       Node *limit = cmp->in(2);
 871 
 872       Node *limit_c = phase->get_ctrl(limit);
 873       if( limit_c == phase->C->top() )
 874         return false;           // Found dead test on live IF?  No RCE!
 875       if( is_member(phase->get_loop(limit_c) ) ) {
 876         // Compare might have operands swapped; commute them


2015   Node *zero = _igvn.intcon(0);
2016   Node *one  = _igvn.intcon(1);
2017   // Use symmetrical int range [-max_jint,max_jint]
2018   Node *mini = _igvn.intcon(-max_jint);
2019   set_ctrl(zero, C->root());
2020   set_ctrl(one,  C->root());
2021   set_ctrl(mini, C->root());
2022 
2023   // Range checks that do not dominate the loop backedge (ie.
2024   // conditionally executed) can lengthen the pre loop limit beyond
2025   // the original loop limit. To prevent this, the pre limit is
2026   // (for stride > 0) MINed with the original loop limit (MAXed
2027   // stride < 0) when some range_check (rc) is conditionally
2028   // executed.
2029   bool conditional_rc = false;
2030 
2031   // Check loop body for tests of trip-counter plus loop-invariant vs
2032   // loop-invariant.
2033   for( uint i = 0; i < loop->_body.size(); i++ ) {
2034     Node *iff = loop->_body[i];
2035     if (iff->Opcode() == Op_If ||
2036         iff->Opcode() == Op_RangeCheck) { // Test?
2037 
2038       // Test is an IfNode, has 2 projections.  If BOTH are in the loop
2039       // we need loop unswitching instead of iteration splitting.
2040       Node *exit = loop->is_loop_exit(iff);
2041       if( !exit ) continue;
2042       int flip = (exit->Opcode() == Op_IfTrue) ? 1 : 0;
2043 
2044       // Get boolean condition to test
2045       Node *i1 = iff->in(1);
2046       if( !i1->is_Bool() ) continue;
2047       BoolNode *bol = i1->as_Bool();
2048       BoolTest b_test = bol->_test;
2049       // Flip sense of test if exit condition is flipped
2050       if( flip )
2051         b_test = b_test.negate();
2052 
2053       // Get compare
2054       Node *cmp = bol->in(1);
2055 
2056       // Look for trip_counter + offset vs limit


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