Message ID | db5db1c1-a46c-5cc7-03c4-c7b1cb3e2a0a@suse.cz |
---|---|
State | New |
Headers | show |
Series | [RFC] Add gimple-cfg.h. | expand |
On Tue, Aug 21, 2018 at 2:58 PM Martin Liška <mliska@suse.cz> wrote: > > Hi. > > I'm considering adding couple of new gimple-related functions that > are related to gswitch statement. > > Is it a good idea? Just add them to tree-cfg.h? That's what should be really called gimple-cfg.h these days... Richard. > Martin > > gcc/ChangeLog: > > 2018-08-06 Martin Liska <mliska@suse.cz> > > * gimple-cfg.h: New file. > * ipa-fnsummary.c (set_switch_stmt_execution_predicate): > Use gimple_switch_edge (and gimple_switch_default_edge). > * tree-switch-conversion.c (switch_conversion::collect): Likewise. > (switch_decision_tree::compute_cases_per_edge): Likewise. > (switch_decision_tree::analyze_switch_statement): Likewise. > (switch_decision_tree::try_switch_expansion): Likewise. > --- > gcc/gimple-cfg.h | 44 ++++++++++++++++++++++++++++++++++++ > gcc/ipa-fnsummary.c | 7 +++--- > gcc/tree-switch-conversion.c | 38 ++++++++++++------------------- > 3 files changed, 62 insertions(+), 27 deletions(-) > create mode 100644 gcc/gimple-cfg.h > >
On 08/21/2018 03:55 PM, Richard Biener wrote: > On Tue, Aug 21, 2018 at 2:58 PM Martin Liška <mliska@suse.cz> wrote: >> >> Hi. >> >> I'm considering adding couple of new gimple-related functions that >> are related to gswitch statement. >> >> Is it a good idea? > > Just add them to tree-cfg.h? That's what should be really called > gimple-cfg.h these days... Yes, done in the patch. I actually added 2 more functions: extern basic_block gimple_switch_bb (gswitch *gs, unsigned index); extern basic_block gimple_switch_default_bb (gswitch *gs); and I clean up the implementation. Apart from that I noticed label_to_block_fn can be removed as all callers use cfun as argument. Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. Ready to be installed? Martin > > Richard. > >> Martin >> >> gcc/ChangeLog: >> >> 2018-08-06 Martin Liska <mliska@suse.cz> >> >> * gimple-cfg.h: New file. >> * ipa-fnsummary.c (set_switch_stmt_execution_predicate): >> Use gimple_switch_edge (and gimple_switch_default_edge). >> * tree-switch-conversion.c (switch_conversion::collect): Likewise. >> (switch_decision_tree::compute_cases_per_edge): Likewise. >> (switch_decision_tree::analyze_switch_statement): Likewise. >> (switch_decision_tree::try_switch_expansion): Likewise. >> --- >> gcc/gimple-cfg.h | 44 ++++++++++++++++++++++++++++++++++++ >> gcc/ipa-fnsummary.c | 7 +++--- >> gcc/tree-switch-conversion.c | 38 ++++++++++++------------------- >> 3 files changed, 62 insertions(+), 27 deletions(-) >> create mode 100644 gcc/gimple-cfg.h >> >> From e59865447c1f19988bc0c6db05d8d4ba78d6785e 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. (label_to_block_fn): Remove. (label_to_block): Replace implementation done in label_to_block_fn. (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_fn): Remove. (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 | 54 ++++++++++++++++++++++++++++-------- gcc/tree-cfg.h | 8 ++++-- gcc/tree-cfgcleanup.c | 5 ++-- gcc/tree-switch-conversion.c | 40 +++++++++----------------- 8 files changed, 74 insertions(+), 62 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..bbfc21158a3 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1397,17 +1397,16 @@ 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); } } -/* Return the basic block holding label DEST. */ +/* Return the basic block holding label DEST for current function. */ basic_block -label_to_block_fn (struct function *ifun, tree dest) +label_to_block (tree dest) { int uid = LABEL_DECL_UID (dest); @@ -1424,9 +1423,9 @@ label_to_block_fn (struct function *ifun, tree dest) gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); uid = LABEL_DECL_UID (dest); } - if (vec_safe_length (ifun->cfg->x_label_to_block_map) <= (unsigned int) uid) + if (vec_safe_length (cfun->cfg->x_label_to_block_map) <= (unsigned int) uid) return NULL; - return (*ifun->cfg->x_label_to_block_map)[uid]; + return (*cfun->cfg->x_label_to_block_map)[uid]; } /* Create edges for a goto statement at block BB. Returns true @@ -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..d8e9c1a56f6 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -33,8 +33,7 @@ extern void init_empty_tree_cfg_for_function (struct function *); extern void init_empty_tree_cfg (void); extern void start_recording_case_labels (void); extern void end_recording_case_labels (void); -extern basic_block label_to_block_fn (struct function *, tree); -#define label_to_block(t) (label_to_block_fn (cfun, t)) +extern basic_block label_to_block (tree); extern void cleanup_dead_labels (void); extern bool group_case_labels_stmt (gswitch *); extern bool group_case_labels (void); @@ -112,6 +111,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. */ @@ -122,5 +125,6 @@ should_remove_lhs_p (tree lhs) && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST && !TREE_ADDRESSABLE (TREE_TYPE (lhs))); } +edge gimple_switch_default_edge (gswitch *gs); #endif /* _TREE_CFG_H */ 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
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
On Mon, Aug 27, 2018 at 9:13 AM Martin Liška <mliska@suse.cz> wrote: > > 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. Please don't @@ -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 (); rather the label_to_block function should go away. OK with removing any such instances in the patch. Richard. > Martin
On 08/27/2018 09:56 AM, Richard Biener wrote: > On Mon, Aug 27, 2018 at 9:13 AM Martin Liška <mliska@suse.cz> wrote: >> >> 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. > > Please don't > > @@ -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 (); > > rather the label_to_block function should go away. OK with removing any > such instances in the patch. > > Richard. > >> Martin Ok, I'm sending one more version where I completely removed label_to_block_fn. Richi, out of the modified function, which would be subject for introduction of a new argument (struct *function)? Martin From aae3a43220a75268b01837a77f7d720a1eeba573 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-27 Martin Liska <mliska@suse.cz> * cfgexpand.c (expand_asm_stmt): Use label_to_block and pass cfun argument explicitly. * gimple-pretty-print.c (dump_gimple_switch): Likewise. * hsa-gen.c (gen_hsa_insns_for_switch_stmt): Use new function gimple_switch_default_bb. (convert_switch_statements): (expand_builtins): * ipa-fnsummary.c (set_switch_stmt_execution_predicate): * stmt.c (label_to_block_fn): Use label_to_block and pass cfun argument explicitly and use gimple_switch_bb. (expand_case): Likewise. * tree-cfg.c (lower_phi_internal_fn): Use label_to_block and pass cfun argument explicitly. Likewise. (make_edges_bb): Likewise. (make_cond_expr_edges): Likewise. (get_cases_for_edge): Likewise. (make_gimple_switch_edges): Likewise. (label_to_block_fn): Likewise. (label_to_block): Likewise. (make_goto_expr_edges): Likewise. (make_gimple_asm_edges): Likewise. (main_block_label): Likewise. (group_case_labels_stmt): Likewise. (find_taken_edge_computed_goto): Likewise. (find_taken_edge_switch_expr): Likewise. (gimple_verify_flow_info): Likewise. (gimple_redirect_edge_and_branch): Likewise. (gimple_switch_bb): New function. (gimple_switch_default_bb): Likewise. (gimple_switch_edge): Likewise. (gimple_switch_default_edge): Likewise. * tree-cfg.h (label_to_block_fn): Remove and replace ... (label_to_block): ... with this. (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 new gimple functions and pass new argument to label_to_block. (cleanup_control_flow_bb): * tree-eh.c (make_eh_dispatch_edges): Use label_to_block and pass cfun argument explicitly. (make_eh_edges): Likewise. (redirect_eh_dispatch_edge): Likewise. (lower_resx): Likewise. (lower_eh_dispatch): Likewise. (maybe_remove_unreachable_handlers): Likewise. (unsplit_eh): Likewise. (cleanup_empty_eh): Likewise. (verify_eh_edges): Likewise. (verify_eh_dispatch_edge): Likewise. * tree-ssa-dom.c (record_edge_info): Likewise. * tree-ssa-forwprop.c (simplify_gimple_switch_label_vec): Likewise. * tree-ssa-threadedge.c (thread_around_empty_blocks): Likewise. (thread_through_normal_block): Likewise. * tree-ssa-uncprop.c (associate_equivalences_with_edges): Likewise. * tree-ssa-uninit.c (convert_control_dep_chain_into_preds): * tree-switch-conversion.c (switch_conversion::collect): Use new gimple functions. (switch_conversion::check_final_bb): Likewise. (switch_conversion::gather_default_values): Pass new argument to label_to_block. (switch_conversion::build_constructors): Likewise. (switch_decision_tree::compute_cases_per_edge): Use new gimple_switch_edge function. (switch_decision_tree::analyze_switch_statement): Pass new argument to label_to_block. (switch_decision_tree::try_switch_expansion): Use gimple_switch_default_edge. * tree-vrp.c (find_switch_asserts): Pass new argument to label_to_block. * vr-values.c (vr_values::vrp_visit_switch_stmt): Likewise. (vr_values::simplify_switch_using_ranges): Likewise. --- gcc/cfgexpand.c | 2 +- gcc/gimple-pretty-print.c | 2 +- gcc/hsa-gen.c | 21 +++------ gcc/ipa-fnsummary.c | 2 +- gcc/stmt.c | 4 +- gcc/tree-cfg.c | 82 +++++++++++++++++++++++++----------- gcc/tree-cfg.h | 7 ++- gcc/tree-cfgcleanup.c | 7 ++- gcc/tree-eh.c | 26 ++++++------ gcc/tree-ssa-dom.c | 3 +- gcc/tree-ssa-forwprop.c | 2 +- gcc/tree-ssa-threadedge.c | 4 +- gcc/tree-ssa-uncprop.c | 2 +- gcc/tree-ssa-uninit.c | 2 +- gcc/tree-switch-conversion.c | 44 +++++++------------ gcc/tree-vrp.c | 2 +- gcc/vr-values.c | 5 ++- 17 files changed, 115 insertions(+), 102 deletions(-) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 3c5b30b79f8..647764b0e94 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 (cfun, label) == fallthru_bb) { if (fallthru_label == NULL_RTX) fallthru_label = gen_label_rtx (); diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index d3c5ec6f79b..dd63a28761b 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -992,7 +992,7 @@ dump_gimple_switch (pretty_printer *buffer, gswitch *gs, int spc, if (cfun && cfun->cfg) { - basic_block dest = label_to_block (label); + basic_block dest = label_to_block (cfun, label); if (dest) { edge label_edge = find_edge (gimple_bb (gs), dest); diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index 6595bedac82..927b5813952 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 (cfun, 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 (cfun, 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 (cfun, 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..07355984de1 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -81,8 +81,6 @@ struct simple_case_node /* Label to jump to when node matches. */ 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 (cfun, 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..6a776e3b7c1 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -389,7 +389,7 @@ lower_phi_internal_fn () { tree arg = gimple_call_arg (stmt, i); if (TREE_CODE (arg) == LABEL_DECL) - pred = label_to_block (arg); + pred = label_to_block (cfun, arg); else { edge e = find_edge (pred, bb); @@ -972,15 +972,15 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index) tree label2 = gimple_transaction_label_uninst (txn); if (label1) - make_edge (bb, label_to_block (label1), EDGE_FALLTHRU); + make_edge (bb, label_to_block (cfun, label1), EDGE_FALLTHRU); if (label2) - make_edge (bb, label_to_block (label2), + make_edge (bb, label_to_block (cfun, label2), EDGE_TM_UNINSTRUMENTED | (label1 ? 0 : EDGE_FALLTHRU)); tree label3 = gimple_transaction_label_over (txn); if (gimple_transaction_subcode (txn) & (GTMA_HAVE_ABORT | GTMA_IS_OUTER)) - make_edge (bb, label_to_block (label3), EDGE_TM_ABORT); + make_edge (bb, label_to_block (cfun, label3), EDGE_TM_ABORT); fallthru = false; } @@ -1265,8 +1265,8 @@ make_cond_expr_edges (basic_block bb) /* Entry basic blocks for each component. */ then_label = gimple_cond_true_label (entry); else_label = gimple_cond_false_label (entry); - then_bb = label_to_block (then_label); - else_bb = label_to_block (else_label); + then_bb = label_to_block (cfun, then_label); + else_bb = label_to_block (cfun, else_label); then_stmt = first_stmt (then_bb); else_stmt = first_stmt (else_bb); @@ -1373,7 +1373,7 @@ get_cases_for_edge (edge e, gswitch *t) { tree elt = gimple_switch_label (t, i); tree lab = CASE_LABEL (elt); - basic_block label_bb = label_to_block (lab); + basic_block label_bb = label_to_block (cfun, lab); edge this_edge = find_edge (e->src, label_bb); /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create @@ -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); } } @@ -1407,7 +1406,7 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb) /* Return the basic block holding label DEST. */ basic_block -label_to_block_fn (struct function *ifun, tree dest) +label_to_block (struct function *ifun, tree dest) { int uid = LABEL_DECL_UID (dest); @@ -1442,7 +1441,7 @@ make_goto_expr_edges (basic_block bb) if (simple_goto_p (goto_t)) { tree dest = gimple_goto_dest (goto_t); - basic_block label_bb = label_to_block (dest); + basic_block label_bb = label_to_block (cfun, dest); edge e = make_edge (bb, label_bb, EDGE_FALLTHRU); e->goto_locus = gimple_location (goto_t); gsi_remove (&last, true); @@ -1464,7 +1463,7 @@ make_gimple_asm_edges (basic_block bb) for (i = 0; i < n; ++i) { tree label = TREE_VALUE (gimple_asm_label_op (stmt, i)); - basic_block label_bb = label_to_block (label); + basic_block label_bb = label_to_block (cfun, label); make_edge (bb, label_bb, 0); } } @@ -1496,7 +1495,7 @@ static struct label_record static tree main_block_label (tree label) { - basic_block bb = label_to_block (label); + basic_block bb = label_to_block (cfun, label); tree main_label = label_for_bb[bb->index].label; /* label_to_block possibly inserted undefined label into the chain. */ @@ -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; @@ -1785,7 +1784,7 @@ group_case_labels_stmt (gswitch *stmt) base_case = gimple_switch_label (stmt, i); gcc_assert (base_case); - base_bb = label_to_block (CASE_LABEL (base_case)); + base_bb = label_to_block (cfun, CASE_LABEL (base_case)); /* Discard cases that have the same destination as the default case or whose destiniation blocks have already been removed as unreachable. */ @@ -1806,7 +1805,7 @@ group_case_labels_stmt (gswitch *stmt) while (next_index < old_size) { tree merge_case = gimple_switch_label (stmt, next_index); - basic_block merge_bb = label_to_block (CASE_LABEL (merge_case)); + basic_block merge_bb = label_to_block (cfun, CASE_LABEL (merge_case)); wide_int bhp1 = wi::to_wide (base_high) + 1; /* Merge the cases if they jump to the same place, @@ -2387,7 +2386,7 @@ find_taken_edge_computed_goto (basic_block bb, tree val) basic_block dest; edge e = NULL; - dest = label_to_block (val); + dest = label_to_block (cfun, val); if (dest) e = find_edge (bb, dest); @@ -2455,7 +2454,7 @@ find_taken_edge_switch_expr (const gswitch *switch_stmt, tree val) else taken_case = find_case_label_for_value (switch_stmt, val); } - dest_bb = label_to_block (CASE_LABEL (taken_case)); + dest_bb = label_to_block (cfun, CASE_LABEL (taken_case)); e = find_edge (gimple_bb (switch_stmt), dest_bb); gcc_assert (e); @@ -5498,7 +5497,7 @@ gimple_verify_flow_info (void) err = 1; } - if (label_to_block (label) != bb) + if (label_to_block (cfun, label) != bb) { error ("label "); print_generic_expr (stderr, label); @@ -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) { @@ -5936,7 +5933,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) for (i = 0; i < n; i++) { tree elt = gimple_switch_label (switch_stmt, i); - if (label_to_block (CASE_LABEL (elt)) == e->dest) + if (label_to_block (cfun, CASE_LABEL (elt)) == e->dest) CASE_LABEL (elt) = label; } } @@ -5952,7 +5949,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) for (i = 0; i < n; ++i) { tree cons = gimple_asm_label_op (asm_stmt, i); - if (label_to_block (TREE_VALUE (cons)) == e->dest) + if (label_to_block (cfun, TREE_VALUE (cons)) == e->dest) { if (!label) label = gimple_block_label (dest); @@ -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 (cfun, 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..fd4217acf57 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -33,8 +33,7 @@ extern void init_empty_tree_cfg_for_function (struct function *); extern void init_empty_tree_cfg (void); extern void start_recording_case_labels (void); extern void end_recording_case_labels (void); -extern basic_block label_to_block_fn (struct function *, tree); -#define label_to_block(t) (label_to_block_fn (cfun, t)) +extern basic_block label_to_block (struct function *, tree); extern void cleanup_dead_labels (void); extern bool group_case_labels_stmt (gswitch *); extern bool group_case_labels (void); @@ -112,6 +111,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..9717e98e8dd 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 (cfun, CASE_LABEL (label)); basic_block bb = gimple_bb (swtch); gcond *cond; @@ -266,7 +265,7 @@ cleanup_control_flow_bb (basic_block bb) label = TREE_OPERAND (gimple_goto_dest (stmt), 0); if (DECL_CONTEXT (label) != cfun->decl) return retval; - target_block = label_to_block (label); + target_block = label_to_block (cfun, label); for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) { if (e->dest != target_block) diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index f367040af45..20e2db9e29a 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2231,7 +2231,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt) case ERT_TRY: for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) { - dst = label_to_block (c->label); + dst = label_to_block (cfun, c->label); make_edge (src, dst, 0); /* A catch-all handler doesn't have a fallthru. */ @@ -2241,7 +2241,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt) break; case ERT_ALLOWED_EXCEPTIONS: - dst = label_to_block (r->u.allowed.label); + dst = label_to_block (cfun, r->u.allowed.label); make_edge (src, dst, 0); break; @@ -2270,7 +2270,7 @@ make_eh_edges (gimple *stmt) gcc_assert (lp != NULL); src = gimple_bb (stmt); - dst = label_to_block (lp->post_landing_pad); + dst = label_to_block (cfun, lp->post_landing_pad); make_edge (src, dst, EDGE_EH); } @@ -2389,7 +2389,7 @@ redirect_eh_dispatch_edge (geh_dispatch *stmt, edge e, basic_block new_bb) case ERT_TRY: for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) { - old_bb = label_to_block (c->label); + old_bb = label_to_block (cfun, c->label); if (old_bb == e->dest) { c->label = new_lab; @@ -2399,7 +2399,7 @@ redirect_eh_dispatch_edge (geh_dispatch *stmt, edge e, basic_block new_bb) break; case ERT_ALLOWED_EXCEPTIONS: - old_bb = label_to_block (r->u.allowed.label); + old_bb = label_to_block (cfun, r->u.allowed.label); gcc_assert (old_bb == e->dest); r->u.allowed.label = new_lab; any_changed = true; @@ -3329,7 +3329,7 @@ lower_resx (basic_block bb, gresx *stmt, else { lab = *slot; - new_bb = label_to_block (lab); + new_bb = label_to_block (cfun, lab); } gcc_assert (EDGE_COUNT (bb->succs) == 0); @@ -3733,7 +3733,7 @@ lower_eh_dispatch (basic_block src, geh_dispatch *stmt) while (tp_node); if (! have_label) { - remove_edge (find_edge (src, label_to_block (lab))); + remove_edge (find_edge (src, label_to_block (cfun, lab))); redirected = true; } } @@ -4046,7 +4046,7 @@ maybe_remove_unreachable_handlers (void) FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp) if (lp && lp->post_landing_pad) { - if (label_to_block (lp->post_landing_pad) == NULL) + if (label_to_block (cfun, lp->post_landing_pad) == NULL) { remove_unreachable_handlers (); return; @@ -4110,7 +4110,7 @@ remove_unreachable_handlers_no_lp (void) static bool unsplit_eh (eh_landing_pad lp) { - basic_block bb = label_to_block (lp->post_landing_pad); + basic_block bb = label_to_block (cfun, lp->post_landing_pad); gimple_stmt_iterator gsi; edge e_in, e_out; @@ -4475,7 +4475,7 @@ infinite_empty_loop_p (edge e_first) static bool cleanup_empty_eh (eh_landing_pad lp) { - basic_block bb = label_to_block (lp->post_landing_pad); + basic_block bb = label_to_block (cfun, lp->post_landing_pad); gimple_stmt_iterator gsi; gimple *resx; eh_region new_region; @@ -4795,7 +4795,7 @@ verify_eh_edges (gimple *stmt) return true; } - if (eh_edge->dest != label_to_block (lp->post_landing_pad)) + if (eh_edge->dest != label_to_block (cfun, lp->post_landing_pad)) { error ("Incorrect EH edge %i->%i", bb->index, eh_edge->dest->index); return true; @@ -4827,7 +4827,7 @@ verify_eh_dispatch_edge (geh_dispatch *stmt) case ERT_TRY: for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) { - dst = label_to_block (c->label); + dst = label_to_block (cfun, c->label); e = find_edge (src, dst); if (e == NULL) { @@ -4846,7 +4846,7 @@ verify_eh_dispatch_edge (geh_dispatch *stmt) break; case ERT_ALLOWED_EXCEPTIONS: - dst = label_to_block (r->u.allowed.label); + dst = label_to_block (cfun, r->u.allowed.label); e = find_edge (src, dst); if (e == NULL) { diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 267880f3b5c..7430fd7e706 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -436,7 +436,8 @@ record_edge_info (basic_block bb) for (i = 0; i < n_labels; i++) { tree label = gimple_switch_label (switch_stmt, i); - basic_block target_bb = label_to_block (CASE_LABEL (label)); + basic_block target_bb + = label_to_block (cfun, CASE_LABEL (label)); if (CASE_HIGH (label) || !CASE_LOW (label) || info[target_bb->index]) diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 56078110b39..4ed61c37a5f 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1071,7 +1071,7 @@ simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type) for (i = 0; i < gimple_switch_num_labels (stmt); i++) { tree elt = gimple_switch_label (stmt, i); - basic_block target = label_to_block (CASE_LABEL (elt)); + basic_block target = label_to_block (cfun, CASE_LABEL (elt)); bitmap_set_bit (target_blocks, target->index); } for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); ) diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index dbc0bbd772a..a2304493495 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -977,7 +977,7 @@ thread_around_empty_blocks (edge taken_edge, || TREE_CODE (cond) == CASE_LABEL_EXPR)) { if (TREE_CODE (cond) == CASE_LABEL_EXPR) - taken_edge = find_edge (bb, label_to_block (CASE_LABEL (cond))); + taken_edge = find_edge (bb, label_to_block (cfun, CASE_LABEL (cond))); else taken_edge = find_taken_edge (bb, cond); @@ -1109,7 +1109,7 @@ thread_through_normal_block (edge e, edge taken_edge; if (TREE_CODE (cond) == CASE_LABEL_EXPR) taken_edge = find_edge (e->dest, - label_to_block (CASE_LABEL (cond))); + label_to_block (cfun, CASE_LABEL (cond))); else taken_edge = find_taken_edge (e->dest, cond); diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index 7d863a71551..98cc79e8607 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -184,7 +184,7 @@ associate_equivalences_with_edges (void) for (i = 0; i < n_labels; i++) { tree label = gimple_switch_label (switch_stmt, i); - basic_block bb = label_to_block (CASE_LABEL (label)); + basic_block bb = label_to_block (cfun, CASE_LABEL (label)); if (CASE_HIGH (label) || !CASE_LOW (label) diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index a93610084f2..f3e42ddbd7f 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -725,7 +725,7 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains, for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx) { tree tl = gimple_switch_label (gs, idx); - if (e->dest == label_to_block (CASE_LABEL (tl))) + if (e->dest == label_to_block (cfun, CASE_LABEL (tl))) { if (!l) l = tl; diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 9a594a01fc4..684fdd0583a 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; @@ -351,7 +342,7 @@ void switch_conversion::gather_default_values (tree default_case) { gphi_iterator gsi; - basic_block bb = label_to_block (CASE_LABEL (default_case)); + basic_block bb = label_to_block (cfun, CASE_LABEL (default_case)); edge e; int i = 0; @@ -388,7 +379,7 @@ switch_conversion::build_constructors () for (i = 1; i < branch_num; i++) { tree cs = gimple_switch_label (m_switch, i); - basic_block bb = label_to_block (CASE_LABEL (cs)); + basic_block bb = label_to_block (cfun, CASE_LABEL (cs)); edge e; tree high; gphi_iterator gsi; @@ -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 (cfun, 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 diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f20730a85ba..e8eb9292506 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3474,7 +3474,7 @@ find_switch_asserts (basic_block bb, gswitch *last) for (idx = 0; idx < n; ++idx) { ci[idx].expr = gimple_switch_label (last, idx); - ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr)); + ci[idx].bb = label_to_block (cfun, CASE_LABEL (ci[idx].expr)); } edge default_edge = find_edge (bb, ci[0].bb); qsort (ci, n, sizeof (struct case_info), compare_case_labels); diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 072d9a7b454..11df1023b6e 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -2707,7 +2707,7 @@ vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p) } *taken_edge_p = find_edge (gimple_bb (stmt), - label_to_block (CASE_LABEL (val))); + label_to_block (cfun, CASE_LABEL (val))); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -3760,7 +3760,8 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt) for (i = 0; i < n2; ++i) { e = find_edge (gimple_bb (stmt), - label_to_block (CASE_LABEL (TREE_VEC_ELT (vec2, i)))); + label_to_block (cfun, + CASE_LABEL (TREE_VEC_ELT (vec2, i)))); e->aux = (void *)-1; }
On Mon, Aug 27, 2018 at 10:43 AM Martin Liška <mliska@suse.cz> wrote: > > On 08/27/2018 09:56 AM, Richard Biener wrote: > > On Mon, Aug 27, 2018 at 9:13 AM Martin Liška <mliska@suse.cz> wrote: > >> > >> 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. > > > > Please don't > > > > @@ -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 (); > > > > rather the label_to_block function should go away. OK with removing any > > such instances in the patch. > > > > Richard. > > > >> Martin > > Ok, I'm sending one more version where I completely removed label_to_block_fn. > Richi, out of the modified function, which would be subject for introduction > of a new argument (struct *function)? Esp. gimple_switch_bb would be ... also, sorry for noticing so late, gimple_switch_bb awfully sounds like gimple_bb which means better call it gimple_switch_label_bb ()? Note doing both things in one patch (adding your wrappers) and cleaning up label_to_block isn't necessary (but I have no issue with that). So - may I ask you for a) change name to gimple_switch_label_bb b) add a cfun argument to this function? To your last question, it's most of the time easy to look up the call chain for static functions and you'll find a function that is called with struct function *. When I(?) added label_to_block_fn I did so for the places I "cleaned up", so it would be nice to not introduce cfun references where it's easy to avoid. From a quick look important cases seem to be - set_switch_stmt_execution_predicate - find_taken_edge_switch_expr (and thus callers) - gimple_redirect_edge_and_branch - gimple_switch_label_bb in most passes using cfun should be "easy" to avoid by passing down the struct function arg from the pass execute() method but that's a bit tedious and IMHO not too important. You'll notice that in GIMPLE / CFG infrastructure one of the ugly facts is that there's no way to go from a basic-block to the containing struct function. Thanks, Richard. > > Martin
On 08/27/2018 12:00 PM, Richard Biener wrote: > On Mon, Aug 27, 2018 at 10:43 AM Martin Liška <mliska@suse.cz> wrote: >> >> On 08/27/2018 09:56 AM, Richard Biener wrote: >>> On Mon, Aug 27, 2018 at 9:13 AM Martin Liška <mliska@suse.cz> wrote: >>>> >>>> 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. >>> >>> Please don't >>> >>> @@ -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 (); >>> >>> rather the label_to_block function should go away. OK with removing any >>> such instances in the patch. >>> >>> Richard. >>> >>>> Martin >> >> Ok, I'm sending one more version where I completely removed label_to_block_fn. >> Richi, out of the modified function, which would be subject for introduction >> of a new argument (struct *function)? > > Esp. gimple_switch_bb would be ... also, sorry for noticing so late, > gimple_switch_bb > awfully sounds like gimple_bb which means better call it > gimple_switch_label_bb ()? Good, done that. > > Note doing both things in one patch (adding your wrappers) and cleaning up > label_to_block isn't necessary (but I have no issue with that). > > So - may I ask you for a) change name to gimple_switch_label_bb b) add a > cfun argument to this function? Done that and sending updated version of that patch. I'm going to install for now. > > To your last question, it's most of the time easy to look up the call chain for > static functions and you'll find a function that is called with struct > function *. > When I(?) added label_to_block_fn I did so for the places I "cleaned up", so > it would be nice to not introduce cfun references where it's easy to avoid. > From a quick look important cases seem to be > - set_switch_stmt_execution_predicate > - find_taken_edge_switch_expr (and thus callers) > - gimple_redirect_edge_and_branch > - gimple_switch_label_bb > > in most passes using cfun should be "easy" to avoid by passing down > the struct function arg from the pass execute() method but that's a bit > tedious and IMHO not too important. Ok, so if it's tedious, I'm leaving that. Martin > > You'll notice that in GIMPLE / CFG infrastructure one of the ugly facts > is that there's no way to go from a basic-block to the containing > struct function. > > Thanks, > Richard. > >> >> Martin From 8410a46301056a2f39b785ed715df27c32a47c99 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-27 Martin Liska <mliska@suse.cz> * cfgexpand.c (expand_asm_stmt): Use label_to_block and pass cfun argument explicitly. * gimple-pretty-print.c (dump_gimple_switch): Likewise. * hsa-gen.c (gen_hsa_insns_for_switch_stmt): Use new function gimple_switch_default_bb. (convert_switch_statements): (expand_builtins): * ipa-fnsummary.c (set_switch_stmt_execution_predicate): * stmt.c (label_to_block_fn): Use label_to_block and pass cfun argument explicitly and use gimple_switch_label_bb. (expand_case): Likewise. * tree-cfg.c (lower_phi_internal_fn): Use label_to_block and pass cfun argument explicitly. Likewise. (make_edges_bb): Likewise. (make_cond_expr_edges): Likewise. (get_cases_for_edge): Likewise. (make_gimple_switch_edges): Likewise. (label_to_block_fn): Likewise. (label_to_block): Likewise. (make_goto_expr_edges): Likewise. (make_gimple_asm_edges): Likewise. (main_block_label): Likewise. (group_case_labels_stmt): Likewise. (find_taken_edge_computed_goto): Likewise. (find_taken_edge_switch_expr): Likewise. (gimple_verify_flow_info): Likewise. (gimple_redirect_edge_and_branch): Likewise. (gimple_switch_label_bb): New function. (gimple_switch_default_bb): Likewise. (gimple_switch_edge): Likewise. (gimple_switch_default_edge): Likewise. * tree-cfg.h (label_to_block_fn): Remove and replace ... (label_to_block): ... with this. (gimple_switch_label_bb): New. (gimple_switch_default_bb): Likewise. (gimple_switch_edge): Likewise. (gimple_switch_default_edge): Likewise. * tree-cfgcleanup.c (convert_single_case_switch): Use new gimple functions and pass new argument to label_to_block. (cleanup_control_flow_bb): * tree-eh.c (make_eh_dispatch_edges): Use label_to_block and pass cfun argument explicitly. (make_eh_edges): Likewise. (redirect_eh_dispatch_edge): Likewise. (lower_resx): Likewise. (lower_eh_dispatch): Likewise. (maybe_remove_unreachable_handlers): Likewise. (unsplit_eh): Likewise. (cleanup_empty_eh): Likewise. (verify_eh_edges): Likewise. (verify_eh_dispatch_edge): Likewise. * tree-ssa-dom.c (record_edge_info): Likewise. * tree-ssa-forwprop.c (simplify_gimple_switch_label_vec): Likewise. * tree-ssa-threadedge.c (thread_around_empty_blocks): Likewise. (thread_through_normal_block): Likewise. * tree-ssa-uncprop.c (associate_equivalences_with_edges): Likewise. * tree-ssa-uninit.c (convert_control_dep_chain_into_preds): * tree-switch-conversion.c (switch_conversion::collect): Use new gimple functions. (switch_conversion::check_final_bb): Likewise. (switch_conversion::gather_default_values): Pass new argument to label_to_block. (switch_conversion::build_constructors): Likewise. (switch_decision_tree::compute_cases_per_edge): Use new gimple_switch_edge function. (switch_decision_tree::analyze_switch_statement): Pass new argument to label_to_block. (switch_decision_tree::try_switch_expansion): Use gimple_switch_default_edge. * tree-vrp.c (find_switch_asserts): Pass new argument to label_to_block. * vr-values.c (vr_values::vrp_visit_switch_stmt): Likewise. (vr_values::simplify_switch_using_ranges): Likewise. --- gcc/cfgexpand.c | 2 +- gcc/gimple-pretty-print.c | 2 +- gcc/hsa-gen.c | 21 +++------ gcc/ipa-fnsummary.c | 2 +- gcc/stmt.c | 4 +- gcc/tree-cfg.c | 83 +++++++++++++++++++++++++----------- gcc/tree-cfg.h | 7 ++- gcc/tree-cfgcleanup.c | 7 ++- gcc/tree-eh.c | 26 +++++------ gcc/tree-ssa-dom.c | 3 +- gcc/tree-ssa-forwprop.c | 2 +- gcc/tree-ssa-threadedge.c | 4 +- gcc/tree-ssa-uncprop.c | 2 +- gcc/tree-ssa-uninit.c | 2 +- gcc/tree-switch-conversion.c | 44 +++++++------------ gcc/tree-vrp.c | 2 +- gcc/vr-values.c | 5 ++- 17 files changed, 116 insertions(+), 102 deletions(-) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 3c5b30b79f8..647764b0e94 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 (cfun, label) == fallthru_bb) { if (fallthru_label == NULL_RTX) fallthru_label = gen_label_rtx (); diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index d3c5ec6f79b..dd63a28761b 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -992,7 +992,7 @@ dump_gimple_switch (pretty_printer *buffer, gswitch *gs, int spc, if (cfun && cfun->cfg) { - basic_block dest = label_to_block (label); + basic_block dest = label_to_block (cfun, label); if (dest) { edge label_edge = find_edge (gimple_bb (gs), dest); diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index 6595bedac82..416de933a22 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 (cfun, 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 (cfun, 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 (cfun, 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_label_bb (cfun, 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 (cfun, 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..d8311d25ab2 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 (cfun, last, case_idx); min = CASE_LOW (cl); max = CASE_HIGH (cl); diff --git a/gcc/stmt.c b/gcc/stmt.c index b8df1818137..07355984de1 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -81,8 +81,6 @@ struct simple_case_node /* Label to jump to when node matches. */ 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 (cfun, 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..b021fb0f97b 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -389,7 +389,7 @@ lower_phi_internal_fn () { tree arg = gimple_call_arg (stmt, i); if (TREE_CODE (arg) == LABEL_DECL) - pred = label_to_block (arg); + pred = label_to_block (cfun, arg); else { edge e = find_edge (pred, bb); @@ -972,15 +972,15 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index) tree label2 = gimple_transaction_label_uninst (txn); if (label1) - make_edge (bb, label_to_block (label1), EDGE_FALLTHRU); + make_edge (bb, label_to_block (cfun, label1), EDGE_FALLTHRU); if (label2) - make_edge (bb, label_to_block (label2), + make_edge (bb, label_to_block (cfun, label2), EDGE_TM_UNINSTRUMENTED | (label1 ? 0 : EDGE_FALLTHRU)); tree label3 = gimple_transaction_label_over (txn); if (gimple_transaction_subcode (txn) & (GTMA_HAVE_ABORT | GTMA_IS_OUTER)) - make_edge (bb, label_to_block (label3), EDGE_TM_ABORT); + make_edge (bb, label_to_block (cfun, label3), EDGE_TM_ABORT); fallthru = false; } @@ -1265,8 +1265,8 @@ make_cond_expr_edges (basic_block bb) /* Entry basic blocks for each component. */ then_label = gimple_cond_true_label (entry); else_label = gimple_cond_false_label (entry); - then_bb = label_to_block (then_label); - else_bb = label_to_block (else_label); + then_bb = label_to_block (cfun, then_label); + else_bb = label_to_block (cfun, else_label); then_stmt = first_stmt (then_bb); else_stmt = first_stmt (else_bb); @@ -1373,7 +1373,7 @@ get_cases_for_edge (edge e, gswitch *t) { tree elt = gimple_switch_label (t, i); tree lab = CASE_LABEL (elt); - basic_block label_bb = label_to_block (lab); + basic_block label_bb = label_to_block (cfun, lab); edge this_edge = find_edge (e->src, label_bb); /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create @@ -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_label_bb (cfun, entry, i); make_edge (bb, label_bb, 0); } } @@ -1407,7 +1406,7 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb) /* Return the basic block holding label DEST. */ basic_block -label_to_block_fn (struct function *ifun, tree dest) +label_to_block (struct function *ifun, tree dest) { int uid = LABEL_DECL_UID (dest); @@ -1442,7 +1441,7 @@ make_goto_expr_edges (basic_block bb) if (simple_goto_p (goto_t)) { tree dest = gimple_goto_dest (goto_t); - basic_block label_bb = label_to_block (dest); + basic_block label_bb = label_to_block (cfun, dest); edge e = make_edge (bb, label_bb, EDGE_FALLTHRU); e->goto_locus = gimple_location (goto_t); gsi_remove (&last, true); @@ -1464,7 +1463,7 @@ make_gimple_asm_edges (basic_block bb) for (i = 0; i < n; ++i) { tree label = TREE_VALUE (gimple_asm_label_op (stmt, i)); - basic_block label_bb = label_to_block (label); + basic_block label_bb = label_to_block (cfun, label); make_edge (bb, label_bb, 0); } } @@ -1496,7 +1495,7 @@ static struct label_record static tree main_block_label (tree label) { - basic_block bb = label_to_block (label); + basic_block bb = label_to_block (cfun, label); tree main_label = label_for_bb[bb->index].label; /* label_to_block possibly inserted undefined label into the chain. */ @@ -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 (cfun, stmt); /* Look for possible opportunities to merge cases. */ new_size = i = 1; @@ -1785,7 +1784,7 @@ group_case_labels_stmt (gswitch *stmt) base_case = gimple_switch_label (stmt, i); gcc_assert (base_case); - base_bb = label_to_block (CASE_LABEL (base_case)); + base_bb = label_to_block (cfun, CASE_LABEL (base_case)); /* Discard cases that have the same destination as the default case or whose destiniation blocks have already been removed as unreachable. */ @@ -1806,7 +1805,7 @@ group_case_labels_stmt (gswitch *stmt) while (next_index < old_size) { tree merge_case = gimple_switch_label (stmt, next_index); - basic_block merge_bb = label_to_block (CASE_LABEL (merge_case)); + basic_block merge_bb = label_to_block (cfun, CASE_LABEL (merge_case)); wide_int bhp1 = wi::to_wide (base_high) + 1; /* Merge the cases if they jump to the same place, @@ -2387,7 +2386,7 @@ find_taken_edge_computed_goto (basic_block bb, tree val) basic_block dest; edge e = NULL; - dest = label_to_block (val); + dest = label_to_block (cfun, val); if (dest) e = find_edge (bb, dest); @@ -2455,7 +2454,7 @@ find_taken_edge_switch_expr (const gswitch *switch_stmt, tree val) else taken_case = find_case_label_for_value (switch_stmt, val); } - dest_bb = label_to_block (CASE_LABEL (taken_case)); + dest_bb = label_to_block (cfun, CASE_LABEL (taken_case)); e = find_edge (gimple_bb (switch_stmt), dest_bb); gcc_assert (e); @@ -5498,7 +5497,7 @@ gimple_verify_flow_info (void) err = 1; } - if (label_to_block (label) != bb) + if (label_to_block (cfun, label) != bb) { error ("label "); print_generic_expr (stderr, label); @@ -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_label_bb (cfun, switch_stmt, i); gcc_assert (!label_bb->aux || label_bb->aux == (void *)1); label_bb->aux = (void *)1; } @@ -5711,8 +5709,8 @@ 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_label_bb (cfun, + switch_stmt, i); if (label_bb->aux != (void *)2) { @@ -5936,7 +5934,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) for (i = 0; i < n; i++) { tree elt = gimple_switch_label (switch_stmt, i); - if (label_to_block (CASE_LABEL (elt)) == e->dest) + if (label_to_block (cfun, CASE_LABEL (elt)) == e->dest) CASE_LABEL (elt) = label; } } @@ -5952,7 +5950,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) for (i = 0; i < n; ++i) { tree cons = gimple_asm_label_op (asm_stmt, i); - if (label_to_block (TREE_VALUE (cons)) == e->dest) + if (label_to_block (cfun, TREE_VALUE (cons)) == e->dest) { if (!label) label = gimple_block_label (dest); @@ -9143,6 +9141,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_label_bb (function *ifun, gswitch *gs, unsigned index) +{ + return label_to_block (ifun, CASE_LABEL (gimple_switch_label (gs, index))); +} + +/* Return the default basic block of a switch statement. */ + +basic_block +gimple_switch_default_bb (function *ifun, gswitch *gs) +{ + return gimple_switch_label_bb (ifun, gs, 0); +} + +/* Return the edge that belongs to label numbered INDEX + of a switch statement. */ + +edge +gimple_switch_edge (function *ifun, gswitch *gs, unsigned index) +{ + return find_edge (gimple_bb (gs), gimple_switch_label_bb (ifun, gs, index)); +} + +/* Return the default edge of a switch statement. */ + +edge +gimple_switch_default_edge (function *ifun, gswitch *gs) +{ + return gimple_switch_edge (ifun, gs, 0); +} + + /* Emit return warnings. */ namespace { diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h index 9491bb45feb..349a9543168 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -33,8 +33,7 @@ extern void init_empty_tree_cfg_for_function (struct function *); extern void init_empty_tree_cfg (void); extern void start_recording_case_labels (void); extern void end_recording_case_labels (void); -extern basic_block label_to_block_fn (struct function *, tree); -#define label_to_block(t) (label_to_block_fn (cfun, t)) +extern basic_block label_to_block (struct function *, tree); extern void cleanup_dead_labels (void); extern bool group_case_labels_stmt (gswitch *); extern bool group_case_labels (void); @@ -112,6 +111,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_label_bb (function *, gswitch *, unsigned); +extern basic_block gimple_switch_default_bb (function *, gswitch *); +extern edge gimple_switch_edge (function *, gswitch *, unsigned); +extern edge gimple_switch_default_edge (function *, gswitch *); /* 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..7fd0430d6cf 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 (cfun, swtch); + basic_block case_bb = label_to_block (cfun, CASE_LABEL (label)); basic_block bb = gimple_bb (swtch); gcond *cond; @@ -266,7 +265,7 @@ cleanup_control_flow_bb (basic_block bb) label = TREE_OPERAND (gimple_goto_dest (stmt), 0); if (DECL_CONTEXT (label) != cfun->decl) return retval; - target_block = label_to_block (label); + target_block = label_to_block (cfun, label); for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) { if (e->dest != target_block) diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index f367040af45..20e2db9e29a 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2231,7 +2231,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt) case ERT_TRY: for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) { - dst = label_to_block (c->label); + dst = label_to_block (cfun, c->label); make_edge (src, dst, 0); /* A catch-all handler doesn't have a fallthru. */ @@ -2241,7 +2241,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt) break; case ERT_ALLOWED_EXCEPTIONS: - dst = label_to_block (r->u.allowed.label); + dst = label_to_block (cfun, r->u.allowed.label); make_edge (src, dst, 0); break; @@ -2270,7 +2270,7 @@ make_eh_edges (gimple *stmt) gcc_assert (lp != NULL); src = gimple_bb (stmt); - dst = label_to_block (lp->post_landing_pad); + dst = label_to_block (cfun, lp->post_landing_pad); make_edge (src, dst, EDGE_EH); } @@ -2389,7 +2389,7 @@ redirect_eh_dispatch_edge (geh_dispatch *stmt, edge e, basic_block new_bb) case ERT_TRY: for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) { - old_bb = label_to_block (c->label); + old_bb = label_to_block (cfun, c->label); if (old_bb == e->dest) { c->label = new_lab; @@ -2399,7 +2399,7 @@ redirect_eh_dispatch_edge (geh_dispatch *stmt, edge e, basic_block new_bb) break; case ERT_ALLOWED_EXCEPTIONS: - old_bb = label_to_block (r->u.allowed.label); + old_bb = label_to_block (cfun, r->u.allowed.label); gcc_assert (old_bb == e->dest); r->u.allowed.label = new_lab; any_changed = true; @@ -3329,7 +3329,7 @@ lower_resx (basic_block bb, gresx *stmt, else { lab = *slot; - new_bb = label_to_block (lab); + new_bb = label_to_block (cfun, lab); } gcc_assert (EDGE_COUNT (bb->succs) == 0); @@ -3733,7 +3733,7 @@ lower_eh_dispatch (basic_block src, geh_dispatch *stmt) while (tp_node); if (! have_label) { - remove_edge (find_edge (src, label_to_block (lab))); + remove_edge (find_edge (src, label_to_block (cfun, lab))); redirected = true; } } @@ -4046,7 +4046,7 @@ maybe_remove_unreachable_handlers (void) FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp) if (lp && lp->post_landing_pad) { - if (label_to_block (lp->post_landing_pad) == NULL) + if (label_to_block (cfun, lp->post_landing_pad) == NULL) { remove_unreachable_handlers (); return; @@ -4110,7 +4110,7 @@ remove_unreachable_handlers_no_lp (void) static bool unsplit_eh (eh_landing_pad lp) { - basic_block bb = label_to_block (lp->post_landing_pad); + basic_block bb = label_to_block (cfun, lp->post_landing_pad); gimple_stmt_iterator gsi; edge e_in, e_out; @@ -4475,7 +4475,7 @@ infinite_empty_loop_p (edge e_first) static bool cleanup_empty_eh (eh_landing_pad lp) { - basic_block bb = label_to_block (lp->post_landing_pad); + basic_block bb = label_to_block (cfun, lp->post_landing_pad); gimple_stmt_iterator gsi; gimple *resx; eh_region new_region; @@ -4795,7 +4795,7 @@ verify_eh_edges (gimple *stmt) return true; } - if (eh_edge->dest != label_to_block (lp->post_landing_pad)) + if (eh_edge->dest != label_to_block (cfun, lp->post_landing_pad)) { error ("Incorrect EH edge %i->%i", bb->index, eh_edge->dest->index); return true; @@ -4827,7 +4827,7 @@ verify_eh_dispatch_edge (geh_dispatch *stmt) case ERT_TRY: for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) { - dst = label_to_block (c->label); + dst = label_to_block (cfun, c->label); e = find_edge (src, dst); if (e == NULL) { @@ -4846,7 +4846,7 @@ verify_eh_dispatch_edge (geh_dispatch *stmt) break; case ERT_ALLOWED_EXCEPTIONS: - dst = label_to_block (r->u.allowed.label); + dst = label_to_block (cfun, r->u.allowed.label); e = find_edge (src, dst); if (e == NULL) { diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 267880f3b5c..7430fd7e706 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -436,7 +436,8 @@ record_edge_info (basic_block bb) for (i = 0; i < n_labels; i++) { tree label = gimple_switch_label (switch_stmt, i); - basic_block target_bb = label_to_block (CASE_LABEL (label)); + basic_block target_bb + = label_to_block (cfun, CASE_LABEL (label)); if (CASE_HIGH (label) || !CASE_LOW (label) || info[target_bb->index]) diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 56078110b39..4ed61c37a5f 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1071,7 +1071,7 @@ simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type) for (i = 0; i < gimple_switch_num_labels (stmt); i++) { tree elt = gimple_switch_label (stmt, i); - basic_block target = label_to_block (CASE_LABEL (elt)); + basic_block target = label_to_block (cfun, CASE_LABEL (elt)); bitmap_set_bit (target_blocks, target->index); } for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); ) diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index dbc0bbd772a..a2304493495 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -977,7 +977,7 @@ thread_around_empty_blocks (edge taken_edge, || TREE_CODE (cond) == CASE_LABEL_EXPR)) { if (TREE_CODE (cond) == CASE_LABEL_EXPR) - taken_edge = find_edge (bb, label_to_block (CASE_LABEL (cond))); + taken_edge = find_edge (bb, label_to_block (cfun, CASE_LABEL (cond))); else taken_edge = find_taken_edge (bb, cond); @@ -1109,7 +1109,7 @@ thread_through_normal_block (edge e, edge taken_edge; if (TREE_CODE (cond) == CASE_LABEL_EXPR) taken_edge = find_edge (e->dest, - label_to_block (CASE_LABEL (cond))); + label_to_block (cfun, CASE_LABEL (cond))); else taken_edge = find_taken_edge (e->dest, cond); diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index 7d863a71551..98cc79e8607 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -184,7 +184,7 @@ associate_equivalences_with_edges (void) for (i = 0; i < n_labels; i++) { tree label = gimple_switch_label (switch_stmt, i); - basic_block bb = label_to_block (CASE_LABEL (label)); + basic_block bb = label_to_block (cfun, CASE_LABEL (label)); if (CASE_HIGH (label) || !CASE_LOW (label) diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index a93610084f2..f3e42ddbd7f 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -725,7 +725,7 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains, for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx) { tree tl = gimple_switch_label (gs, idx); - if (e->dest == label_to_block (CASE_LABEL (tl))) + if (e->dest == label_to_block (cfun, CASE_LABEL (tl))) { if (!l) l = tl; diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 9a594a01fc4..ef08bdc990d 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 (cfun, 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 (cfun, 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_label_bb (cfun, m_switch, i) == bb) { m_reason = reason; return false; @@ -351,7 +342,7 @@ void switch_conversion::gather_default_values (tree default_case) { gphi_iterator gsi; - basic_block bb = label_to_block (CASE_LABEL (default_case)); + basic_block bb = label_to_block (cfun, CASE_LABEL (default_case)); edge e; int i = 0; @@ -388,7 +379,7 @@ switch_conversion::build_constructors () for (i = 1; i < branch_num; i++) { tree cs = gimple_switch_label (m_switch, i); - basic_block bb = label_to_block (CASE_LABEL (cs)); + basic_block bb = label_to_block (cfun, CASE_LABEL (cs)); edge e; tree high; gphi_iterator gsi; @@ -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 (cfun, 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 (cfun, 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 (cfun, 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 (cfun, 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 diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f20730a85ba..e8eb9292506 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3474,7 +3474,7 @@ find_switch_asserts (basic_block bb, gswitch *last) for (idx = 0; idx < n; ++idx) { ci[idx].expr = gimple_switch_label (last, idx); - ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr)); + ci[idx].bb = label_to_block (cfun, CASE_LABEL (ci[idx].expr)); } edge default_edge = find_edge (bb, ci[0].bb); qsort (ci, n, sizeof (struct case_info), compare_case_labels); diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 072d9a7b454..11df1023b6e 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -2707,7 +2707,7 @@ vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p) } *taken_edge_p = find_edge (gimple_bb (stmt), - label_to_block (CASE_LABEL (val))); + label_to_block (cfun, CASE_LABEL (val))); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -3760,7 +3760,8 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt) for (i = 0; i < n2; ++i) { e = find_edge (gimple_bb (stmt), - label_to_block (CASE_LABEL (TREE_VEC_ELT (vec2, i)))); + label_to_block (cfun, + CASE_LABEL (TREE_VEC_ELT (vec2, i)))); e->aux = (void *)-1; }
diff --git a/gcc/gimple-cfg.h b/gcc/gimple-cfg.h new file mode 100644 index 00000000000..1e95338bede --- /dev/null +++ b/gcc/gimple-cfg.h @@ -0,0 +1,44 @@ +/* Gimple IR definitions related to CFG. + + Copyright (C) 2007-2018 Free Software Foundation, Inc. + Contributed by Martin Liska <mliska@suse.cz> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_GIMPLE_CFG_H +#define GCC_GIMPLE_CFG_H + +/* Return the edge that belongs to label numbered INDEX + of a switch statement. */ + +static inline edge +gimple_switch_edge (gswitch *gs, unsigned index) +{ + tree label = CASE_LABEL (gimple_switch_label (gs, index)); + return find_edge (gimple_bb (gs), label_to_block (label)); +} + +/* Return the default edge of a switch statement. */ + +static inline edge +gimple_switch_default_edge (gswitch *gs) +{ + tree label = CASE_LABEL (gimple_switch_label (gs, 0)); + return find_edge (gimple_bb (gs), label_to_block (label)); +} + +#endif /* GCC_GIMPLE_CFG_H */ diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index a8fc2c2df9a..2991e647fc4 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -56,7 +56,10 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "backend.h" #include "tree.h" +#include "cfganal.h" #include "gimple.h" +#include "tree-cfg.h" +#include "gimple-cfg.h" #include "alloc-pool.h" #include "tree-pass.h" #include "ssa.h" @@ -68,9 +71,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "gimple-pretty-print.h" #include "params.h" -#include "cfganal.h" #include "gimple-iterator.h" -#include "tree-cfg.h" #include "tree-ssa-loop-niter.h" #include "tree-ssa-loop.h" #include "symbol-summary.h" @@ -1291,7 +1292,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/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 9a594a01fc4..492cd365a30 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -29,6 +29,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "insn-codes.h" #include "rtl.h" #include "tree.h" +#include "cfganal.h" +#include "tree-cfg.h" #include "gimple.h" #include "cfghooks.h" #include "tree-pass.h" @@ -40,8 +42,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "fold-const.h" #include "varasm.h" #include "stor-layout.h" -#include "cfganal.h" #include "gimplify.h" +#include "gimple-cfg.h" #include "gimple-iterator.h" #include "gimplify-me.h" #include "tree-cfg.h" @@ -78,7 +80,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 +88,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 +120,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. @@ -1577,15 +1571,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); } } @@ -1602,7 +1592,7 @@ switch_decision_tree::analyze_switch_statement () 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 = label_to_block (default_label); m_case_bbs.reserve (l); m_case_bbs.quick_push (default_bb); @@ -1619,8 +1609,9 @@ switch_decision_tree::analyze_switch_statement () 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 +1685,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