From 4b01bd1658cc87a0d9a674606b4ae78a3b4594fe Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 20 Dec 2000 17:11:31 -0800 Subject: [PATCH] rtl.h (REG_NON_LOCAL_GOTO): New. * rtl.h (REG_NON_LOCAL_GOTO): New. * rtl.c (reg_note_name): Update. * stmt.c (expand_goto): Emit a REG_NON_LOCAL_GOTO note. * builtins.c (expand_builtin_longjmp): Likewise. * flow.c (make_edges): Check for REG_NON_LOCAL_GOTO and do not emit an edge. From-SVN: r38408 --- gcc/ChangeLog | 9 +++++++++ gcc/builtins.c | 14 +++++++++++++- gcc/flow.c | 15 ++++++++++----- gcc/rtl.c | 3 ++- gcc/rtl.h | 6 +++++- gcc/stmt.c | 11 ++++++++++- 6 files changed, 49 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 72dd495a9a1..724c8cca300 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2000-12-20 Richard Henderson + + * rtl.h (REG_NON_LOCAL_GOTO): New. + * rtl.c (reg_note_name): Update. + * stmt.c (expand_goto): Emit a REG_NON_LOCAL_GOTO note. + * builtins.c (expand_builtin_longjmp): Likewise. + * flow.c (make_edges): Check for REG_NON_LOCAL_GOTO and do + not emit an edge. + 2000-12-20 Marek Michalkiewicz * config/avr/avr.c (out_movsi_r_mr, out_movsi_mr_r, out_movhi_mr_r): diff --git a/gcc/builtins.c b/gcc/builtins.c index cbf9acd55de..3d746814298 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -649,7 +649,7 @@ void expand_builtin_longjmp (buf_addr, value) rtx buf_addr, value; { - rtx fp, lab, stack; + rtx fp, lab, stack, insn; enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); if (setjmp_alias_set == -1) @@ -706,6 +706,18 @@ expand_builtin_longjmp (buf_addr, value) emit_indirect_jump (lab); } } + + /* Search backwards and mark the jump insn as a non-local goto. + Note that this precludes the use of __builtin_longjmp to a + __builtin_setjmp target in the same function. However, we've + already cautioned the user that these functions are for + internal exception handling use only. */ + for (insn = get_last_insn (); + GET_CODE (insn) != JUMP_INSN; + insn = PREV_INSN (insn)) + continue; + REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx, + REG_NOTES (insn)); } /* Get a MEM rtx for expression EXP which is the address of an operand diff --git a/gcc/flow.c b/gcc/flow.c index ae98448f44c..61371177437 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -1094,12 +1094,17 @@ make_edges (label_value_list) { rtx tmp; + /* Recognize a non-local goto as a branch outside the + current function. */ + if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) + ; + /* ??? Recognize a tablejump and do the right thing. */ - if ((tmp = JUMP_LABEL (insn)) != NULL_RTX - && (tmp = NEXT_INSN (tmp)) != NULL_RTX - && GET_CODE (tmp) == JUMP_INSN - && (GET_CODE (PATTERN (tmp)) == ADDR_VEC - || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)) + else if ((tmp = JUMP_LABEL (insn)) != NULL_RTX + && (tmp = NEXT_INSN (tmp)) != NULL_RTX + && GET_CODE (tmp) == JUMP_INSN + && (GET_CODE (PATTERN (tmp)) == ADDR_VEC + || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)) { rtvec vec; int j; diff --git a/gcc/rtl.c b/gcc/rtl.c index 48efc2640c9..f463a02d916 100644 --- a/gcc/rtl.c +++ b/gcc/rtl.c @@ -288,7 +288,8 @@ 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_NORETURN" + "REG_EH_RETHROW", "REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN", + "REG_NON_LOCAL_GOTO" }; static htab_t md_constants; diff --git a/gcc/rtl.h b/gcc/rtl.h index ce35cd8315c..397ea98040e 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -549,7 +549,11 @@ enum reg_note REG_MAYBE_DEAD, /* Indicates that a call does not return. */ - REG_NORETURN + REG_NORETURN, + + /* Indicates that an indirect jump is a non-local goto instead of a + computed goto. */ + REG_NON_LOCAL_GOTO }; /* The base value for branch probability notes. */ diff --git a/gcc/stmt.c b/gcc/stmt.c index d4b047c9a9c..7489613fa40 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -783,7 +783,7 @@ expand_goto (label) { struct function *p = find_function_data (context); rtx label_ref = gen_rtx_LABEL_REF (Pmode, label_rtx (label)); - rtx handler_slot, static_chain, save_area; + rtx handler_slot, static_chain, save_area, insn; tree link; /* Find the corresponding handler slot for this label. */ @@ -836,6 +836,15 @@ expand_goto (label) emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); emit_indirect_jump (handler_slot); } + + /* Search backwards to the jump insn and mark it as a + non-local goto. */ + for (insn = get_last_insn (); + GET_CODE (insn) != JUMP_INSN; + insn = PREV_INSN (insn)) + continue; + REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx, + REG_NOTES (insn)); } else expand_goto_internal (label, label_rtx (label), NULL_RTX); -- 2.30.2