X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-ssa-loop-ch.c;h=fb5f7f68fb51839395286fb7e30f2ade7debf8d6;hb=99617355e9cba5fc47f5283caefbe0f22ef8c578;hp=e307528b2a8fbaae44cac157bebf725cdc87cbdd;hpb=dda28f7c7652c920e2c5e184dcf42e8f38054e94;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index e307528b2a8..fb5f7f68fb5 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -1,5 +1,5 @@ /* Loop header copying on trees. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -60,7 +60,7 @@ should_duplicate_loop_header_p (basic_block header, struct loop *loop, return false; gcc_assert (EDGE_COUNT (header->succs) > 0); - if (EDGE_COUNT (header->succs) == 1) + if (single_succ_p (header)) return false; if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest) && flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 1)->dest)) @@ -68,7 +68,7 @@ should_duplicate_loop_header_p (basic_block header, struct loop *loop, /* If this is not the original loop header, we want it to have just one predecessor in order to match the && pattern. */ - if (header != loop->header && EDGE_COUNT (header->preds) >= 2) + if (header != loop->header && !single_pred_p (header)) return false; last = last_stmt (header); @@ -127,14 +127,16 @@ copy_loop_headers (void) unsigned i; struct loop *loop; basic_block header; - edge exit; - basic_block *bbs; + edge exit, entry; + basic_block *bbs, *copied_bbs; unsigned n_bbs; + unsigned bbs_size; + gcov_type entry_count, body_count, total_count; loops = loop_optimizer_init (dump_file); if (!loops) return; - rewrite_into_loop_closed_ssa (); + rewrite_into_loop_closed_ssa (NULL); /* We do not try to keep the information about irreducible regions up-to-date. */ @@ -145,6 +147,8 @@ copy_loop_headers (void) #endif bbs = xmalloc (sizeof (basic_block) * n_basic_blocks); + copied_bbs = xmalloc (sizeof (basic_block) * n_basic_blocks); + bbs_size = n_basic_blocks; for (i = 1; i < loops->num; i++) { @@ -180,6 +184,7 @@ copy_loop_headers (void) else exit = EDGE_SUCC (header, 1); bbs[n_bbs++] = header; + gcc_assert (bbs_size > n_bbs); header = exit->dest; } @@ -193,16 +198,36 @@ copy_loop_headers (void) /* Ensure that the header will have just the latch as a predecessor inside the loop. */ - if (EDGE_COUNT (exit->dest->preds) > 1) - exit = EDGE_SUCC (loop_split_edge_with (exit, NULL), 0); + if (!single_pred_p (exit->dest)) + exit = single_succ_edge (loop_split_edge_with (exit, NULL)); - if (!tree_duplicate_sese_region (loop_preheader_edge (loop), exit, - bbs, n_bbs, NULL)) + entry = loop_preheader_edge (loop); + entry_count = entry->src->count; + body_count = exit->dest->count; + + if (!tree_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs)) { fprintf (dump_file, "Duplication failed.\n"); continue; } + /* Fix profiling info. Scaling is done in gcov_type arithmetic to + avoid losing information; this is slow, but is done at most + once per loop. We special case 0 to avoid division by 0; + probably other special cases exist. */ + total_count = body_count + entry_count; + if (total_count == 0LL) + { + scale_bbs_frequencies_int (bbs, n_bbs, 0, 1); + scale_bbs_frequencies_int (copied_bbs, n_bbs, 0, 1); + } + else + { + scale_bbs_frequencies_gcov_type (bbs, n_bbs, body_count, total_count); + scale_bbs_frequencies_gcov_type (copied_bbs, n_bbs, entry_count, + total_count); + } + /* Ensure that the latch and the preheader is simple (we know that they are not now, since there was the loop exit condition. */ loop_split_edge_with (loop_preheader_edge (loop), NULL); @@ -210,6 +235,7 @@ copy_loop_headers (void) } free (bbs); + free (copied_bbs); #ifdef ENABLE_CHECKING verify_loop_closed_ssa ();