Hi. I'm considering adding couple of new gimple-related functions that are related to gswitch statement.
Is it a good idea? Martin gcc/ChangeLog: 2018-08-06 Martin Liska <mli...@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
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 <mli...@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