| Index: gcc/gcc/cfgloopanal.c
|
| diff --git a/gcc/gcc/cfgloopanal.c b/gcc/gcc/cfgloopanal.c
|
| index 2d31ca8a34040719edfbbcda66b5bfe8fb6f4e65..129ec25a331bb0e6d260c790a85cb119f32c37ea 100644
|
| --- a/gcc/gcc/cfgloopanal.c
|
| +++ b/gcc/gcc/cfgloopanal.c
|
| @@ -52,26 +52,6 @@ just_once_each_iteration_p (const struct loop *loop, const_basic_block bb)
|
| return true;
|
| }
|
|
|
| -/* Marks the edge E in graph G irreducible if it connects two vertices in the
|
| - same scc. */
|
| -
|
| -static void
|
| -check_irred (struct graph *g, struct graph_edge *e)
|
| -{
|
| - edge real = (edge) e->data;
|
| -
|
| - /* All edges should lead from a component with higher number to the
|
| - one with lower one. */
|
| - gcc_assert (g->vertices[e->src].component >= g->vertices[e->dest].component);
|
| -
|
| - if (g->vertices[e->src].component != g->vertices[e->dest].component)
|
| - return;
|
| -
|
| - real->flags |= EDGE_IRREDUCIBLE_LOOP;
|
| - if (flow_bb_inside_loop_p (real->src->loop_father, real->dest))
|
| - real->src->flags |= BB_IRREDUCIBLE_LOOP;
|
| -}
|
| -
|
| /* Marks blocks and edges that are part of non-recognized loops; i.e. we
|
| throw away all latch edges and mark blocks inside any remaining cycle.
|
| Everything is a bit complicated due to fact we do not want to do this
|
| @@ -84,10 +64,11 @@ check_irred (struct graph *g, struct graph_edge *e)
|
| #define LOOP_REPR(LOOP) ((LOOP)->num + last_basic_block)
|
| #define BB_REPR(BB) ((BB)->index + 1)
|
|
|
| -void
|
| +bool
|
| mark_irreducible_loops (void)
|
| {
|
| basic_block act;
|
| + struct graph_edge *ge;
|
| edge e;
|
| edge_iterator ei;
|
| int src, dest;
|
| @@ -95,6 +76,8 @@ mark_irreducible_loops (void)
|
| struct graph *g;
|
| int num = number_of_loops ();
|
| struct loop *cloop;
|
| + bool irred_loop_found = false;
|
| + int i;
|
|
|
| gcc_assert (current_loops != NULL);
|
|
|
| @@ -154,11 +137,30 @@ mark_irreducible_loops (void)
|
| graphds_scc (g, NULL);
|
|
|
| /* Mark the irreducible loops. */
|
| - for_each_edge (g, check_irred);
|
| + for (i = 0; i < g->n_vertices; i++)
|
| + for (ge = g->vertices[i].succ; ge; ge = ge->succ_next)
|
| + {
|
| + edge real = (edge) ge->data;
|
| + /* edge E in graph G is irreducible if it connects two vertices in the
|
| + same scc. */
|
| +
|
| + /* All edges should lead from a component with higher number to the
|
| + one with lower one. */
|
| + gcc_assert (g->vertices[ge->src].component >= g->vertices[ge->dest].component);
|
| +
|
| + if (g->vertices[ge->src].component != g->vertices[ge->dest].component)
|
| + continue;
|
| +
|
| + real->flags |= EDGE_IRREDUCIBLE_LOOP;
|
| + irred_loop_found = true;
|
| + if (flow_bb_inside_loop_p (real->src->loop_father, real->dest))
|
| + real->src->flags |= BB_IRREDUCIBLE_LOOP;
|
| + }
|
|
|
| free_graph (g);
|
|
|
| loops_state_set (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS);
|
| + return irred_loop_found;
|
| }
|
|
|
| /* Counts number of insns inside LOOP. */
|
| @@ -173,12 +175,14 @@ num_loop_insns (const struct loop *loop)
|
| for (i = 0; i < loop->num_nodes; i++)
|
| {
|
| bb = bbs[i];
|
| - ninsns++;
|
| - for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
|
| - if (INSN_P (insn))
|
| + FOR_BB_INSNS (bb, insn)
|
| + if (NONDEBUG_INSN_P (insn))
|
| ninsns++;
|
| }
|
| - free(bbs);
|
| + free (bbs);
|
| +
|
| + if (!ninsns)
|
| + ninsns = 1; /* To avoid division by zero. */
|
|
|
| return ninsns;
|
| }
|
| @@ -197,9 +201,9 @@ average_num_loop_insns (const struct loop *loop)
|
| {
|
| bb = bbs[i];
|
|
|
| - binsns = 1;
|
| - for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
|
| - if (INSN_P (insn))
|
| + binsns = 0;
|
| + FOR_BB_INSNS (bb, insn)
|
| + if (NONDEBUG_INSN_P (insn))
|
| binsns++;
|
|
|
| ratio = loop->header->frequency == 0
|
| @@ -207,7 +211,7 @@ average_num_loop_insns (const struct loop *loop)
|
| : (bb->frequency * BB_FREQ_MAX) / loop->header->frequency;
|
| ninsns += binsns * ratio;
|
| }
|
| - free(bbs);
|
| + free (bbs);
|
|
|
| ninsns /= BB_FREQ_MAX;
|
| if (!ninsns)
|
|
|