hotspot/src/share/vm/opto/loopopts.cpp
changeset 8732 16fc1c68714b
parent 7397 5b173b4ca846
child 9101 ff58f9a8e31c
child 8921 14bfe81f2a9d
equal deleted inserted replaced
8731:0dccf5d963cc 8732:16fc1c68714b
    40     // ConvI2L may have type information on it which is unsafe to push up
    40     // ConvI2L may have type information on it which is unsafe to push up
    41     // so disable this for now
    41     // so disable this for now
    42     return NULL;
    42     return NULL;
    43   }
    43   }
    44   int wins = 0;
    44   int wins = 0;
    45   assert( !n->is_CFG(), "" );
    45   assert(!n->is_CFG(), "");
    46   assert( region->is_Region(), "" );
    46   assert(region->is_Region(), "");
    47 
    47 
    48   const Type* type = n->bottom_type();
    48   const Type* type = n->bottom_type();
    49   const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
    49   const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
    50   Node *phi;
    50   Node *phi;
    51   if( t_oop != NULL && t_oop->is_known_instance_field() ) {
    51   if (t_oop != NULL && t_oop->is_known_instance_field()) {
    52     int iid    = t_oop->instance_id();
    52     int iid    = t_oop->instance_id();
    53     int index  = C->get_alias_index(t_oop);
    53     int index  = C->get_alias_index(t_oop);
    54     int offset = t_oop->offset();
    54     int offset = t_oop->offset();
    55     phi = new (C,region->req()) PhiNode(region, type, NULL, iid, index, offset);
    55     phi = new (C,region->req()) PhiNode(region, type, NULL, iid, index, offset);
    56   } else {
    56   } else {
    57     phi = PhiNode::make_blank(region, n);
    57     phi = PhiNode::make_blank(region, n);
    58   }
    58   }
    59   uint old_unique = C->unique();
    59   uint old_unique = C->unique();
    60   for( uint i = 1; i < region->req(); i++ ) {
    60   for (uint i = 1; i < region->req(); i++) {
    61     Node *x;
    61     Node *x;
    62     Node* the_clone = NULL;
    62     Node* the_clone = NULL;
    63     if( region->in(i) == C->top() ) {
    63     if (region->in(i) == C->top()) {
    64       x = C->top();             // Dead path?  Use a dead data op
    64       x = C->top();             // Dead path?  Use a dead data op
    65     } else {
    65     } else {
    66       x = n->clone();           // Else clone up the data op
    66       x = n->clone();           // Else clone up the data op
    67       the_clone = x;            // Remember for possible deletion.
    67       the_clone = x;            // Remember for possible deletion.
    68       // Alter data node to use pre-phi inputs
    68       // Alter data node to use pre-phi inputs
    69       if( n->in(0) == region )
    69       if (n->in(0) == region)
    70         x->set_req( 0, region->in(i) );
    70         x->set_req( 0, region->in(i) );
    71       for( uint j = 1; j < n->req(); j++ ) {
    71       for (uint j = 1; j < n->req(); j++) {
    72         Node *in = n->in(j);
    72         Node *in = n->in(j);
    73         if( in->is_Phi() && in->in(0) == region )
    73         if (in->is_Phi() && in->in(0) == region)
    74           x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
    74           x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
    75       }
    75       }
    76     }
    76     }
    77     // Check for a 'win' on some paths
    77     // Check for a 'win' on some paths
    78     const Type *t = x->Value(&_igvn);
    78     const Type *t = x->Value(&_igvn);
    83     // along a particular edge. In most cases, this is OK, and the Phi will
    83     // along a particular edge. In most cases, this is OK, and the Phi will
    84     // be eliminated later in an Ideal call. However, we can't allow this to
    84     // be eliminated later in an Ideal call. However, we can't allow this to
    85     // happen if the singleton occurs on loop entry, as the elimination of
    85     // happen if the singleton occurs on loop entry, as the elimination of
    86     // the PhiNode may cause the resulting node to migrate back to a previous
    86     // the PhiNode may cause the resulting node to migrate back to a previous
    87     // loop iteration.
    87     // loop iteration.
    88     if( singleton && t == Type::TOP ) {
    88     if (singleton && t == Type::TOP) {
    89       // Is_Loop() == false does not confirm the absence of a loop (e.g., an
    89       // Is_Loop() == false does not confirm the absence of a loop (e.g., an
    90       // irreducible loop may not be indicated by an affirmative is_Loop());
    90       // irreducible loop may not be indicated by an affirmative is_Loop());
    91       // therefore, the only top we can split thru a phi is on a backedge of
    91       // therefore, the only top we can split thru a phi is on a backedge of
    92       // a loop.
    92       // a loop.
    93       singleton &= region->is_Loop() && (i != LoopNode::EntryControl);
    93       singleton &= region->is_Loop() && (i != LoopNode::EntryControl);
    94     }
    94     }
    95 
    95 
    96     if( singleton ) {
    96     if (singleton) {
    97       wins++;
    97       wins++;
    98       x = ((PhaseGVN&)_igvn).makecon(t);
    98       x = ((PhaseGVN&)_igvn).makecon(t);
    99     } else {
    99     } else {
   100       // We now call Identity to try to simplify the cloned node.
   100       // We now call Identity to try to simplify the cloned node.
   101       // Note that some Identity methods call phase->type(this).
   101       // Note that some Identity methods call phase->type(this).
   106       // If x is a TypeNode, capture any more-precise type permanently into Node
   106       // If x is a TypeNode, capture any more-precise type permanently into Node
   107       // otherwise it will be not updated during igvn->transform since
   107       // otherwise it will be not updated during igvn->transform since
   108       // igvn->type(x) is set to x->Value() already.
   108       // igvn->type(x) is set to x->Value() already.
   109       x->raise_bottom_type(t);
   109       x->raise_bottom_type(t);
   110       Node *y = x->Identity(&_igvn);
   110       Node *y = x->Identity(&_igvn);
   111       if( y != x ) {
   111       if (y != x) {
   112         wins++;
   112         wins++;
   113         x = y;
   113         x = y;
   114       } else {
   114       } else {
   115         y = _igvn.hash_find(x);
   115         y = _igvn.hash_find(x);
   116         if( y ) {
   116         if (y) {
   117           wins++;
   117           wins++;
   118           x = y;
   118           x = y;
   119         } else {
   119         } else {
   120           // Else x is a new node we are keeping
   120           // Else x is a new node we are keeping
   121           // We do not need register_new_node_with_optimizer
   121           // We do not need register_new_node_with_optimizer
   127     if (x != the_clone && the_clone != NULL)
   127     if (x != the_clone && the_clone != NULL)
   128       _igvn.remove_dead_node(the_clone);
   128       _igvn.remove_dead_node(the_clone);
   129     phi->set_req( i, x );
   129     phi->set_req( i, x );
   130   }
   130   }
   131   // Too few wins?
   131   // Too few wins?
   132   if( wins <= policy ) {
   132   if (wins <= policy) {
   133     _igvn.remove_dead_node(phi);
   133     _igvn.remove_dead_node(phi);
   134     return NULL;
   134     return NULL;
   135   }
   135   }
   136 
   136 
   137   // Record Phi
   137   // Record Phi
   138   register_new_node( phi, region );
   138   register_new_node( phi, region );
   139 
   139 
   140   for( uint i2 = 1; i2 < phi->req(); i2++ ) {
   140   for (uint i2 = 1; i2 < phi->req(); i2++) {
   141     Node *x = phi->in(i2);
   141     Node *x = phi->in(i2);
   142     // If we commoned up the cloned 'x' with another existing Node,
   142     // If we commoned up the cloned 'x' with another existing Node,
   143     // the existing Node picks up a new use.  We need to make the
   143     // the existing Node picks up a new use.  We need to make the
   144     // existing Node occur higher up so it dominates its uses.
   144     // existing Node occur higher up so it dominates its uses.
   145     Node *old_ctrl;
   145     Node *old_ctrl;
   146     IdealLoopTree *old_loop;
   146     IdealLoopTree *old_loop;
   147 
   147 
       
   148     if (x->is_Con()) {
       
   149       // Constant's control is always root.
       
   150       set_ctrl(x, C->root());
       
   151       continue;
       
   152     }
   148     // The occasional new node
   153     // The occasional new node
   149     if( x->_idx >= old_unique ) {   // Found a new, unplaced node?
   154     if (x->_idx >= old_unique) {     // Found a new, unplaced node?
   150       old_ctrl = x->is_Con() ? C->root() : NULL;
   155       old_ctrl = NULL;
   151       old_loop = NULL;              // Not in any prior loop
   156       old_loop = NULL;               // Not in any prior loop
   152     } else {
   157     } else {
   153       old_ctrl = x->is_Con() ? C->root() : get_ctrl(x);
   158       old_ctrl = get_ctrl(x);
   154       old_loop = get_loop(old_ctrl); // Get prior loop
   159       old_loop = get_loop(old_ctrl); // Get prior loop
   155     }
   160     }
   156     // New late point must dominate new use
   161     // New late point must dominate new use
   157     Node *new_ctrl = dom_lca( old_ctrl, region->in(i2) );
   162     Node *new_ctrl = dom_lca(old_ctrl, region->in(i2));
       
   163     if (new_ctrl == old_ctrl) // Nothing is changed
       
   164       continue;
       
   165 
       
   166     IdealLoopTree *new_loop = get_loop(new_ctrl);
       
   167 
       
   168     // Don't move x into a loop if its uses are
       
   169     // outside of loop. Otherwise x will be cloned
       
   170     // for each use outside of this loop.
       
   171     IdealLoopTree *use_loop = get_loop(region);
       
   172     if (!new_loop->is_member(use_loop) &&
       
   173         (old_loop == NULL || !new_loop->is_member(old_loop))) {
       
   174       // Take early control, later control will be recalculated
       
   175       // during next iteration of loop optimizations.
       
   176       new_ctrl = get_early_ctrl(x);
       
   177       new_loop = get_loop(new_ctrl);
       
   178     }
   158     // Set new location
   179     // Set new location
   159     set_ctrl(x, new_ctrl);
   180     set_ctrl(x, new_ctrl);
   160     IdealLoopTree *new_loop = get_loop( new_ctrl );
       
   161     // If changing loop bodies, see if we need to collect into new body
   181     // If changing loop bodies, see if we need to collect into new body
   162     if( old_loop != new_loop ) {
   182     if (old_loop != new_loop) {
   163       if( old_loop && !old_loop->_child )
   183       if (old_loop && !old_loop->_child)
   164         old_loop->_body.yank(x);
   184         old_loop->_body.yank(x);
   165       if( !new_loop->_child )
   185       if (!new_loop->_child)
   166         new_loop->_body.push(x);  // Collect body info
   186         new_loop->_body.push(x);  // Collect body info
   167     }
   187     }
   168   }
   188   }
   169 
   189 
   170   return phi;
   190   return phi;
   172 
   192 
   173 //------------------------------dominated_by------------------------------------
   193 //------------------------------dominated_by------------------------------------
   174 // Replace the dominated test with an obvious true or false.  Place it on the
   194 // Replace the dominated test with an obvious true or false.  Place it on the
   175 // IGVN worklist for later cleanup.  Move control-dependent data Nodes on the
   195 // IGVN worklist for later cleanup.  Move control-dependent data Nodes on the
   176 // live path up to the dominating control.
   196 // live path up to the dominating control.
   177 void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff ) {
   197 void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip ) {
   178 #ifndef PRODUCT
   198 #ifndef PRODUCT
   179   if( VerifyLoopOptimizations && PrintOpto ) tty->print_cr("dominating test");
   199   if (VerifyLoopOptimizations && PrintOpto) tty->print_cr("dominating test");
   180 #endif
   200 #endif
   181 
   201 
   182 
   202 
   183   // prevdom is the dominating projection of the dominating test.
   203   // prevdom is the dominating projection of the dominating test.
   184   assert( iff->is_If(), "" );
   204   assert( iff->is_If(), "" );
   185   assert( iff->Opcode() == Op_If || iff->Opcode() == Op_CountedLoopEnd, "Check this code when new subtype is added");
   205   assert( iff->Opcode() == Op_If || iff->Opcode() == Op_CountedLoopEnd, "Check this code when new subtype is added");
   186   int pop = prevdom->Opcode();
   206   int pop = prevdom->Opcode();
   187   assert( pop == Op_IfFalse || pop == Op_IfTrue, "" );
   207   assert( pop == Op_IfFalse || pop == Op_IfTrue, "" );
       
   208   if (flip) {
       
   209     if (pop == Op_IfTrue)
       
   210       pop = Op_IfFalse;
       
   211     else
       
   212       pop = Op_IfTrue;
       
   213   }
   188   // 'con' is set to true or false to kill the dominated test.
   214   // 'con' is set to true or false to kill the dominated test.
   189   Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO);
   215   Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO);
   190   set_ctrl(con, C->root()); // Constant gets a new use
   216   set_ctrl(con, C->root()); // Constant gets a new use
   191   // Hack the dominated test
   217   // Hack the dominated test
   192   _igvn.hash_delete(iff);
   218   _igvn.hash_delete(iff);
   195 
   221 
   196   // If I dont have a reachable TRUE and FALSE path following the IfNode then
   222   // If I dont have a reachable TRUE and FALSE path following the IfNode then
   197   // I can assume this path reaches an infinite loop.  In this case it's not
   223   // I can assume this path reaches an infinite loop.  In this case it's not
   198   // important to optimize the data Nodes - either the whole compilation will
   224   // important to optimize the data Nodes - either the whole compilation will
   199   // be tossed or this path (and all data Nodes) will go dead.
   225   // be tossed or this path (and all data Nodes) will go dead.
   200   if( iff->outcnt() != 2 ) return;
   226   if (iff->outcnt() != 2) return;
   201 
   227 
   202   // Make control-dependent data Nodes on the live path (path that will remain
   228   // Make control-dependent data Nodes on the live path (path that will remain
   203   // once the dominated IF is removed) become control-dependent on the
   229   // once the dominated IF is removed) become control-dependent on the
   204   // dominating projection.
   230   // dominating projection.
   205   Node* dp = ((IfNode*)iff)->proj_out(pop == Op_IfTrue);
   231   Node* dp = ((IfNode*)iff)->proj_out(pop == Op_IfTrue);
   206   IdealLoopTree *old_loop = get_loop(dp);
   232   IdealLoopTree *old_loop = get_loop(dp);
   207 
   233 
   208   for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
   234   for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
   209     Node* cd = dp->fast_out(i); // Control-dependent node
   235     Node* cd = dp->fast_out(i); // Control-dependent node
   210     if( cd->depends_only_on_test() ) {
   236     if (cd->depends_only_on_test()) {
   211       assert( cd->in(0) == dp, "" );
   237       assert(cd->in(0) == dp, "");
   212       _igvn.hash_delete( cd );
   238       _igvn.hash_delete(cd);
   213       cd->set_req(0, prevdom);
   239       cd->set_req(0, prevdom);
   214       set_early_ctrl( cd );
   240       set_early_ctrl(cd);
   215       _igvn._worklist.push(cd);
   241       _igvn._worklist.push(cd);
   216       IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
   242       IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
   217       if( old_loop != new_loop ) {
   243       if (old_loop != new_loop) {
   218         if( !old_loop->_child ) old_loop->_body.yank(cd);
   244         if (!old_loop->_child) old_loop->_body.yank(cd);
   219         if( !new_loop->_child ) new_loop->_body.push(cd);
   245         if (!new_loop->_child) new_loop->_body.push(cd);
   220       }
   246       }
   221       --i;
   247       --i;
   222       --imax;
   248       --imax;
   223     }
   249     }
   224   }
   250   }
  2336   if (first_not_peeled == NULL || first_not_peeled == head) {
  2362   if (first_not_peeled == NULL || first_not_peeled == head) {
  2337     return false;
  2363     return false;
  2338   }
  2364   }
  2339 
  2365 
  2340 #if !defined(PRODUCT)
  2366 #if !defined(PRODUCT)
       
  2367   if (TraceLoopOpts) {
       
  2368     tty->print("PartialPeel  ");
       
  2369     loop->dump_head();
       
  2370   }
       
  2371 
  2341   if (TracePartialPeeling) {
  2372   if (TracePartialPeeling) {
  2342     tty->print_cr("before partial peel one iteration");
  2373     tty->print_cr("before partial peel one iteration");
  2343     Node_List wl;
  2374     Node_List wl;
  2344     Node* t = head->in(2);
  2375     Node* t = head->in(2);
  2345     while (true) {
  2376     while (true) {
  2479   // Step 3: clone loop, retarget control, and insert new phis
  2510   // Step 3: clone loop, retarget control, and insert new phis
  2480 
  2511 
  2481   // Create new loop head for new phis and to hang
  2512   // Create new loop head for new phis and to hang
  2482   // the nodes being moved (sinked) from the peel region.
  2513   // the nodes being moved (sinked) from the peel region.
  2483   LoopNode* new_head = new (C, 3) LoopNode(last_peel, last_peel);
  2514   LoopNode* new_head = new (C, 3) LoopNode(last_peel, last_peel);
       
  2515   new_head->set_unswitch_count(head->unswitch_count()); // Preserve
  2484   _igvn.register_new_node_with_optimizer(new_head);
  2516   _igvn.register_new_node_with_optimizer(new_head);
  2485   assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled");
  2517   assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled");
  2486   first_not_peeled->set_req(0, new_head);
  2518   first_not_peeled->set_req(0, new_head);
  2487   set_loop(new_head, loop);
  2519   set_loop(new_head, loop);
  2488   loop->_body.push(new_head);
  2520   loop->_body.push(new_head);
  2649 //------------------------------reorg_offsets----------------------------------
  2681 //------------------------------reorg_offsets----------------------------------
  2650 // Reorganize offset computations to lower register pressure.  Mostly
  2682 // Reorganize offset computations to lower register pressure.  Mostly
  2651 // prevent loop-fallout uses of the pre-incremented trip counter (which are
  2683 // prevent loop-fallout uses of the pre-incremented trip counter (which are
  2652 // then alive with the post-incremented trip counter forcing an extra
  2684 // then alive with the post-incremented trip counter forcing an extra
  2653 // register move)
  2685 // register move)
  2654 void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) {
  2686 void PhaseIdealLoop::reorg_offsets(IdealLoopTree *loop) {
       
  2687   // Perform it only for canonical counted loops.
       
  2688   // Loop's shape could be messed up by iteration_split_impl.
       
  2689   if (!loop->_head->is_CountedLoop())
       
  2690     return;
       
  2691   if (!loop->_head->as_Loop()->is_valid_counted_loop())
       
  2692     return;
  2655 
  2693 
  2656   CountedLoopNode *cl = loop->_head->as_CountedLoop();
  2694   CountedLoopNode *cl = loop->_head->as_CountedLoop();
  2657   CountedLoopEndNode *cle = cl->loopexit();
  2695   CountedLoopEndNode *cle = cl->loopexit();
  2658   if( !cle ) return;            // The occasional dead loop
       
  2659   // Find loop exit control
       
  2660   Node *exit = cle->proj_out(false);
  2696   Node *exit = cle->proj_out(false);
  2661   assert( exit->Opcode() == Op_IfFalse, "" );
  2697   Node *phi = cl->phi();
  2662 
  2698 
  2663   // Check for the special case of folks using the pre-incremented
  2699   // Check for the special case of folks using the pre-incremented
  2664   // trip-counter on the fall-out path (forces the pre-incremented
  2700   // trip-counter on the fall-out path (forces the pre-incremented
  2665   // and post-incremented trip counter to be live at the same time).
  2701   // and post-incremented trip counter to be live at the same time).
  2666   // Fix this by adjusting to use the post-increment trip counter.
  2702   // Fix this by adjusting to use the post-increment trip counter.
  2667   Node *phi = cl->phi();
       
  2668   if( !phi ) return;            // Dead infinite loop
       
  2669 
       
  2670   // Shape messed up, probably by iteration_split_impl
       
  2671   if (phi->in(LoopNode::LoopBackControl) != cl->incr()) return;
       
  2672 
  2703 
  2673   bool progress = true;
  2704   bool progress = true;
  2674   while (progress) {
  2705   while (progress) {
  2675     progress = false;
  2706     progress = false;
  2676     for (DUIterator_Fast imax, i = phi->fast_outs(imax); i < imax; i++) {
  2707     for (DUIterator_Fast imax, i = phi->fast_outs(imax); i < imax; i++) {
  2677       Node* use = phi->fast_out(i);   // User of trip-counter
  2708       Node* use = phi->fast_out(i);   // User of trip-counter
  2678       if (!has_ctrl(use))  continue;
  2709       if (!has_ctrl(use))  continue;
  2679       Node *u_ctrl = get_ctrl(use);
  2710       Node *u_ctrl = get_ctrl(use);
  2680       if( use->is_Phi() ) {
  2711       if (use->is_Phi()) {
  2681         u_ctrl = NULL;
  2712         u_ctrl = NULL;
  2682         for( uint j = 1; j < use->req(); j++ )
  2713         for (uint j = 1; j < use->req(); j++)
  2683           if( use->in(j) == phi )
  2714           if (use->in(j) == phi)
  2684             u_ctrl = dom_lca( u_ctrl, use->in(0)->in(j) );
  2715             u_ctrl = dom_lca(u_ctrl, use->in(0)->in(j));
  2685       }
  2716       }
  2686       IdealLoopTree *u_loop = get_loop(u_ctrl);
  2717       IdealLoopTree *u_loop = get_loop(u_ctrl);
  2687       // Look for loop-invariant use
  2718       // Look for loop-invariant use
  2688       if( u_loop == loop ) continue;
  2719       if (u_loop == loop) continue;
  2689       if( loop->is_member( u_loop ) ) continue;
  2720       if (loop->is_member(u_loop)) continue;
  2690       // Check that use is live out the bottom.  Assuming the trip-counter
  2721       // Check that use is live out the bottom.  Assuming the trip-counter
  2691       // update is right at the bottom, uses of of the loop middle are ok.
  2722       // update is right at the bottom, uses of of the loop middle are ok.
  2692       if( dom_lca( exit, u_ctrl ) != exit ) continue;
  2723       if (dom_lca(exit, u_ctrl) != exit) continue;
  2693       // protect against stride not being a constant
       
  2694       if( !cle->stride_is_con() ) continue;
       
  2695       // Hit!  Refactor use to use the post-incremented tripcounter.
  2724       // Hit!  Refactor use to use the post-incremented tripcounter.
  2696       // Compute a post-increment tripcounter.
  2725       // Compute a post-increment tripcounter.
  2697       Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
  2726       Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
  2698       register_new_node( opaq, u_ctrl );
  2727       register_new_node( opaq, u_ctrl );
  2699       Node *neg_stride = _igvn.intcon(-cle->stride_con());
  2728       Node *neg_stride = _igvn.intcon(-cle->stride_con());
  2700       set_ctrl(neg_stride, C->root());
  2729       set_ctrl(neg_stride, C->root());
  2701       Node *post = new (C, 3) AddINode( opaq, neg_stride);
  2730       Node *post = new (C, 3) AddINode( opaq, neg_stride);
  2702       register_new_node( post, u_ctrl );
  2731       register_new_node( post, u_ctrl );
  2703       _igvn.hash_delete(use);
  2732       _igvn.hash_delete(use);
  2704       _igvn._worklist.push(use);
  2733       _igvn._worklist.push(use);
  2705       for( uint j = 1; j < use->req(); j++ )
  2734       for (uint j = 1; j < use->req(); j++) {
  2706         if( use->in(j) == phi )
  2735         if (use->in(j) == phi)
  2707           use->set_req(j, post);
  2736           use->set_req(j, post);
       
  2737       }
  2708       // Since DU info changed, rerun loop
  2738       // Since DU info changed, rerun loop
  2709       progress = true;
  2739       progress = true;
  2710       break;
  2740       break;
  2711     }
  2741     }
  2712   }
  2742   }