re PR middle-end/53590 (compiler fails to generate SIMD instruction for FP division)

PR middle-end/53590
	* common.opt (-fdelete-dead-exceptions): New switch.
	* doc/invoke.texi (Code Gen Options): Document it.
	* cse.c (count_reg_usage) <CALL_INSN>: Use !insn_nothrow_p in lieu of
	insn_could_throw_p predicate.  Do not skip an insn that could throw
	if dead exceptions can be deleted.
	(insn_live_p): Likewise, do not return true in that case.
	* 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): Use !insn_nothrow_p in lieu of insn_could_throw_
	predicate. Do not preserve an insn that could throw if dead exceptions
	can be deleted.
	* function.h (struct function): Add can_delete_dead_exceptions flag.
	* function.c (allocate_struct_function): Set it.
	* lto-streamer-in.c (input_struct_function_base): Stream it.
	* lto-streamer-out.c (input_struct_function_base): Likewise.
	* 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.

From-SVN: r188651
This commit is contained in:
Eric Botcazou 2012-06-15 09:22:00 +00:00 committed by Eric Botcazou
parent 6724292e72
commit 2da02156af
13 changed files with 71 additions and 10 deletions

View File

@ -1,3 +1,27 @@
2012-06-15 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/53590
* common.opt (-fdelete-dead-exceptions): New switch.
* doc/invoke.texi (Code Gen Options): Document it.
* cse.c (count_reg_usage) <CALL_INSN>: Use !insn_nothrow_p in lieu of
insn_could_throw_p predicate. Do not skip an insn that could throw
if dead exceptions can be deleted.
(insn_live_p): Likewise, do not return true in that case.
* 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): Use !insn_nothrow_p in lieu of insn_could_throw_
predicate. Do not preserve an insn that could throw if dead exceptions
can be deleted.
* function.h (struct function): Add can_delete_dead_exceptions flag.
* function.c (allocate_struct_function): Set it.
* lto-streamer-in.c (input_struct_function_base): Stream it.
* lto-streamer-out.c (input_struct_function_base): Likewise.
* 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.
2012-06-14 Maxim Kuvyrkov <maxim@codesourcery.com>
* config/tilegx/sync.md (atomic_fetch_sub<mode>): Fix typo.

View File

@ -1,3 +1,9 @@
2012-06-15 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/53590
* gcc-interface/misc.c (gnat_init_options_struct): Set
opts->x_flag_delete_dead_exceptions to 1.
2012-06-14 Jose Ruiz <ruiz@adacore.com>
* gcc-interface/Make-lang.in (ada.install-common, ada.uninstall):

View File

@ -167,6 +167,9 @@ gnat_init_options_struct (struct gcc_options *opts)
{
/* Uninitialized really means uninitialized in Ada. */
opts->x_flag_zero_initialized_in_bss = 0;
/* We can delete dead instructions that may throw exceptions in Ada. */
opts->x_flag_delete_dead_exceptions = 1;
}
/* Initialize for option processing. */

View File

@ -979,6 +979,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)
Delete dead instructions that may throw exceptions
fdelete-null-pointer-checks
Common Report Var(flag_delete_null_pointer_checks) Init(1) Optimization
Delete useless null pointer checks

View File

@ -599,7 +599,6 @@ static void invalidate_from_clobbers (rtx);
static void invalidate_from_sets_and_clobbers (rtx);
static rtx cse_process_notes (rtx, rtx, bool *);
static void cse_extended_basic_block (struct cse_basic_block_data *);
static void count_reg_usage (rtx, int *, rtx, int);
static int check_for_label_ref (rtx *, void *);
extern void dump_class (struct table_elt*);
static void get_cse_reg_info_1 (unsigned int regno);
@ -6692,10 +6691,11 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
case CALL_INSN:
case INSN:
case JUMP_INSN:
/* We expect dest to be NULL_RTX here. If the insn may trap,
/* We expect dest to be NULL_RTX here. If the insn may throw,
or if it cannot be deleted due to side-effects, mark this fact
by setting DEST to pc_rtx. */
if (insn_could_throw_p (x) || side_effects_p (PATTERN (x)))
if ((!cfun->can_delete_dead_exceptions && !insn_nothrow_p (x))
|| side_effects_p (PATTERN (x)))
dest = pc_rtx;
if (code == CALL_INSN)
count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr);
@ -6800,7 +6800,7 @@ static bool
insn_live_p (rtx insn, int *counts)
{
int i;
if (insn_could_throw_p (insn))
if (!cfun->can_delete_dead_exceptions && !insn_nothrow_p (insn))
return true;
else if (GET_CODE (PATTERN (insn)) == SET)
return set_live_p (PATTERN (insn), insn, counts);

View File

@ -47,6 +47,9 @@ along with GCC; see the file COPYING3. If not see
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,9 @@ deletable_insn_p (rtx insn, bool fast, bitmap arg_stores)
if (!NONJUMP_INSN_P (insn))
return false;
/* Don't delete insns that can throw. */
if (!insn_nothrow_p (insn))
/* Don't delete insns that may throw if we cannot do so. */
if (!(cfun->can_delete_dead_exceptions && can_alter_cfg)
&& !insn_nothrow_p (insn))
return false;
body = PATTERN (insn);
@ -711,7 +715,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);

