aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2000-12-20 17:11:31 -0800
committerRichard Henderson <rth@gcc.gnu.org>2000-12-20 17:11:31 -0800
commit4b01bd1658cc87a0d9a674606b4ae78a3b4594fe (patch)
treeffba52aed7e19dec753b233566b9ab484e11d29e /gcc
parent1e248ee3875e64165a8a5c928e175603be975ffa (diff)
downloadgcc-4b01bd1658cc87a0d9a674606b4ae78a3b4594fe.zip
gcc-4b01bd1658cc87a0d9a674606b4ae78a3b4594fe.tar.gz
gcc-4b01bd1658cc87a0d9a674606b4ae78a3b4594fe.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/builtins.c14
-rw-r--r--gcc/flow.c15
-rw-r--r--gcc/rtl.c3
-rw-r--r--gcc/rtl.h6
-rw-r--r--gcc/stmt.c11
6 files changed, 49 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 72dd495..724c8cc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2000-12-20 Richard Henderson <rth@redhat.com>
+
+ * 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 <marekm@linux.org.pl>
* 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 cbf9acd..3d74681 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 ae98448..6137117 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 48efc26..f463a02 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 ce35cd8..397ea98 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 d4b047c..7489613 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);