[gcc(refs/users/marxin/heads/if-to-switch-v4)] Allow more transforms.
Martin Liska
marxin@gcc.gnu.org
Tue Oct 13 13:13:49 GMT 2020
https://gcc.gnu.org/g:b064cbf06fa6aa4c59debe93686405058e59d3e9
commit b064cbf06fa6aa4c59debe93686405058e59d3e9
Author: Martin Liska <mliska@suse.cz>
Date: Tue Oct 13 15:11:16 2020 +0200
Allow more transforms.
Diff:
---
gcc/gimple-if-to-switch.cc | 78 ++++++++++++++++----------------------------
gcc/tree-switch-conversion.h | 11 +++++--
2 files changed, 37 insertions(+), 52 deletions(-)
diff --git a/gcc/gimple-if-to-switch.cc b/gcc/gimple-if-to-switch.cc
index 2a25650c3dc..ba78a2c7233 100644
--- a/gcc/gimple-if-to-switch.cc
+++ b/gcc/gimple-if-to-switch.cc
@@ -100,8 +100,7 @@ condition_info::record_phi_mapping (edge e, mapping_vec *vec)
struct if_chain
{
/* Default constructor. */
- if_chain():
- m_first_condition (NULL), m_index (NULL_TREE), m_entries ()
+ if_chain(): m_entries ()
{
m_entries.create (2);
}
@@ -112,9 +111,6 @@ struct if_chain
m_entries.release ();
}
- /* Set index and check that it is not a different one. */
- bool set_and_check_index (tree index);
-
/* Verify that all case ranges do not overlap. */
bool check_non_overlapping_cases ();
@@ -122,26 +118,10 @@ struct if_chain
a bit test (at least partially). */
bool is_beneficial ();
- /* First condition of the chain. */
- gcond *m_first_condition;
- /* Switch index. */
- tree m_index;
/* If chain entries. */
vec<condition_info *> m_entries;
};
-bool
-if_chain::set_and_check_index (tree index)
-{
- if (TREE_CODE (index) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (index)))
- return false;
-
- if (m_index == NULL)
- m_index = index;
-
- return index == m_index;
-}
-
/* Compare two case ranges by minimum value. */
static int
@@ -215,10 +195,11 @@ if_chain::is_beneficial ()
for (unsigned j = 0; j < info->m_ranges.length (); j++)
{
range_entry *range = &info->m_ranges[j];
+ basic_block bb = info->m_true_edge->dest;
+ bool has_forwarder = !info->m_true_edge_phi_mapping.is_empty ();
clusters.safe_push (new simple_cluster (range->low, range->high,
- NULL_TREE,
- info->m_true_edge->dest,
- prob));
+ NULL_TREE, bb, prob,
+ has_forwarder));
}
}
@@ -234,7 +215,9 @@ if_chain::is_beneficial ()
simple_cluster *right = static_cast<simple_cluster *> (clusters[i]);
tree type = TREE_TYPE (left->get_low ());
tree pos_one = build_int_cst (type, 1);
- if (left->m_case_bb == right->m_case_bb)
+ if (!left->m_has_forward_bb
+ && !right->m_has_forward_bb
+ && left->m_case_bb == right->m_case_bb)
{
tree next = int_const_binop (PLUS_EXPR, left->get_high (), pos_one);
if (tree_int_cst_equal (next, right->get_low ()))
@@ -472,25 +455,13 @@ public:
unsigned int
pass_if_to_switch::execute (function *fun)
{
+ auto_vec<if_chain *> all_candidates;
hash_map<basic_block, condition_info> conditions_in_bbs;
basic_block bb;
FOR_EACH_BB_FN (bb, fun)
find_conditions (bb, &conditions_in_bbs);
- FOR_EACH_BB_FN (bb, fun)
- {
- condition_info *info = conditions_in_bbs.get (bb);
- if (info)
- {
- debug_bb (gimple_bb (info->m_cond));
- for (unsigned i = 0; i < info->m_ranges.length (); i++)
- debug_range_entry (&info->m_ranges[i]);
- }
- }
-
- fprintf (stderr, "=====================\n");
-
int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
unsigned n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
@@ -522,26 +493,35 @@ pass_if_to_switch::execute (function *fun)
info = info2;
}
- fprintf (stderr, "Found chain with %d items\n", chain->m_entries.length ());
chain->m_entries.reverse ();
- for (unsigned i = 0; i < chain->m_entries.length (); i++)
+ if (chain->m_entries.length () >= 3
+ && chain->is_beneficial ())
{
- debug_bb (chain->m_entries[i]->m_true_edge->src);
- }
-
- if (chain->m_entries.length () >= 4)
- {
- convert_if_conditions_to_switch (chain);
- // TODO
- break;
+ expanded_location loc
+ = expand_location (gimple_location (chain->m_entries[0]->m_cond));
+ if (dump_file)
+ {
+ fprintf (dump_file, "Condition chain (at %s:%d) with %d BBs "
+ "transformed into a switch statement.\n",
+ loc.file, loc.line,
+ chain->m_entries.length ());
+ }
+ all_candidates.safe_push (chain);
}
}
}
+ for (unsigned i = 0; i < all_candidates.length (); i++)
+ {
+ convert_if_conditions_to_switch (all_candidates[i]);
+ delete all_candidates[i];
+ }
+
free (rpo);
free_dominance_info (CDI_DOMINATORS);
- mark_virtual_operands_for_renaming (fun);
+ if (!all_candidates.is_empty ())
+ mark_virtual_operands_for_renaming (fun);
return 0;
}
diff --git a/gcc/tree-switch-conversion.h b/gcc/tree-switch-conversion.h
index 1e25087a21d..62cfde168c8 100644
--- a/gcc/tree-switch-conversion.h
+++ b/gcc/tree-switch-conversion.h
@@ -122,7 +122,8 @@ class simple_cluster: public cluster
public:
/* Constructor. */
inline simple_cluster (tree low, tree high, tree case_label_expr,
- basic_block case_bb, profile_probability prob);
+ basic_block case_bb, profile_probability prob,
+ bool has_forward_bb = false);
/* Destructor. */
~simple_cluster ()
@@ -187,12 +188,16 @@ public:
/* True if case is a range. */
bool m_range_p;
+
+ /* True if the case will use a forwarder BB. */
+ bool m_has_forward_bb;
};
simple_cluster::simple_cluster (tree low, tree high, tree case_label_expr,
- basic_block case_bb, profile_probability prob):
+ basic_block case_bb, profile_probability prob,
+ bool has_forward_bb):
cluster (case_label_expr, case_bb, prob, prob),
- m_low (low), m_high (high)
+ m_low (low), m_high (high), m_has_forward_bb (has_forward_bb)
{
m_range_p = m_high != NULL;
if (m_high == NULL)
More information about the Gcc-cvs
mailing list