OSDN Git Service

* rtl.h (LCT_NORETURN): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 28 Mar 2001 03:35:05 +0000 (03:35 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 28 Mar 2001 03:35:05 +0000 (03:35 +0000)
        * calls.c (emit_library_call_value_1): Handle it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@40897 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/calls.c
gcc/rtl.h

index 0f24eae..24fdc05 100644 (file)
@@ -3,6 +3,9 @@
        * function.c (expand_function_start): Set DECL_REGISTER on
        a pseudo used for DECL_RESULT.
 
+       * rtl.h (LCT_NORETURN): New.
+       * calls.c (emit_library_call_value_1): Handle it.
+
 2001-03-27  Stan Shebs  <shebs@apple.com>
 
        * objc/objc-act.c (objc_init): Use dump_base_name.
index a5c29af..3162b46 100644 (file)
@@ -3504,6 +3504,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
   int flags = 0;
   int reg_parm_stack_space = 0;
   int needed;
+  rtx before_call;
 
 #ifdef REG_PARM_STACK_SPACE
   /* Define the boundary of the register parm stack space that needs to be
@@ -3528,6 +3529,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
     flags |= ECF_CONST;
   else if (fn_type == LCT_PURE_MAKE_BLOCK)
     flags |= ECF_PURE;
+  else if (fn_type == LCT_NORETURN)
+    flags |= ECF_NORETURN;
   fun = orgfun;
 
   if (libfunc_nothrow (fun))
@@ -4041,6 +4044,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
     abort ();
 #endif
 
+  before_call = get_last_insn ();
+
   /* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
      will set inhibit_defer_pop to that value.  */
   /* The return type is needed to decide how many bytes the function pops.
@@ -4058,6 +4063,34 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
               valreg,
               old_inhibit_defer_pop + 1, call_fusage, flags);
 
+  /* For calls to `setjmp', etc., inform flow.c it should complain
+     if nonvolatile values are live.  For functions that cannot return,
+     inform flow that control does not fall through.  */
+
+  if (flags & (ECF_RETURNS_TWICE | ECF_NORETURN | ECF_LONGJMP))
+    {
+      /* The barrier or NOTE_INSN_SETJMP note must be emitted
+        immediately after the CALL_INSN.  Some ports emit more than
+        just a CALL_INSN above, so we must search for it here.  */
+
+      rtx last = get_last_insn ();
+      while (GET_CODE (last) != CALL_INSN)
+       {
+         last = PREV_INSN (last);
+         /* There was no CALL_INSN?  */
+         if (last == before_call)
+           abort ();
+       }
+
+      if (flags & ECF_RETURNS_TWICE)
+       {
+         emit_note_after (NOTE_INSN_SETJMP, last);
+         current_function_calls_setjmp = 1;
+       }
+      else
+       emit_barrier_after (last);
+    }
+
   /* Now restore inhibit_defer_pop to its actual original value.  */
   OK_DEFER_POP;
 
index 58f7428..a15fda2 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1972,7 +1972,8 @@ enum libcall_type
   LCT_CONST = 1,
   LCT_PURE = 2,
   LCT_CONST_MAKE_BLOCK = 3,
-  LCT_PURE_MAKE_BLOCK = 4
+  LCT_PURE_MAKE_BLOCK = 4,
+  LCT_NORETURN = 5
 };
 
 extern void emit_library_call          PARAMS ((rtx, enum libcall_type,