aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-switch-conversion.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-08-13 17:22:35 +0200
committerMartin Liska <mliska@suse.cz>2021-08-16 13:37:49 +0200
commitc517cf2e685e2903b591d63c1034ff9726cb3822 (patch)
tree723f4bb29ab6783546386005b2b17a3a1f51907c /gcc/tree-switch-conversion.c
parent29020d0527512ae0444ad32b1461b7f8526e7427 (diff)
downloadgcc-c517cf2e685e2903b591d63c1034ff9726cb3822.zip
gcc-c517cf2e685e2903b591d63c1034ff9726cb3822.tar.gz
gcc-c517cf2e685e2903b591d63c1034ff9726cb3822.tar.bz2
Speed up jump table switch detection.
PR tree-optimization/100393 gcc/ChangeLog: * tree-switch-conversion.c (group_cluster::dump): Use get_comparison_count. (jump_table_cluster::find_jump_tables): Pre-compute number of comparisons and then decrement it. Cache also max_ratio. (jump_table_cluster::can_be_handled): Change signature. * tree-switch-conversion.h (get_comparison_count): New.
Diffstat (limited to 'gcc/tree-switch-conversion.c')
-rw-r--r--gcc/tree-switch-conversion.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 294b545..244cf4b 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -1091,7 +1091,7 @@ group_cluster::dump (FILE *f, bool details)
for (unsigned i = 0; i < m_cases.length (); i++)
{
simple_cluster *sc = static_cast<simple_cluster *> (m_cases[i]);
- comparison_count += sc->m_range_p ? 2 : 1;
+ comparison_count += sc->get_comparison_count ();
}
unsigned HOST_WIDE_INT range = get_range (get_low (), get_high ());
@@ -1186,11 +1186,24 @@ jump_table_cluster::find_jump_tables (vec<cluster *> &clusters)
min.quick_push (min_cluster_item (0, 0, 0));
+ unsigned HOST_WIDE_INT max_ratio
+ = (optimize_insn_for_size_p ()
+ ? param_jump_table_max_growth_ratio_for_size
+ : param_jump_table_max_growth_ratio_for_speed);
+
for (unsigned i = 1; i <= l; i++)
{
/* Set minimal # of clusters with i-th item to infinite. */
min.quick_push (min_cluster_item (INT_MAX, INT_MAX, INT_MAX));
+ /* Pre-calculate number of comparisons for the clusters. */
+ HOST_WIDE_INT comparison_count = 0;
+ for (unsigned k = 0; k <= i - 1; k++)
+ {
+ simple_cluster *sc = static_cast<simple_cluster *> (clusters[k]);
+ comparison_count += sc->get_comparison_count ();
+ }
+
for (unsigned j = 0; j < i; j++)
{
unsigned HOST_WIDE_INT s = min[j].m_non_jt_cases;
@@ -1201,10 +1214,15 @@ jump_table_cluster::find_jump_tables (vec<cluster *> &clusters)
if ((min[j].m_count + 1 < min[i].m_count
|| (min[j].m_count + 1 == min[i].m_count
&& s < min[i].m_non_jt_cases))
- && can_be_handled (clusters, j, i - 1))
+ && can_be_handled (clusters, j, i - 1, max_ratio,
+ comparison_count))
min[i] = min_cluster_item (min[j].m_count + 1, j, s);
+
+ simple_cluster *sc = static_cast<simple_cluster *> (clusters[j]);
+ comparison_count -= sc->get_comparison_count ();
}
+ gcc_checking_assert (comparison_count == 0);
gcc_checking_assert (min[i].m_count != INT_MAX);
}
@@ -1242,7 +1260,9 @@ jump_table_cluster::find_jump_tables (vec<cluster *> &clusters)
bool
jump_table_cluster::can_be_handled (const vec<cluster *> &clusters,
- unsigned start, unsigned end)
+ unsigned start, unsigned end,
+ unsigned HOST_WIDE_INT max_ratio,
+ unsigned HOST_WIDE_INT comparison_count)
{
/* If the switch is relatively small such that the cost of one
indirect jump on the target are higher than the cost of a
@@ -1261,10 +1281,6 @@ jump_table_cluster::can_be_handled (const vec<cluster *> &clusters,
if (start == end)
return true;
- unsigned HOST_WIDE_INT max_ratio
- = (optimize_insn_for_size_p ()
- ? param_jump_table_max_growth_ratio_for_size
- : param_jump_table_max_growth_ratio_for_speed);
unsigned HOST_WIDE_INT range = get_range (clusters[start]->get_low (),
clusters[end]->get_high ());
/* Check overflow. */
@@ -1278,18 +1294,6 @@ jump_table_cluster::can_be_handled (const vec<cluster *> &clusters,
if (lhs < range)
return false;
- /* First make quick guess as each cluster
- can add at maximum 2 to the comparison_count. */
- if (lhs > 2 * max_ratio * (end - start + 1))
- return false;
-
- unsigned HOST_WIDE_INT comparison_count = 0;
- for (unsigned i = start; i <= end; i++)
- {
- simple_cluster *sc = static_cast<simple_cluster *> (clusters[i]);
- comparison_count += sc->m_range_p ? 2 : 1;
- }
-
return lhs <= max_ratio * comparison_count;
}