* 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
+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.
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) \
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);
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
#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;
struct graph *g;
int num = number_of_loops ();
struct loop *cloop;
+ bool irred_loop_found = false;
+ int i;
gcc_assert (current_loops != NULL);
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. */
#include "diagnostic.h"
#include "langhooks.h"
#include "target.h"
+#include "cfgloop.h"
+#include "tree-scalar-evolution.h"
static struct pointer_set_t *visited_nodes;
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))
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).
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",
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",
/* 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;
}