This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] make loop2 a series of separate passes


Hi,

One of the advantages of splitting "I do everything" passes up into
multiple patches, is that you can have separate dump files for them
and separate flags, etc.  Unfortunately, loop2 still produces only
a single dump.  I figured it would be better to separate the loop2
passes into different passes (d'oh).  Which is what the patch below
does.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK?

Gr.
Steven

	* loop-init.c (rest_of_handle_loop2): Remove.
	(rtl_loop_init, rtl_loop_done, rtl_move_loop_invariants,
	rtl_unswitch, rtl_unroll_and_peel_loops, rtl_doloop): New functions.
	(pass_rtl_loop_init, pass_rtl_loop_done,
	pass_rtl_move_loop_invariants, pass_rtl_unswitch,
	pass_rtl_unroll_and_peel_loops, pass_rtl_doloop): New passes.
	* tree-ssa-loop.c (pass_loop, pass_loop_init, pass_loop_done,
	pass_unswitch): Rename to pass_tree_loop, pass_tree_loop_init,
	pass_tree_loop_done, and pass_tree_unswitch.
	(gate_loop): Rename to gate_tree_loop.
	* passes.c (init_optimization_passes): Update for renamed tree
	loop passes.  Add the new loop2 passes as subpasses of loop2.
	* tree-pass.h: Add extern declarations for the new loop2 subpasses.
	Update for the renamed tree loop passes.

Index: loop-init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop-init.c,v
retrieving revision 1.18
diff -u -3 -p -r1.18 loop-init.c
--- loop-init.c	5 Jul 2005 16:20:05 -0000	1.18
+++ loop-init.c	14 Jul 2005 16:25:23 -0000
@@ -1,4 +1,4 @@
-/* Loop optimizer initialization routines.
+/* Loop optimizer initialization routines and RTL loop optimizaiton passes.
    Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -32,7 +32,9 @@ Software Foundation, 51 Franklin Street,
 #include "timevar.h"
 #include "flags.h"
 
-/* Initialize loop optimizer.  */
+
+/* Initialize loop optimizer.  This is used by the tree and RTL loop
+   optimizers.  */
 
 struct loops *
 loop_optimizer_init (FILE *dumpfile)
@@ -119,7 +121,11 @@ loop_optimizer_finalize (struct loops *l
   verify_flow_info ();
 #endif
 }
+
 
+/* Gate for the RTL loop superpass.  The actual passes are subpasses.
+   See passes.c for more on that.  */
+
 static bool
 gate_handle_loop2 (void)
 {
@@ -131,45 +137,64 @@ gate_handle_loop2 (void)
               || flag_branch_on_count_reg));
 }
 
-/* Perform loop optimizations.  It might be better to do them a bit
-   sooner, but we want the profile feedback to work more
-   efficiently.  */
-static void
-rest_of_handle_loop2 (void)
+struct tree_opt_pass pass_loop2 =
 {
-  struct loops *loops;
-  basic_block bb;
+  "loop2",                              /* name */
+  gate_handle_loop2, 		        /* gate */
+  NULL,                                 /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_LOOP,                              /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func |
+  TODO_ggc_collect,                     /* todo_flags_finish */
+  'L'                                   /* letter */
+};
 
+
+/* Initialization of the RTL loop passes.  */
+static void
+rtl_loop_init (void)
+{
   if (dump_file)
     dump_flow_info (dump_file);
 
   /* Initialize structures for layout changes.  */
   cfg_layout_initialize (0);
 
-  loops = loop_optimizer_init (dump_file);
+  current_loops = loop_optimizer_init (dump_file);
+}
 
