From: Richard Henderson Date: Wed, 28 Mar 2001 03:35:05 +0000 (-0800) Subject: rtl.h (LCT_NORETURN): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=695ee791dc1dbae7a86216a69a2a34c8e74f7f9d;p=gcc.git rtl.h (LCT_NORETURN): New. * rtl.h (LCT_NORETURN): New. * calls.c (emit_library_call_value_1): Handle it. From-SVN: r40897 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f24eae0065..24fdc0514e4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 * objc/objc-act.c (objc_init): Use dump_base_name. diff --git a/gcc/calls.c b/gcc/calls.c index a5c29af9953..3162b4654a6 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; diff --git a/gcc/rtl.h b/gcc/rtl.h index 58f74282767..a15fda29e55 100644 --- 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,