1132718Skan/* Natural loop analysis code for GNU compiler. 2169689Skan Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 3132718Skan 4132718SkanThis file is part of GCC. 5132718Skan 6132718SkanGCC is free software; you can redistribute it and/or modify it under 7132718Skanthe terms of the GNU General Public License as published by the Free 8132718SkanSoftware Foundation; either version 2, or (at your option) any later 9132718Skanversion. 10132718Skan 11132718SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 12132718SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 13132718SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14132718Skanfor more details. 15132718Skan 16132718SkanYou should have received a copy of the GNU General Public License 17132718Skanalong with GCC; see the file COPYING. If not, write to the Free 18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 19169689Skan02110-1301, USA. */ 20132718Skan 21132718Skan#include "config.h" 22132718Skan#include "system.h" 23132718Skan#include "coretypes.h" 24132718Skan#include "tm.h" 25132718Skan#include "rtl.h" 26132718Skan#include "hard-reg-set.h" 27169689Skan#include "obstack.h" 28132718Skan#include "basic-block.h" 29132718Skan#include "cfgloop.h" 30132718Skan#include "expr.h" 31132718Skan#include "output.h" 32132718Skan 33169689Skan/* Checks whether BB is executed exactly once in each LOOP iteration. */ 34132718Skan 35132718Skanbool 36169689Skanjust_once_each_iteration_p (const struct loop *loop, basic_block bb) 37132718Skan{ 38132718Skan /* It must be executed at least once each iteration. */ 39132718Skan if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb)) 40132718Skan return false; 41132718Skan 42132718Skan /* And just once. */ 43132718Skan if (bb->loop_father != loop) 44132718Skan return false; 45132718Skan 46132718Skan /* But this was not enough. We might have some irreducible loop here. */ 47132718Skan if (bb->flags & BB_IRREDUCIBLE_LOOP) 48132718Skan return false; 49132718Skan 50132718Skan return true; 51132718Skan} 52132718Skan 53169689Skan/* Structure representing edge of a graph. */ 54132718Skan 55169689Skanstruct edge 56132718Skan{ 57169689Skan int src, dest; /* Source and destination. */ 58169689Skan struct edge *pred_next, *succ_next; 59169689Skan /* Next edge in predecessor and successor lists. */ 60169689Skan void *data; /* Data attached to the edge. */ 61169689Skan}; 62132718Skan 63169689Skan/* Structure representing vertex of a graph. */ 64169689Skan 65169689Skanstruct vertex 66132718Skan{ 67169689Skan struct edge *pred, *succ; 68169689Skan /* Lists of predecessors and successors. */ 69169689Skan int component; /* Number of dfs restarts before reaching the 70169689Skan vertex. */ 71169689Skan int post; /* Postorder number. */ 72169689Skan}; 73132718Skan 74169689Skan/* Structure representing a graph. */ 75132718Skan 76169689Skanstruct graph 77132718Skan{ 78169689Skan int n_vertices; /* Number of vertices. */ 79169689Skan struct vertex *vertices; 80169689Skan /* The vertices. */ 81132718Skan}; 82132718Skan 83169689Skan/* Dumps graph G into F. */ 84132718Skan 85169689Skanextern void dump_graph (FILE *, struct graph *); 86132718Skan 87169689Skanvoid 88169689Skandump_graph (FILE *f, struct graph *g) 89132718Skan{ 90132718Skan int i; 91169689Skan struct edge *e; 92132718Skan 93169689Skan for (i = 0; i < g->n_vertices; i++) 94132718Skan { 95169689Skan if (!g->vertices[i].pred 96169689Skan && !g->vertices[i].succ) 97169689Skan continue; 98132718Skan 99169689Skan fprintf (f, "%d (%d)\t<-", i, g->vertices[i].component); 100169689Skan for (e = g->vertices[i].pred; e; e = e->pred_next) 101169689Skan fprintf (f, " %d", e->src); 102169689Skan fprintf (f, "\n"); 103132718Skan 104169689Skan fprintf (f, "\t->"); 105169689Skan for (e = g->vertices[i].succ; e; e = e->succ_next) 106169689Skan fprintf (f, " %d", e->dest); 107169689Skan fprintf (f, "\n"); 108132718Skan } 109132718Skan} 110132718Skan 111169689Skan/* Creates a new graph with N_VERTICES vertices. */ 112132718Skan 113169689Skanstatic struct graph * 114169689Skannew_graph (int n_vertices) 115132718Skan{ 116169689Skan struct graph *g = XNEW (struct graph); 117132718Skan 118169689Skan g->n_vertices = n_vertices; 119169689Skan g->vertices = XCNEWVEC (struct vertex, n_vertices); 120132718Skan 121169689Skan return g; 122132718Skan} 123132718Skan 124169689Skan/* Adds an edge from F to T to graph G, with DATA attached. */ 125132718Skan 126169689Skanstatic void 127169689Skanadd_edge (struct graph *g, int f, int t, void *data) 128132718Skan{ 129169689Skan struct edge *e = xmalloc (sizeof (struct edge)); 130132718Skan 131169689Skan e->src = f; 132169689Skan e->dest = t; 133169689Skan e->data = data; 134132718Skan 135169689Skan e->pred_next = g->vertices[t].pred; 136169689Skan g->vertices[t].pred = e; 137132718Skan 138169689Skan e->succ_next = g->vertices[f].succ; 139169689Skan g->vertices[f].succ = e; 140132718Skan} 141132718Skan 142169689Skan/* Runs dfs search over vertices of G, from NQ vertices in queue QS. 143169689Skan The vertices in postorder are stored into QT. If FORWARD is false, 144169689Skan backward dfs is run. */ 145132718Skan 146169689Skanstatic void 147169689Skandfs (struct graph *g, int *qs, int nq, int *qt, bool forward) 148132718Skan{ 149169689Skan int i, tick = 0, v, comp = 0, top; 150169689Skan struct edge *e; 151169689Skan struct edge **stack = xmalloc (sizeof (struct edge *) * g->n_vertices); 152132718Skan 153169689Skan for (i = 0; i < g->n_vertices; i++) 154132718Skan { 155169689Skan g->vertices[i].component = -1; 156169689Skan g->vertices[i].post = -1; 157132718Skan } 158132718Skan 159169689Skan#define FST_EDGE(V) (forward ? g->vertices[(V)].succ : g->vertices[(V)].pred) 160169689Skan#define NEXT_EDGE(E) (forward ? (E)->succ_next : (E)->pred_next) 161169689Skan#define EDGE_SRC(E) (forward ? (E)->src : (E)->dest) 162169689Skan#define EDGE_DEST(E) (forward ? (E)->dest : (E)->src) 163132718Skan 164169689Skan for (i = 0; i < nq; i++) 165132718Skan { 166169689Skan v = qs[i]; 167169689Skan if (g->vertices[v].post != -1) 168132718Skan continue; 169132718Skan 170169689Skan g->vertices[v].component = comp++; 171169689Skan e = FST_EDGE (v); 172169689Skan top = 0; 173132718Skan 174169689Skan while (1) 175169689Skan { 176169689Skan while (e && g->vertices[EDGE_DEST (e)].component != -1) 177169689Skan e = NEXT_EDGE (e); 178132718Skan 179169689Skan if (!e) 180169689Skan { 181169689Skan if (qt) 182169689Skan qt[tick] = v; 183169689Skan g->vertices[v].post = tick++; 184132718Skan 185169689Skan if (!top) 186169689Skan break; 187132718Skan 188169689Skan e = stack[--top]; 189169689Skan v = EDGE_SRC (e); 190169689Skan e = NEXT_EDGE (e); 191169689Skan continue; 192169689Skan } 193132718Skan 194169689Skan stack[top++] = e; 195169689Skan v = EDGE_DEST (e); 196169689Skan e = FST_EDGE (v); 197169689Skan g->vertices[v].component = comp - 1; 198132718Skan } 199132718Skan } 200132718Skan 201169689Skan free (stack); 202132718Skan} 203132718Skan 204169689Skan/* Marks the edge E in graph G irreducible if it connects two vertices in the 205169689Skan same scc. */ 206132718Skan 207169689Skanstatic void 208169689Skancheck_irred (struct graph *g, struct edge *e) 209132718Skan{ 210169689Skan edge real = e->data; 211132718Skan 212169689Skan /* All edges should lead from a component with higher number to the 213169689Skan one with lower one. */ 214169689Skan gcc_assert (g->vertices[e->src].component >= g->vertices[e->dest].component); 215132718Skan 216169689Skan if (g->vertices[e->src].component != g->vertices[e->dest].component) 217169689Skan return; 218132718Skan 219169689Skan real->flags |= EDGE_IRREDUCIBLE_LOOP; 220169689Skan if (flow_bb_inside_loop_p (real->src->loop_father, real->dest)) 221169689Skan real->src->flags |= BB_IRREDUCIBLE_LOOP; 222132718Skan} 223132718Skan 224169689Skan/* Runs CALLBACK for all edges in G. */ 225132718Skan 226169689Skanstatic void 227169689Skanfor_each_edge (struct graph *g, 228169689Skan void (callback) (struct graph *, struct edge *)) 229132718Skan{ 230169689Skan struct edge *e; 231169689Skan int i; 232132718Skan 233169689Skan for (i = 0; i < g->n_vertices; i++) 234169689Skan for (e = g->vertices[i].succ; e; e = e->succ_next) 235169689Skan callback (g, e); 236132718Skan} 237132718Skan 238169689Skan/* Releases the memory occupied by G. */ 239132718Skan 240169689Skanstatic void 241169689Skanfree_graph (struct graph *g) 242132718Skan{ 243169689Skan struct edge *e, *n; 244169689Skan int i; 245132718Skan 246169689Skan for (i = 0; i < g->n_vertices; i++) 247169689Skan for (e = g->vertices[i].succ; e; e = n) 248169689Skan { 249169689Skan n = e->succ_next; 250169689Skan free (e); 251169689Skan } 252169689Skan free (g->vertices); 253169689Skan free (g); 254132718Skan} 255132718Skan 256132718Skan/* Marks blocks and edges that are part of non-recognized loops; i.e. we 257132718Skan throw away all latch edges and mark blocks inside any remaining cycle. 258132718Skan Everything is a bit complicated due to fact we do not want to do this 259132718Skan for parts of cycles that only "pass" through some loop -- i.e. for 260132718Skan each cycle, we want to mark blocks that belong directly to innermost 261169689Skan loop containing the whole cycle. 262169689Skan 263169689Skan LOOPS is the loop tree. */ 264169689Skan 265169689Skan#define LOOP_REPR(LOOP) ((LOOP)->num + last_basic_block) 266169689Skan#define BB_REPR(BB) ((BB)->index + 1) 267169689Skan 268132718Skanvoid 269132718Skanmark_irreducible_loops (struct loops *loops) 270132718Skan{ 271132718Skan basic_block act; 272169689Skan edge e; 273169689Skan edge_iterator ei; 274169689Skan int i, src, dest; 275169689Skan struct graph *g; 276169689Skan int *queue1 = XNEWVEC (int, last_basic_block + loops->num); 277169689Skan int *queue2 = XNEWVEC (int, last_basic_block + loops->num); 278169689Skan int nq, depth; 279132718Skan struct loop *cloop; 280132718Skan 281132718Skan /* Reset the flags. */ 282132718Skan FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb) 283132718Skan { 284132718Skan act->flags &= ~BB_IRREDUCIBLE_LOOP; 285169689Skan FOR_EACH_EDGE (e, ei, act->succs) 286132718Skan e->flags &= ~EDGE_IRREDUCIBLE_LOOP; 287132718Skan } 288132718Skan 289169689Skan /* Create the edge lists. */ 290169689Skan g = new_graph (last_basic_block + loops->num); 291132718Skan 292132718Skan FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb) 293169689Skan FOR_EACH_EDGE (e, ei, act->succs) 294132718Skan { 295169689Skan /* Ignore edges to exit. */ 296169689Skan if (e->dest == EXIT_BLOCK_PTR) 297132718Skan continue; 298169689Skan 299132718Skan /* And latch edges. */ 300132718Skan if (e->dest->loop_father->header == e->dest 301132718Skan && e->dest->loop_father->latch == act) 302132718Skan continue; 303169689Skan 304132718Skan /* Edges inside a single loop should be left where they are. Edges 305132718Skan to subloop headers should lead to representative of the subloop, 306169689Skan but from the same place. 307169689Skan 308169689Skan Edges exiting loops should lead from representative 309132718Skan of the son of nearest common ancestor of the loops in that 310132718Skan act lays. */ 311132718Skan 312169689Skan src = BB_REPR (act); 313169689Skan dest = BB_REPR (e->dest); 314132718Skan 315169689Skan if (e->dest->loop_father->header == e->dest) 316169689Skan dest = LOOP_REPR (e->dest->loop_father); 317169689Skan 318169689Skan if (!flow_bb_inside_loop_p (act->loop_father, e->dest)) 319132718Skan { 320169689Skan depth = find_common_loop (act->loop_father, 321169689Skan e->dest->loop_father)->depth + 1; 322169689Skan if (depth == act->loop_father->depth) 323169689Skan cloop = act->loop_father; 324169689Skan else 325169689Skan cloop = act->loop_father->pred[depth]; 326169689Skan 327169689Skan src = LOOP_REPR (cloop); 328132718Skan } 329169689Skan 330169689Skan add_edge (g, src, dest, e); 331132718Skan } 332132718Skan 333169689Skan /* Find the strongly connected components. Use the algorithm of Tarjan -- 334169689Skan first determine the postorder dfs numbering in reversed graph, then 335169689Skan run the dfs on the original graph in the order given by decreasing 336169689Skan numbers assigned by the previous pass. */ 337169689Skan nq = 0; 338169689Skan FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb) 339132718Skan { 340169689Skan queue1[nq++] = BB_REPR (act); 341132718Skan } 342169689Skan for (i = 1; i < (int) loops->num; i++) 343132718Skan if (loops->parray[i]) 344169689Skan queue1[nq++] = LOOP_REPR (loops->parray[i]); 345169689Skan dfs (g, queue1, nq, queue2, false); 346169689Skan for (i = 0; i < nq; i++) 347169689Skan queue1[i] = queue2[nq - i - 1]; 348169689Skan dfs (g, queue1, nq, NULL, true); 349132718Skan 350169689Skan /* Mark the irreducible loops. */ 351169689Skan for_each_edge (g, check_irred); 352132718Skan 353169689Skan free_graph (g); 354169689Skan free (queue1); 355169689Skan free (queue2); 356132718Skan 357132718Skan loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS; 358132718Skan} 359132718Skan 360132718Skan/* Counts number of insns inside LOOP. */ 361132718Skanint 362132718Skannum_loop_insns (struct loop *loop) 363132718Skan{ 364132718Skan basic_block *bbs, bb; 365132718Skan unsigned i, ninsns = 0; 366132718Skan rtx insn; 367132718Skan 368132718Skan bbs = get_loop_body (loop); 369132718Skan for (i = 0; i < loop->num_nodes; i++) 370132718Skan { 371132718Skan bb = bbs[i]; 372132718Skan ninsns++; 373132718Skan for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn)) 374132718Skan if (INSN_P (insn)) 375132718Skan ninsns++; 376132718Skan } 377132718Skan free(bbs); 378132718Skan 379132718Skan return ninsns; 380132718Skan} 381132718Skan 382132718Skan/* Counts number of insns executed on average per iteration LOOP. */ 383132718Skanint 384132718Skanaverage_num_loop_insns (struct loop *loop) 385132718Skan{ 386132718Skan basic_block *bbs, bb; 387132718Skan unsigned i, binsns, ninsns, ratio; 388132718Skan rtx insn; 389132718Skan 390132718Skan ninsns = 0; 391132718Skan bbs = get_loop_body (loop); 392132718Skan for (i = 0; i < loop->num_nodes; i++) 393132718Skan { 394132718Skan bb = bbs[i]; 395132718Skan 396132718Skan binsns = 1; 397132718Skan for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn)) 398132718Skan if (INSN_P (insn)) 399132718Skan binsns++; 400132718Skan 401132718Skan ratio = loop->header->frequency == 0 402132718Skan ? BB_FREQ_MAX 403132718Skan : (bb->frequency * BB_FREQ_MAX) / loop->header->frequency; 404132718Skan ninsns += binsns * ratio; 405132718Skan } 406132718Skan free(bbs); 407132718Skan 408132718Skan ninsns /= BB_FREQ_MAX; 409132718Skan if (!ninsns) 410132718Skan ninsns = 1; /* To avoid division by zero. */ 411132718Skan 412132718Skan return ninsns; 413132718Skan} 414132718Skan 415132718Skan/* Returns expected number of LOOP iterations. 416132718Skan Compute upper bound on number of iterations in case they do not fit integer 417132718Skan to help loop peeling heuristics. Use exact counts if at all possible. */ 418132718Skanunsigned 419132718Skanexpected_loop_iterations (const struct loop *loop) 420132718Skan{ 421132718Skan edge e; 422169689Skan edge_iterator ei; 423132718Skan 424169689Skan if (loop->latch->count || loop->header->count) 425132718Skan { 426132718Skan gcov_type count_in, count_latch, expected; 427132718Skan 428132718Skan count_in = 0; 429132718Skan count_latch = 0; 430132718Skan 431169689Skan FOR_EACH_EDGE (e, ei, loop->header->preds) 432132718Skan if (e->src == loop->latch) 433132718Skan count_latch = e->count; 434132718Skan else 435132718Skan count_in += e->count; 436132718Skan 437132718Skan if (count_in == 0) 438169689Skan expected = count_latch * 2; 439169689Skan else 440169689Skan expected = (count_latch + count_in - 1) / count_in; 441132718Skan 442132718Skan /* Avoid overflows. */ 443132718Skan return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected); 444132718Skan } 445132718Skan else 446132718Skan { 447132718Skan int freq_in, freq_latch; 448132718Skan 449132718Skan freq_in = 0; 450132718Skan freq_latch = 0; 451132718Skan 452169689Skan FOR_EACH_EDGE (e, ei, loop->header->preds) 453132718Skan if (e->src == loop->latch) 454132718Skan freq_latch = EDGE_FREQUENCY (e); 455132718Skan else 456132718Skan freq_in += EDGE_FREQUENCY (e); 457132718Skan 458132718Skan if (freq_in == 0) 459169689Skan return freq_latch * 2; 460132718Skan 461132718Skan return (freq_latch + freq_in - 1) / freq_in; 462132718Skan } 463132718Skan} 464132718Skan 465169689Skan/* Returns the maximum level of nesting of subloops of LOOP. */ 466169689Skan 467169689Skanunsigned 468169689Skanget_loop_level (const struct loop *loop) 469132718Skan{ 470169689Skan const struct loop *ploop; 471169689Skan unsigned mx = 0, l; 472132718Skan 473169689Skan for (ploop = loop->inner; ploop; ploop = ploop->next) 474169689Skan { 475169689Skan l = get_loop_level (ploop); 476169689Skan if (l >= mx) 477169689Skan mx = l + 1; 478169689Skan } 479169689Skan return mx; 480132718Skan} 481132718Skan 482169689Skan/* Returns estimate on cost of computing SEQ. */ 483169689Skan 484169689Skanstatic unsigned 485169689Skanseq_cost (rtx seq) 486132718Skan{ 487169689Skan unsigned cost = 0; 488132718Skan rtx set; 489132718Skan 490169689Skan for (; seq; seq = NEXT_INSN (seq)) 491169689Skan { 492169689Skan set = single_set (seq); 493169689Skan if (set) 494169689Skan cost += rtx_cost (set, SET); 495169689Skan else 496169689Skan cost++; 497169689Skan } 498132718Skan 499169689Skan return cost; 500169689Skan} 501132718Skan 502169689Skan/* The properties of the target. */ 503132718Skan 504169689Skanunsigned target_avail_regs; /* Number of available registers. */ 505169689Skanunsigned target_res_regs; /* Number of reserved registers. */ 506169689Skanunsigned target_small_cost; /* The cost for register when there is a free one. */ 507169689Skanunsigned target_pres_cost; /* The cost for register when there are not too many 508169689Skan free ones. */ 509169689Skanunsigned target_spill_cost; /* The cost for register when we need to spill. */ 510132718Skan 511169689Skan/* Initialize the constants for computing set costs. */ 512169689Skan 513169689Skanvoid 514169689Skaninit_set_costs (void) 515169689Skan{ 516169689Skan rtx seq; 517169689Skan rtx reg1 = gen_raw_REG (SImode, FIRST_PSEUDO_REGISTER); 518169689Skan rtx reg2 = gen_raw_REG (SImode, FIRST_PSEUDO_REGISTER + 1); 519169689Skan rtx addr = gen_raw_REG (Pmode, FIRST_PSEUDO_REGISTER + 2); 520169689Skan rtx mem = validize_mem (gen_rtx_MEM (SImode, addr)); 521169689Skan unsigned i; 522169689Skan 523169689Skan for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 524169689Skan if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i) 525169689Skan && !fixed_regs[i]) 526169689Skan target_avail_regs++; 527169689Skan 528169689Skan target_res_regs = 3; 529169689Skan 530169689Skan /* These are really just heuristic values. */ 531169689Skan 532169689Skan start_sequence (); 533169689Skan emit_move_insn (reg1, reg2); 534169689Skan seq = get_insns (); 535169689Skan end_sequence (); 536169689Skan target_small_cost = seq_cost (seq); 537169689Skan target_pres_cost = 2 * target_small_cost; 538169689Skan 539169689Skan start_sequence (); 540169689Skan emit_move_insn (mem, reg1); 541169689Skan emit_move_insn (reg2, mem); 542169689Skan seq = get_insns (); 543169689Skan end_sequence (); 544169689Skan target_spill_cost = seq_cost (seq); 545132718Skan} 546132718Skan 547169689Skan/* Calculates cost for having SIZE new loop global variables. REGS_USED is the 548169689Skan number of global registers used in loop. N_USES is the number of relevant 549169689Skan variable uses. */ 550169689Skan 551169689Skanunsigned 552169689Skanglobal_cost_for_size (unsigned size, unsigned regs_used, unsigned n_uses) 553169689Skan{ 554169689Skan unsigned regs_needed = regs_used + size; 555169689Skan unsigned cost = 0; 556169689Skan 557169689Skan if (regs_needed + target_res_regs <= target_avail_regs) 558169689Skan cost += target_small_cost * size; 559169689Skan else if (regs_needed <= target_avail_regs) 560169689Skan cost += target_pres_cost * size; 561169689Skan else 562169689Skan { 563169689Skan cost += target_pres_cost * size; 564169689Skan cost += target_spill_cost * n_uses * (regs_needed - target_avail_regs) / regs_needed; 565169689Skan } 566169689Skan 567169689Skan return cost; 568169689Skan} 569169689Skan 570169689Skan/* Sets EDGE_LOOP_EXIT flag for all exits of LOOPS. */ 571169689Skan 572169689Skanvoid 573169689Skanmark_loop_exit_edges (struct loops *loops) 574169689Skan{ 575169689Skan basic_block bb; 576169689Skan edge e; 577169689Skan 578169689Skan if (loops->num <= 1) 579169689Skan return; 580169689Skan 581169689Skan FOR_EACH_BB (bb) 582169689Skan { 583169689Skan edge_iterator ei; 584169689Skan 585169689Skan FOR_EACH_EDGE (e, ei, bb->succs) 586169689Skan { 587169689Skan if (bb->loop_father->outer 588169689Skan && loop_exit_edge_p (bb->loop_father, e)) 589169689Skan e->flags |= EDGE_LOOP_EXIT; 590169689Skan else 591169689Skan e->flags &= ~EDGE_LOOP_EXIT; 592169689Skan } 593169689Skan } 594169689Skan} 595169689Skan 596