-  if (loops)
-    {
-      /* The optimizations:  */
-      if (flag_move_loop_invariants)
-        move_loop_invariants (loops);
-
-      if (flag_unswitch_loops)
-        unswitch_loops (loops);
-
-      if (flag_peel_loops || flag_unroll_loops)
-        unroll_and_peel_loops (loops,
-                               (flag_peel_loops ? UAP_PEEL : 0) |
-                               (flag_unroll_loops ? UAP_UNROLL : 0) |
-                               (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0));
+struct tree_opt_pass pass_rtl_loop_init =
+{
+  "loopinit",                           /* name */
+  NULL,                                 /* gate */
+  rtl_loop_init,                        /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_LOOP,                              /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func,                       /* todo_flags_finish */
+  'L'                                   /* letter */
+};
 
-#ifdef HAVE_doloop_end
-      if (flag_branch_on_count_reg && HAVE_doloop_end)
-        doloop_optimize_loops (loops);
-#endif /* HAVE_doloop_end */
+
+/* Finalization of the RTL loop passes.  */
+static void
+rtl_loop_done (void)
+{
+  basic_block bb;
 
-      loop_optimizer_finalize (loops, dump_file);
-    }
+  if (current_loops)
+    loop_optimizer_finalize (current_loops, dump_file);
 
   free_dominance_info (CDI_DOMINATORS);
 
@@ -184,13 +209,15 @@ rest_of_handle_loop2 (void)
   reg_scan (get_insns (), max_reg_num ());
   if (dump_file)
     dump_flow_info (dump_file);
+
+  current_loops = NULL;
 }
 
-struct tree_opt_pass pass_loop2 =
+struct tree_opt_pass pass_rtl_loop_done =
 {
-  "loop2",                              /* name */
-  gate_handle_loop2, 		        /* gate */
-  rest_of_handle_loop2,      		/* execute */
+  "loopdone",                           /* name */
+  NULL,                                 /* gate */
+  rtl_loop_done,                        /* execute */
   NULL,                                 /* sub */
   NULL,                                 /* next */
   0,                                    /* static_pass_number */
@@ -199,8 +226,126 @@ struct tree_opt_pass pass_loop2 =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func |
-  TODO_ggc_collect,                     /* todo_flags_finish */
+  TODO_dump_func,                       /* todo_flags_finish */
+  'L'                                   /* letter */
+};
+
+
+/* Loop invariant code motion.  */
+static void
+rtl_move_loop_invariants (void)
+{
+  if (current_loops && flag_move_loop_invariants)
+    move_loop_invariants (current_loops);
+}
+
+struct tree_opt_pass pass_rtl_move_loop_invariants =
+{
+  "loop_invariant",                     /* name */
+  NULL,                                 /* gate */
+  rtl_move_loop_invariants,             /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_LOOP,                              /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func,                       /* todo_flags_finish */
+  'L'                                   /* letter */
+};
+
+
+/* Loop unswitching for RTL.  */
+static void
+rtl_unswitch (void)
+{
+  if (current_loops && flag_unswitch_loops)
+    unswitch_loops (current_loops);
+}
+
+struct tree_opt_pass pass_rtl_unswitch =
+{
+  "loop_unswitch",                      /* name */
+  NULL,                                 /* gate */
+  rtl_unswitch,                         /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_LOOP,                              /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func,                       /* todo_flags_finish */
+  'L'                                   /* letter */
+};
+
+
+/* Loop unswitching for RTL.  */
+static void
+rtl_unroll_and_peel_loops (void)
+{
+  if (current_loops
+      && (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops))
+    {
+      int flags = 0;
+
+      if (flag_peel_loops)
+	flags |= UAP_PEEL;
+      if (flag_unroll_loops)
+	flags |= UAP_UNROLL;
+      if (flag_unroll_all_loops)
+	flags |= UAP_UNROLL_ALL;
+
+      unroll_and_peel_loops (current_loops, flags);
+    }
+}
+
+struct tree_opt_pass pass_rtl_unroll_and_peel_loops =
+{
+  "loop_unroll",                        /* name */
+  NULL,                                 /* gate */
+  rtl_unroll_and_peel_loops,            /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_LOOP,                              /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func,                       /* todo_flags_finish */
+  'L'                                   /* letter */
+};
+
+
+/* The doloop optimization.  */
+static void
+rtl_doloop (void)
+{
+#ifdef HAVE_doloop_end
+  if (current_loops
+      && (flag_branch_on_count_reg && HAVE_doloop_end))
+    doloop_optimize_loops (current_loops);
+#endif
+}
+
+struct tree_opt_pass pass_rtl_doloop =
+{
+  "loop_doloop",                        /* name */
+  NULL,                                 /* gate */
+  rtl_doloop,                           /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_LOOP,                              /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func,                       /* todo_flags_finish */
   'L'                                   /* letter */
 };
 
