OSDN Git Service

* cfgloopanal.c (check_irred): Move into ...
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Jun 2009 14:56:37 +0000 (14:56 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Jun 2009 14:56:37 +0000 (14:56 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149101 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/cfgloop.h
gcc/cfgloopanal.c
gcc/ipa-pure-const.c
gcc/params.def
gcc/tree-cfg.c

index ff192b0..4eb3f62 100644 (file)
@@ -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.
index a638a78..18089fb 100644 (file)
@@ -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) \
index fe0120e..2bc965b 100644 (file)
@@ -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);
index 2d31ca8..36e0d15 100644 (file)
@@ -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.  */
index 35d27a3..8faa00c 100644 (file)
@@ -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))
index e3a6470..76c90a4 100644 (file)
@@ -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",
index 4c7c0db..049dd1d 100644 (file)
@@ -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;
 }