aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-03-19 18:13:39 -0800
committerRichard Henderson <rth@gcc.gnu.org>2002-03-19 18:13:39 -0800
commit15b5aef3e72ff167751f52111b7a7be3429aae14 (patch)
treeb494bd2379913f69721d6206bfacbe19e6522eb1 /gcc
parent02a7a3fda139c2e6ddaca51063d9dc0f38b3077b (diff)
downloadgcc-15b5aef3e72ff167751f52111b7a7be3429aae14.zip
gcc-15b5aef3e72ff167751f52111b7a7be3429aae14.tar.gz
gcc-15b5aef3e72ff167751f52111b7a7be3429aae14.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/ia64/ia64-protos.h1
-rw-r--r--gcc/config/ia64/ia64.c28
-rw-r--r--gcc/config/ia64/ia64.h4
-rw-r--r--gcc/doc/tm.texi6
-rw-r--r--gcc/flow.c50
6 files changed, 85 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 93095a3..c09bbcc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,15 @@
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-19 Richard Henderson <rth@redhat.com>
+
* varasm.c (output_constant_def): Fix stupid typo.
2002-03-19 Richard Henderson <rth@redhat.com>
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h
index 332b076..cedeee2 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 a9ea756..a667ae3 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 c0d81ec..8a4a759 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 20d9fa1..3f37cdb 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 04a3dc6..659815c 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. */