Index: passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.101
diff -u -3 -p -r2.101 passes.c
--- passes.c	11 Jul 2005 23:59:07 -0000	2.101
+++ passes.c	14 Jul 2005 16:25:23 -0000
@@ -520,7 +520,7 @@ init_optimization_passes (void)
   NEXT_PASS (pass_reassoc);
   NEXT_PASS (pass_pre);
   NEXT_PASS (pass_sink_code);
-  NEXT_PASS (pass_loop);
+  NEXT_PASS (pass_tree_loop);
   NEXT_PASS (pass_dominator);
   NEXT_PASS (pass_copy_prop);
   NEXT_PASS (pass_cd_dce);
@@ -548,11 +548,11 @@ init_optimization_passes (void)
   NEXT_PASS (pass_cleanup_cfg_post_optimizing);
   *p = NULL;
 
-  p = &pass_loop.sub;
-  NEXT_PASS (pass_loop_init);
+  p = &pass_tree_loop.sub;
+  NEXT_PASS (pass_tree_loop_init);
   NEXT_PASS (pass_copy_prop);
   NEXT_PASS (pass_lim);
-  NEXT_PASS (pass_unswitch);
+  NEXT_PASS (pass_tree_unswitch);
   NEXT_PASS (pass_scev_cprop);
   NEXT_PASS (pass_empty_loop);
   NEXT_PASS (pass_record_bounds);
@@ -566,9 +566,18 @@ init_optimization_passes (void)
   NEXT_PASS (pass_lower_vector_ssa);
   NEXT_PASS (pass_complete_unroll);
   NEXT_PASS (pass_iv_optimize);
-  NEXT_PASS (pass_loop_done);
+  NEXT_PASS (pass_tree_loop_done);
   *p = NULL;
 
+  p = &pass_loop2.sub;
+  NEXT_PASS (pass_rtl_loop_init);
+  NEXT_PASS (pass_rtl_move_loop_invariants);
+  NEXT_PASS (pass_rtl_unswitch);
+  NEXT_PASS (pass_rtl_unroll_and_peel_loops);
+  NEXT_PASS (pass_rtl_doloop);
+  NEXT_PASS (pass_rtl_loop_done);
+  *p = NULL;
+  
   p = &pass_rest_of_compilation.sub;
   NEXT_PASS (pass_remove_unnecessary_notes);
   NEXT_PASS (pass_init_function);
@@ -587,6 +596,9 @@ init_optimization_passes (void)
   NEXT_PASS (pass_profiling);
   NEXT_PASS (pass_rtl_ifcvt);
   NEXT_PASS (pass_tracer);
+  /* Perform loop optimizations.  It might be better to do them a bit
+     sooner, but we want the profile feedback to work more
+     efficiently.  */
   NEXT_PASS (pass_loop2);
   NEXT_PASS (pass_web);
   NEXT_PASS (pass_cse2);
Index: tree-pass.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-pass.h,v
retrieving revision 2.49
diff -u -3 -p -r2.49 tree-pass.h
--- tree-pass.h	11 Jul 2005 23:59:11 -0000	2.49
+++ tree-pass.h	14 Jul 2005 16:25:24 -0000
@@ -222,10 +222,10 @@ extern struct tree_opt_pass pass_referen
 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_tree_loop;
+extern struct tree_opt_pass pass_tree_loop_init;
 extern struct tree_opt_pass pass_lim;
-extern struct tree_opt_pass pass_unswitch;
+extern struct tree_opt_pass pass_tree_unswitch;
 extern struct tree_opt_pass pass_iv_canon;
 extern struct tree_opt_pass pass_scev_cprop;
 extern struct tree_opt_pass pass_empty_loop;
@@ -234,7 +234,7 @@ extern struct tree_opt_pass pass_if_conv
 extern struct tree_opt_pass pass_vectorize;
 extern struct tree_opt_pass pass_complete_unroll;
 extern struct tree_opt_pass pass_iv_optimize;
-extern struct tree_opt_pass pass_loop_done;
+extern struct tree_opt_pass pass_tree_loop_done;
 extern struct tree_opt_pass pass_ch;
 extern struct tree_opt_pass pass_ccp;
 extern struct tree_opt_pass pass_build_ssa;
@@ -311,7 +311,15 @@ extern struct tree_opt_pass pass_cfg;
 extern struct tree_opt_pass pass_profiling;
 extern struct tree_opt_pass pass_rtl_ifcvt;
 extern struct tree_opt_pass pass_tracer;
+
 extern struct tree_opt_pass pass_loop2;
+extern struct tree_opt_pass pass_rtl_loop_init;
+extern struct tree_opt_pass pass_rtl_move_loop_invariants;
+extern struct tree_opt_pass pass_rtl_unswitch;
+extern struct tree_opt_pass pass_rtl_unroll_and_peel_loops;
+extern struct tree_opt_pass pass_rtl_doloop;
+extern struct tree_opt_pass pass_rtl_loop_done;
+
 extern struct tree_opt_pass pass_web;
 extern struct tree_opt_pass pass_cse2;
 extern struct tree_opt_pass pass_life;
Index: tree-ssa-loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop.c,v
retrieving revision 2.32
diff -u -3 -p -r2.32 tree-ssa-loop.c
--- tree-ssa-loop.c	11 Jul 2005 23:59:12 -0000	2.32
+++ tree-ssa-loop.c	14 Jul 2005 16:25:24 -0000
@@ -61,15 +61,15 @@ tree_loop_optimizer_init (FILE *dump)
 /* The loop superpass.  */
 
 static bool
-gate_loop (void)
+gate_tree_loop (void)
 {
   return flag_tree_loop_optimize != 0;
 }
 
-struct tree_opt_pass pass_loop = 
+struct tree_opt_pass pass_tree_loop = 
 {
   "loop",				/* name */
-  gate_loop,				/* gate */
+  gate_tree_loop,			/* gate */
   NULL,					/* execute */
   NULL,					/* sub */
   NULL,					/* next */
@@ -98,7 +98,7 @@ tree_ssa_loop_init (void)
   scev_initialize (current_loops);
 }
   
-struct tree_opt_pass pass_loop_init = 
+struct tree_opt_pass pass_tree_loop_init = 
 {
   "loopinit",				/* name */
   NULL,					/* gate */
@@ -166,7 +166,7 @@ gate_tree_ssa_loop_unswitch (void)
   return flag_unswitch_loops != 0;
 }
 
-struct tree_opt_pass pass_unswitch = 
+struct tree_opt_pass pass_tree_unswitch = 
 {
   "unswitch",				/* name */
   gate_tree_ssa_loop_unswitch,		/* gate */
@@ -454,7 +454,7 @@ tree_ssa_loop_done (void)
   current_loops = NULL;
 }
   
-struct tree_opt_pass pass_loop_done = 
+struct tree_opt_pass pass_tree_loop_done = 
 {
   "loopdone",				/* name */
   NULL,					/* gate */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]