From: Martin Jambor Date: Sat, 26 Jan 2019 22:19:17 +0000 (+0100) Subject: [PR ipa/88933] Careful CFG cleanup in IPA-CP function transformation X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=95a2ed0325864069bb0368d75bcf85a8b22c4127;p=gcc.git [PR ipa/88933] Careful CFG cleanup in IPA-CP function transformation 2019-01-26 Martin Jambor PR ipa/88933 * tree-inline.c: Include tree-cfgcleanup.h. (delete_unreachable_blocks_update_callgraph): Move... * tree-cfgcleanup.c (delete_unreachable_blocks_update_callgraph): ...here, make externally visible, make second argument bool, adjust all callers. * tree-cfgcleanup.c: Include cgraph.h. * tree-cfgcleanup.h (delete_unreachable_blocks_update_callgraph): Declare. * ipa-prop.c: Include tree-cfgcleanup.h. (ipcp_transform_function): Call delete_unreachable_blocks_update_callgraph instead of cleaning uo CFG. testsuite/ * gfortran.dg/gomp/pr88933.f90: New test. From-SVN: r268305 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0518053ad85..269b6652249 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2019-01-26 Martin Jambor + + PR ipa/88933 + * tree-inline.c: Include tree-cfgcleanup.h. + (delete_unreachable_blocks_update_callgraph): Move... + * tree-cfgcleanup.c (delete_unreachable_blocks_update_callgraph): + ...here, make externally visible, make second argument bool, adjust + all callers. + * tree-cfgcleanup.c: Include cgraph.h. + * tree-cfgcleanup.h (delete_unreachable_blocks_update_callgraph): + Declare. + * ipa-prop.c: Include tree-cfgcleanup.h. + (ipcp_transform_function): Call + delete_unreachable_blocks_update_callgraph instead of cleaning uo CFG. + 2019-01-25 Vladimir Makarov PR rtl-optimization/88846 diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 40ab130b750..d86c2f3db55 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see #include "dbgcnt.h" #include "domwalk.h" #include "builtins.h" +#include "tree-cfgcleanup.h" /* Function summary where the parameter infos are actually stored. */ ipa_node_params_t *ipa_node_params_sum = NULL; @@ -5173,10 +5174,11 @@ ipcp_transform_function (struct cgraph_node *node) if (!something_changed) return 0; - else if (cfg_changed) - return TODO_update_ssa_only_virtuals | TODO_cleanup_cfg; - else - return TODO_update_ssa_only_virtuals; + + if (cfg_changed) + delete_unreachable_blocks_update_callgraph (node, false); + + return TODO_update_ssa_only_virtuals; } #include "gt-ipa-prop.h" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f1e89d56010..9fe74a08600 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-01-26 Martin Jambor + + PR ipa/88933 + * gfortran.dg/gomp/pr88933.f90: New test. + 2019-01-26 Iain Buclaw PR d/89042 diff --git a/gcc/testsuite/gfortran.dg/gomp/pr88933.f90 b/gcc/testsuite/gfortran.dg/gomp/pr88933.f90 new file mode 100644 index 00000000000..e4f30ae9f3e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr88933.f90 @@ -0,0 +1,39 @@ +! PR ipa/88933 +! { dg-do compile } +! { dg-options "-O1 -fexceptions -fipa-cp -fnon-call-exceptions -fopenmp -fno-inline-functions-called-once" } + +!$omp parallel +!$omp single + call a +!$omp end single +!$omp end parallel +contains + subroutine b (c, d, e, f, g, h, i, j, k, m) + character (*) c + character d + integer, dimension (m) :: e + integer, dimension (m) :: f + character g + character h + real, dimension (:, :, :) :: i + double precision, dimension (:, :, :) :: j + integer, dimension (:, :, :) :: k + + integer, dimension (m) :: l +!$omp task firstprivate (k) firstprivate (l) + !$omp end task + c = '' + end + subroutine a + character c + character d + integer, dimension (7) :: e + integer, dimension (7) :: f + character g + character h + real, dimension (5, 6, 7) :: i + double precision, dimension (6, 6, 7) :: j + integer, dimension (5, 7, 6) :: k + call b (c, d, e, f, g, h, i, j, k, 7) + end +end diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 2adb3953d6b..f2e8b96ee8e 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-match.h" #include "gimple-fold.h" #include "tree-ssa-loop-niter.h" - +#include "cgraph.h" /* The set of blocks in that at least one of the following changes happened: -- the statement at the end of the block was changed @@ -1380,3 +1380,76 @@ make_pass_cleanup_cfg_post_optimizing (gcc::context *ctxt) } +/* Delete all unreachable basic blocks and update callgraph. + Doing so is somewhat nontrivial because we need to update all clones and + remove inline function that become unreachable. */ + +bool +delete_unreachable_blocks_update_callgraph (cgraph_node *dst_node, + bool update_clones) +{ + bool changed = false; + basic_block b, next_bb; + + find_unreachable_blocks (); + + /* Delete all unreachable basic blocks. */ + + for (b = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; b + != EXIT_BLOCK_PTR_FOR_FN (cfun); b = next_bb) + { + next_bb = b->next_bb; + + if (!(b->flags & BB_REACHABLE)) + { + gimple_stmt_iterator bsi; + + for (bsi = gsi_start_bb (b); !gsi_end_p (bsi); gsi_next (&bsi)) + { + struct cgraph_edge *e; + struct cgraph_node *node; + + dst_node->remove_stmt_references (gsi_stmt (bsi)); + + if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL + &&(e = dst_node->get_edge (gsi_stmt (bsi))) != NULL) + { + if (!e->inline_failed) + e->callee->remove_symbol_and_inline_clones (dst_node); + else + e->remove (); + } + if (update_clones && dst_node->clones) + for (node = dst_node->clones; node != dst_node;) + { + node->remove_stmt_references (gsi_stmt (bsi)); + if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL + && (e = node->get_edge (gsi_stmt (bsi))) != NULL) + { + if (!e->inline_failed) + e->callee->remove_symbol_and_inline_clones (dst_node); + else + e->remove (); + } + + if (node->clones) + node = node->clones; + else if (node->next_sibling_clone) + node = node->next_sibling_clone; + else + { + while (node != dst_node && !node->next_sibling_clone) + node = node->clone_of; + if (node != dst_node) + node = node->next_sibling_clone; + } + } + } + delete_basic_block (b); + changed = true; + } + } + + return changed; +} + diff --git a/gcc/tree-cfgcleanup.h b/gcc/tree-cfgcleanup.h index e133bbdfbec..bd27505fd5c 100644 --- a/gcc/tree-cfgcleanup.h +++ b/gcc/tree-cfgcleanup.h @@ -24,5 +24,7 @@ along with GCC; see the file COPYING3. If not see extern bitmap cfgcleanup_altered_bbs; extern bool cleanup_tree_cfg (void); extern bool fixup_noreturn_call (gimple *stmt); +extern bool delete_unreachable_blocks_update_callgraph (cgraph_node *dst_node, + bool update_clones); #endif /* GCC_TREE_CFGCLEANUP_H */ diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index eb5073c5f61..5c0c4c5ab91 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "attribs.h" #include "sreal.h" +#include "tree-cfgcleanup.h" /* I'm not real happy about this, but we need to handle gimple and non-gimple trees. */ @@ -132,7 +133,6 @@ static tree copy_decl_to_var (tree, copy_body_data *); static tree copy_result_decl_to_var (tree, copy_body_data *); static tree copy_decl_maybe_to_var (tree, copy_body_data *); static gimple_seq remap_gimple_stmt (gimple *, copy_body_data *); -static bool delete_unreachable_blocks_update_callgraph (copy_body_data *id); static void insert_init_stmt (copy_body_data *, basic_block, gimple *); /* Insert a tree->tree mapping for ID. Despite the name suggests @@ -5124,7 +5124,8 @@ optimize_inline_calls (tree fn) /* Renumber the lexical scoping (non-code) blocks consecutively. */ number_blocks (fn); - delete_unreachable_blocks_update_callgraph (&id); + delete_unreachable_blocks_update_callgraph (id.dst_node, false); + if (flag_checking) id.dst_node->verify (); @@ -5708,79 +5709,6 @@ tree_versionable_function_p (tree fndecl) && copy_forbidden (DECL_STRUCT_FUNCTION (fndecl)) == NULL); } -/* Delete all unreachable basic blocks and update callgraph. - Doing so is somewhat nontrivial because we need to update all clones and - remove inline function that become unreachable. */ - -static bool -delete_unreachable_blocks_update_callgraph (copy_body_data *id) -{ - bool changed = false; - basic_block b, next_bb; - - find_unreachable_blocks (); - - /* Delete all unreachable basic blocks. */ - - for (b = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; b - != EXIT_BLOCK_PTR_FOR_FN (cfun); b = next_bb) - { - next_bb = b->next_bb; - - if (!(b->flags & BB_REACHABLE)) - { - gimple_stmt_iterator bsi; - - for (bsi = gsi_start_bb (b); !gsi_end_p (bsi); gsi_next (&bsi)) - { - struct cgraph_edge *e; - struct cgraph_node *node; - - id->dst_node->remove_stmt_references (gsi_stmt (bsi)); - - if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL - &&(e = id->dst_node->get_edge (gsi_stmt (bsi))) != NULL) - { - if (!e->inline_failed) - e->callee->remove_symbol_and_inline_clones (id->dst_node); - else - e->remove (); - } - if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES - && id->dst_node->clones) - for (node = id->dst_node->clones; node != id->dst_node;) - { - node->remove_stmt_references (gsi_stmt (bsi)); - if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL - && (e = node->get_edge (gsi_stmt (bsi))) != NULL) - { - if (!e->inline_failed) - e->callee->remove_symbol_and_inline_clones (id->dst_node); - else - e->remove (); - } - - if (node->clones) - node = node->clones; - else if (node->next_sibling_clone) - node = node->next_sibling_clone; - else - { - while (node != id->dst_node && !node->next_sibling_clone) - node = node->clone_of; - if (node != id->dst_node) - node = node->next_sibling_clone; - } - } - } - delete_basic_block (b); - changed = true; - } - } - - return changed; -} - /* Update clone info after duplication. */ static void @@ -6094,7 +6022,7 @@ tree_function_versioning (tree old_decl, tree new_decl, update_max_bb_count (); fold_marked_statements (0, id.statements_to_fold); delete id.statements_to_fold; - delete_unreachable_blocks_update_callgraph (&id); + delete_unreachable_blocks_update_callgraph (id.dst_node, update_clones); if (id.dst_node->definition) cgraph_edge::rebuild_references (); if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))