Commit 95a2ed03 by Martin Jambor Committed by Martin Jambor

[PR ipa/88933] Careful CFG cleanup in IPA-CP function transformation

2019-01-26  Martin Jambor  <mjambor@suse.cz>

	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
parent e4e13e26
2019-01-26 Martin Jambor <mjambor@suse.cz>
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 <vmakarov@redhat.com>
PR rtl-optimization/88846
......
......@@ -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"
2019-01-26 Martin Jambor <mjambor@suse.cz>
PR ipa/88933
* gfortran.dg/gomp/pr88933.f90: New test.
2019-01-26 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/89042
......
! 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
......@@ -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;
}
......@@ -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 */
......@@ -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))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment