Patchwork Fix c++/53602, part 2

login
register
mail settings
Submitter Richard Henderson
Date June 9, 2012, 4:40 p.m.
Message ID <4FD37C67.2010500@redhat.com>
Download mbox | patch
Permalink /patch/163936/
State New
Headers show

Comments

Richard Henderson - June 9, 2012, 4:40 p.m.
The second patch that would have hidden the ICE rather than truly fixing it.

At first I was simply annoyed that I didn't have a dump file to look at that matched up with the actual input to the CSA pass.  That alone warranted splitting out the CLEANUP_CROSSJUMP call to its own pass.

However, I got to thinking about it more and its right for even more reasons:

 * -fno-combine-stack-adjustments overrides -fcrossjumping

 * The CSA pass is a block-local optimization that works better when it can
   see more code.  Indeed, with this particular test case the reason that we
   don't ICE with this patch is that CSA was able to propagate the ARGS_SIZE
   note onto a following stack push insn (which post cross-jumping is split
   into a new block), obviating the need for the clobber insn that the Part1
   patch introduces.

 * The crossjumping pass works better with fewer insns to compare.  Therefore
   let the CSA pass run first and have it delete what it can.

Note that I renamed the old jump2 pass.  I felt silly adding a jump3 pass when
the original jump1 pass no longer exists.

Committed only to mainline after testing on x86_64 and i686.


r~
PR c++/53602
            * cfgcleanup.c (execute_jump): Rename from rest_of_handle_jump2.
            (pass_jump): Rename from pass_jump2.
            (execute_jump2, pass_jump2): New.
            * combine-stack-adj.c (rest_of_handle_stack_adjustments): Don't
            perform cfg cleanup here.  Move the test of PUSH_ROUNDING
            and ACCUMULATE_OUTGOING_ARGS test...
            (gate_handle_stack_adjustments): ... here.
            * passes.c (init_optimization_passes): Update for pass_jump2 rename.
            Place new pass_jump2 after pass_stack_adjustments.
            * tree-pass.h (pass_jump): Declare.

Patch

diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 619b274..1aa4cbb 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -2990,7 +2990,7 @@  cleanup_cfg (int mode)
 }
 
 static unsigned int
-rest_of_handle_jump2 (void)
+execute_jump (void)
 {
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
   if (dump_file)
@@ -3000,22 +3000,47 @@  rest_of_handle_jump2 (void)
   return 0;
 }
 
+struct rtl_opt_pass pass_jump =
+{
+ {
+  RTL_PASS,
+  "jump",				/* name */
+  NULL,					/* gate */
+  execute_jump,				/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  TV_JUMP,				/* tv_id */
+  0,					/* properties_required */
+  0,					/* properties_provided */
+  0,					/* properties_destroyed */
+  TODO_ggc_collect,			/* todo_flags_start */
+  TODO_verify_rtl_sharing,		/* todo_flags_finish */
+ }
+};
+
+static unsigned int
+execute_jump2 (void)
+{
+  cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0);
+  return 0;
+}
 
 struct rtl_opt_pass pass_jump2 =
 {
  {
   RTL_PASS,
-  "jump",                               /* name */
-  NULL,                                 /* gate */
-  rest_of_handle_jump2,			/* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  TV_JUMP,                              /* tv_id */
-  0,                                    /* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  TODO_ggc_collect,                     /* todo_flags_start */
-  TODO_verify_rtl_sharing,              /* todo_flags_finish */
+  "jump2",				/* name */
+  NULL,					/* gate */
+  execute_jump2,			/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  TV_JUMP,				/* tv_id */
+  0,					/* properties_required */
+  0,					/* properties_provided */
+  0,					/* properties_destroyed */
+  TODO_ggc_collect,			/* todo_flags_start */
+  TODO_verify_rtl_sharing,		/* todo_flags_finish */
  }
 };
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index b46fe3b..65e8f04 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -626,26 +626,23 @@  combine_stack_adjustments_for_block (basic_block bb)
 static bool
 gate_handle_stack_adjustments (void)
 {
-  return flag_combine_stack_adjustments;
-}
-
-static unsigned int
-rest_of_handle_stack_adjustments (void)
-{
-  cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0);
-
   /* This is kind of a heuristic.  We need to run combine_stack_adjustments
      even for machines with possibly nonzero TARGET_RETURN_POPS_ARGS
      and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
      push instructions will have popping returns.  */
 #ifndef PUSH_ROUNDING
-  if (!ACCUMULATE_OUTGOING_ARGS)
+  if (ACCUMULATE_OUTGOING_ARGS)
+    return false;
 #endif
-    {
-      df_note_add_problem ();
-      df_analyze ();
-      combine_stack_adjustments ();
-    }
+  return flag_combine_stack_adjustments;
+}
+
+static unsigned int
+rest_of_handle_stack_adjustments (void)
+{
+  df_note_add_problem ();
+  df_analyze ();
+  combine_stack_adjustments ();
   return 0;
 }
 
diff --git a/gcc/passes.c b/gcc/passes.c
index bfd4ce3..3974231 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1515,7 +1515,7 @@  init_optimization_passes (void)
       struct opt_pass **p = &pass_rest_of_compilation.pass.sub;
       NEXT_PASS (pass_instantiate_virtual_regs);
       NEXT_PASS (pass_into_cfg_layout_mode);
-      NEXT_PASS (pass_jump2);
+      NEXT_PASS (pass_jump);
       NEXT_PASS (pass_lower_subreg);
       NEXT_PASS (pass_df_initialize_opt);
       NEXT_PASS (pass_cse);
@@ -1577,6 +1577,7 @@  init_optimization_passes (void)
 	  NEXT_PASS (pass_thread_prologue_and_epilogue);
 	  NEXT_PASS (pass_rtl_dse2);
 	  NEXT_PASS (pass_stack_adjustments);
+	  NEXT_PASS (pass_jump2);
 	  NEXT_PASS (pass_peephole2);
 	  NEXT_PASS (pass_if_after_reload);
 	  NEXT_PASS (pass_regrename);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index aa2959c..0552937 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -484,6 +484,7 @@  extern struct rtl_opt_pass pass_expand;
 extern struct rtl_opt_pass pass_instantiate_virtual_regs;
 extern struct rtl_opt_pass pass_rtl_fwprop;
 extern struct rtl_opt_pass pass_rtl_fwprop_addr;
+extern struct rtl_opt_pass pass_jump;
 extern struct rtl_opt_pass pass_jump2;
 extern struct rtl_opt_pass pass_lower_subreg;
 extern struct rtl_opt_pass pass_cse;