common.opt (ftree-loop-optimize): New flag.
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
Wed, 30 Jun 2004 21:29:00 +0000 (23:29 +0200)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Wed, 30 Jun 2004 21:29:00 +0000 (21:29 +0000)
* common.opt (ftree-loop-optimize): New flag.
* tree-flow.h (kill_redundant_phi_nodes): Declare.
* tree-optimize.c (init_tree_optimization_passes): Add pass_loop.
* tree-pass.h (pass_loop_init, pass_loop_done): Declare.
* tree-ssa-loop.c (current_loops): New variable.
(tree_loop_optimizer_init, gate_loop, tree_ssa_loop_init,
tree_ssa_loop_done): New functions.
(pass_loop, pass_loop_init, pass_loop_done): New passes.
* tree-ssa.c (kill_redundant_phi_nodes): Export.
* doc/invoke.texi (-ftree-loop-optimize): Document.

From-SVN: r83933

gcc/ChangeLog
gcc/common.opt
gcc/doc/invoke.texi
gcc/tree-flow.h
gcc/tree-optimize.c
gcc/tree-pass.h
gcc/tree-ssa-loop.c
gcc/tree-ssa.c

index 1cf4e55d1bd69708a6fe95a6c6b19ea110dd680d..8244666a5cbfe11213cc41d128d974b94c9fd3fe 100644 (file)
@@ -1,3 +1,16 @@
+2004-06-30  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
+
+       * common.opt (ftree-loop-optimize): New flag.
+       * tree-flow.h (kill_redundant_phi_nodes): Declare.
+       * tree-optimize.c (init_tree_optimization_passes): Add pass_loop.
+       * tree-pass.h (pass_loop_init, pass_loop_done): Declare.
+       * tree-ssa-loop.c (current_loops): New variable.
+       (tree_loop_optimizer_init, gate_loop, tree_ssa_loop_init,
+       tree_ssa_loop_done): New functions.
+       (pass_loop, pass_loop_init, pass_loop_done): New passes.
+       * tree-ssa.c (kill_redundant_phi_nodes): Export.
+       * doc/invoke.texi (-ftree-loop-optimize): Document.
+
 2004-06-30  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
 
        * tree-ssa-loop-ch.c: New file.
index 3cf0ec92ec37176bdba6410225e04eddb1106511..1c75bc2505007840ff4666efafb33b24c734bcad 100644 (file)
@@ -777,6 +777,10 @@ ftree-fre
 Common Report Var(flag_tree_fre)
 Enable Full Redundancy Elimination (FRE) on trees
 
+ftree-loop-optimize
+Common Report Var(flag_tree_loop_optimize) Init(1)
+Enable loop optimizations on tree level
+
 ftree-points-to=
 Common Joined RejectNegative
 
index 510eda967ba6d737ce4b38fc263172810b7ba8b9..ede70f67a46033148f38651acb0b0ea10b847a5f 100644 (file)
@@ -312,7 +312,7 @@ in the following sections.
 -fstrength-reduce  -fstrict-aliasing  -ftracer  -fthread-jumps @gol
 -funroll-all-loops  -funroll-loops  -fpeel-loops @gol
 -funswitch-loops  -fold-unroll-loops  -fold-unroll-all-loops @gol
--ftree-pre  -ftree-ccp  -ftree-dce  @gol
+-ftree-pre  -ftree-ccp  -ftree-dce -ftree-loop-optimize @gol
 -ftree-dominator-opts -ftree-dse -ftree-copyrename @gol
 -ftree-ch -ftree-sra -ftree-ter -ftree-lrs -ftree-fre @gol
 --param @var{name}=@var{value}
@@ -4400,6 +4400,10 @@ effectivity of code motion optimizations.  It also saves one jump.  This flag
 is enabled by default at -O and higher.  It is not enabled for -Os, since it
 usually increases code size.
 
+@item -ftree-loop-optimize
+Perform loop optimizations on trees.  This flag is enabled by default at -O
+and higher.
+
 @item -ftree-sra
 Perform scalar replacement of aggregates.  This pass replaces structure
 references with scalars to prevent committing structures to memory too
index 8d8f58a9eeb5362e0e5ede6d75c6cdae06071b47..f0bfba4c153dd496c334a5a0c9068fc12fb4615c 100644 (file)
@@ -573,6 +573,7 @@ extern void verify_ssa (void);
 extern void delete_tree_ssa (void);
 extern void register_new_def (tree, varray_type *);
 extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *);
+extern void kill_redundant_phi_nodes (void);
 
 /* In tree-into-ssa.c  */
 extern void rewrite_into_ssa (bool);
