This PR is about straight-line code not being as much vectorized in Ada as in C or C++. The problem stems from the very conservative semantics implemented under -fnon-call-exceptions for the sake of Java. We don't need it in Ada.
Tested on x86_64-suse-linux, OK for the mainline? 2012-06-13 Eric Botcazou <ebotca...@adacore.com> PR middle-end/53590 * common.opt (-fdelete-dead-exceptions): New switch. * doc/invoke.texi (Optimization Options): Document it. * cse.c (insn_live_p): Do not return true for an insn that could throw if dead exceptions can be deleted. * dce.c (can_alter_cfg): New flag. (deletable_insn_p): Do not return false for an insn that can throw if the CFG can be altered and dead exceptions can be deleted. (init_dce): Set can_alter_cfg to false for fast DCE, true otherwise. * dse.c (scan_insn): Do not preserve an insn that could throw if dead exceptions can be deleted. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Do not mark a statement that could throw as necessary if dead exceptions can be deleted. ada/ * gcc-interface/misc.c (gnat_init_options_struct): Set opts->x_flag_delete_dead_exceptions to 1. -- Eric Botcazou
Index: common.opt =================================================================== --- common.opt (revision 188445) +++ common.opt (working copy) @@ -979,6 +987,10 @@ fdelayed-branch Common Report Var(flag_delayed_branch) Optimization Attempt to fill delay slots of branch instructions +fdelete-dead-exceptions +Common Report Var(flag_delete_dead_exceptions) Init(0) Optimization +Delete dead statements that may raise exceptions + fdelete-null-pointer-checks Common Report Var(flag_delete_null_pointer_checks) Init(1) Optimization Delete useless null pointer checks Index: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 188445) +++ doc/invoke.texi (working copy) @@ -359,7 +359,7 @@ Objective-C and Objective-C++ Dialects}. -fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules @gol -fcx-limited-range @gol -fdata-sections -fdce -fdelayed-branch @gol --fdelete-null-pointer-checks -fdevirtualize -fdse @gol +-fdelete-dead-exceptions -fdelete-null-pointer-checks -fdevirtualize -fdse @gol -fearly-inlining -fipa-sra -fexpensive-optimizations -ffat-lto-objects @gol -ffast-math -ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol -fforward-propagate -ffp-contract=@var{style} -ffunction-sections @gol @@ -6774,6 +6786,16 @@ branch-less equivalents. Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}. +@item -fdelete-dead-exceptions +@opindex fdelete-dead-exceptions +Assume that statements that may raise exceptions but don't otherwise contribute +to the execution of the program can be optimized away. + +Most languages supporting exceptions disable this option at all levels. +Otherwise it is enabled at all levels: @option{-O0}, @option{-O1}, +@option{-O2}, @option{-O3}, @option{-Os}. Passes that use the information +are enabled independently at different optimization levels. + @item -fdelete-null-pointer-checks @opindex fdelete-null-pointer-checks Assume that programs cannot safely dereference null pointers, and that Index: cse.c =================================================================== --- cse.c (revision 188445) +++ cse.c (working copy) @@ -6800,7 +6800,7 @@ static bool insn_live_p (rtx insn, int *counts) { int i; - if (insn_could_throw_p (insn)) + if (!flag_delete_dead_exceptions && insn_could_throw_p (insn)) return true; else if (GET_CODE (PATTERN (insn)) == SET) return set_live_p (PATTERN (insn), insn, counts); Index: dce.c =================================================================== --- dce.c (revision 188445) +++ dce.c (working copy) @@ -47,6 +47,9 @@ along with GCC; see the file COPYING3. we don't want to reenter it. */ static bool df_in_progress = false; +/* True if we are allowed to alter the CFG in this pass. */ +static bool can_alter_cfg = false; + /* Instructions that have been marked but whose dependencies have not yet been processed. */ static VEC(rtx,heap) *worklist; @@ -113,8 +116,10 @@ deletable_insn_p (rtx insn, bool fast, b if (!NONJUMP_INSN_P (insn)) return false; - /* Don't delete insns that can throw. */ - if (!insn_nothrow_p (insn)) + /* Don't delete insns that can throw if we need to preserve the CFG or + statements that may raise exceptions. */ + if ((!can_alter_cfg || !flag_delete_dead_exceptions) + && !insn_nothrow_p (insn)) return false; body = PATTERN (insn); @@ -711,7 +716,10 @@ init_dce (bool fast) { bitmap_obstack_initialize (&dce_blocks_bitmap_obstack); bitmap_obstack_initialize (&dce_tmp_bitmap_obstack); + can_alter_cfg = false; } + else + can_alter_cfg = true; marked = sbitmap_alloc (get_max_uid () + 1); sbitmap_zero (marked); Index: dse.c =================================================================== --- dse.c (revision 188445) +++ dse.c (working copy) @@ -2628,7 +2628,7 @@ scan_insn (bb_info_t bb_info, rtx insn) them. */ if ((GET_CODE (PATTERN (insn)) == CLOBBER) || volatile_refs_p (PATTERN (insn)) - || insn_could_throw_p (insn) + || (!flag_delete_dead_exceptions && insn_could_throw_p (insn)) || (RTX_FRAME_RELATED_P (insn)) || find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX)) insn_info->cannot_delete = true; Index: tree-ssa-dce.c =================================================================== --- tree-ssa-dce.c (revision 188445) +++ tree-ssa-dce.c (working copy) @@ -272,8 +272,10 @@ static void mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive) { /* With non-call exceptions, we have to assume that all statements could - throw. If a statement may throw, it is inherently necessary. */ - if (cfun->can_throw_non_call_exceptions && stmt_could_throw_p (stmt)) + throw. If a statement could throw, it can be deemed necessary. */ + if (cfun->can_throw_non_call_exceptions + && !flag_delete_dead_exceptions + && stmt_could_throw_p (stmt)) { mark_stmt_necessary (stmt, true); return; Index: ada/gcc-interface/misc.c =================================================================== --- ada/gcc-interface/misc.c (revision 188445) +++ ada/gcc-interface/misc.c (working copy) @@ -167,6 +164,9 @@ gnat_init_options_struct (struct gcc_opt { /* Uninitialized really means uninitialized in Ada. */ opts->x_flag_zero_initialized_in_bss = 0; + + /* We can delete dead statements that may raise exceptions in Ada. */ + opts->x_flag_delete_dead_exceptions = 1; } /* Initialize for option processing. */