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.  */

Reply via email to