]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Eliminate false DV warnings for predicated calls to noreturn functions.
authorJim Wilson <wilson@cygnus.com>
Fri, 1 Sep 2000 22:22:54 +0000 (22:22 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Fri, 1 Sep 2000 22:22:54 +0000 (15:22 -0700)
* calls.c (emit_call_1): Add REG_NORETURN note to call if ECF_NORETURN.
* combine.c (distribute_notes): Handle REG_NORETURN.
* rtl.c (reg_note_name): Add REG_NORETURN.
* rtl.h (enum reg_note): Likewise.
* config/ia64/ia64-protos.h (emit_safe_across_calls): Renamed from
ia64_file_start.
* config/ia64/ia64.c (emit_safe_across_calls): Likewise.
(rtx_needs_barrier): Handle unspec_volatile 8 and 9.
(emit_predicate_relation_info): Handle conditional calls with
REG_NORETURN.
* config/ia64/ia64.h (ASM_FILE_START): Call emit_safe_across_calls
instead of ia64_file_start.
* config/ia64/sysv4.h (ASM_FILE_START): Likewise.
* config/ia64/ia64.md (safe_across_calls_all,
save_across_calls_normal): New patterns.

From-SVN: r36107

gcc/ChangeLog
gcc/calls.c
gcc/combine.c
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/ia64/ia64.md
gcc/config/ia64/sysv4.h
gcc/rtl.c
gcc/rtl.h

index 52204553f1cafe005ecf528fe0cbc026a43bc752..e2bb8124b44ffd5b20789d97dd418ff96d6f1567 100644 (file)
 
 2000-09-01  Jim Wilson  <wilson@cygnus.com>
 
+       * calls.c (emit_call_1): Add REG_NORETURN note to call if ECF_NORETURN.
+       * combine.c (distribute_notes): Handle REG_NORETURN.
+       * rtl.c (reg_note_name): Add REG_NORETURN.
+       * rtl.h (enum reg_note): Likewise.
+
+       * config/ia64/ia64-protos.h (emit_safe_across_calls): Renamed from
+       ia64_file_start.
+       * config/ia64/ia64.c (emit_safe_across_calls): Likewise.
+       (rtx_needs_barrier): Handle unspec_volatile 8 and 9.
+       (emit_predicate_relation_info): Handle conditional calls with
+       REG_NORETURN.
+       * config/ia64/ia64.h (ASM_FILE_START): Call emit_safe_across_calls
+       instead of ia64_file_start.
+       * config/ia64/sysv4.h (ASM_FILE_START): Likewise.
+       * config/ia64/ia64.md (safe_across_calls_all,
+       save_across_calls_normal): New patterns.
+
        * loop.c (check_final_value): Check for biv use before checking for
        giv use.  Check for both biv and giv uses.  Always set last_giv_use
        if there is a giv use.
index ed35daf9a64b88cb43e005080e0ea5b92bc72e60..6d0a3b290bc11e4698b532992c02e8d570898144 100644 (file)
@@ -605,6 +605,10 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
     REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, const0_rtx,
                                               REG_NOTES (call_insn));
 
+  if (ecf_flags & ECF_NORETURN)
+    REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_NORETURN, const0_rtx,
+                                              REG_NOTES (call_insn));
+
   SIBLING_CALL_P (call_insn) = ((ecf_flags & ECF_SIBCALL) != 0);
 
   /* Restore this now, so that we do defer pops for this call's args
index 881c65356d51631f0ea41c1b72133303fbc607e6..df5314b9b6750f808bf445cc1f22b4bd3eee0cbe 100644 (file)
@@ -12036,6 +12036,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
 
        case REG_EH_REGION:
        case REG_EH_RETHROW:
+       case REG_NORETURN:
          /* These notes must remain with the call.  It should not be
             possible for both I2 and I3 to be a call.  */
          if (GET_CODE (i3) == CALL_INSN)
index 8aead0ab855edf937e8b726889654554d46b6331..36a67eb26ac21e31f4f5de0427a2f881f5c6b155 100644 (file)
@@ -118,7 +118,7 @@ extern void ia64_encode_section_info PARAMS((tree));
 
 extern int ia64_register_move_cost PARAMS((enum reg_class, enum reg_class));
 extern int ia64_epilogue_uses PARAMS((int));
-extern void ia64_file_start PARAMS((FILE *));
+extern void emit_safe_across_calls PARAMS((FILE *));
 extern void ia64_output_end_prologue PARAMS((FILE *));
 extern void ia64_init_builtins PARAMS((void));
 extern void ia64_override_options PARAMS((void));
index f42d7b1a4df921abcbdda8668117555f428791f1..7b422351b96ce1f1cd3296bbb8f898559b41fb31 100644 (file)
@@ -984,7 +984,7 @@ spill_tfmode_operand (in, force)
 /* Begin the assembly file.  */
 
 void
