summaryrefslogtreecommitdiff
path: root/gcc/stmt.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-05 10:32:23 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-05 10:32:23 +0000
commitfe410b3e0f7de0376d98b922113c80f9ab4bd192 (patch)
tree2907bc726434f732f093ecd43d5f5ba62ac08265 /gcc/stmt.c
parent941f2a0d21995a3e06f340891a639c4462850312 (diff)
downloadgcc-fe410b3e0f7de0376d98b922113c80f9ab4bd192.tar.gz
2008-04-05 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r133930 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@133932 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/stmt.c')
-rw-r--r--gcc/stmt.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/gcc/stmt.c b/gcc/stmt.c
index aacb1840dec..aeea50970f6 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -160,8 +160,7 @@ force_label_rtx (tree label)
else
p = cfun;
- p->expr->x_forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref,
- p->expr->x_forced_labels);
+ forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref, forced_labels);
return ref;
}
@@ -1821,7 +1820,7 @@ expand_nl_goto_receiver (void)
/* Now restore our arg pointer from the address at which it
was saved in our stack frame. */
emit_move_insn (virtual_incoming_args_rtx,
- copy_to_reg (get_arg_pointer_save_area (cfun)));
+ copy_to_reg (get_arg_pointer_save_area ()));
}
}
#endif
@@ -2259,8 +2258,9 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
mode = TYPE_MODE (index_type);
expr = expand_normal (range);
- emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,
- default_label);
+ if (default_label)
+ emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,
+ default_label);
index = convert_to_mode (word_mode, index, 0);
index = expand_binop (word_mode, ashl_optab, const1_rtx,
@@ -2275,7 +2275,8 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
word_mode, 1, test[i].label);
}
- emit_jump (default_label);
+ if (default_label)
+ emit_jump (default_label);
}
#ifndef HAVE_casesi
@@ -2321,7 +2322,7 @@ expand_case (tree exp)
struct case_node *case_list = 0;
/* Label to jump to if no case matches. */
- tree default_label_decl;
+ tree default_label_decl = NULL_TREE;
alloc_pool case_node_pool = create_alloc_pool ("struct case_node pool",
sizeof (struct case_node),
@@ -2339,18 +2340,21 @@ expand_case (tree exp)
{
tree elt;
bitmap label_bitmap;
+ int vl = TREE_VEC_LENGTH (vec);
/* cleanup_tree_cfg removes all SWITCH_EXPR with their index
expressions being INTEGER_CST. */
gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
- /* The default case is at the end of TREE_VEC. */
- elt = TREE_VEC_ELT (vec, TREE_VEC_LENGTH (vec) - 1);
- gcc_assert (!CASE_HIGH (elt));
- gcc_assert (!CASE_LOW (elt));
- default_label_decl = CASE_LABEL (elt);
+ /* The default case, if ever taken, is at the end of TREE_VEC. */
+ elt = TREE_VEC_ELT (vec, vl - 1);
+ if (!CASE_LOW (elt) && !CASE_HIGH (elt))
+ {
+ default_label_decl = CASE_LABEL (elt);
+ --vl;
+ }
- for (i = TREE_VEC_LENGTH (vec) - 1; --i >= 0; )
+ for (i = vl - 1; i >= 0; --i)
{
tree low, high;
elt = TREE_VEC_ELT (vec, i);
@@ -2369,7 +2373,8 @@ expand_case (tree exp)
before_case = start = get_last_insn ();
- default_label = label_rtx (default_label_decl);
+ if (default_label_decl)
+ default_label = label_rtx (default_label_decl);
/* Get upper and lower bounds of case values. */
@@ -2414,7 +2419,8 @@ expand_case (tree exp)
type, so we may still get a zero here. */
if (count == 0)
{
- emit_jump (default_label);
+ if (default_label)
+ emit_jump (default_label);
free_alloc_pool (case_node_pool);
return;
}
@@ -2510,13 +2516,15 @@ expand_case (tree exp)
&& estimate_case_costs (case_list));
balance_case_nodes (&case_list, NULL);
emit_case_nodes (index, case_list, default_label, index_type);
- emit_jump (default_label);
+ if (default_label)
+ emit_jump (default_label);
}
else
{
+ rtx fallback_label = label_rtx (case_list->code_label);
table_label = gen_label_rtx ();
if (! try_casesi (index_type, index_expr, minval, range,
- table_label, default_label))
+ table_label, default_label, fallback_label))
{
bool ok;
@@ -2559,7 +2567,12 @@ expand_case (tree exp)
= gen_rtx_LABEL_REF (Pmode, label_rtx (n->code_label));
}
- /* Fill in the gaps with the default. */
+ /* Fill in the gaps with the default. We may have gaps at
+ the beginning if we tried to avoid the minval subtraction,
+ so substitute some label even if the default label was
+ deemed unreachable. */
+ if (!default_label)
+ default_label = fallback_label;
for (i = 0; i < ncases; i++)
if (labelvec[i] == 0)
labelvec[i] = gen_rtx_LABEL_REF (Pmode, default_label);
@@ -3044,7 +3057,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
emit_case_nodes (index, node->left, default_label, index_type);
/* If left-hand subtree does nothing,
go to default. */
- emit_jump (default_label);
+ if (default_label)
+ emit_jump (default_label);
/* Code branches here for the right-hand subtree. */
expand_label (test_label);
@@ -3179,7 +3193,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
{
/* If the left-hand subtree fell through,
don't let it fall into the right-hand subtree. */
- emit_jump (default_label);
+ if (default_label)
+ emit_jump (default_label);
expand_label (test_label);
emit_case_nodes (index, node->right, default_label, index_type);