diff options
author | Martin Liska <mliska@suse.cz> | 2021-08-13 17:22:35 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-08-16 13:37:49 +0200 |
commit | c517cf2e685e2903b591d63c1034ff9726cb3822 (patch) | |
tree | 723f4bb29ab6783546386005b2b17a3a1f51907c /gcc/tree-switch-conversion.c | |
parent | 29020d0527512ae0444ad32b1461b7f8526e7427 (diff) | |
download | gcc-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.c | 42 |
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; } |