-ia64_file_start (f)
+emit_safe_across_calls (f)
      FILE *f;
 {
   unsigned int rs, re;
@@ -4003,6 +4003,8 @@ rtx_needs_barrier (x, flags, pred)
           break;
 
        case 7: /* pred.rel.mutex */
+       case 8: /* safe_across_calls all */
+       case 9: /* safe_across_calls normal */
          return 0;
 
        default:
@@ -4249,6 +4251,35 @@ emit_predicate_relation_info (insns)
            head = n;
          }
     }
+
+  /* Look for conditional calls that do not return, and protect predicate
+     relations around them.  Otherwise the assembler will assume the call
+     returns, and complain about uses of call-clobbered predicates after
+     the call.  */
+  for (i = n_basic_blocks - 1; i >= 0; --i)
+    {
+      basic_block bb = BASIC_BLOCK (i);
+      rtx insn = bb->head;
+      
+      while (1)
+       {
+         if (GET_CODE (insn) == CALL_INSN
+             && GET_CODE (PATTERN (insn)) == COND_EXEC
+             && find_reg_note (insn, REG_NORETURN, NULL_RTX))
+           {
+             rtx b = emit_insn_before (gen_safe_across_calls_all (), insn);
+             rtx a = emit_insn_after (gen_safe_across_calls_normal (), insn);
+             if (bb->head == insn)
+               bb->head = b;
+             if (bb->end == insn)
+               bb->end = a;
+           }
+         
+         if (insn == bb->end)
+           break;
+         insn = NEXT_INSN (insn);
+       }
+    }
 }
 
 /* Perform machine dependent operations on the rtl chain INSNS.  */
index 0c8197ab6ac01f194330f866f8ddc49ccf21c08d..b19cb59c53d244ab3b23998992ccfa99b63ba492 100644 (file)
@@ -1479,7 +1479,7 @@ do {                                                                      \
 /* Output at beginning of assembler file.  */
 
 #define ASM_FILE_START(FILE) \
-  ia64_file_start (FILE)
+  emit_safe_across_calls (FILE)
 
 /* A C compound statement that outputs the assembler code for a thunk function,
    used to implement C++ virtual function calls with multiple inheritance.  */
index 2bbf1a221042f3ac4634caaefa7ae7f3f1b9f34f..391ca15a476cc77f2922adbb594783fc9d32553e 100644 (file)
@@ -70,6 +70,8 @@
 ;;     2       insn_group_barrier
 ;;     5       set_bsp
 ;;     7       pred.rel.mutex
+;;     8       pred.safe_across_calls all
+;;     9       pred.safe_across_calls normal
 \f
 ;; ::::::::::::::::::::
 ;; ::
   ".pred.rel.mutex %0, %I0"
   [(set_attr "type" "unknown")
    (set_attr "predicable" "no")])
+
+(define_insn "safe_across_calls_all"
+  [(unspec_volatile [(const_int 0)] 8)]
+  ""
+  ".pred.safe_across_calls p1-p63"
+  [(set_attr "type" "unknown")
+   (set_attr "predicable" "no")])
+
+(define_insn "safe_across_calls_normal"
+  [(unspec_volatile [(const_int 0)] 9)]
+  ""
+  "*
+{
+  emit_safe_across_calls (asm_out_file);
+  return \"\";
+}"
+  [(set_attr "type" "unknown")
+   (set_attr "predicable" "no")])
+
index e269fdd23db4f2534f242ac805ae690823835567..af92839d3eebbb6e0c1b4a2807fadc7474ca9c03 100644 (file)
@@ -178,7 +178,7 @@ do {                                                                        \
 #define ASM_FILE_START(STREAM) \
 do {                                                                   \
   output_file_directive (STREAM, main_input_filename);                 \
-  ia64_file_start(STREAM);                                             \
+  emit_safe_across_calls (STREAM);                                     \
 } while (0)
 
 /* Case label alignment is handled by ADDR_VEC_ALIGN now.  */
index ad89fff092068b9ec850675a2426efe17359fd71..90d760e00c518958c4e8e0f7ca98528346d32cda 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -277,7 +277,7 @@ const char * const reg_note_name[] =
   "REG_LABEL", "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
   "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
   "REG_FRAME_RELATED_EXPR", "REG_EH_CONTEXT", "REG_EH_REGION",
-  "REG_EH_RETHROW", "REG_SAVE_NOTE", "REG_MAYBE_DEAD"
+  "REG_EH_RETHROW", "REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN"
 };
 
 static void fatal_with_file_and_line PARAMS ((FILE *, const char *, ...))
index 42b8f425728b829692c179ce9fe42ad15d31ef4c..44a5e8da6e2c00728f21c9915dee00b1d74e9d1d 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -543,7 +543,10 @@ enum reg_note
      a value which might not be used later, and if so it's OK to delete
      the insn.  Normally, deleting any insn in the prologue is an error. 
      At present the parameter is unused and set to (const_int 0).  */
-  REG_MAYBE_DEAD
+  REG_MAYBE_DEAD,
+
+  /* Indicates that a call does not return.  */
+  REG_NORETURN
 };
 
 /* The base value for branch probability notes.  */