From: Martin Liska Date: Wed, 3 Jan 2018 14:53:39 +0000 (+0100) Subject: Clean-up EH after strlen transformation (PR tree-optimization/83593). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fa9544ab4df0e88946488fb82f4b994bf36a97ff;p=gcc.git Clean-up EH after strlen transformation (PR tree-optimization/83593). 2018-01-03 Martin Liska 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 PR tree-optimization/83593 * gcc.dg/pr83593.c: New test. From-SVN: r256178 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad327b955d3..95b5ed2468d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2018-01-03 Martin Liska + + 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 PR ipa/83549 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 969ce39efef..f389dea6971 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-01-03 Martin Liska + + PR tree-optimization/83593 + * gcc.dg/pr83593.c: New test. + 2018-01-03 Martin Liska PR ipa/83549 diff --git a/gcc/testsuite/gcc.dg/pr83593.c b/gcc/testsuite/gcc.dg/pr83593.c new file mode 100644 index 00000000000..eddecc0606a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83593.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/83593 */ +/* { dg-options "-O2 -fno-tree-dominator-opts -fnon-call-exceptions -fno-tree-pre -fexceptions -fno-code-hoisting -fno-tree-fre" } */ + +void +hr (int *ed, signed char *ju) +{ + int kc; + { + int xj; + int *q2 = (*ed == 0) ? &xj : &kc; + + *ju = 0; + kc = *ju; + } +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index c8b86b69dbe..8f7020c14b3 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