summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-04 13:03:02 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-04 13:03:02 +0000
commit49a701754404dae1846ba49062fbc54a3b7c24a2 (patch)
treee122d3a36874476f12e63764b611e6ee436001d2 /gcc
parentc1a60a68d27bb1918025c040ed41c27548e4f0aa (diff)
downloadgcc-49a701754404dae1846ba49062fbc54a3b7c24a2.tar.gz
* gimple.h (gimple_build_switch): Remove.
(gimple_build_switch_vec): Promote to the new gimple_build_switch. (gimple_switch_default_label): Assert the default case label is really a default case label. (gimple_switch_set_default_label): Likewise. * gimple.c (gimple_build_switch_nlabels): Make sure a default label is passed in, and simplify accordingly. (gimple_build_switch): Removed. (gimple_build_switch_vec): Rename to gimple_build_switch. * gimplify.c (gimplify_switch_expr): Update gimple_build_switch use. * gimple-pretty-print.c (dump_gimple_switch): Do not accept a NULL case label. * stmt.c (expand_case): Simplify using the fact that every GIMPLE switch must have a default case. * tree-cfg.c (group_case_labels_stmt): Likewise. (verify_gimple_switch): Use gimple_switch_label in verifier to get the label at index 0, and verify that it is a valid default case. * except.c (sjlj_emit_dispatch_table): Rewrite construction of the switch for dispatching. * tree-eh.c (lower_try_finally_switch): Update gimple_build_switch use. (lower_eh_dispatch): Likewise. * tree-vrp.c (execute_vrp): Use gimple_switch_label to get the case label at index 0 before turning it into a default case label. * omp-low.c (expand_omp_sections): Update gimple_build_switch use. * tree-switch-conversion.c (emit_case_bit_tests): Get the default case label using gimple_switch_default_label. (collect_switch_conv_info): Likewise. (process_switch): Likewise. * doc/gimple.texi: Update documentation of gimple_build_switch. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190925 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog32
-rw-r--r--gcc/doc/gimple.texi19
-rw-r--r--gcc/except.c25
-rw-r--r--gcc/gimple-pretty-print.c4
-rw-r--r--gcc/gimple.c39
-rw-r--r--gcc/gimple.h8
-rw-r--r--gcc/gimplify.c6
-rw-r--r--gcc/omp-low.c2
-rw-r--r--gcc/stmt.c15
-rw-r--r--gcc/tree-cfg.c21
-rw-r--r--gcc/tree-eh.c6
-rw-r--r--gcc/tree-switch-conversion.c12
-rw-r--r--gcc/tree-vrp.c2
13 files changed, 83 insertions, 108 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3709a6357f6..e9ef4939ed5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,35 @@
+2012-09-04 Steven Bosscher <steven@gcc.gnu.org>
+
+ * gimple.h (gimple_build_switch): Remove.
+ (gimple_build_switch_vec): Promote to the new gimple_build_switch.
+ (gimple_switch_default_label): Assert the default case label is
+ really a default case label.
+ (gimple_switch_set_default_label): Likewise.
+ * gimple.c (gimple_build_switch_nlabels): Make sure a default label
+ is passed in, and simplify accordingly.
+ (gimple_build_switch): Removed.
+ (gimple_build_switch_vec): Rename to gimple_build_switch.
+ * gimplify.c (gimplify_switch_expr): Update gimple_build_switch use.
+ * gimple-pretty-print.c (dump_gimple_switch): Do not accept a NULL
+ case label.
+ * stmt.c (expand_case): Simplify using the fact that every GIMPLE
+ switch must have a default case.
+ * tree-cfg.c (group_case_labels_stmt): Likewise.
+ (verify_gimple_switch): Use gimple_switch_label in verifier to get
+ the label at index 0, and verify that it is a valid default case.
+ * except.c (sjlj_emit_dispatch_table): Rewrite construction of the
+ switch for dispatching.
+ * tree-eh.c (lower_try_finally_switch): Update gimple_build_switch use.
+ (lower_eh_dispatch): Likewise.
+ * tree-vrp.c (execute_vrp): Use gimple_switch_label to get the case
+ label at index 0 before turning it into a default case label.
+ * omp-low.c (expand_omp_sections): Update gimple_build_switch use.
+ * tree-switch-conversion.c (emit_case_bit_tests): Get the default case
+ label using gimple_switch_default_label.
+ (collect_switch_conv_info): Likewise.
+ (process_switch): Likewise.
+ * doc/gimple.texi: Update documentation of gimple_build_switch.
+
2012-09-04 Georg-Johann Lay <avr@gjlay.de>
PR target/54476
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index fa31eb00ea0..f4a65478d13 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -2034,21 +2034,12 @@ Set @code{RETVAL} to be the return value for @code{GIMPLE_RETURN} @code{G}.
@subsection @code{GIMPLE_SWITCH}
@cindex @code{GIMPLE_SWITCH}
-@deftypefn {GIMPLE function} gimple gimple_build_switch (unsigned nlabels, @
-tree index, tree default_label, ...)
-Build a @code{GIMPLE_SWITCH} statement. @code{NLABELS} are the number of
-labels excluding the default label. The default label is passed
-in @code{DEFAULT_LABEL}. The rest of the arguments are trees
-representing the labels. Each label is a tree of code
-@code{CASE_LABEL_EXPR}.
-@end deftypefn
-
-@deftypefn {GIMPLE function} gimple gimple_build_switch_vec (tree index, tree @
+@deftypefn {GIMPLE function} gimple gimple_build_switch (tree index, tree @
default_label, @code{VEC}(tree,heap) *args)
-This function is an alternate way of building @code{GIMPLE_SWITCH}
-statements. @code{INDEX} and @code{DEFAULT_LABEL} are as in
-gimple_build_switch. @code{ARGS} is a vector of @code{CASE_LABEL_EXPR} trees
-that contain the labels.
+Build a @code{GIMPLE_SWITCH} statement. @code{INDEX} is the index variable
+to switch on, and @code{DEFAULT_LABEL} represents the default label.
+@code{ARGS} is a vector of @code{CASE_LABEL_EXPR} trees that contain the
+non-default case labels. Each label is a tree of code @code{CASE_LABEL_EXPR}.
@end deftypefn
@deftypefn {GIMPLE function} unsigned gimple_switch_num_labels (gimple g)
diff --git a/gcc/except.c b/gcc/except.c
index 01745125a8e..ae5a11fdaa0 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1243,7 +1243,7 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
eh_region r;
edge e;
int i, disp_index;
- gimple switch_stmt;
+ VEC(tree, heap) *dispatch_labels = NULL;
fc = crtl->eh.sjlj_fc;
@@ -1289,17 +1289,8 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
/* If there's exactly one call site in the function, don't bother
generating a switch statement. */
- switch_stmt = NULL;
if (num_dispatch > 1)
- {
- tree disp;
-
- mem = adjust_address (fc, TYPE_MODE (integer_type_node),
- sjlj_fc_call_site_ofs);
- disp = make_tree (integer_type_node, mem);
-
- switch_stmt = gimple_build_switch_nlabels (num_dispatch, disp, NULL);
- }
+ dispatch_labels = VEC_alloc (tree, heap, num_dispatch);
for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
if (lp && lp->post_landing_pad)
@@ -1317,8 +1308,7 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
t_label = create_artificial_label (UNKNOWN_LOCATION);
t = build_int_cst (integer_type_node, disp_index);
case_elt = build_case_label (t, NULL, t_label);
- gimple_switch_set_label (switch_stmt, disp_index, case_elt);
-
+ VEC_quick_push (tree, dispatch_labels, case_elt);
label = label_rtx (t_label);
}
else
@@ -1371,7 +1361,16 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
if (num_dispatch > 1)
{
+ gimple switch_stmt;
+ tree default_label = create_artificial_label (UNKNOWN_LOCATION);
+ rtx disp = adjust_address (fc, TYPE_MODE (integer_type_node),
+ sjlj_fc_call_site_ofs);
+ switch_stmt = gimple_build_switch (make_tree (integer_type_node, disp),
+ build_case_label (NULL, NULL,
+ default_label),
+ dispatch_labels);
expand_case (switch_stmt);
+ emit_label (label_rtx (default_label));
expand_builtin_trap ();
}
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 658e0beea74..e4550c01104 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -770,9 +770,7 @@ dump_gimple_switch (pretty_printer *buffer, gimple gs, int spc, int flags)
for (i = 0; i < gimple_switch_num_labels (gs); i++)
{
tree case_label = gimple_switch_label (gs, i);
- if (case_label == NULL_TREE)
- continue;
-
+ gcc_checking_assert (case_label != NULL_TREE);
dump_generic_node (buffer, case_label, spc, flags, false);
pp_character (buffer, ' ');
dump_generic_node (buffer, CASE_LABEL (case_label), spc, flags, false);
diff --git a/gcc/gimple.c b/gcc/gimple.c
index d78c60f22e8..88fa7627e84 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -803,39 +803,14 @@ gimple
gimple_build_switch_nlabels (unsigned nlabels, tree index, tree default_label)
{
/* nlabels + 1 default label + 1 index. */
+ gcc_checking_assert (default_label);
gimple p = gimple_build_with_ops (GIMPLE_SWITCH, ERROR_MARK,
- 1 + (default_label != NULL) + nlabels);
+ 1 + 1 + nlabels);
gimple_switch_set_index (p, index);
- if (default_label)
- gimple_switch_set_default_label (p, default_label);
+ gimple_switch_set_default_label (p, default_label);
return p;
}
-
-/* Build a GIMPLE_SWITCH statement.
-
- INDEX is the switch's index.
- NLABELS is the number of labels in the switch excluding the DEFAULT_LABEL.
- ... are the labels excluding the default. */
-
-gimple
-gimple_build_switch (unsigned nlabels, tree index, tree default_label, ...)
-{
- va_list al;
- unsigned i, offset;
- gimple p = gimple_build_switch_nlabels (nlabels, index, default_label);
-
- /* Store the rest of the labels. */
- va_start (al, default_label);
- offset = (default_label != NULL);
- for (i = 0; i < nlabels; i++)
- gimple_switch_set_label (p, i + offset, va_arg (al, tree));
- va_end (al);
-
- return p;
-}
-
-
/* Build a GIMPLE_SWITCH statement.
INDEX is the switch's index.
@@ -843,15 +818,15 @@ gimple_build_switch (unsigned nlabels, tree index, tree default_label, ...)
ARGS is a vector of labels excluding the default. */
gimple
-gimple_build_switch_vec (tree index, tree default_label, VEC(tree, heap) *args)
+gimple_build_switch (tree index, tree default_label, VEC(tree, heap) *args)
{
- unsigned i, offset, nlabels = VEC_length (tree, args);
+ unsigned i, nlabels = VEC_length (tree, args);
+
gimple p = gimple_build_switch_nlabels (nlabels, index, default_label);
/* Copy the labels from the vector to the switch statement. */
- offset = (default_label != NULL);
for (i = 0; i < nlabels; i++)
- gimple_switch_set_label (p, i + offset, VEC_index (tree, args, i));
+ gimple_switch_set_label (p, i + 1, VEC_index (tree, args, i));
return p;
}
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 827103d0eb3..15b597fc187 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -781,8 +781,7 @@ gimple gimple_build_wce (gimple_seq);
gimple gimple_build_resx (int);
gimple gimple_build_eh_dispatch (int);
gimple gimple_build_switch_nlabels (unsigned, tree, tree);
-gimple gimple_build_switch (unsigned, tree, tree, ...);
-gimple gimple_build_switch_vec (tree, tree, VEC(tree,heap) *);
+gimple gimple_build_switch (tree, tree, VEC(tree,heap) *);
gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree);
gimple gimple_build_omp_for (gimple_seq, tree, size_t, gimple_seq);
@@ -3639,7 +3638,9 @@ gimple_switch_set_label (gimple gs, unsigned index, tree label)
static inline tree
gimple_switch_default_label (const_gimple gs)
{
- return gimple_switch_label (gs, 0);
+ tree label = gimple_switch_label (gs, 0);
+ gcc_checking_assert (!CASE_LOW (label) && !CASE_HIGH (label));
+ return label;
}
/* Set the default label for a switch statement. */
@@ -3647,6 +3648,7 @@ gimple_switch_default_label (const_gimple gs)
static inline void
gimple_switch_set_default_label (gimple gs, tree label)
{
+ gcc_checking_assert (!CASE_LOW (label) && !CASE_HIGH (label));
gimple_switch_set_label (gs, 0, label);
}
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 27930277c9c..03973537ee6 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1675,7 +1675,7 @@ preprocess_case_label_vec_for_gimple (VEC(tree,heap) *labels,
gcc_assert (!default_case);
default_case = elt;
/* The default case must be passed separately to the
- gimple_build_switch routines. But if DEFAULT_CASEP
+ gimple_build_switch routine. But if DEFAULT_CASEP
is NULL, we do not remove the default case (it would
be completely lost). */
if (default_casep)
@@ -1788,8 +1788,8 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
gimplify_seq_add_stmt (&switch_body_seq, new_default);
}
- gimple_switch = gimple_build_switch_vec (SWITCH_COND (switch_expr),
- default_case, labels);
+ gimple_switch = gimple_build_switch (SWITCH_COND (switch_expr),
+ default_case, labels);
gimplify_seq_add_stmt (pre_p, gimple_switch);
gimplify_seq_add_seq (pre_p, switch_body_seq);
VEC_free(tree, heap, labels);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index adbd0345f9e..9474167ce6d 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -4873,7 +4873,7 @@ expand_omp_sections (struct omp_region *region)
u = build_case_label (NULL, NULL, t);
make_edge (l0_bb, default_bb, 0);
- stmt = gimple_build_switch_vec (vmain, u, label_vec);
+ stmt = gimple_build_switch (vmain, u, label_vec);
gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
gsi_remove (&switch_si, true);
VEC_free (tree, heap, label_vec);
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 11180e4dc4a..8d76b3eea08 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -1951,7 +1951,7 @@ expand_case (gimple stmt)
tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
rtx default_label = NULL_RTX;
unsigned int count, uniq;
- int i, stopi = 0;
+ int i;
rtx before_case, end;
int ncases = gimple_switch_num_labels (stmt);
tree index_expr = gimple_switch_index (stmt);
@@ -1986,16 +1986,11 @@ expand_case (gimple stmt)
do_pending_stack_adjust ();
- /* The default case, if ever taken, is the first element. */
- elt = gimple_switch_label (stmt, 0);
- if (!CASE_LOW (elt) && !CASE_HIGH (elt))
- {
- default_label = label_rtx (CASE_LABEL (elt));
- stopi = 1;
- }
+ /* Find the default case target label. */
+ default_label = label_rtx (CASE_LABEL (gimple_switch_default_label (stmt)));
/* Get upper and lower bounds of case values. */
- elt = gimple_switch_label (stmt, stopi);
+ elt = gimple_switch_label (stmt, 1);
minval = fold_convert (index_type, CASE_LOW (elt));
elt = gimple_switch_label (stmt, ncases - 1);
if (CASE_HIGH (elt))
@@ -2011,7 +2006,7 @@ expand_case (gimple stmt)
uniq = 0;
count = 0;
label_bitmap = BITMAP_ALLOC (NULL);
- for (i = gimple_switch_num_labels (stmt) - 1; i >= stopi; --i)
+ for (i = gimple_switch_num_labels (stmt) - 1; i >= 1; --i)
{
tree low, high;
rtx lab;
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 9b2ae50bc6f..44715271822 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1334,26 +1334,11 @@ group_case_labels_stmt (gimple stmt)
int old_size = gimple_switch_num_labels (stmt);
int i, j, new_size = old_size;
basic_block default_bb = NULL;
- bool has_default;
- /* The default label is always the first case in a switch
- statement after gimplification if it was not optimized
- away */
- if (!CASE_LOW (gimple_switch_default_label (stmt))
- && !CASE_HIGH (gimple_switch_default_label (stmt)))
- {
- tree default_case = gimple_switch_default_label (stmt);
- default_bb = label_to_block (CASE_LABEL (default_case));
- has_default = true;
- }
- else
- has_default = false;
+ default_bb = label_to_block (CASE_LABEL (gimple_switch_default_label (stmt)));
/* Look for possible opportunities to merge cases. */
- if (has_default)
- i = 1;
- else
- i = 0;
+ i = 1;
while (i < old_size)
{
tree base_case, base_high;
@@ -4148,7 +4133,7 @@ verify_gimple_switch (gimple stmt)
return true;
}
- elt = gimple_switch_default_label (stmt);
+ elt = gimple_switch_label (stmt, 0);
if (CASE_LOW (elt) != NULL_TREE || CASE_HIGH (elt) != NULL_TREE)
{
error ("invalid default case label in switch statement");
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 9220931ffff..ec74d9d4c41 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -1487,8 +1487,8 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
/* Build the switch statement, setting last_case to be the default
label. */
- switch_stmt = gimple_build_switch_vec (finally_tmp, last_case,
- case_label_vec);
+ switch_stmt = gimple_build_switch (finally_tmp, last_case,
+ case_label_vec);
gimple_set_location (switch_stmt, finally_loc);
/* Need to link SWITCH_STMT after running replace_goto_queue
@@ -3376,7 +3376,7 @@ lower_eh_dispatch (basic_block src, gimple stmt)
default_label = build_case_label (NULL, NULL, default_label);
sort_case_labels (labels);
- x = gimple_build_switch_vec (filter, default_label, labels);
+ x = gimple_build_switch (filter, default_label, labels);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
VEC_free (tree, heap, labels);
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index df88ddf77e8..87baefc07cf 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -318,7 +318,7 @@ emit_case_bit_tests (gimple swtch, tree index_expr,
memset (&test, 0, sizeof (test));
/* Get the edge for the default case. */
- tmp = gimple_switch_label (swtch, 0);
+ tmp = gimple_switch_default_label (swtch);
default_bb = label_to_block (CASE_LABEL (tmp));
default_edge = find_edge (switch_bb, default_bb);
@@ -612,14 +612,12 @@ collect_switch_conv_info (gimple swtch, struct switch_conv_info *info)
memset (info, 0, sizeof (*info));
/* The gimplifier has already sorted the cases by CASE_LOW and ensured there
- is a default label which is the first in the vector. */
- gcc_assert (CASE_LOW (gimple_switch_label (swtch, 0)) == NULL_TREE);
-
- /* Collect the bits we can deduce from the CFG. */
+ is a default label which is the first in the vector.
+ Collect the bits we can deduce from the CFG. */
info->index_expr = gimple_switch_index (swtch);
info->switch_bb = gimple_bb (swtch);
info->default_bb =
- label_to_block (CASE_LABEL (gimple_switch_label (swtch, 0)));
+ label_to_block (CASE_LABEL (gimple_switch_default_label (swtch)));
e_default = find_edge (info->switch_bb, info->default_bb);
info->default_prob = e_default->probability;
info->default_count = e_default->count;
@@ -1393,7 +1391,7 @@ process_switch (gimple swtch)
transformation. */
create_temp_arrays (&info);
- gather_default_values (gimple_switch_label (swtch, 0), &info);
+ gather_default_values (gimple_switch_default_label (swtch), &info);
build_constructors (swtch, &info);
build_arrays (swtch, &info); /* Build the static arrays and assignments. */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index f949e8b9bee..067b60f168f 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -9142,7 +9142,7 @@ execute_vrp (void)
/* As we may have replaced the default label with a regular one
make sure to make it a real default label again. This ensures
optimal expansion. */
- label = gimple_switch_default_label (su->stmt);
+ label = gimple_switch_label (su->stmt, 0);
CASE_LOW (label) = NULL_TREE;
CASE_HIGH (label) = NULL_TREE;
}