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: r51058
This commit is contained in:
parent
d82fb1fa54
commit
bfc23077d9
|
@ -1,3 +1,13 @@
|
|||
2002-03-19 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* 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-20 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* defaults.h (SUPPORTS_WEAK): Set if ASM_WEAKEN_DECL.
|
||||
|
|
|
@ -122,6 +122,7 @@ extern void ia64_encode_section_info PARAMS((tree));
|
|||
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));
|
||||
|
|
|
@ -6815,6 +6815,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.
|
||||
|
||||
|
|
|
@ -1412,6 +1412,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) \
|
||||
|
|
|
@ -3956,6 +3956,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
|
||||
|
|
50
gcc/flow.c
50
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
|
||||
|
@ -1111,21 +1114,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. */
|
||||
|
|
Loading…
Reference in New Issue