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