X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcfgloopanal.c;h=02f026576991ded3cf4e9396bd1abfacee2bd784;hb=5d25efc0fd72fef10dbc606561fade95f2c99a88;hp=d59fa2fb50597ff6d9c1ca5637e3552d71ad1001;hpb=f529eb25672cac0bded2a446786242465fc7f4b5;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index d59fa2fb505..02f02657699 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -1,5 +1,6 @@ /* Natural loop analysis code for GNU compiler. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. This file is part of GCC. @@ -31,6 +32,11 @@ along with GCC; see the file COPYING3. If not see #include "graphds.h" #include "params.h" +struct target_cfgloop default_target_cfgloop; +#if SWITCHABLE_TARGET +struct target_cfgloop *this_target_cfgloop = &default_target_cfgloop; +#endif + /* Checks whether BB is executed exactly once in each LOOP iteration. */ bool @@ -51,26 +57,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 @@ -83,10 +69,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; @@ -94,6 +81,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); @@ -153,11 +142,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. */ @@ -172,12 +180,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; } @@ -196,9 +206,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 @@ -206,7 +216,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) @@ -312,17 +322,6 @@ seq_cost (const_rtx seq, bool speed) return cost; } -/* The properties of the target. */ - -unsigned target_avail_regs; /* Number of available registers. */ -unsigned target_res_regs; /* Number of registers reserved for temporary - expressions. */ -unsigned target_reg_cost[2]; /* The cost for register when there still - is some reserve, but we are approaching - the number of available registers. */ -unsigned target_spill_cost[2]; /* The cost for register when we need - to spill. */ - /* Initialize the constants for computing set costs. */ void @@ -337,10 +336,15 @@ init_set_costs (void) unsigned i; target_avail_regs = 0; + target_clobbered_regs = 0; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i) && !fixed_regs[i]) - target_avail_regs++; + { + target_avail_regs++; + if (call_used_regs[i]) + target_clobbered_regs++; + } target_res_regs = 3; @@ -374,20 +378,29 @@ init_set_costs (void) /* Estimates cost of increased register pressure caused by making N_NEW new registers live around the loop. N_OLD is the number of registers live - around the loop. */ + around the loop. If CALL_P is true, also take into account that + call-used registers may be clobbered in the loop body, reducing the + number of available registers before we spill. */ unsigned -estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed) +estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed, + bool call_p) { unsigned cost; unsigned regs_needed = n_new + n_old; + unsigned available_regs = target_avail_regs; + + /* If there is a call in the loop body, the call-clobbered registers + are not available for loop invariants. */ + if (call_p) + available_regs = available_regs - target_clobbered_regs; /* If we have enough registers, we should use them and not restrict the transformations unnecessarily. */ - if (regs_needed + target_res_regs <= target_avail_regs) + if (regs_needed + target_res_regs <= available_regs) return 0; - if (regs_needed <= target_avail_regs) + if (regs_needed <= available_regs) /* If we are close to running out of registers, try to preserve them. */ cost = target_reg_cost [speed] * n_new; @@ -396,8 +409,8 @@ estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed) one. */ cost = target_spill_cost [speed] * n_new; - if (optimize && flag_ira && (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL - || flag_ira_algorithm == IRA_ALGORITHM_MIXED) + if (optimize && (flag_ira_region == IRA_REGION_ALL + || flag_ira_region == IRA_REGION_MIXED) && number_of_loops () <= (unsigned) IRA_MAX_LOOPS_NUM) /* IRA regional allocation deals with high register pressure better. So decrease the cost (to do more accurate the cost