hotspot/src/share/vm/opto/loopnode.cpp
changeset 2154 72a9b7284ccf
parent 2105 347008ce7984
parent 2131 98f9cef66a34
child 2348 4e71ed4c2709
equal deleted inserted replaced
2106:ec595a5e793e 2154:72a9b7284ccf
   272   // =================================================
   272   // =================================================
   273   // ---- SUCCESS!   Found A Trip-Counted Loop!  -----
   273   // ---- SUCCESS!   Found A Trip-Counted Loop!  -----
   274   //
   274   //
   275   // Canonicalize the condition on the test.  If we can exactly determine
   275   // Canonicalize the condition on the test.  If we can exactly determine
   276   // the trip-counter exit value, then set limit to that value and use
   276   // the trip-counter exit value, then set limit to that value and use
   277   // a '!=' test.  Otherwise use conditon '<' for count-up loops and
   277   // a '!=' test.  Otherwise use condition '<' for count-up loops and
   278   // '>' for count-down loops.  If the condition is inverted and we will
   278   // '>' for count-down loops.  If the condition is inverted and we will
   279   // be rolling through MININT to MAXINT, then bail out.
   279   // be rolling through MININT to MAXINT, then bail out.
   280 
   280 
   281   C->print_method("Before CountedLoop", 3);
   281   C->print_method("Before CountedLoop", 3);
   282 
   282 
   288   }
   288   }
   289 
   289 
   290 
   290 
   291   // If compare points to incr, we are ok.  Otherwise the compare
   291   // If compare points to incr, we are ok.  Otherwise the compare
   292   // can directly point to the phi; in this case adjust the compare so that
   292   // can directly point to the phi; in this case adjust the compare so that
   293   // it points to the incr by adusting the limit.
   293   // it points to the incr by adjusting the limit.
   294   if( cmp->in(1) == phi || cmp->in(2) == phi )
   294   if( cmp->in(1) == phi || cmp->in(2) == phi )
   295     limit = gvn->transform(new (C, 3) AddINode(limit,stride));
   295     limit = gvn->transform(new (C, 3) AddINode(limit,stride));
   296 
   296 
   297   // trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride.
   297   // trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride.
   298   // Final value for iterator should be: trip_count * stride + init_trip.
   298   // Final value for iterator should be: trip_count * stride + init_trip.
   469   // Fix all data nodes placed at the old loop head.
   469   // Fix all data nodes placed at the old loop head.
   470   // Uses the lazy-update mechanism of 'get_ctrl'.
   470   // Uses the lazy-update mechanism of 'get_ctrl'.
   471   lazy_replace( x, l );
   471   lazy_replace( x, l );
   472   set_idom(l, init_control, dom_depth(x));
   472   set_idom(l, init_control, dom_depth(x));
   473 
   473 
   474   // Check for immediately preceeding SafePoint and remove
   474   // Check for immediately preceding SafePoint and remove
   475   Node *sfpt2 = le->in(0);
   475   Node *sfpt2 = le->in(0);
   476   if( sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2))
   476   if( sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2))
   477     lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
   477     lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
   478 
   478 
   479   // Free up intermediate goo
   479   // Free up intermediate goo
  1504     }
  1504     }
  1505   }
  1505   }
  1506 
  1506 
  1507   // Build Dominators for elision of NULL checks & loop finding.
  1507   // Build Dominators for elision of NULL checks & loop finding.
  1508   // Since nodes do not have a slot for immediate dominator, make
  1508   // Since nodes do not have a slot for immediate dominator, make
  1509   // a persistant side array for that info indexed on node->_idx.
  1509   // a persistent side array for that info indexed on node->_idx.
  1510   _idom_size = C->unique();
  1510   _idom_size = C->unique();
  1511   _idom      = NEW_RESOURCE_ARRAY( Node*, _idom_size );
  1511   _idom      = NEW_RESOURCE_ARRAY( Node*, _idom_size );
  1512   _dom_depth = NEW_RESOURCE_ARRAY( uint,  _idom_size );
  1512   _dom_depth = NEW_RESOURCE_ARRAY( uint,  _idom_size );
  1513   _dom_stk   = NULL; // Allocated on demand in recompute_dom_depth
  1513   _dom_stk   = NULL; // Allocated on demand in recompute_dom_depth
  1514   memset( _dom_depth, 0, _idom_size * sizeof(uint) );
  1514   memset( _dom_depth, 0, _idom_size * sizeof(uint) );
  1527     }
  1527     }
  1528   }
  1528   }
  1529 
  1529 
  1530   // Given dominators, try to find inner loops with calls that must
  1530   // Given dominators, try to find inner loops with calls that must
  1531   // always be executed (call dominates loop tail).  These loops do
  1531   // always be executed (call dominates loop tail).  These loops do
  1532   // not need a seperate safepoint.
  1532   // not need a separate safepoint.
  1533   Node_List cisstack(a);
  1533   Node_List cisstack(a);
  1534   _ltree_root->check_safepts(visited, cisstack);
  1534   _ltree_root->check_safepts(visited, cisstack);
  1535 
  1535 
  1536   // Walk the DATA nodes and place into loops.  Find earliest control
  1536   // Walk the DATA nodes and place into loops.  Find earliest control
  1537   // node.  For CFG nodes, the _nodes array starts out and remains
  1537   // node.  For CFG nodes, the _nodes array starts out and remains
  2330         }
  2330         }
  2331       }
  2331       }
  2332       if (done) {
  2332       if (done) {
  2333         // All of n's inputs have been processed, complete post-processing.
  2333         // All of n's inputs have been processed, complete post-processing.
  2334 
  2334 
  2335         // Compute earilest point this Node can go.
  2335         // Compute earliest point this Node can go.
  2336         // CFG, Phi, pinned nodes already know their controlling input.
  2336         // CFG, Phi, pinned nodes already know their controlling input.
  2337         if (!has_node(n)) {
  2337         if (!has_node(n)) {
  2338           // Record earliest legal location
  2338           // Record earliest legal location
  2339           set_early_ctrl( n );
  2339           set_early_ctrl( n );
  2340         }
  2340         }
  2670     case Op_StrComp:            // Does a bunch of load-like effects
  2670     case Op_StrComp:            // Does a bunch of load-like effects
  2671     case Op_AryEq:
  2671     case Op_AryEq:
  2672       pinned = false;
  2672       pinned = false;
  2673     }
  2673     }
  2674     if( pinned ) {
  2674     if( pinned ) {
  2675       IdealLoopTree *choosen_loop = get_loop(n->is_CFG() ? n : get_ctrl(n));
  2675       IdealLoopTree *chosen_loop = get_loop(n->is_CFG() ? n : get_ctrl(n));
  2676       if( !choosen_loop->_child )       // Inner loop?
  2676       if( !chosen_loop->_child )       // Inner loop?
  2677         choosen_loop->_body.push(n); // Collect inner loops
  2677         chosen_loop->_body.push(n); // Collect inner loops
  2678       return;
  2678       return;
  2679     }
  2679     }
  2680   } else {                      // No slot zero
  2680   } else {                      // No slot zero
  2681     if( n->is_CFG() ) {         // CFG with no slot 0 is dead
  2681     if( n->is_CFG() ) {         // CFG with no slot 0 is dead
  2682       _nodes.map(n->_idx,0);    // No block setting, it's globally dead
  2682       _nodes.map(n->_idx,0);    // No block setting, it's globally dead
  2744   // Assign discovered "here or above" point
  2744   // Assign discovered "here or above" point
  2745   least = find_non_split_ctrl(least);
  2745   least = find_non_split_ctrl(least);
  2746   set_ctrl(n, least);
  2746   set_ctrl(n, least);
  2747 
  2747 
  2748   // Collect inner loop bodies
  2748   // Collect inner loop bodies
  2749   IdealLoopTree *choosen_loop = get_loop(least);
  2749   IdealLoopTree *chosen_loop = get_loop(least);
  2750   if( !choosen_loop->_child )   // Inner loop?
  2750   if( !chosen_loop->_child )   // Inner loop?
  2751     choosen_loop->_body.push(n);// Collect inner loops
  2751     chosen_loop->_body.push(n);// Collect inner loops
  2752 }
  2752 }
  2753 
  2753 
  2754 #ifndef PRODUCT
  2754 #ifndef PRODUCT
  2755 //------------------------------dump-------------------------------------------
  2755 //------------------------------dump-------------------------------------------
  2756 void PhaseIdealLoop::dump( ) const {
  2756 void PhaseIdealLoop::dump( ) const {