aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2009-06-30 16:56:37 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2009-06-30 14:56:37 +0000
commit2de58650f962e371b06f00bdefd0b01b5f7e3f6a (patch)
treeb0873a32071a823e01701ec13011a3c5038ec083
parent46db44ccaea515d561f7a63d0e07ee6ddbc1b869 (diff)
downloadgcc-2de58650f962e371b06f00bdefd0b01b5f7e3f6a.zip
gcc-2de58650f962e371b06f00bdefd0b01b5f7e3f6a.tar.gz
gcc-2de58650f962e371b06f00bdefd0b01b5f7e3f6a.tar.bz2
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/cfgloop.h2
-rw-r--r--gcc/cfgloopanal.c46
-rw-r--r--gcc/ipa-pure-const.c31
-rw-r--r--gcc/params.def10
-rw-r--r--gcc/tree-cfg.c11
7 files changed, 80 insertions, 32 deletions
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 <jh@suse.cz>
+
+ * 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 <basile@starynkevitch.net>
* 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;
}