[ was: Re: Expand oacc kernels after pass_fre ]
On 04/06/15 18:02, Tom de Vries wrote:
Please move this out of the class body.
Fixed and committed (ommitting patch as trivial).
+ {
+ unsigned res = execute_expand_omp ();
+
+ /* After running pass_expand_omp_ssa to expand the oacc kernels
+ directive, we are left in the original function with anonymous
+ SSA_NAMEs, with a defining statement that has been deleted. This
+ pass finds those SSA_NAMEs and releases them.
+ TODO: Either fix this elsewhere, or make the fix unnecessary. */
+ unsigned int i;
+ for (i = 1; i < num_ssa_names; ++i)
+ {
+ tree name = ssa_name (i);
+ if (name == NULL_TREE)
+ continue;
+
+ gimple stmt = SSA_NAME_DEF_STMT (name);
+ bool found = false;
+
+ ssa_op_iter op_iter;
+ def_operand_p def_p;
+ FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_ALL_DEFS)
+ {
+ tree def = DEF_FROM_PTR (def_p);
+ if (def == name)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Released dangling ssa name %u\n", i);
+ release_ssa_name (name);
+ }
+ }
+
+ return res;
+ }
This patch implements the TODO.
The cause of the problems is that in replace_ssa_name, we create a new
ssa_name with the def stmt of the old ssa_name, but do not reset the def
stmt of the old ssa_name, leaving the ssa_name in the original function
having a def stmt in the split-off function.
[ And if we don't do anything about that, at some point in another pass
we use 'gimple_bb (SSA_NAME_DEF_STMT (name))->index' (a bb index in the
split-off function) as an index into an array with as length the number
of bbs in the original function. So the index may be out of bounds. ]
This patch fixes that by making sure we reset the def stmt to NULL. This
means we can simplify release_dangling_ssa_names to just test for NULL
def stmts.
Default defs are skipped by release_ssa_name, so setting the def stmt
for default defs to NULL does not result in the name being released, but
in an ssa-verification error. So instead, we keep the def stmt nop, and
create a new nop for the copy in the split-off function.
[ The default def bit seems only to be triggered for the default def
created by expand_omp_target:
...
/* If we are in ssa form, we must load the value from the default
definition of the argument. That should not be defined now,
since the argument is not used uninitialized. */
gcc_assert (ssa_default_def (cfun, arg) == NULL);
narg = make_ssa_name (arg, gimple_build_nop ());
set_ssa_default_def (cfun, arg, narg);
...
]
Bootstrapped and reg-tested on x86_64.
Committed to gomp-4_0-branch.
Thanks,
- Tom
Fix release_dangling_ssa_names
2015-08-05 Tom de Vries <t...@codesourcery.com>
* omp-low.c (release_dangling_ssa_names): Release SSA_NAMEs with NULL
def stmt.
* tree-cfg.c (replace_ssa_name): Don't move default def nops. Set def
stmt of unused SSA_NAME to NULL.
---
gcc/omp-low.c | 35 +++++++++++------------------------
gcc/tree-cfg.c | 17 ++++++++++++++++-
2 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 0ebbbe1..cd2076f 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -10349,11 +10349,10 @@ make_pass_expand_omp (gcc::context *ctxt)
return new pass_expand_omp (ctxt);
}
-/* After running pass_expand_omp_ssa to expand the oacc kernels
- directive, we are left in the original function with anonymous
- SSA_NAMEs, with a defining statement that has been deleted. This
- pass finds those SSA_NAMEs and releases them.
- TODO: Either fix this elsewhere, or make the fix unnecessary. */
+/* After running pass_expand_omp_ssa to expand the oacc kernels directive, we
+ are left in the original function with anonymous SSA_NAMEs, with a NULL
+ defining statement. This function finds those SSA_NAMEs and releases
+ them. */
static void
release_dangling_ssa_names (void)
@@ -10366,26 +10365,14 @@ release_dangling_ssa_names (void)
continue;
gimple stmt = SSA_NAME_DEF_STMT (name);
- bool found = false;
-
- ssa_op_iter op_iter;
- def_operand_p def_p;
- FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_ALL_DEFS)
- {
- tree def = DEF_FROM_PTR (def_p);
- if (def == name)
- {
- found = true;
- break;
- }
- }
+ if (stmt != NULL)
+ continue;
- if (!found)
- {
- if (dump_file)
- fprintf (dump_file, "Released dangling ssa name %u\n", i);
- release_ssa_name (name);
- }
+ release_ssa_name (name);
+ gcc_assert (SSA_NAME_IN_FREE_LIST (name));
+ if (dump_file
+ && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Released dangling ssa name %u\n", i);
}
}
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index cb9fe6d..6a00b25 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -6467,8 +6467,17 @@ replace_ssa_name (tree name, hash_map<tree, tree> *vars_map,
if (decl)
{
replace_by_duplicate_decl (&decl, vars_map, to_context);
+ /* If name is a default def, then we don't move the defining stmt
+ (which is a nop). Because (1) the nop doesn't belong to the sese
+ region, and (2) while setting the def stmt of name to NULL would
+ trigger release_ssa_name in release_dangling_ssa_names, it wouldn't
+ be released since it's a default def, and subsequently cause an
+ ssa verification failure. */
+ gimple def_stmt = (SSA_NAME_IS_DEFAULT_DEF (name)
+ ? gimple_build_nop ()
+ : SSA_NAME_DEF_STMT (name));
new_name = make_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context),
- decl, SSA_NAME_DEF_STMT (name));
+ decl, def_stmt);
if (SSA_NAME_IS_DEFAULT_DEF (name))
set_ssa_default_def (DECL_STRUCT_FUNCTION (to_context),
decl, new_name);
@@ -6478,6 +6487,12 @@ replace_ssa_name (tree name, hash_map<tree, tree> *vars_map,
name, SSA_NAME_DEF_STMT (name));
vars_map->put (name, new_name);
+
+ if (!SSA_NAME_IS_DEFAULT_DEF (name))
+ /* The statement has been moved to the child function. It no longer
+ defines name in the original function. Mark the def stmt NULL, and
+ let release_dangling_ssa_names deal with it. */
+ SSA_NAME_DEF_STMT (name) = NULL;
}
else
new_name = *loc;
--
1.9.1