aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKazu Hirata <kazu@cs.umass.edu>2004-03-25 16:16:41 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2004-03-25 16:16:41 +0000
commit43a21dfc46151a5f50f7372fda42b6eba36950c9 (patch)
treeb8180448c0f7c82d4935723ff1e395c1211301e7 /gcc
parent6d11af89b1c8723f644edcd243ba109b0cb2507d (diff)
downloadgcc-43a21dfc46151a5f50f7372fda42b6eba36950c9.zip
gcc-43a21dfc46151a5f50f7372fda42b6eba36950c9.tar.gz
gcc-43a21dfc46151a5f50f7372fda42b6eba36950c9.tar.bz2
re PR middle-end/9707 (Unnecessary range test in switches with less than 4 cases)
PR optimization/9707. * stmt.c (emit_case_nodes): Emit equality comparisons instead of recursing if both children are single-valued cases with no children. From-SVN: r79954
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/stmt.c36
2 files changed, 43 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 505adac..e63bbff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2004-03-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR optimization/9707.
+ * stmt.c (emit_case_nodes): Emit equality comparisons instead
+ of recursing if both children are single-valued cases with no
+ children.
+
2004-03-25 Paul Brook <paul@codesourcery.com>
* config/arm/arm.c (vfp_print_multi): Remove.
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 3d5da37..a28a014 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -6200,6 +6200,42 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
emit_case_nodes (index, node->right, default_label, index_type);
}
+ /* If both children are single-valued cases with no
+ children, finish up all the work. This way, we can save
+ one ordered comparison. */
+ else if (tree_int_cst_equal (node->right->low, node->right->high)
+ && node->right->left == 0
+ && node->right->right == 0
+ && tree_int_cst_equal (node->left->low, node->left->high)
+ && node->left->left == 0
+ && node->left->right == 0)
+ {
+ /* Neither node is bounded. First distinguish the two sides;
+ then emit the code for one side at a time. */
+
+ /* See if the value matches what the right hand side
+ wants. */
+ do_jump_if_equal (index,
+ convert_modes (mode, imode,
+ expand_expr (node->right->low,
+ NULL_RTX,
+ VOIDmode, 0),
+ unsignedp),
+ label_rtx (node->right->code_label),
+ unsignedp);
+
+ /* See if the value matches what the left hand side
+ wants. */
+ do_jump_if_equal (index,
+ convert_modes (mode, imode,
+ expand_expr (node->left->low,
+ NULL_RTX,
+ VOIDmode, 0),
+ unsignedp),
+ label_rtx (node->left->code_label),
+ unsignedp);
+ }
+
else
{
/* Neither node is bounded. First distinguish the two sides;