This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RE: Persistent IA64 (and others?) exception failure
- From: "Boehm, Hans" <hans_boehm at hp dot com>
- To: "'Richard Henderson'" <rth at redhat dot com>, "Boehm, Hans" <hans_boehm at hp dot com>
- Cc: "'gcc at gcc dot gnu dot org'" <gcc at gcc dot gnu dot org>, "'tromey at redhat dot com'" <tromey at redhat dot com>, "MOSBERGER, DAVID (HP-PaloAlto,unix3)" <davidm at hpl dot hp dot com>
- Date: Tue, 19 Mar 2002 17:05:47 -0800
- Subject: RE: Persistent IA64 (and others?) exception failure
Thanks, Richard.
That works for me. SPECjbb works (with the signal handling patches still
under discussion). I no longer need my flow.c patch.
With this patch, the libjava tests have only 5 unexpected failures on
Itanium. Cxxtest fails because it can't find a library. I haven't tried to
track that down yet.
The other 4 failures are from PR218.java which tests NullPointer handling in
leaf procedures. Those seem to be unrelated. The immediate cause fo the
failure is that code to unwind through a signal handler fails to restore b0.
Oops. But after fixing that I still seem to have problems restoring stacked
registers. I'm looking at that now, but it also seems to be yet another
problem in the unwinder, unrelated to this patch.
Tom- I suspect those test results are a bit optimistic. Gij still seems to
have some other issues that aren't reflected in the test results.
Hans
> -----Original Message-----
> From: Richard Henderson [mailto:rth@redhat.com]
> Sent: Sunday, March 17, 2002 12:32 PM
> To: Boehm, Hans
> Cc: 'gcc@gcc.gnu.org'; 'tromey@redhat.com'; MOSBERGER, DAVID
> (HP-PaloAlto,unix3)
> Subject: Re: Persistent IA64 (and others?) exception failure
>
>
> On Thu, Mar 14, 2002 at 09:55:14AM -0800, Boehm, Hans wrote:
> > The gcc back end still occasionally optimizes away saving
> of the return
> > address at function calls that are known not to return,
> e.g. because they
> > always raise an exception. This was first pointed out a
> long time ago
> > (http://gcc.gnu.org/ml/gcc/2001-11/msg00960.html). Richard
> Henderson
> > suggested a better approach
> > (http://gcc.gnu.org/ml/gcc/2001-11/msg01290.html). But at
> least as of a
> > couple of days ago, this was still broken in 3.1.
>
> Try this.
>
>
> r~
>
>
>
> * flow.c (EH_USES): Provide default.
> (calculate_global_regs_live): Use it for EH edges and
> noreturn calls.
> * doc/tm.texi (EH_USES): New.
>
> * config/ia64/ia64.c (ia64_eh_uses): New.
> * config/ia64/ia64-protos.h: Update.
> * config/ia64/ia64.h (EH_USES): New.
>
> Index: flow.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/flow.c,v
> retrieving revision 1.505
> diff -c -p -d -r1.505 flow.c
> *** flow.c 2002/02/19 02:53:17 1.505
> --- flow.c 2002/03/17 20:30:59
> *************** Software Foundation, 59 Temple Place - S
> *** 167,172 ****
> --- 167,175 ----
> #ifndef EPILOGUE_USES
> #define EPILOGUE_USES(REGNO) 0
> #endif
> + #ifndef EH_USES
> + #define EH_USES(REGNO) 0
> + #endif
>
> #ifdef HAVE_conditional_execution
> #ifndef REVERSE_CONDEXEC_PREDICATES_P
> *************** calculate_global_regs_live (blocks_in, b
> *** 1111,1131 ****
>
> /* Begin by propagating live_at_start from the
> successor blocks. */
> CLEAR_REG_SET (new_live_at_end);
> - for (e = bb->succ; e; e = e->succ_next)
> - {
> - basic_block sb = e->dest;
>
> ! /* Call-clobbered registers die across exception and
> call edges. */
> ! /* ??? Abnormal call edges ignored for the moment, as
> this gets
> ! confused by sibling call edges, which crashes
> reg-stack. */
> ! if (e->flags & EDGE_EH)
> ! {
> ! bitmap_operation (tmp, sb->global_live_at_start,
> ! call_used, BITMAP_AND_COMPL);
> ! IOR_REG_SET (new_live_at_end, tmp);
> ! }
> ! else
> ! IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
> }
>
> /* The all-important stack pointer must always be live. */
> --- 1114,1153 ----
>
> /* Begin by propagating live_at_start from the
> successor blocks. */
> CLEAR_REG_SET (new_live_at_end);
>
> ! if (bb->succ)
> ! for (e = bb->succ; e; e = e->succ_next)
> ! {
> ! basic_block sb = e->dest;
> !
> ! /* Call-clobbered registers die across exception and
> ! call edges. */
> ! /* ??? Abnormal call edges ignored for the moment,
> as this gets
> ! confused by sibling call edges, which crashes
> reg-stack. */
> ! if (e->flags & EDGE_EH)
> ! {
> ! bitmap_operation (tmp, sb->global_live_at_start,
> ! call_used, BITMAP_AND_COMPL);
> ! IOR_REG_SET (new_live_at_end, tmp);
> ! }
> ! else
> ! IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
> !
> ! /* If a target saves one register in another (instead of on
> ! the stack) the save register will need to be
> live for EH. */
> ! if (e->flags & EDGE_EH)
> ! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> ! if (EH_USES (i))
> ! SET_REGNO_REG_SET (new_live_at_end, i);
> ! }
> ! else
> ! {
> ! /* This might be a noreturn function that throws. And
> ! even if it isn't, getting the unwind info right helps
> ! debugging. */
> ! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> ! if (EH_USES (i))
> ! SET_REGNO_REG_SET (new_live_at_end, i);
> }
>
> /* The all-important stack pointer must always be live. */
> Index: doc/tm.texi
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
> retrieving revision 1.102
> diff -c -p -d -r1.102 tm.texi
> *** tm.texi 2002/02/23 12:59:09 1.102
> --- tm.texi 2002/03/17 20:30:59
> *************** Define this macro as a C expression that
> *** 3956,3961 ****
> --- 3956,3967 ----
> used by the epilogue or the @samp{return} pattern. The
> stack and frame
> pointer registers are already be assumed to be used as needed.
>
> + @findex EH_USES
> + @item EH_USES (@var{regno})
> + Define this macro as a C expression that is nonzero for
> registers that are
> + used by the exception handling mechanism, and so should be
> considered live
> + on entry to an exception edge.
> +
> @findex DELAY_SLOTS_FOR_EPILOGUE
> @item DELAY_SLOTS_FOR_EPILOGUE
> Define this macro if the function epilogue contains delay
> slots to which
> Index: config/ia64/ia64-protos.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64-protos.h,v
> retrieving revision 1.36
> diff -c -p -d -r1.36 ia64-protos.h
> *** ia64-protos.h 2002/01/21 02:24:02 1.36
> --- ia64-protos.h 2002/03/17 20:30:59
> *************** extern void ia64_encode_section_info PAR
> *** 122,127 ****
> --- 122,128 ----
> extern int ia64_register_move_cost PARAMS((enum
> machine_mode, enum reg_class,
> enum reg_class));
> extern int ia64_epilogue_uses PARAMS((int));
> + extern int ia64_eh_uses PARAMS((int));
> extern void emit_safe_across_calls PARAMS((FILE *));
> extern void ia64_init_builtins PARAMS((void));
> extern void ia64_override_options PARAMS((void));
> Index: config/ia64/ia64.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
> retrieving revision 1.139.2.6
> diff -c -p -d -r1.139.2.6 ia64.c
> *** ia64.c 2002/03/15 06:43:17 1.139.2.6
> --- ia64.c 2002/03/17 20:30:59
> *************** static rtx ia64_expand_compare_and_swap
> *** 138,144 ****
> static rtx ia64_expand_lock_test_and_set PARAMS ((enum machine_mode,
> tree, rtx));
> static rtx ia64_expand_lock_release PARAMS ((enum
> machine_mode, tree, rtx));
> - const struct attribute_spec ia64_attribute_table[];
> static bool ia64_assemble_integer PARAMS ((rtx, unsigned int, int));
> static void ia64_output_function_prologue PARAMS ((FILE *,
> HOST_WIDE_INT));
> static void ia64_output_function_epilogue PARAMS ((FILE *,
> HOST_WIDE_INT));
> --- 138,143 ----
> *************** static int ia64_variable_issue PARAMS ((
> *** 156,161 ****
> --- 155,168 ----
> static rtx ia64_cycle_display PARAMS ((int, rtx));
>
> >
> + /* Table of valid machine attributes. */
> + static const struct attribute_spec ia64_attribute_table[] =
> + {
> + /* { name, min_len, max_len, decl_req, type_req,
> fn_type_req, handler } */
> + { "syscall_linkage", 0, 0, false, true, true, NULL },
> + { NULL, 0, 0, false, false, false, NULL }
> + };
> +
> /* Initialize the GCC target structure. */
> #undef TARGET_ATTRIBUTE_TABLE
> #define TARGET_ATTRIBUTE_TABLE ia64_attribute_table
> *************** ia64_epilogue_uses (regno)
> *** 6808,6820 ****
> }
> }
>
> ! /* Table of valid machine attributes. */
> ! const struct attribute_spec ia64_attribute_table[] =
> {
> ! /* { name, min_len, max_len, decl_req, type_req,
> fn_type_req, handler } */
> ! { "syscall_linkage", 0, 0, false, true, true, NULL },
> ! { NULL, 0, 0, false, false, false, NULL }
> ! };
> >
> /* For ia64, SYMBOL_REF_FLAG set means that it is a function.
>
> --- 6815,6847 ----
> }
> }
>
> ! /* Return true if REGNO is used by the frame unwinder. */
> !
> ! int
> ! ia64_eh_uses (regno)
> ! int regno;
> {
> ! if (! reload_completed)
> ! return 0;
> !
> ! if (current_frame_info.reg_save_b0
> ! && regno == current_frame_info.reg_save_b0)
> ! return 1;
> ! if (current_frame_info.reg_save_pr
> ! && regno == current_frame_info.reg_save_pr)
> ! return 1;
> ! if (current_frame_info.reg_save_ar_pfs
> ! && regno == current_frame_info.reg_save_ar_pfs)
> ! return 1;
> ! if (current_frame_info.reg_save_ar_unat
> ! && regno == current_frame_info.reg_save_ar_unat)
> ! return 1;
> ! if (current_frame_info.reg_save_ar_lc
> ! && regno == current_frame_info.reg_save_ar_lc)
> ! return 1;
> !
> ! return 0;
> ! }
> >
> /* For ia64, SYMBOL_REF_FLAG set means that it is a function.
>
> Index: config/ia64/ia64.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.h,v
> retrieving revision 1.99
> diff -c -p -d -r1.99 ia64.h
> *** ia64.h 2002/01/21 06:22:12 1.99
> --- ia64.h 2002/03/17 20:31:00
> *************** do {
> \
> *** 1404,1409 ****
> --- 1404,1413 ----
>
> #define EPILOGUE_USES(REGNO) ia64_epilogue_uses (REGNO)
>
> + /* Nonzero for registers used by the exception handling
> mechanism. */
> +
> + #define EH_USES(REGNO) ia64_eh_uses (REGNO)
> +
> /* Output at beginning of assembler file. */
>
> #define ASM_FILE_START(FILE) \
>