From 15b5aef3e72ff167751f52111b7a7be3429aae14 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 19 Mar 2002 18:13:39 -0800 Subject: [PATCH] flow.c (EH_USES): Provide default. * 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. From-SVN: r51060 --- gcc/ChangeLog | 10 +++++++ gcc/config/ia64/ia64-protos.h | 1 + gcc/config/ia64/ia64.c | 28 ++++++++++++++++++++ gcc/config/ia64/ia64.h | 4 +++ gcc/doc/tm.texi | 6 +++++ gcc/flow.c | 50 +++++++++++++++++++++++++---------- 6 files changed, 85 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 93095a39b74..c09bbccfba4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2002-03-19 Richard Henderson + + * 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. + 2002-03-19 Richard Henderson * varasm.c (output_constant_def): Fix stupid typo. diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 332b07690b8..cedeee20ec5 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -122,6 +122,7 @@ extern void ia64_encode_section_info PARAMS((tree, int)); 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)); diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index a9ea756d37a..a667ae3dbc7 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -6816,6 +6816,34 @@ ia64_epilogue_uses (regno) return 0; } } + +/* 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. diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index c0d81ec69f1..8a4a759ec52 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1406,6 +1406,10 @@ do { \ #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) \ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 20d9fa12566..3f37cdb3e60 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4042,6 +4042,12 @@ Define this macro as a C expression that is nonzero for registers that are 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 diff --git a/gcc/flow.c b/gcc/flow.c index 04a3dc6b4a5..659815c5043 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -167,6 +167,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #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 @@ -1144,21 +1147,40 @@ calculate_global_regs_live (blocks_in, blocks_out, flags) /* 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); + 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. */ -- 2.30.2