index 00ddc20827f857274b251f62a0d83bf4d85ca9f5..be663bb75fde139e663c997c425c4b2667dd4b79 100644 (file)
@@ -319,6 +319,7 @@ init_tree_optimization_passes (void)
   NEXT_PASS (pass_fold_builtins);
   NEXT_PASS (pass_split_crit_edges);
   NEXT_PASS (pass_pre);
+  NEXT_PASS (pass_loop);
   NEXT_PASS (DUP_PASS (pass_dominator));
   NEXT_PASS (DUP_PASS (pass_redundant_phi));
   NEXT_PASS (pass_cd_dce);
@@ -333,6 +334,11 @@ init_tree_optimization_passes (void)
   NEXT_PASS (pass_remove_useless_vars);
   *p = NULL;
 
+  p = &pass_loop.sub;
+  NEXT_PASS (pass_loop_init);
+  NEXT_PASS (pass_loop_done);
+  *p = NULL;
+
 #undef NEXT_PASS
 #undef DUP_PASS
 
index 18c2197dbbc65491bc1bb94fb42b0a323015417f..276de395bd1f2e72c89f02483555d09ef00328a8 100644 (file)
@@ -106,6 +106,8 @@ extern struct tree_opt_pass pass_sra;
 extern struct tree_opt_pass pass_tail_recursion;
 extern struct tree_opt_pass pass_tail_calls;
 extern struct tree_opt_pass pass_loop;
+extern struct tree_opt_pass pass_loop_init;
+extern struct tree_opt_pass pass_loop_done;
 extern struct tree_opt_pass pass_ch;
 extern struct tree_opt_pass pass_ccp;
 extern struct tree_opt_pass pass_build_ssa;
index 4ceb2820b3841b88379cfd8ab2a85fc634129e4f..885954e5e859e668d09d72de4d1cd5162d7b5f3f 100644 (file)
@@ -38,4 +38,106 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "flags.h"
 #include "tree-inline.h"
 
+/* The loop tree currently optimized.  */
+
+struct loops *current_loops;
+
+/* Initializes the loop structures.  DUMP is the file to that the details
+   about the analysis should be dumped.  */
+
+static struct loops *
+tree_loop_optimizer_init (FILE *dump)
+{
+  struct loops *loops = loop_optimizer_init (dump);
+
+  if (!loops)
+    return NULL;
+
+  /* Creation of preheaders may create redundant phi nodes if the loop is
+     entered by more than one edge, but the initial value of the induction
+     variable is the same on all of them.  */
+  kill_redundant_phi_nodes ();
+  rewrite_into_ssa (false);
+  bitmap_clear (vars_to_rename);
+
+  return loops;
+}
+
+/* The loop superpass.  */
+
+static bool
+gate_loop (void)
+{
+  return flag_tree_loop_optimize != 0;
+}
+
+struct tree_opt_pass pass_loop = 
+{
+  "loop",                              /* name */
+  gate_loop,                           /* gate */
+  NULL,                                        /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_TREE_LOOP,                                /* tv_id */
+  PROP_cfg,                            /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  TODO_ggc_collect,                    /* todo_flags_start */
+  TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect  /* todo_flags_finish */
+};
+
+/* Loop optimizer initialization.  */
+
+static void
+tree_ssa_loop_init (void)
+{
+  current_loops = tree_loop_optimizer_init (dump_file);
+}
+  
+struct tree_opt_pass pass_loop_init = 
+{
+  "loopinit",                          /* name */
+  NULL,                                        /* gate */
+  tree_ssa_loop_init,                  /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  0,                                   /* tv_id */
+  PROP_cfg,                            /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  0                                    /* todo_flags_finish */
+};
+
+/* Loop optimizer finalization.  */
+
+static void
+tree_ssa_loop_done (void)
+{
+  if (!current_loops)
+    return;
+
+  loop_optimizer_finalize (current_loops,
+                          (dump_flags & TDF_DETAILS ? dump_file : NULL));
+  current_loops = NULL;
+  cleanup_tree_cfg ();
+}
+  
+struct tree_opt_pass pass_loop_done = 
+{
+  "loopdone",                          /* name */
+  NULL,                                        /* gate */
+  tree_ssa_loop_done,                  /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  0,                                   /* tv_id */
+  PROP_cfg,                            /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  0                                    /* todo_flags_finish */
+};
 
index a931d9f7fef6c769919e568aff7f4adb37dedfba..37b83bfeca59ebb580fc5adab29e63f9a211b1e7 100644 (file)
@@ -926,7 +926,7 @@ check_phi_redundancy (tree phi, tree *eq_to)
    The most important effect of this pass is to remove degenerate PHI
    nodes created by removing unreachable code.  */
 
-static void
+void
 kill_redundant_phi_nodes (void)
 {
   tree *eq_to;