On 22/04/15 09:36, Richard Biener wrote:
On Tue, 21 Apr 2015, Thomas Schwinge wrote:Hi! On Tue, 25 Nov 2014 12:22:02 +0100, Tom de Vries <tom_devr...@mentor.com> wrote:On 24-11-14 11:56, Tom de Vries wrote:On 15-11-14 18:19, Tom de Vries wrote:On 15-11-14 13:14, Tom de Vries wrote:I'm submitting a patch series with initial support for the oacc kernels directive. The patch series uses pass_parallelize_loops to implement parallelization of loops in the oacc kernels region. The patch series consists of these 8 patches: ... 1 Expand oacc kernels after pass_build_ealias 2 Add pass_oacc_kernels 3 Add pass_ch_oacc_kernels to pass_oacc_kernels 4 Add pass_tree_loop_{init,done} to pass_oacc_kernels 5 Add pass_loop_im to pass_oacc_kernels 6 Add pass_ccp to pass_oacc_kernels 7 Add pass_parloops_oacc_kernels to pass_oacc_kernels 8 Do simple omp lowering for no address taken var ...This patch moves omp expansion of the oacc kernels directive to after pass_build_ealias. The rationale is that in order to use pass_parallelize_loops for analysis and transformation of an oacc kernels region, we postpone omp expansion of that region until the earliest point in the pass list where enough information is availabe to run pass_parallelize_loops, in other words, after pass_build_ealias. The patch postpones expansion in expand_omp, and ensures expansion by adding pass_expand_omp_ssa: - after pass_build_ealias, and - after pass_all_early_optimizations for the case we're not optimizing. In order to make sure the oacc kernels region arrives at pass_expand_omp_ssa, the way it left expand_omp, the patch makes pass_ccp and pass_forwprop aware of lowered omp code, to handle it conservatively. The patch contains changes in expand_omp_target to deal with ssa-code, similar to what is already present in expand_omp_taskreg. Furthermore, the patch forces the .omp_data_sizes and .omp_data_kinds to not be static for oacc kernels. It does this to get some references to .omp_data_sizes and .omp_data_kinds in the ssa code. Without these references, the definitions will be removed. The reference of the variables in GIMPLE_OACC_KERNELS is not enough to have them not removed. [ In vries/oacc-kernels, I used a BUILT_IN_USE kludge for this purpose ]. Finally, at the end of pass_expand_omp_ssa we're left with SSA_NAMEs in the original function of which the definition has been removed (as in moved to the split off function). TODO_remove_unused_locals takes care of some of them, but not the anonymous ones. So the patch iterates over all SSA_NAMEs to find these dangling SSA_NAMEs and releases them.Reposting with small update: I've replaced the use of the rather generic gimple_stmt_omp_lowering_p with the more specific gimple_stmt_omp_data_i_init_p. Bootstrapped and reg-tested in the same way as before.I've moved pass_expand_omp_ssa one down in the pass list, past pass_fre. This allows fre to unify references to the same omp variable before entering pass_oacc_kernels, which helps pass_lim in pass_oacc_kernels. F.i. this reduction fragment: ... # VUSE <.MEM_8> # PT = { D.2282 } _67 = .omp_data_i_59->sumD.2270; # VUSE <.MEM_8> _68 = *_67; _70 = _66 + _68; # VUSE <.MEM_8> # PT = { D.2282 } _69 = .omp_data_i_59->sumD.2270; # .MEM_71 = VDEF <.MEM_8> *_69 = _70; ... is transformed by fre into: ... # VUSE <.MEM_8> # PT = { D.2282 } _67 = .omp_data_i_59->sumD.2270; # VUSE <.MEM_8> _68 = *_67; _70 = _66 + _68; # .MEM_71 = VDEF <.MEM_8> *_67 = _70; ... In order for pass_fre to respect the kernels region boundaries, I've added a change in tree-ssa-sccvn.c:visit_use to handle the .omp_data_i init conservatively. Bootstrapped and reg-tested as before. OK for trunk?Committed to gomp-4_0-branch in r222279: commit 93557ac5e30c26ee1a3d1255e31265b287171a0d Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue Apr 21 19:37:19 2015 +0000 Expand oacc kernels after pass_fre gcc/ * omp-low.c: Include gimple-pretty-print.h. (release_first_vuse_in_edge_dest): New function. (expand_omp_target): When not in ssa, don't split off oacc kernels region, clear PROP_gimple_eomp in cfun->curr_properties to force later expanssion, and add GOACC_kernels_internal call. When in ssa, split off oacc kernels and convert GOACC_kernels_internal into GOACC_kernels call. Handle ssa-code. (pass_data_expand_omp): Don't set PROP_gimple_eomp unconditionally in properties_provided field. (pass_expand_omp::execute): Set PROP_gimple_eomp in cfun->curr_properties tentatively. (pass_data_expand_omp_ssa): Add TODO_remove_unused_locals to todo_flags_finish field. (pass_expand_omp_ssa::execute): Release dangling SSA_NAMEs after calling execute_expand_omp. (gimple_stmt_ssa_operand_references_var_p) (gimple_stmt_omp_data_i_init_p): New function. * omp-low.h (gimple_stmt_omp_data_i_init_p): Declare. * passes.def: Add pass_expand_omp_ssa after pass_fre. Add pass_expand_omp_ssa after pass_all_early_optimizations. * tree-ssa-ccp.c: Include omp-low.h. (surely_varying_stmt_p, ccp_visit_stmt): Handle .omp_data_i init conservatively. * tree-ssa-forwprop.c: Include omp-low.h. (pass_forwprop::execute): Handle .omp_data_i init conservatively. * tree-ssa-sccvn.c: Include omp-low.h. (visit_use): Handle .omp_data_i init conservatively. * cgraph.c (cgraph_node::release_body): Don't release offloadable functions. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gomp-4_0-branch@222279 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog.gomp | 30 +++++++ gcc/cgraph.c | 9 ++ gcc/omp-low.c | 214 ++++++++++++++++++++++++++++++++++++++++++++--- gcc/omp-low.h | 1 + gcc/passes.def | 2 + gcc/tree-ssa-ccp.c | 6 ++ gcc/tree-ssa-forwprop.c | 4 +- gcc/tree-ssa-sccvn.c | 4 +- 8 files changed, 257 insertions(+), 13 deletions(-) diff --git gcc/ChangeLog.gomp gcc/ChangeLog.gomp index 7885189..1f86160 100644 --- gcc/ChangeLog.gomp +++ gcc/ChangeLog.gomp @@ -1,5 +1,35 @@ 2015-04-21 Tom de Vries <t...@codesourcery.com> + * omp-low.c: Include gimple-pretty-print.h. + (release_first_vuse_in_edge_dest): New function. + (expand_omp_target): When not in ssa, don't split off oacc kernels + region, clear PROP_gimple_eomp in cfun->curr_properties to force later + expanssion, and add GOACC_kernels_internal call. + When in ssa, split off oacc kernels and convert GOACC_kernels_internal + into GOACC_kernels call. Handle ssa-code. + (pass_data_expand_omp): Don't set PROP_gimple_eomp unconditionally in + properties_provided field. + (pass_expand_omp::execute): Set PROP_gimple_eomp in + cfun->curr_properties tentatively. + (pass_data_expand_omp_ssa): Add TODO_remove_unused_locals to + todo_flags_finish field. + (pass_expand_omp_ssa::execute): Release dangling SSA_NAMEs after calling + execute_expand_omp. + (gimple_stmt_ssa_operand_references_var_p) + (gimple_stmt_omp_data_i_init_p): New function. + * omp-low.h (gimple_stmt_omp_data_i_init_p): Declare. + * passes.def: Add pass_expand_omp_ssa after pass_fre. Add + pass_expand_omp_ssa after pass_all_early_optimizations. + * tree-ssa-ccp.c: Include omp-low.h. + (surely_varying_stmt_p, ccp_visit_stmt): Handle .omp_data_i init + conservatively. + * tree-ssa-forwprop.c: Include omp-low.h. + (pass_forwprop::execute): Handle .omp_data_i init conservatively. + * tree-ssa-sccvn.c: Include omp-low.h. + (visit_use): Handle .omp_data_i init conservatively. + * cgraph.c (cgraph_node::release_body): Don't release offloadable + functions. + * builtin-attrs.def (DOT_DOT_DOT_r_r_r): Add DEF_ATTR_FOR_STRING. (ATTR_FNSPEC_DOT_DOT_DOT_r_r_r_NOTHROW_LIST): Add DEF_ATTR_TREE_LIST. diff --git gcc/cgraph.c gcc/cgraph.c index e099856..c608d7e 100644 --- gcc/cgraph.c +++ gcc/cgraph.c @@ -1706,6 +1706,15 @@ release_function_body (tree decl) void cgraph_node::release_body (bool keep_arguments) { + /* The omp-expansion of the oacc kernels directive is post-poned till after + all_small_ipa_passes. That means pass_ipa_free_lang_data, which tries to + release the body of the offload function, is run before omp_expand_target + can process the oacc kernels directive, and omp_expand_target would crash + trying to access the body. This snippet works around this problem. + FIXME: This should probably be fixed in a different way. */ + if (offloadable) + return; + ipa_transforms_to_apply.release (); if (!used_as_abstract_origin && symtab->state != PARSING) { diff --git gcc/omp-low.c gcc/omp-low.c index 4134f3d..16d9a5e 100644 --- gcc/omp-low.c +++ gcc/omp-low.c @@ -108,6 +108,7 @@ along with GCC; see the file COPYING3. If not see #include "context.h" #include "lto-section-names.h" #include "gomp-constants.h" +#include "gimple-pretty-print.h" /* Lowering of OMP parallel and workshare constructs proceeds in two @@ -5353,6 +5354,35 @@ expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from) } } +static void +release_first_vuse_in_edge_dest (edge e)All functions need a comment with documentation.
Fixed and committed (ommitting patch as trivial).
+{ + gimple_stmt_iterator i; + basic_block bb = e->dest; + + for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) + { + gimple phi = gsi_stmt (i); + tree arg = PHI_ARG_DEF_FROM_EDGE (phi, e); + + if (!virtual_operand_p (arg)) + continue; + + mark_virtual_operand_for_renaming (arg); + return; + } + + for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next_nondebug (&i)) + { + gimple stmt = gsi_stmt (i); + if (gimple_vuse (stmt) == NULL_TREE) + continue; + + mark_virtual_operand_for_renaming (gimple_vuse (stmt)); + return; + } +} + /* Expand the OpenMP parallel or task directive starting at REGION. */ static void @@ -8770,8 +8800,11 @@ expand_omp_target (struct omp_region *region) gimple stmt; edge e; bool offloaded, data_region; + bool do_emit_library_call = true; + bool do_splitoff = true; entry_stmt = as_a <gomp_target *> (last_stmt (region->entry)); + new_bb = region->entry; offloaded = is_gimple_omp_offloaded (entry_stmt); @@ -8804,12 +8837,48 @@ expand_omp_target (struct omp_region *region) /* Supported by expand_omp_taskreg, but not here. */ if (child_cfun != NULL) gcc_checking_assert (!child_cfun->cfg); - gcc_checking_assert (!gimple_in_ssa_p (cfun)); entry_bb = region->entry; exit_bb = region->exit; - if (offloaded) + if (gimple_omp_target_kind (entry_stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS) + { + if (!gimple_in_ssa_p (cfun)) + { + /* We need to do analysis and optimizations on the kernels region + before splitoff. Since that's hard to do on low gimple, we + postpone the splitoff until we're in SSA. + However, we do the emit of the corresponding function call already, + in order to keep the arguments of the call alive until the + splitoff. + Since at this point the function that is called is empty, we can + model the function as BUILT_IN_GOACC_KERNELS_INTERNAL, which marks + some of it's function arguments as non-escaping, so it acts less + as an optimization barrier. */ + do_splitoff = false; + cfun->curr_properties &= ~PROP_gimple_eomp; + } + else + { + /* Don't emit the library call. We've already done that. */ + do_emit_library_call = false; + /* Transform BUILT_IN_GOACC_KERNELS_INTERNAL into + BUILT_IN_GOACC_KERNELS_INTERNAL. Now that the function body will be + split off, we can no longer regard the omp_data_array reference as + non-escaping. */ + gsi = gsi_last_bb (entry_bb); + gsi_prev (&gsi); + gcall *call = as_a <gcall *> (gsi_stmt (gsi)); + gcc_assert (gimple_call_builtin_p (call, BUILT_IN_GOACC_KERNELS_INTERNAL)); + tree fndecl = builtin_decl_explicit (BUILT_IN_GOACC_KERNELS); + gimple_call_set_fndecl (call, fndecl); + gimple_call_set_fntype (call, TREE_TYPE (fndecl)); + gimple_call_reset_alias_info (call); + } + } + + if (offloaded + && do_splitoff) { unsigned srcidx, dstidx, num; @@ -8831,7 +8900,7 @@ expand_omp_target (struct omp_region *region) { basic_block entry_succ_bb = single_succ (entry_bb); gimple_stmt_iterator gsi; - tree arg; + tree arg, narg; gimple tgtcopy_stmt = NULL; tree sender = TREE_VEC_ELT (data_arg, 0); @@ -8861,8 +8930,27 @@ expand_omp_target (struct omp_region *region) gcc_assert (tgtcopy_stmt != NULL); arg = DECL_ARGUMENTS (child_fn); - gcc_assert (gimple_assign_lhs (tgtcopy_stmt) == arg); - gsi_remove (&gsi, true); + if (!gimple_in_ssa_p (cfun)) + { + gcc_assert (gimple_assign_lhs (tgtcopy_stmt) == arg); + gsi_remove (&gsi, true); + } + else + { + gcc_assert (SSA_NAME_VAR (gimple_assign_lhs (tgtcopy_stmt)) + == arg); + + /* 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); + /* ?? Is setting the subcode really necessary ?? */ + gimple_omp_set_subcode (tgtcopy_stmt, TREE_CODE (narg)); + gimple_assign_set_rhs1 (tgtcopy_stmt, narg); + update_stmt (tgtcopy_stmt); + } } /* Declare local variables needed in CHILD_CFUN. */ @@ -8905,11 +8993,23 @@ expand_omp_target (struct omp_region *region) stmt = gimple_build_return (NULL); gsi_insert_after (&gsi, stmt, GSI_SAME_STMT); gsi_remove (&gsi, true); + + /* A vuse in single_succ (exit_bb) may use a vdef from the region + which is about to be split off. Mark the vdef for renaming. */ + release_first_vuse_in_edge_dest (single_succ_edge (exit_bb)); } /* Move the offloading region into CHILD_CFUN. */ - block = gimple_block (entry_stmt); + if (gimple_in_ssa_p (cfun)) + { + init_tree_ssa (child_cfun); + init_ssa_operands (child_cfun); + child_cfun->gimple_df->in_ssa_p = true; + block = NULL_TREE; + } + else + block = gimple_block (entry_stmt); new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block); if (exit_bb) @@ -8969,9 +9069,18 @@ expand_omp_target (struct omp_region *region) if (changed) cleanup_tree_cfg (); } + if (gimple_in_ssa_p (cfun)) + update_ssa (TODO_update_ssa); pop_cfun (); } + if (!do_emit_library_call) + { + if (gimple_in_ssa_p (cfun)) + update_ssa (TODO_update_ssa_only_virtuals); + return; + } + /* Emit a library call to launch the offloading region, or do data transfers. */ tree t1, t2, t3, t4, device, cond, c, clauses; @@ -8993,7 +9102,7 @@ expand_omp_target (struct omp_region *region) start_ix = BUILT_IN_GOACC_PARALLEL; break; case GF_OMP_TARGET_KIND_OACC_KERNELS: - start_ix = BUILT_IN_GOACC_KERNELS; + start_ix = BUILT_IN_GOACC_KERNELS_INTERNAL; break; case GF_OMP_TARGET_KIND_OACC_DATA: start_ix = BUILT_IN_GOACC_DATA_START; @@ -9128,6 +9237,7 @@ expand_omp_target (struct omp_region *region) case BUILT_IN_GOACC_DATA_START: case BUILT_IN_GOACC_ENTER_EXIT_DATA: case BUILT_IN_GOACC_KERNELS: + case BUILT_IN_GOACC_KERNELS_INTERNAL: case BUILT_IN_GOACC_PARALLEL: case BUILT_IN_GOACC_UPDATE: break; @@ -9146,6 +9256,7 @@ expand_omp_target (struct omp_region *region) case BUILT_IN_GOMP_TARGET_UPDATE: break; case BUILT_IN_GOACC_KERNELS: + case BUILT_IN_GOACC_KERNELS_INTERNAL: case BUILT_IN_GOACC_PARALLEL: { tree t_num_gangs, t_num_workers, t_vector_length; @@ -9249,6 +9360,8 @@ expand_omp_target (struct omp_region *region) gcc_assert (g && gimple_code (g) == GIMPLE_OMP_RETURN); gsi_remove (&gsi, true); } + if (gimple_in_ssa_p (cfun)) + update_ssa (TODO_update_ssa_only_virtuals); } @@ -9503,7 +9616,7 @@ const pass_data pass_data_expand_omp = OPTGROUP_NONE, /* optinfo_flags */ TV_NONE, /* tv_id */ PROP_gimple_any, /* properties_required */ - PROP_gimple_eomp, /* properties_provided */ + 0 /* Possibly PROP_gimple_eomp. */, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ 0, /* todo_flags_finish */ @@ -9517,12 +9630,14 @@ public: {} /* opt_pass methods: */ - virtual unsigned int execute (function *) + virtual unsigned int execute (function *fun) { bool gate = ((flag_cilkplus != 0 || flag_openacc != 0 || flag_openmp != 0 || flag_openmp_simd != 0) && !seen_error ()); + fun->curr_properties |= PROP_gimple_eomp; + /* This pass always runs, to provide PROP_gimple_eomp. But often, there is nothing to do. */ if (!gate) @@ -9553,7 +9668,8 @@ const pass_data pass_data_expand_omp_ssa = PROP_gimple_eomp, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_cleanup_cfg | TODO_rebuild_alias, /* todo_flags_finish */ + TODO_cleanup_cfg | TODO_rebuild_alias + | TODO_remove_unused_locals, /* todo_flags_finish */ }; class pass_expand_omp_ssa : public gimple_opt_pass @@ -9568,7 +9684,48 @@ public: { return !(fun->curr_properties & PROP_gimple_eomp); } - virtual unsigned int execute (function *) { return execute_expand_omp (); } + virtual unsigned int execute (function *)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; + } + opt_pass * clone () { return new pass_expand_omp_ssa (m_ctxt); } }; // class pass_expand_omp_ssa @@ -13728,4 +13885,39 @@ omp_finish_file (void) } } +static bool +gimple_stmt_ssa_operand_references_var_p (gimple stmt, const char **varnames, + unsigned int nr_varnames, + unsigned int flags)Missing comment.+{ + tree use; + ssa_op_iter iter; + const char *s; + + FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, flags) + { + if (SSA_NAME_IDENTIFIER (use) == NULL_TREE) + continue; + s = IDENTIFIER_POINTER (SSA_NAME_IDENTIFIER (use)); + + unsigned int i; + for (i = 0; i < nr_varnames; ++i) + if (strcmp (varnames[i], s) == 0) + return true;Eh? This surely is crap - you can't ever have semantics depend on identifiers.+ } + + return false; +} + +/* Return true if STMT is .omp_data_i init. */ + +bool +gimple_stmt_omp_data_i_init_p (gimple stmt) +{ + const char *varnames[] = { ".omp_data_i" }; + unsigned int nr_varnames = sizeof (varnames) / sizeof (varnames[0]); + return gimple_stmt_ssa_operand_references_var_p (stmt, varnames, nr_varnames, + SSA_OP_DEF);So no - this isn't possible this way and I suspect it's not reliable anyway.
Rewritten gimple_stmt_omp_data_i_init_p to not use identifier names, attached and committed.
+} + #include "gt-omp-low.h" diff --git gcc/omp-low.h gcc/omp-low.h index 8a4052e..3d30c3b 100644 --- gcc/omp-low.h +++ gcc/omp-low.h @@ -28,6 +28,7 @@ extern void free_omp_regions (void); extern tree omp_reduction_init (tree, tree); extern bool make_gimple_omp_edges (basic_block, struct omp_region **, int *); extern void omp_finish_file (void); +extern bool gimple_stmt_omp_data_i_init_p (gimple); extern GTY(()) vec<tree, va_gc> *offload_funcs; extern GTY(()) vec<tree, va_gc> *offload_vars; diff --git gcc/passes.def gcc/passes.def index 2bc5dcd..db0dd18 100644 --- gcc/passes.def +++ gcc/passes.def @@ -86,6 +86,7 @@ along with GCC; see the file COPYING3. If not see execute TODO_rebuild_alias at this point. */ NEXT_PASS (pass_build_ealias); NEXT_PASS (pass_fre); + NEXT_PASS (pass_expand_omp_ssa); NEXT_PASS (pass_merge_phi); NEXT_PASS (pass_cd_dce); NEXT_PASS (pass_early_ipa_sra); @@ -99,6 +100,7 @@ along with GCC; see the file COPYING3. If not see late. */ NEXT_PASS (pass_split_functions); POP_INSERT_PASSES () + NEXT_PASS (pass_expand_omp_ssa); NEXT_PASS (pass_release_ssa_names); NEXT_PASS (pass_rebuild_cgraph_edges); NEXT_PASS (pass_inline_parameters); diff --git gcc/tree-ssa-ccp.c gcc/tree-ssa-ccp.c index d45a3ff..46fe1c7 100644 --- gcc/tree-ssa-ccp.c +++ gcc/tree-ssa-ccp.c @@ -172,6 +172,7 @@ along with GCC; see the file COPYING3. If not see #include "wide-int-print.h" #include "builtins.h" #include "tree-chkp.h" +#include "omp-low.h" /* Possible lattice values. */ @@ -796,6 +797,9 @@ surely_varying_stmt_p (gimple stmt) && gimple_code (stmt) != GIMPLE_CALL) return true; + if (gimple_stmt_omp_data_i_init_p (stmt)) + return true; +No.return false; } @@ -2329,6 +2333,8 @@ ccp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p) switch (gimple_code (stmt)) { case GIMPLE_ASSIGN: + if (gimple_stmt_omp_data_i_init_p (stmt)) + break; /* If the statement is an assignment that produces a single output value, evaluate its RHS to see if the lattice value of its output has changed. */ diff --git gcc/tree-ssa-forwprop.c gcc/tree-ssa-forwprop.c index d8db20a..554a5a5 100644 --- gcc/tree-ssa-forwprop.c +++ gcc/tree-ssa-forwprop.c @@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-cfgcleanup.h" #include "tree-into-ssa.h" #include "cfganal.h" +#include "omp-low.h" /* This pass propagates the RHS of assignment statements into use sites of the LHS of the assignment. It's basically a specialized @@ -2155,7 +2156,8 @@ pass_forwprop::execute (function *fun) tree lhs, rhs; enum tree_code code; - if (!is_gimple_assign (stmt)) + if (!is_gimple_assign (stmt) + || gimple_stmt_omp_data_i_init_p (stmt))No.{ gsi_next (&gsi); continue; diff --git gcc/tree-ssa-sccvn.c gcc/tree-ssa-sccvn.c index e417a15..449a615 100644 --- gcc/tree-ssa-sccvn.c +++ gcc/tree-ssa-sccvn.c @@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-ref.h" #include "plugin-api.h" #include "cgraph.h" +#include "omp-low.h" /* This algorithm is based on the SCC algorithm presented by Keith Cooper and L. Taylor Simpson in "SCC-Based Value numbering" @@ -3542,7 +3543,8 @@ visit_use (tree use) { if (gimple_code (stmt) == GIMPLE_PHI) changed = visit_phi (stmt); - else if (gimple_has_volatile_ops (stmt)) + else if (gimple_has_volatile_ops (stmt) + || gimple_stmt_omp_data_i_init_p (stmt))No. What is the intent of these changes?
These are changes to handle the kernels region conservatively, in order to not undo the omp-lowering before getting to the oacc-parloops pass.
Thanks, - Tom
Rewrite gimple_stmt_omp_data_i_init_p 2015-06-03 Tom de Vries <t...@codesourcery.com> * omp-low.c (gimple_stmt_ssa_operand_references_var_p): Remove function. (gimple_stmt_omp_data_i_init_p): Rewrite without gimple_stmt_ssa_operand_references_var_p. --- gcc/omp-low.c | 59 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/gcc/omp-low.c b/gcc/omp-low.c index f847d5c..0b31992 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -15368,39 +15368,40 @@ omp_finish_file (void) } } -static bool -gimple_stmt_ssa_operand_references_var_p (gimple stmt, const char **varnames, - unsigned int nr_varnames, - unsigned int flags) -{ - tree use; - ssa_op_iter iter; - const char *s; - - FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, flags) - { - if (SSA_NAME_IDENTIFIER (use) == NULL_TREE) - continue; - s = IDENTIFIER_POINTER (SSA_NAME_IDENTIFIER (use)); - - unsigned int i; - for (i = 0; i < nr_varnames; ++i) - if (strcmp (varnames[i], s) == 0) - return true; - } - - return false; -} - -/* Return true if STMT is .omp_data_i init. */ +/* Return true if STMT is copy assignment .omp_data_i = &.omp_data_arr. */ bool gimple_stmt_omp_data_i_init_p (gimple stmt) { - const char *varnames[] = { ".omp_data_i" }; - unsigned int nr_varnames = sizeof (varnames) / sizeof (varnames[0]); - return gimple_stmt_ssa_operand_references_var_p (stmt, varnames, nr_varnames, - SSA_OP_DEF); + /* Extract obj from stmt 'a = &obj. */ + if (!gimple_assign_cast_p (stmt) + && !gimple_assign_single_p (stmt)) + return false; + tree rhs = gimple_assign_rhs1 (stmt); + if (TREE_CODE (rhs) != ADDR_EXPR) + return false; + tree obj = TREE_OPERAND (rhs, 0); + + /* Check that the last statement in the preceding bb is an oacc kernels + stmt. */ + basic_block bb = gimple_bb (stmt); + if (!single_pred_p (bb)) + return false; + gimple last = last_stmt (single_pred (bb)); + if (last == NULL + || gimple_code (last) != GIMPLE_OMP_TARGET) + return false; + gomp_target *kernels = as_a <gomp_target *> (last); + if (gimple_omp_target_kind (kernels) + != GF_OMP_TARGET_KIND_OACC_KERNELS) + return false; + + /* Get omp_data_arr from the oacc kernels stmt. */ + tree data_arg = gimple_omp_target_data_arg (kernels); + tree omp_data_arr = TREE_VEC_ELT (data_arg, 0); + + /* If obj is omp_data_arr, we've found the .omp_data_i init statement. */ + return operand_equal_p (obj, omp_data_arr, 0); } namespace { -- 1.9.1