+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
#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;
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
--- /dev/null
+! 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
#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
}
+/* 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;
+}
+
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 */
#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. */
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
/* 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 ();
&& 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
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))