This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] EH_USES df fix (PR target/37378, take 2)
Jakub Jelinek wrote:
> Hi!
>
> As pointed out by Hans-Peter Nilsson, we want to make EH_USES regs live even
> if some code path ends with an endless loop, the insns in between still
> might throw, or during debugging the debugger (or something called from
> async signal handler) might want to do a backtrace). The patch I've posted
> earlier doesn't cure e.g.
>
>
i seriously doubt that this patch will bootstrap on a non ia-64 target,
but once you fix that, the patch is ok. (the problem is that the
declaration of i needs to be in an ifdef EH_USES.)
> extern int foo (int, int);
> extern int bar (void);
>
> int
> baz (int x, int y)
> {
> if (__builtin_expect (y == 0, 0))
> {
> foo (x + y, x * y);
> bar ();
> while (1)
> ;
> }
>
> if (x == (int) 0x80000000L && y == -1)
> return x;
>
> return x / y;
> }
> at -O2 - rp is saved into a local register only if y != 0.
> The following alternative patch makes EH_USES registers just live
> everywhere, which IMHO matches best what we really want - let those
> registers stay live through the whole function.
>
> Bootstrapped/regtested on ia64-linux, ok for trunk?
>
> 2008-10-27 Jakub Jelinek <jakub@redhat.com>
>
> PR target/37378
> * df-scan.c (df_bb_refs_collect): Don't handle EH_USES here.
> (df_get_entry_block_def_set): Neither here.
> (df_get_regular_block_artificial_uses): Add EH_USES registers.
>
> --- gcc/df-scan.c.jj 2008-10-14 07:58:50.000000000 -0400
> +++ gcc/df-scan.c 2008-10-27 14:13:41.000000000 -0400
> @@ -3555,29 +3555,6 @@ df_bb_refs_collect (struct df_collection
> }
> #endif
>
> -
> -#ifdef EH_USES
> - if (bb_has_eh_pred (bb))
> - {
> - unsigned int i;
> - /* This code is putting in an artificial ref for the use at the
> - TOP of the block that receives the exception. It is too
> - cumbersome to actually put the ref on the edge. We could
> - either model this at the top of the receiver block or the
> - bottom of the sender block.
> -
> - The bottom of the sender block is problematic because not all
> - out-edges of a block are eh-edges. However, it is true
> - that all edges into a block are either eh-edges or none of
> - them are eh-edges. Thus, we can model this at the top of the
> - eh-receiver for all of the edges at once. */
> - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> - if (EH_USES (i))
> - df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
> - bb, NULL, DF_REF_REG_USE, DF_REF_AT_TOP, -1, -1, 0);
> - }
> -#endif
> -
> /* Add the hard_frame_pointer if this block is the target of a
> non-local goto. */
> if (bb->flags & BB_NON_LOCAL_GOTO_TARGET)
> @@ -3667,6 +3644,8 @@ df_bb_refs_record (int bb_index, bool sc
> static void
> df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses)
> {
> + unsigned int i;
> +
> bitmap_clear (regular_block_artificial_uses);
>
> if (reload_completed)
> @@ -3702,6 +3681,20 @@ df_get_regular_block_artificial_uses (bi
> }
> /* The all-important stack pointer must always be live. */
> bitmap_set_bit (regular_block_artificial_uses, STACK_POINTER_REGNUM);
> +
> +#ifdef EH_USES
> + /* EH_USES registers are used:
> + 1) at all insns that might throw (calls or with -fnon-call-exceptions
> + trapping insns)
> + 2) in all EH edges
> + 3) to support backtraces and/or debugging, anywhere between their
> + initialization and where they the saved registers are restored
> + from them, including the cases where we don't reach the epilogue
> + (noreturn call or infinite loop). */
> + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> + if (EH_USES (i))
> + bitmap_set_bit (regular_block_artificial_uses, i);
> +#endif
> }
>
>
> @@ -3826,16 +3819,6 @@ df_get_entry_block_def_set (bitmap entry
> /* These registers are live everywhere. */
> if (!reload_completed)
> {
> -#ifdef EH_USES
> - /* The ia-64, the only machine that uses this, does not define these
> - until after reload. */
> - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> - if (EH_USES (i))
> - {
> - bitmap_set_bit (entry_block_defs, i);
> - }
> -#endif
> -
> #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
> /* Pseudos with argument area equivalences may require
> reloading via the argument pointer. */
>
>
> Jakub
>