[PATCH 4/5] tree-inline: implement SIMT privatization, part 3

Jakub Jelinek jakub@redhat.com
Thu Mar 23 16:23:00 GMT 2017


On Thu, Mar 23, 2017 at 07:15:52PM +0300, Alexander Monakov wrote:
> 	* tree-inline.h (struct copy_body_data): New field dst_simt_vars.
>         * tree-inline.c (expand_call_inline): Handle SIMT privatization.
>         (copy_decl_for_dup_finish): Ditto.
> ---
>  gcc/tree-inline.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++------
>  gcc/tree-inline.h |  4 ++++
>  2 files changed, 62 insertions(+), 7 deletions(-)
> 
> @@ -4588,15 +4593,26 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
>    id->src_cfun = DECL_STRUCT_FUNCTION (fn);
>    id->call_stmt = call_stmt;
>  
> +  /* When inlining into an OpenMP SIMD-on-SIMT loop, arrange for new automatic
> +     variables to be added to IFN_GOMP_SIMT_ENTER argument list.  */
> +  dst_cfun = DECL_STRUCT_FUNCTION (id->dst_fn);
> +  if (!(dst_cfun->curr_properties & PROP_gimple_lomp_dev)
> +      && (simduid = bb->loop_father->simduid) != NULL_TREE
> +      && (simduid = ssa_default_def (dst_cfun, simduid)) != NULL_TREE
> +      && single_imm_use (simduid, &use, &simtenter_stmt)
> +      && is_gimple_call (simtenter_stmt)
> +      && gimple_call_internal_p (simtenter_stmt, IFN_GOMP_SIMT_ENTER))
> +    {
> +      simtvars_st = id->dst_simt_vars;
> +      vec_alloc (id->dst_simt_vars, 0);
> +    }

One more thing.  If the above if condition is false, you keep
id->dst_simt_vars what it was (which means simtvars_st is NULL).
If it was non-NULL already, then:

> @@ -4730,6 +4746,31 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
>    if (cfun->gimple_df)
>      pt_solution_reset (&cfun->gimple_df->escaped);
>  
> +  /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments.  */
> +  if (id->dst_simt_vars)
> +    {

This will be true.

> +      if (id->dst_simt_vars->length () > 0)
> +	{
> +	  size_t nargs = gimple_call_num_args (simtenter_stmt);
> +	  vec<tree> *vars = id->dst_simt_vars;
> +	  auto_vec<tree> newargs (nargs + vars->length ());
> +	  for (size_t i = 0; i < nargs; i++)
> +	    newargs.quick_push (gimple_call_arg (simtenter_stmt, i));
> +	  for (tree *pvar = vars->begin (); pvar != vars->end (); pvar++)
> +	    {
> +	      tree ptrtype = build_pointer_type (TREE_TYPE (*pvar));
> +	      newargs.quick_push (build1 (ADDR_EXPR, ptrtype, *pvar));
> +	    }
> +	  gcall *g
> +	    = gimple_build_call_internal_vec (IFN_GOMP_SIMT_ENTER, newargs);
> +	  gimple_call_set_lhs (g, gimple_call_lhs (simtenter_stmt));
> +	  gimple_stmt_iterator gsi = gsi_for_stmt (simtenter_stmt);
> +	  gsi_replace (&gsi, g, false);
> +	}

And you handle dst_simt_vars from some other invocation.

> +      vec_free (id->dst_simt_vars);
> +      id->dst_simt_vars = simtvars_st;

And then clear it.  That doesn't look like the right thing.

So either you need some bool variable whether you've actually allocated
the vector in the current expand_call_inline and use that instead of
if (id->dst_simt_vars), or maybe you should clear id->dst_simt_vars
otherwise and save/restore it around unconditionally.

	Jakub



More information about the Gcc-patches mailing list