This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][RFC] Add gimple-cfg.h.
Hi.
There's updated version with notes that were discussed with Richi
on IRC. As pointed out label_to_block can potentially lead to
quadratic complexity, but it's not ambition of the patch to resolve
that.
Martin
>From 393a0b87d7d667f0db6e512a840f2da3f51c8f7b Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 Aug 2018 14:54:32 +0200
Subject: [PATCH] Add new gswitch related functions into tree-cfg.c.
gcc/ChangeLog:
2018-08-23 Martin Liska <mliska@suse.cz>
* cfgexpand.c (expand_asm_stmt): Use label_to_block
instead of label_to_block_fn.
* hsa-gen.c (gen_hsa_insns_for_switch_stmt): Use new
function gimple_switch_default_bb.
(convert_switch_statements): Use cfun directly and
use label_to_block.
(expand_builtins): Use cfun directly.
* ipa-fnsummary.c (set_switch_stmt_execution_predicate):
Use new function gimple_switch_edge.
* stmt.c (label_to_block_fn): Remove declaration.
(expand_case): Use label_to_block.
* tree-cfg.c (make_gimple_switch_edges): Use new
function gimple_switch_bb.
(group_case_labels_stmt): Use gimple_switch_default_bb.
(gimple_verify_flow_info): Use gimple_switch_bb.
(gimple_switch_bb): New.
(gimple_switch_default_bb): Likewise.
(gimple_switch_edge): Likewise.
(gimple_switch_default_edge): Likewise.
* tree-cfg.h (label_to_block): Make proper extern symbol.
(gimple_switch_bb): New.
(gimple_switch_default_bb): Likewise.
(gimple_switch_edge): Likewise.
(gimple_switch_default_edge): Likewise.
* tree-cfgcleanup.c (convert_single_case_switch):
Use gimple_switch_default_bb.
* tree-switch-conversion.c (switch_conversion::collect):
Use gimple_switch_default_edge and gimple_switch_edge
functions.
(switch_conversion::check_final_bb): Use gimple_switch_bb.
(switch_decision_tree::compute_cases_per_edge):
Use gimple_switch_edge.
(switch_decision_tree::analyze_switch_statement): Do not
use label_to_block_fn.
(switch_decision_tree::try_switch_expansion): Use
gimple_switch_default_edge.
---
gcc/cfgexpand.c | 2 +-
gcc/hsa-gen.c | 21 ++++++----------
gcc/ipa-fnsummary.c | 2 +-
gcc/stmt.c | 4 +---
gcc/tree-cfg.c | 46 ++++++++++++++++++++++++++++++------
gcc/tree-cfg.h | 4 ++++
gcc/tree-cfgcleanup.c | 5 ++--
gcc/tree-switch-conversion.c | 40 ++++++++++---------------------
8 files changed, 68 insertions(+), 56 deletions(-)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3c5b30b79f8..156a529d730 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
may insert further instructions into the same basic block after
asm goto and if we don't do this, insertion of instructions on
the fallthru edge might misbehave. See PR58670. */
- if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
+ if (fallthru_bb && label_to_block (label) == fallthru_bb)
{
if (fallthru_label == NULL_RTX)
fallthru_label = gen_label_rtx ();
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 6595bedac82..39bd42e4522 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -3475,7 +3475,6 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
e->flags &= ~EDGE_FALLTHRU;
e->flags |= EDGE_TRUE_VALUE;
- function *func = DECL_STRUCT_FUNCTION (current_function_decl);
tree index_tree = gimple_switch_index (s);
tree lowest = get_switch_low (s);
tree highest = get_switch_high (s);
@@ -3499,9 +3498,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
hbb->append_insn (new hsa_insn_cbr (cmp_reg));
- tree default_label = gimple_switch_default_label (s);
- basic_block default_label_bb = label_to_block_fn (func,
- CASE_LABEL (default_label));
+ basic_block default_label_bb = gimple_switch_default_bb (s);
if (!gimple_seq_empty_p (phi_nodes (default_label_bb)))
{
@@ -3536,7 +3533,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
for (unsigned i = 1; i < labels; i++)
{
tree label = gimple_switch_label (s, i);
- basic_block bb = label_to_block_fn (func, CASE_LABEL (label));
+ basic_block bb = label_to_block (CASE_LABEL (label));
unsigned HOST_WIDE_INT sub_low
= tree_to_uhwi (int_const_binop (MINUS_EXPR, CASE_LOW (label), lowest));
@@ -6290,12 +6287,11 @@ LD: hard_work_3 ();
static bool
convert_switch_statements (void)
{
- function *func = DECL_STRUCT_FUNCTION (current_function_decl);
basic_block bb;
bool modified_cfg = false;
- FOR_EACH_BB_FN (bb, func)
+ FOR_EACH_BB_FN (bb, cfun)
{
gimple_stmt_iterator gsi = gsi_last_bb (bb);
if (gsi_end_p (gsi))
@@ -6318,7 +6314,7 @@ convert_switch_statements (void)
tree index_type = TREE_TYPE (index);
tree default_label = gimple_switch_default_label (s);
basic_block default_label_bb
- = label_to_block_fn (func, CASE_LABEL (default_label));
+ = label_to_block (CASE_LABEL (default_label));
basic_block cur_bb = bb;
auto_vec <edge> new_edges;
@@ -6330,8 +6326,7 @@ convert_switch_statements (void)
should be fixed after we add new collection of edges. */
for (unsigned i = 0; i < labels; i++)
{
- tree label = gimple_switch_label (s, i);
- basic_block label_bb = label_to_block_fn (func, CASE_LABEL (label));
+ basic_block label_bb = gimple_switch_bb (s, i);
edge e = find_edge (bb, label_bb);
edge_counts.safe_push (e->count ());
edge_probabilities.safe_push (e->probability);
@@ -6413,8 +6408,7 @@ convert_switch_statements (void)
gsi_insert_before (&cond_gsi, c, GSI_SAME_STMT);
- basic_block label_bb
- = label_to_block_fn (func, CASE_LABEL (label));
+ basic_block label_bb = label_to_block (CASE_LABEL (label));
edge new_edge = make_edge (cur_bb, label_bb, EDGE_TRUE_VALUE);
profile_probability prob_sum = sum_slice <profile_probability>
(edge_probabilities, i, labels, profile_probability::never ())
@@ -6481,10 +6475,9 @@ convert_switch_statements (void)
static void
expand_builtins ()
{
- function *func = DECL_STRUCT_FUNCTION (current_function_decl);
basic_block bb;
- FOR_EACH_BB_FN (bb, func)
+ FOR_EACH_BB_FN (bb, cfun)
{
for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
gsi_next (&gsi))
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..8aac26812f6 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -1291,7 +1291,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
tree min, max;
predicate p;
- e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
+ e = gimple_switch_edge (last, case_idx);
min = CASE_LOW (cl);
max = CASE_HIGH (cl);
diff --git a/gcc/stmt.c b/gcc/stmt.c
index b8df1818137..dc443a6fd66 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -82,8 +82,6 @@ struct simple_case_node
tree m_code_label;
};
-extern basic_block label_to_block_fn (struct function *, tree);
-
static bool check_unique_operand_names (tree, tree, tree);
static char *resolve_operand_name_1 (char *, tree, tree, tree);
@@ -907,7 +905,7 @@ expand_case (gswitch *stmt)
/* Find the default case target label. */
tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
default_label = jump_target_rtx (default_lab);
- basic_block default_bb = label_to_block_fn (cfun, default_lab);
+ basic_block default_bb = label_to_block (default_lab);
edge default_edge = find_edge (bb, default_bb);
/* Get upper and lower bounds of case values. */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 463dd8a3bf9..39157ade8aa 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1397,8 +1397,7 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb)
for (i = 0; i < n; ++i)
{
- tree lab = CASE_LABEL (gimple_switch_label (entry, i));
- basic_block label_bb = label_to_block (lab);
+ basic_block label_bb = gimple_switch_bb (entry, i);
make_edge (bb, label_bb, 0);
}
}
@@ -1773,7 +1772,7 @@ group_case_labels_stmt (gswitch *stmt)
int i, next_index, new_size;
basic_block default_bb = NULL;
- default_bb = label_to_block (CASE_LABEL (gimple_switch_default_label (stmt)));
+ default_bb = gimple_switch_default_bb (stmt);
/* Look for possible opportunities to merge cases. */
new_size = i = 1;
@@ -5655,8 +5654,7 @@ gimple_verify_flow_info (void)
/* Mark all the destination basic blocks. */
for (i = 0; i < n; ++i)
{
- tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
- basic_block label_bb = label_to_block (lab);
+ basic_block label_bb = gimple_switch_bb (switch_stmt, i);
gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
label_bb->aux = (void *)1;
}
@@ -5711,8 +5709,7 @@ gimple_verify_flow_info (void)
/* Check that we have all of them. */
for (i = 0; i < n; ++i)
{
- tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
- basic_block label_bb = label_to_block (lab);
+ basic_block label_bb = gimple_switch_bb (switch_stmt, i);
if (label_bb->aux != (void *)2)
{
@@ -9143,6 +9140,41 @@ generate_range_test (basic_block bb, tree index, tree low, tree high,
gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
}
+/* Return the basic block that belongs to label numbered INDEX
+ of a switch statement. */
+
+basic_block
+gimple_switch_bb (gswitch *gs, unsigned index)
+{
+ return label_to_block (CASE_LABEL (gimple_switch_label (gs, index)));
+}
+
+/* Return the default basic block of a switch statement. */
+
+basic_block
+gimple_switch_default_bb (gswitch *gs)
+{
+ return gimple_switch_bb (gs, 0);
+}
+
+/* Return the edge that belongs to label numbered INDEX
+ of a switch statement. */
+
+edge
+gimple_switch_edge (gswitch *gs, unsigned index)
+{
+ return find_edge (gimple_bb (gs), gimple_switch_bb (gs, index));
+}
+
+/* Return the default edge of a switch statement. */
+
+edge
+gimple_switch_default_edge (gswitch *gs)
+{
+ return gimple_switch_edge (gs, 0);
+}
+
+
/* Emit return warnings. */
namespace {
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 9491bb45feb..28194476cd1 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -112,6 +112,10 @@ extern bool extract_true_false_controlled_edges (basic_block, basic_block,
edge *, edge *);
extern void generate_range_test (basic_block bb, tree index, tree low,
tree high, tree *lhs, tree *rhs);
+extern basic_block gimple_switch_bb (gswitch *gs, unsigned index);
+extern basic_block gimple_switch_default_bb (gswitch *gs);
+extern edge gimple_switch_edge (gswitch *gs, unsigned index);
+extern edge gimple_switch_default_edge (gswitch *gs);
/* Return true if the LHS of a call should be removed. */
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b27ba8a7333..adac1d5f487 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -84,13 +84,12 @@ convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi)
return false;
tree index = gimple_switch_index (swtch);
- tree default_label = CASE_LABEL (gimple_switch_default_label (swtch));
tree label = gimple_switch_label (swtch, 1);
tree low = CASE_LOW (label);
tree high = CASE_HIGH (label);
- basic_block default_bb = label_to_block_fn (cfun, default_label);
- basic_block case_bb = label_to_block_fn (cfun, CASE_LABEL (label));
+ basic_block default_bb = gimple_switch_default_bb (swtch);
+ basic_block case_bb = label_to_block (CASE_LABEL (label));
basic_block bb = gimple_bb (swtch);
gcond *cond;
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 9a594a01fc4..c3d52fb3e74 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -78,7 +78,6 @@ switch_conversion::collect (gswitch *swtch)
unsigned int i;
edge e, e_default, e_first;
edge_iterator ei;
- basic_block first;
m_switch = swtch;
@@ -87,9 +86,8 @@ switch_conversion::collect (gswitch *swtch)
Collect the bits we can deduce from the CFG. */
m_index_expr = gimple_switch_index (swtch);
m_switch_bb = gimple_bb (swtch);
- m_default_bb
- = label_to_block (CASE_LABEL (gimple_switch_default_label (swtch)));
- e_default = find_edge (m_switch_bb, m_default_bb);
+ e_default = gimple_switch_default_edge (swtch);
+ m_default_bb = e_default->dest;
m_default_prob = e_default->probability;
m_default_count = e_default->count ();
FOR_EACH_EDGE (e, ei, m_switch_bb->succs)
@@ -120,15 +118,9 @@ switch_conversion::collect (gswitch *swtch)
}
if (m_contiguous_range)
- {
- first = label_to_block (CASE_LABEL (gimple_switch_label (swtch, 1)));
- e_first = find_edge (m_switch_bb, first);
- }
+ e_first = gimple_switch_edge (swtch, 1);
else
- {
- first = m_default_bb;
- e_first = e_default;
- }
+ e_first = e_default;
/* See if there is one common successor block for all branch
targets. If it exists, record it in FINAL_BB.
@@ -306,8 +298,7 @@ switch_conversion::check_final_bb ()
unsigned int branch_num = gimple_switch_num_labels (m_switch);
for (unsigned int i = 1; i < branch_num; i++)
{
- tree lab = CASE_LABEL (gimple_switch_label (m_switch, i));
- if (label_to_block (lab) == bb)
+ if (gimple_switch_bb (m_switch, i) == bb)
{
m_reason = reason;
return false;
@@ -1577,15 +1568,11 @@ bit_test_cluster::hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
void
switch_decision_tree::compute_cases_per_edge ()
{
- basic_block bb = gimple_bb (m_switch);
reset_out_edges_aux ();
int ncases = gimple_switch_num_labels (m_switch);
for (int i = ncases - 1; i >= 1; --i)
{
- tree elt = gimple_switch_label (m_switch, i);
- tree lab = CASE_LABEL (elt);
- basic_block case_bb = label_to_block_fn (cfun, lab);
- edge case_edge = find_edge (bb, case_bb);
+ edge case_edge = gimple_switch_edge (m_switch, i);
case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + 1);
}
}
@@ -1601,8 +1588,7 @@ switch_decision_tree::analyze_switch_statement ()
auto_vec<cluster *> clusters;
clusters.create (l - 1);
- tree default_label = CASE_LABEL (gimple_switch_default_label (m_switch));
- basic_block default_bb = label_to_block_fn (cfun, default_label);
+ basic_block default_bb = gimple_switch_default_bb (m_switch);
m_case_bbs.reserve (l);
m_case_bbs.quick_push (default_bb);
@@ -1612,15 +1598,16 @@ switch_decision_tree::analyze_switch_statement ()
{
tree elt = gimple_switch_label (m_switch, i);
tree lab = CASE_LABEL (elt);
- basic_block case_bb = label_to_block_fn (cfun, lab);
+ basic_block case_bb = label_to_block (lab);
edge case_edge = find_edge (bb, case_bb);
tree low = CASE_LOW (elt);
tree high = CASE_HIGH (elt);
profile_probability p
= case_edge->probability.apply_scale (1, (intptr_t) (case_edge->aux));
- clusters.quick_push (new simple_cluster (low, high, elt, case_bb, p));
- m_case_bbs.quick_push (case_bb);
+ clusters.quick_push (new simple_cluster (low, high, elt, case_edge->dest,
+ p));
+ m_case_bbs.quick_push (case_edge->dest);
}
reset_out_edges_aux ();
@@ -1694,9 +1681,8 @@ switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters)
return false;
/* Find the default case target label. */
- tree default_label_expr = CASE_LABEL (gimple_switch_default_label (m_switch));
- m_default_bb = label_to_block_fn (cfun, default_label_expr);
- edge default_edge = find_edge (bb, m_default_bb);
+ edge default_edge = gimple_switch_default_edge (m_switch);
+ m_default_bb = default_edge->dest;
/* Do the insertion of a case label into m_case_list. The labels are
fed to us in descending order from the sorted vector of case labels used
--
2.18.0