diff options
author | Martin Liska <mliska@suse.cz> | 2018-01-03 15:53:39 +0100 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2018-01-03 14:53:39 +0000 |
commit | fa9544ab4df0e88946488fb82f4b994bf36a97ff (patch) | |
tree | 492c3269956564477d25ff7f41e7c18a26b09745 /gcc/tree-ssa-strlen.c | |
parent | ca04a532f3fcf91939ec03da628aa94207eaa067 (diff) | |
download | gcc-fa9544ab4df0e88946488fb82f4b994bf36a97ff.zip gcc-fa9544ab4df0e88946488fb82f4b994bf36a97ff.tar.gz gcc-fa9544ab4df0e88946488fb82f4b994bf36a97ff.tar.bz2 |
Clean-up EH after strlen transformation (PR tree-optimization/83593).
2018-01-03 Martin Liska <mliska@suse.cz>
PR tree-optimization/83593
* tree-ssa-strlen.c: Include tree-cfg.h.
(strlen_check_and_optimize_stmt): Add new argument cleanup_eh.
(strlen_dom_walker): Add new member variable m_cleanup_cfg.
(strlen_dom_walker::strlen_dom_walker): Initialize m_cleanup_cfg
to false.
(strlen_dom_walker::before_dom_children): Call
gimple_purge_dead_eh_edges. Dump tranformation with details
dump flags.
(strlen_dom_walker::before_dom_children): Update call by adding
new argument cleanup_eh.
(pass_strlen::execute): Return TODO_cleanup_cfg if needed.
2018-01-03 Martin Liska <mliska@suse.cz>
PR tree-optimization/83593
* gcc.dg/pr83593.c: New test.
From-SVN: r256178
Diffstat (limited to 'gcc/tree-ssa-strlen.c')
-rw-r--r-- | gcc/tree-ssa-strlen.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index c8b86b6..8f7020c 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-iterator.h" #include "gimplify-me.h" #include "expr.h" +#include "tree-cfg.h" #include "tree-dfa.h" #include "domwalk.h" #include "tree-ssa-alias.h" @@ -3051,10 +3052,12 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt) } /* Attempt to check for validity of the performed access a single statement - at *GSI using string length knowledge, and to optimize it. */ + at *GSI using string length knowledge, and to optimize it. + If the given basic block needs clean-up of EH, CLEANUP_EH is set to + true. */ static bool -strlen_check_and_optimize_stmt (gimple_stmt_iterator *gsi) +strlen_check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh) { gimple *stmt = gsi_stmt (*gsi); @@ -3201,11 +3204,27 @@ strlen_check_and_optimize_stmt (gimple_stmt_iterator *gsi) if (w1 == w2 && si->full_string_p) { + if (dump_file && (dump_flags & TDF_DETAILS) != 0) + { + fprintf (dump_file, "Optimizing: "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } + /* Reading the final '\0' character. */ tree zero = build_int_cst (TREE_TYPE (lhs), 0); gimple_set_vuse (stmt, NULL_TREE); gimple_assign_set_rhs_from_tree (gsi, zero); - update_stmt (gsi_stmt (*gsi)); + *cleanup_eh + |= maybe_clean_or_replace_eh_stmt (stmt, + gsi_stmt (*gsi)); + stmt = gsi_stmt (*gsi); + update_stmt (stmt); + + if (dump_file && (dump_flags & TDF_DETAILS) != 0) + { + fprintf (dump_file, "into: "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } } else if (w1 > w2) { @@ -3318,10 +3337,16 @@ do_invalidate (basic_block dombb, gimple *phi, bitmap visited, int *count) class strlen_dom_walker : public dom_walker { public: - strlen_dom_walker (cdi_direction direction) : dom_walker (direction) {} + strlen_dom_walker (cdi_direction direction) + : dom_walker (direction), m_cleanup_cfg (false) + {} virtual edge before_dom_children (basic_block); virtual void after_dom_children (basic_block); + + /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen + execute function. */ + bool m_cleanup_cfg; }; /* Callback for walk_dominator_tree. Attempt to optimize various @@ -3399,11 +3424,16 @@ strlen_dom_walker::before_dom_children (basic_block bb) } } + bool cleanup_eh = false; + /* Attempt to optimize individual statements. */ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) - if (strlen_check_and_optimize_stmt (&gsi)) + if (strlen_check_and_optimize_stmt (&gsi, &cleanup_eh)) gsi_next (&gsi); + if (cleanup_eh && gimple_purge_dead_eh_edges (bb)) + m_cleanup_cfg = true; + bb->aux = stridx_to_strinfo; if (vec_safe_length (stridx_to_strinfo) && !strinfo_shared ()) (*stridx_to_strinfo)[0] = (strinfo *) bb; @@ -3477,7 +3507,8 @@ pass_strlen::execute (function *fun) /* String length optimization is implemented as a walk of the dominator tree and a forward walk of statements within each block. */ - strlen_dom_walker (CDI_DOMINATORS).walk (fun->cfg->x_entry_block_ptr); + strlen_dom_walker walker (CDI_DOMINATORS); + walker.walk (fun->cfg->x_entry_block_ptr); ssa_ver_to_stridx.release (); strinfo_pool.release (); @@ -3498,7 +3529,7 @@ pass_strlen::execute (function *fun) strlen_to_stridx = NULL; } - return 0; + return walker.m_cleanup_cfg ? TODO_cleanup_cfg : 0; } } // anon namespace |