diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-03-28 03:35:05 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-03-28 03:35:05 +0000 |
commit | 644c283b8e75bb5168355e9f9be7209cd23aab04 (patch) | |
tree | 920ea0bd9f76af3237a61a78395386b780e427d3 | |
parent | ef1f652f06993d87b20dcb308b98a25612fd8d0a (diff) | |
download | gcc-644c283b8e75bb5168355e9f9be7209cd23aab04.tar.gz |
* rtl.h (LCT_NORETURN): New.
* 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
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/calls.c | 33 | ||||
-rw-r--r-- | gcc/rtl.h | 3 |
3 files changed, 38 insertions, 1 deletions
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 <shebs@apple.com> * 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, |