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 <[email protected]>
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. */