aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-switch-conversion.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2018-08-27 14:17:54 +0200
committerMartin Liska <marxin@gcc.gnu.org>2018-08-27 12:17:54 +0000
commitdbdfaaba50c5d7d85c1e64751988d00114fd7d6b (patch)
tree5c8f893e4a884022f9007c23ad181990fb45cdce /gcc/tree-switch-conversion.c
parent61ff5d6f4ed5000ee427e054ee803bc8f5535bdd (diff)
Fix probabilities for jump table (PR tree-optimization/86702).
2018-08-27 Martin Liska <mliska@suse.cz> PR tree-optimization/86702 * tree-switch-conversion.c (jump_table_cluster::emit): Make probabilities even for values in jump table according to number of cases handled. (switch_decision_tree::compute_cases_per_edge): Pass argument to reset_out_edges_aux function. (switch_decision_tree::analyze_switch_statement): Likewise. * tree-switch-conversion.h (switch_decision_tree::reset_out_edges_aux): Make it static. From-SVN: r263877
Diffstat (limited to 'gcc/tree-switch-conversion.c')
-rw-r--r--gcc/tree-switch-conversion.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index ef08bdc990d..00a463b1dde 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -1061,6 +1061,9 @@ void
jump_table_cluster::emit (tree index_expr, tree,
tree default_label_expr, basic_block default_bb)
{
+ unsigned HOST_WIDE_INT range = get_range (get_low (), get_high ());
+ unsigned HOST_WIDE_INT nondefault_range = 0;
+
/* For jump table we just emit a new gswitch statement that will
be latter lowered to jump table. */
auto_vec <tree> labels;
@@ -1077,6 +1080,39 @@ jump_table_cluster::emit (tree index_expr, tree,
unshare_expr (default_label_expr), labels);
gimple_stmt_iterator gsi = gsi_start_bb (m_case_bb);
gsi_insert_after (&gsi, s, GSI_NEW_STMT);
+
+ /* Set up even probabilities for all cases. */
+ for (unsigned i = 0; i < m_cases.length (); i++)
+ {
+ simple_cluster *sc = static_cast<simple_cluster *> (m_cases[i]);
+ edge case_edge = find_edge (m_case_bb, sc->m_case_bb);
+ unsigned HOST_WIDE_INT case_range
+ = sc->get_range (sc->get_low (), sc->get_high ());
+ nondefault_range += case_range;
+
+ /* case_edge->aux is number of values in a jump-table that are covered
+ by the case_edge. */
+ case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + case_range);
+ }
+
+ edge default_edge = gimple_switch_default_edge (cfun, s);
+ default_edge->probability = profile_probability::never ();
+
+ for (unsigned i = 0; i < m_cases.length (); i++)
+ {
+ simple_cluster *sc = static_cast<simple_cluster *> (m_cases[i]);
+ edge case_edge = find_edge (m_case_bb, sc->m_case_bb);
+ case_edge->probability
+ = profile_probability::always ().apply_scale ((intptr_t)case_edge->aux,
+ range);
+ }
+
+ /* Number of non-default values is probability of default edge. */
+ default_edge->probability
+ += profile_probability::always ().apply_scale (nondefault_range,
+ range).invert ();
+
+ switch_decision_tree::reset_out_edges_aux (s);
}
/* Find jump tables of given CLUSTERS, where all members of the vector
@@ -1568,7 +1604,7 @@ bit_test_cluster::hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
void
switch_decision_tree::compute_cases_per_edge ()
{
- reset_out_edges_aux ();
+ reset_out_edges_aux (m_switch);
int ncases = gimple_switch_num_labels (m_switch);
for (int i = ncases - 1; i >= 1; --i)
{
@@ -1610,7 +1646,7 @@ switch_decision_tree::analyze_switch_statement ()
m_case_bbs.quick_push (case_edge->dest);
}
- reset_out_edges_aux ();
+ reset_out_edges_aux (m_switch);
/* Find jump table clusters. */
vec<cluster *> output = jump_table_cluster::find_jump_tables (clusters);