View File

@ -975,7 +975,7 @@ See S/390 and zSeries Options.
@xref{Code Gen Options,,Options for Code Generation Conventions}.
@gccoptlist{-fcall-saved-@var{reg} -fcall-used-@var{reg} @gol
-ffixed-@var{reg} -fexceptions @gol
-fnon-call-exceptions -funwind-tables @gol
-fnon-call-exceptions -fdelete-dead-exceptions -funwind-tables @gol
-fasynchronous-unwind-tables @gol
-finhibit-size-directive -finstrument-functions @gol
-finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{} @gol
@ -19317,6 +19317,14 @@ instructions to throw exceptions, i.e.@: memory references or floating-point
instructions. It does not allow exceptions to be thrown from
arbitrary signal handlers such as @code{SIGALRM}.
@item -fdelete-dead-exceptions
@opindex fdelete-dead-exceptions
Consider that instructions that may throw exceptions but don't otherwise
contribute to the execution of the program can be optimized away.
This option is enabled by default for the Ada front end, as permitted by
the Ada language specification.
Optimization passes that cause dead exceptions to be removed are enabled independently at different optimization levels.
@item -funwind-tables
@opindex funwind-tables
Similar to @option{-fexceptions}, except that it just generates any needed

View File

@ -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)
|| (!cfun->can_delete_dead_exceptions && !insn_nothrow_p (insn))
|| (RTX_FRAME_RELATED_P (insn))
|| find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX))
insn_info->cannot_delete = true;

View File

@ -4496,6 +4496,7 @@ allocate_struct_function (tree fndecl, bool abstract_p)
/* ??? This could be set on a per-function basis by the front-end
but is this worth the hassle? */
cfun->can_throw_non_call_exceptions = flag_non_call_exceptions;
cfun->can_delete_dead_exceptions = flag_delete_dead_exceptions;
}
}

View File

@ -615,6 +615,10 @@ struct GTY(()) function {
exceptions. */
unsigned int can_throw_non_call_exceptions : 1;
/* Nonzero if instructions that may throw exceptions but don't otherwise
contribute to the execution of the program can be deleted. */
unsigned int can_delete_dead_exceptions : 1;
/* Fields below this point are not set for abstract functions; see
allocate_struct_function. */

View File

@ -803,6 +803,7 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
fn->returns_pcc_struct = bp_unpack_value (&bp, 1);
fn->returns_struct = bp_unpack_value (&bp, 1);
fn->can_throw_non_call_exceptions = bp_unpack_value (&bp, 1);
fn->can_delete_dead_exceptions = bp_unpack_value (&bp, 1);
fn->always_inline_functions_inlined = bp_unpack_value (&bp, 1);
fn->after_inlining = bp_unpack_value (&bp, 1);
fn->stdarg = bp_unpack_value (&bp, 1);

View File

@ -761,6 +761,7 @@ output_struct_function_base (struct output_block *ob, struct function *fn)
bp_pack_value (&bp, fn->returns_pcc_struct, 1);
bp_pack_value (&bp, fn->returns_struct, 1);
bp_pack_value (&bp, fn->can_throw_non_call_exceptions, 1);
bp_pack_value (&bp, fn->can_delete_dead_exceptions, 1);
bp_pack_value (&bp, fn->always_inline_functions_inlined, 1);
bp_pack_value (&bp, fn->after_inlining, 1);
bp_pack_value (&bp, fn->stdarg, 1);

View File

@ -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
&& !cfun->can_delete_dead_exceptions
&& stmt_could_throw_p (stmt))
{
mark_stmt_necessary (stmt, true);
return;