[backport gcc-4.8/trunk r188360, adjusted for the fact that pass_jump(1) remains in 4.7 so the jump2->jump renaming is omitted and the new pass is called jump3; fixes PR47389 ] Date: Sat, 09 Jun 2012 09:40:07 -0700 From: Richard Henderson Subject: Fix c++/53602, part 2 List-Archive: 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~ gcc/ 2012-06-09 Richard Henderson PR c++/53602 * cfgcleanup.c (execute_jump3, pass_jump3): 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): Place new pass_jump3 after pass_stack_adjustments. * tree-pass.h (pass_jump3): Declare. --- gcc-4.7.3/gcc/cfgcleanup.c.~1~ 2013-02-01 15:00:12.000000000 +0100 +++ gcc-4.7.3/gcc/cfgcleanup.c 2013-05-19 18:20:44.806959881 +0200 @@ -3063,3 +3063,29 @@ struct rtl_opt_pass pass_jump2 = TODO_verify_rtl_sharing, /* todo_flags_finish */ } }; + +static unsigned int +execute_jump3 (void) +{ + cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0); + return 0; +} + +struct rtl_opt_pass pass_jump3 = +{ + { + RTL_PASS, + "jump3", /* name */ + NULL, /* gate */ + execute_jump3, /* 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 */ + } +}; --- gcc-4.7.3/gcc/combine-stack-adj.c.~1~ 2012-06-09 08:14:27.000000000 +0200 +++ gcc-4.7.3/gcc/combine-stack-adj.c 2013-05-19 18:16:57.447640003 +0200 @@ -626,26 +626,23 @@ combine_stack_adjustments_for_block (bas 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; } --- gcc-4.7.3/gcc/passes.c.~1~ 2012-02-24 12:38:39.000000000 +0100 +++ gcc-4.7.3/gcc/passes.c 2013-05-19 18:17:46.367493298 +0200 @@ -1498,6 +1498,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_jump3); NEXT_PASS (pass_peephole2); NEXT_PASS (pass_if_after_reload); NEXT_PASS (pass_regrename); --- gcc-4.7.3/gcc/tree-pass.h.~1~ 2011-12-22 16:01:25.000000000 +0100 +++ gcc-4.7.3/gcc/tree-pass.h 2013-05-19 18:17:23.337562243 +0200 @@ -494,6 +494,7 @@ extern struct rtl_opt_pass pass_instanti extern struct rtl_opt_pass pass_rtl_fwprop; extern struct rtl_opt_pass pass_rtl_fwprop_addr; extern struct rtl_opt_pass pass_jump2; +extern struct rtl_opt_pass pass_jump3; extern struct rtl_opt_pass pass_lower_subreg; extern struct rtl_opt_pass pass_cse; extern struct rtl_opt_pass pass_fast_rtl_dce;