flow.c (EH_USES): Provide default.
authorRichard Henderson <rth@redhat.com>
Wed, 20 Mar 2002 02:13:39 +0000 (18:13 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 20 Mar 2002 02:13:39 +0000 (18:13 -0800)
        * 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
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/doc/tm.texi
gcc/flow.c

index 93095a39b74102f378d7fc660bc769e34df7631f..c09bbccfba4446e86158c09af7cf577f57a6166e 100644 (file)
@@ -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-19  Richard Henderson  <rth@redhat.com>
 
        * varasm.c (output_constant_def): Fix stupid typo.
index 332b07690b832faebeb9aa8d340d8e695bffe6cf..cedeee20ec553ef0060988ac51fc4e0e7760d569 100644 (file)
@@ -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));
index a9ea756d37a0b33a68f995603c103fd825910dd4..a667ae3dbc766ee378373fa1bc75c05d7807ac42 100644 (file)
@@ -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;
+}
 \f
 /* For ia64, SYMBOL_REF_FLAG set means that it is a function.
 
index c0d81ec69f152c7793a26dc35b5f79af7129f666..8a4a759ec528b57b54f10888d9676122d2b374ae 100644 (file)
@@ -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) \
index 20d9fa125662d9866c5d89f2973bccc0ffa828aa..3f37cdb3e6003d896784072f490b0018d4fd31d4 100644 (file)
@@ -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
index 04a3dc6b4a54a296fd7e7ad7ae709e4dea040dab..659815c5043fd854e66dd86491442faa610b41b8 100644 (file)
@@ -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.  */