aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-switch-conversion.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-switch-conversion.c')
-rw-r--r--gcc/tree-switch-conversion.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 029ce8c..ddd8cba 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -1121,6 +1121,8 @@ jump_table_cluster::find_jump_tables (vec<cluster *> &clusters)
&& can_be_handled (clusters, j, i - 1))
min[i] = min_cluster_item (min[j].m_count + 1, j, s);
}
+
+ gcc_checking_assert (min[i].m_count != INT_MAX);
}
/* No result. */
@@ -1172,8 +1174,13 @@ jump_table_cluster::can_be_handled (const vec<cluster *> &clusters,
if (!flag_jump_tables)
return false;
- unsigned HOST_WIDE_INT max_ratio = optimize_insn_for_size_p () ? 3 : 8;
+ /* For algorithm correctness, jump table for a single case must return
+ true. We bail out in is_beneficial if it's called just for
+ a single case. */
+ if (start == end)
+ return true;
+ unsigned HOST_WIDE_INT max_ratio = optimize_insn_for_size_p () ? 3 : 8;
unsigned HOST_WIDE_INT range = get_range (clusters[start]->get_low (),
clusters[end]->get_high ());
/* Check overflow. */
@@ -1197,6 +1204,10 @@ bool
jump_table_cluster::is_beneficial (const vec<cluster *> &,
unsigned start, unsigned end)
{
+ /* Single case bail out. */
+ if (start == end)
+ return false;
+
return end - start + 1 >= case_values_threshold ();
}
@@ -1226,6 +1237,8 @@ bit_test_cluster::find_bit_tests (vec<cluster *> &clusters)
&& can_be_handled (clusters, j, i - 1))
min[i] = min_cluster_item (min[j].m_count + 1, j, INT_MAX);
}
+
+ gcc_checking_assert (min[i].m_count != INT_MAX);
}
/* No result. */
@@ -1277,6 +1290,12 @@ bool
bit_test_cluster::can_be_handled (const vec<cluster *> &clusters,
unsigned start, unsigned end)
{
+ /* For algorithm correctness, bit test for a single case must return
+ true. We bail out in is_beneficial if it's called just for
+ a single case. */
+ if (start == end)
+ return true;
+
unsigned HOST_WIDE_INT range = get_range (clusters[start]->get_low (),
clusters[end]->get_high ());
auto_bitmap dest_bbs;
@@ -1308,6 +1327,10 @@ bool
bit_test_cluster::is_beneficial (const vec<cluster *> &clusters,
unsigned start, unsigned end)
{
+ /* Single case bail out. */
+ if (start == end)
+ return false;
+
auto_bitmap dest_bbs;
for (unsigned i = start; i <= end; i++)
@@ -1599,7 +1622,7 @@ switch_decision_tree::analyze_switch_statement ()
/* Find jump table clusters. */
vec<cluster *> output = jump_table_cluster::find_jump_tables (clusters);
- /* Find jump table clusters. */
+ /* Find bit test clusters. */
vec<cluster *> output2;
auto_vec<cluster *> tmp;
output2.create (1);