From: Jan Hubicka Date: Tue, 30 Jun 2009 14:56:37 +0000 (+0200) Subject: cfgloopanal.c (check_irred): Move into ... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2de58650f962e371b06f00bdefd0b01b5f7e3f6a;p=platform%2Fupstream%2Fgcc.git cfgloopanal.c (check_irred): Move into ... * cfgloopanal.c (check_irred): Move into ... (mark_irreducible_loops): ... here; return true if ireducible loops was found. * ipa-pure-const.c: Include cfgloop.h and tree-scalar-evolution.h (analyze_function): Try to prove loop finiteness. * cfgloop.h (mark_irreducible_loops): Update prototype. * Makefile.in (ipa-pure-const.o): Add dependency on SCEV and CFGLOOP. From-SVN: r149101 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff192b0..4eb3f62 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2009-06-30 Jan Hubicka + + * cfgloopanal.c (check_irred): Move into ... + (mark_irreducible_loops): ... here; return true if ireducible + loops was found. + * ipa-pure-const.c: Include cfgloop.h and tree-scalar-evolution.h + (analyze_function): Try to prove loop finiteness. + * cfgloop.h (mark_irreducible_loops): Update prototype. + * Makefile.in (ipa-pure-const.o): Add dependency on SCEV and CFGLOOP. + 2009-06-30 Basile Starynkevitch * Makefile.in (PLUGIN_HEADERS): added ggc, tree-dump, pretty-print. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index a638a78..18089fb 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2725,7 +2725,7 @@ ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(TARGET_H) \ $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) $(TIMEVAR_H) \ - $(DIAGNOSTIC_H) + $(DIAGNOSTIC_H) $(CFGLOOP_H) $(SCEV_H) ipa-type-escape.o : ipa-type-escape.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ pointer-set.h $(GGC_H) $(IPA_TYPE_ESCAPE_H) $(IPA_UTILS_H) $(SPLAY_TREE_H) \ diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index fe0120e..2bc965b 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -205,7 +205,7 @@ struct loop *alloc_loop (void); extern void flow_loop_free (struct loop *); int flow_loop_nodes_find (basic_block, struct loop *); void fix_loop_structure (bitmap changed_bbs); -void mark_irreducible_loops (void); +bool mark_irreducible_loops (void); void release_recorded_exits (void); void record_loop_exits (void); void rescan_loop_exit (edge, bool, bool); diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index 2d31ca8..36e0d15 100644 --- a/gcc/cfgloopanal.c +++ b/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. */ diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 35d27a3..8faa00c 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic.h" #include "langhooks.h" #include "target.h" +#include "cfgloop.h" +#include "tree-scalar-evolution.h" static struct pointer_set_t *visited_nodes; @@ -522,8 +524,33 @@ end: indication of possible infinite loop side effect. */ if (mark_dfs_back_edges ()) - l->looping = true; - + { + loop_optimizer_init (LOOPS_HAVE_PREHEADERS); + if (dump_file && (dump_flags & TDF_DETAILS)) + flow_loops_dump (dump_file, NULL, 0); + if (mark_irreducible_loops ()) + { + if (dump_file) + fprintf (dump_file, " has irreducible loops\n"); + l->looping = true; + } + else + { + loop_iterator li; + struct loop *loop; + scev_initialize (); + FOR_EACH_LOOP (li, loop, 0) + if (!finite_loop_p (loop)) + { + if (dump_file) + fprintf (dump_file, " can not prove finiteness of loop %i\n", loop->num); + l->looping =true; + break; + } + scev_finalize (); + } + loop_optimizer_finalize (); + } } if (TREE_READONLY (decl)) diff --git a/gcc/params.def b/gcc/params.def index e3a6470..76c90a4 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -70,7 +70,7 @@ DEFPARAM (PARAM_PREDICTABLE_BRANCH_OUTCOME, DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, "max-inline-insns-single", "The maximum number of instructions in a single function eligible for inlining", - 400, 0, 0) + 150, 0, 0) /* The single function inlining limit for functions that are inlined by virtue of -finline-functions (-O3). @@ -82,17 +82,17 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO, "max-inline-insns-auto", "The maximum number of instructions when automatically inlining", - 60, 0, 0) + 40, 0, 0) DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE, "max-inline-insns-recursive", "The maximum number of instructions inline function can grow to via recursive inlining", - 450, 0, 0) + 300, 0, 0) DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO, "max-inline-insns-recursive-auto", "The maximum number of instructions non-inline function can grow to via recursive inlining", - 450, 0, 0) + 200, 0, 0) DEFPARAM (PARAM_MAX_INLINE_RECURSIVE_DEPTH, "max-inline-recursive-depth", @@ -185,7 +185,7 @@ DEFPARAM(PARAM_IPCP_UNIT_GROWTH, DEFPARAM(PARAM_EARLY_INLINING_INSNS, "early-inlining-insns", "maximal estimated growth of function body caused by early inlining of single call", - 12, 0, 0) + 8, 0, 0) DEFPARAM(PARAM_LARGE_STACK_FRAME, "large-stack-frame", "The size of stack frame to be considered large", diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 4c7c0db..049dd1d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -5131,8 +5131,17 @@ gimple_move_block_after (basic_block bb, basic_block after) /* Return true if basic_block can be duplicated. */ static bool -gimple_can_duplicate_bb_p (const_basic_block bb ATTRIBUTE_UNUSED) +gimple_can_duplicate_bb_p (const_basic_block bb) { + gimple_stmt_iterator gsi = gsi_last_bb (bb); + + /* RTL expander has quite artificial limitation to at most one RESX instruction + per region. It can be fixed by turning 1-1 map to 1-many map, but since the + code needs to be rewritten to gimple level lowering and there is little reason + for duplicating RESX instructions in order to optimize code performance, we + just disallow it for the moment. */ + if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_RESX) + return false; return true; }