aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2001-03-27 19:35:05 -0800
committerRichard Henderson <rth@gcc.gnu.org>2001-03-27 19:35:05 -0800
commit695ee791dc1dbae7a86216a69a2a34c8e74f7f9d (patch)
tree920ea0bd9f76af3237a61a78395386b780e427d3 /gcc/calls.c
parent3d74dad834986e7f0c1d06dd29adef3d1a8a5974 (diff)
downloadgcc-695ee791dc1dbae7a86216a69a2a34c8e74f7f9d.zip
gcc-695ee791dc1dbae7a86216a69a2a34c8e74f7f9d.tar.gz
gcc-695ee791dc1dbae7a86216a69a2a34c8e74f7f9d.tar.bz2
rtl.h (LCT_NORETURN): New.
* rtl.h (LCT_NORETURN): New. * calls.c (emit_library_call_value_1): Handle it. From-SVN: r40897
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index a5c29af..3162b46 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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;