Re: [PATCH 4/5] tree-inline: implement SIMT privatization, part 3
On Thu, Mar 23, 2017 at 08:00:11PM +0300, Alexander Monakov wrote: > On Thu, 23 Mar 2017, Jakub Jelinek wrote: > > 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. > > Yes, thanks for catching this. I went for the latter approach in the > following > patch. Ok for trunk, thanks. For the nvptx bits, I think you need to ask Bernd to review it. Jakub
Re: [PATCH 4/5] tree-inline: implement SIMT privatization, part 3
On Thu, 23 Mar 2017, Jakub Jelinek wrote: > 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. Yes, thanks for catching this. I went for the latter approach in the following patch. --- gcc/tree-inline.c | 61 --- gcc/tree-inline.h | 4 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6b6d489..b3bb3d6 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4385,6 +4385,11 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) gcall *call_stmt; unsigned int i; unsigned int prop_mask, src_properties; + struct function *dst_cfun; + tree simduid; + use_operand_p use; + gimple *simtenter_stmt = NULL; + vec *simtvars_save; /* The gimplifier uses input_location in too many places, such as internal_get_tmp_var (). */ @@ -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); + simtvars_save = id->dst_simt_vars; + 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, , _stmt) + && is_gimple_call (simtenter_stmt) + && gimple_call_internal_p (simtenter_stmt, IFN_GOMP_SIMT_ENTER)) +vec_alloc (id->dst_simt_vars, 0); + else +id->dst_simt_vars = NULL; + /* If the src function contains an IFN_VA_ARG, then so will the dst function after inlining. Likewise for IFN_GOMP_USE_SIMT. */ prop_mask = PROP_gimple_lva | PROP_gimple_lomp_dev; src_properties = id->src_cfun->curr_properties & prop_mask; if (src_properties != prop_mask) -{ - struct function *dst_cfun = DECL_STRUCT_FUNCTION (id->dst_fn); - dst_cfun->curr_properties &= src_properties | ~prop_mask; -} +dst_cfun->curr_properties &= src_properties | ~prop_mask; gcc_assert (!id->src_cfun->after_inlining); @@ -4730,6 +4746,27 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) if (cfun->gimple_df) pt_solution_reset (>gimple_df->escaped); + /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */ + if (id->dst_simt_vars && id->dst_simt_vars->length () > 0) +{ + size_t nargs = gimple_call_num_args (simtenter_stmt); + vec *vars = id->dst_simt_vars; + auto_vec 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 (, g, false); +} + vec_free (id->dst_simt_vars); + id->dst_simt_vars = simtvars_save; + /* Clean up. */ if (id->debug_map) { @@ -5453,9 +5490,19 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy) function. */ ; else -/* Ordinary automatic local variables are now in the scope of the - new function. */ -DECL_CONTEXT (copy) = id->dst_fn; +{ + /* Ordinary automatic local variables are now in the scope of the +new function. */ + DECL_CONTEXT (copy) = id->dst_fn; + if (VAR_P (copy) && id->dst_simt_vars && !is_gimple_reg (copy)) + { + if (!lookup_attribute ("omp simt private", DECL_ATTRIBUTES (copy))) + DECL_ATTRIBUTES (copy) + = tree_cons (get_identifier ("omp simt private"), NULL, + DECL_ATTRIBUTES (copy)); + id->dst_simt_vars->safe_push (copy); + } +} return copy; } diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h index 88b3286..ffb8333 100644 --- a/gcc/tree-inline.h +++ b/gcc/tree-inline.h @@ -145,6 +145,10 @@ struct copy_body_data equivalents in the function into which it is being inlined. */ hash_map*dependence_map; + /* A list of addressable local variables remapped into the caller + when inlining a call within an OpenMP SIMD-on-SIMT loop. */ + vec
Re: [PATCH 4/5] tree-inline: implement SIMT privatization, part 3
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, , _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 (>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 *vars = id->dst_simt_vars; > + auto_vec 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 (, 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
Re: [PATCH 4/5] tree-inline: implement SIMT privatization, part 3
On Thu, 23 Mar 2017, Jakub Jelinek wrote: > > Sorry for missing the IR stability issue. This code relies on dst_simt_vars > > being a set and thus having no duplicate entries (so the implicit lookup > > when > > adding an element is needed). > > > > However, I think I was overly cautious: looking again, I think we can't > > enter > > copy_decl_for_dup_finish twice with the same 'copy' VAR_DECL. Changing it > > to a > > vec should be fine then? > > Yeah, callers of copy_decl* should look the orig var in the decl map first, > plus if you look at all copy_decl_for_dup_finish callers, all of them first > create a new tree (usually copy_node) and then pass it as copy to > copy_decl_for_dup_finish, so you'll never get the same copy in there. > > So, please change it into a vector. Thanks — here's the updated patch. I've also noticed there's no need to rebuild the existing SIMT_ENTER statement if we didn't add any new privatized variables. * 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(-) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6b6d489..a84e569 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4385,6 +4385,11 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) gcall *call_stmt; unsigned int i; unsigned int prop_mask, src_properties; + struct function *dst_cfun; + tree simduid; + use_operand_p use; + gimple *simtenter_stmt = NULL; + vec *simtvars_st = NULL; /* The gimplifier uses input_location in too many places, such as internal_get_tmp_var (). */ @@ -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, , _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); +} + /* If the src function contains an IFN_VA_ARG, then so will the dst function after inlining. Likewise for IFN_GOMP_USE_SIMT. */ prop_mask = PROP_gimple_lva | PROP_gimple_lomp_dev; src_properties = id->src_cfun->curr_properties & prop_mask; if (src_properties != prop_mask) -{ - struct function *dst_cfun = DECL_STRUCT_FUNCTION (id->dst_fn); - dst_cfun->curr_properties &= src_properties | ~prop_mask; -} +dst_cfun->curr_properties &= src_properties | ~prop_mask; gcc_assert (!id->src_cfun->after_inlining); @@ -4730,6 +4746,31 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) if (cfun->gimple_df) pt_solution_reset (>gimple_df->escaped); + /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */ + if (id->dst_simt_vars) +{ + if (id->dst_simt_vars->length () > 0) + { + size_t nargs = gimple_call_num_args (simtenter_stmt); + vec *vars = id->dst_simt_vars; + auto_vec 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 (, g, false); + } + vec_free (id->dst_simt_vars); + id->dst_simt_vars = simtvars_st; +} + /* Clean up. */ if (id->debug_map) { @@ -5453,9 +5494,19 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy) function. */ ; else -/* Ordinary automatic local variables are now in the scope of the - new function. */ -DECL_CONTEXT (copy) = id->dst_fn; +{ + /* Ordinary automatic local variables are now in the scope of the +new function. */ + DECL_CONTEXT (copy) = id->dst_fn; + if (VAR_P (copy) && id->dst_simt_vars && !is_gimple_reg (copy)) + { + if
Re: [PATCH 4/5] tree-inline: implement SIMT privatization, part 3
On Thu, Mar 23, 2017 at 02:13:45PM +0300, Alexander Monakov wrote: > On Thu, 23 Mar 2017, Jakub Jelinek wrote: > > On Wed, Mar 22, 2017 at 06:46:34PM +0300, Alexander Monakov wrote: > > > @@ -4730,6 +4746,25 @@ expand_call_inline (basic_block bb, gimple *stmt, > > > copy_body_data *id) > > >if (cfun->gimple_df) > > > pt_solution_reset (>gimple_df->escaped); > > > > > > + /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */ > > > + if (id->dst_simt_vars) > > > +{ > > > + size_t nargs = gimple_call_num_args (simtenter_stmt); > > > + hash_set *vars = id->dst_simt_vars; > > > + auto_vec newargs (nargs + vars->elements ()); > > > + for (size_t i = 0; i < nargs; i++) > > > + newargs.quick_push (gimple_call_arg (simtenter_stmt, i)); > > > + for (hash_set::iterator i = vars->begin (); i != vars->end > > > (); ++i) > > > + newargs.quick_push (build1 (ADDR_EXPR, > > > + build_pointer_type (TREE_TYPE (*i)), *i)); > > > > Traversing a hash table where the traversal affects code generation is > > -fcompare-debug unfriendly. > > Do you actually need a hash_set and not say just a vec of the vars? I can't > > find where you'd actually do any lookups there, just add and traverse. > > Sorry for missing the IR stability issue. This code relies on dst_simt_vars > being a set and thus having no duplicate entries (so the implicit lookup when > adding an element is needed). > > However, I think I was overly cautious: looking again, I think we can't enter > copy_decl_for_dup_finish twice with the same 'copy' VAR_DECL. Changing it to > a > vec should be fine then? Yeah, callers of copy_decl* should look the orig var in the decl map first, plus if you look at all copy_decl_for_dup_finish callers, all of them first create a new tree (usually copy_node) and then pass it as copy to copy_decl_for_dup_finish, so you'll never get the same copy in there. So, please change it into a vector. Jakub
Re: [PATCH 4/5] tree-inline: implement SIMT privatization, part 3
On Thu, 23 Mar 2017, Jakub Jelinek wrote: > On Wed, Mar 22, 2017 at 06:46:34PM +0300, Alexander Monakov wrote: > > @@ -4730,6 +4746,25 @@ expand_call_inline (basic_block bb, gimple *stmt, > > copy_body_data *id) > >if (cfun->gimple_df) > > pt_solution_reset (>gimple_df->escaped); > > > > + /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */ > > + if (id->dst_simt_vars) > > +{ > > + size_t nargs = gimple_call_num_args (simtenter_stmt); > > + hash_set *vars = id->dst_simt_vars; > > + auto_vec newargs (nargs + vars->elements ()); > > + for (size_t i = 0; i < nargs; i++) > > + newargs.quick_push (gimple_call_arg (simtenter_stmt, i)); > > + for (hash_set::iterator i = vars->begin (); i != vars->end (); > > ++i) > > + newargs.quick_push (build1 (ADDR_EXPR, > > + build_pointer_type (TREE_TYPE (*i)), *i)); > > Traversing a hash table where the traversal affects code generation is > -fcompare-debug unfriendly. > Do you actually need a hash_set and not say just a vec of the vars? I can't > find where you'd actually do any lookups there, just add and traverse. Sorry for missing the IR stability issue. This code relies on dst_simt_vars being a set and thus having no duplicate entries (so the implicit lookup when adding an element is needed). However, I think I was overly cautious: looking again, I think we can't enter copy_decl_for_dup_finish twice with the same 'copy' VAR_DECL. Changing it to a vec should be fine then? Thanks. Alexander
Re: [PATCH 4/5] tree-inline: implement SIMT privatization, part 3
On Wed, Mar 22, 2017 at 06:46:34PM +0300, Alexander Monakov wrote: > @@ -4730,6 +4746,25 @@ expand_call_inline (basic_block bb, gimple *stmt, > copy_body_data *id) >if (cfun->gimple_df) > pt_solution_reset (>gimple_df->escaped); > > + /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */ > + if (id->dst_simt_vars) > +{ > + size_t nargs = gimple_call_num_args (simtenter_stmt); > + hash_set *vars = id->dst_simt_vars; > + auto_vec newargs (nargs + vars->elements ()); > + for (size_t i = 0; i < nargs; i++) > + newargs.quick_push (gimple_call_arg (simtenter_stmt, i)); > + for (hash_set::iterator i = vars->begin (); i != vars->end (); > ++i) > + newargs.quick_push (build1 (ADDR_EXPR, > + build_pointer_type (TREE_TYPE (*i)), *i)); Traversing a hash table where the traversal affects code generation is -fcompare-debug unfriendly. Do you actually need a hash_set and not say just a vec of the vars? I can't find where you'd actually do any lookups there, just add and traverse. Jakub
[PATCH 4/5] tree-inline: implement SIMT privatization, part 3
This patch implements privatization for SIMT during inlining. We need to discover if the call being inlined belongs to a SIMT region (by looking at simduid of the containing loop), and if so, treat them similar to OpenMP-SIMD privatization: add the "omp simt private" attribute and mention them among arguments of GOMP_SIMT_ENTER. OpenMP-SIMD privatization also adds a clobber at the end of the region; I'm not sure if it's required here: in the example I've looked at, inlined code already contained a clobber. * 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 | 59 --- gcc/tree-inline.h | 4 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6b6d489..56817e4 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4385,6 +4385,11 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) gcall *call_stmt; unsigned int i; unsigned int prop_mask, src_properties; + struct function *dst_cfun; + tree simduid; + use_operand_p use; + gimple *simtenter_stmt = NULL; + hash_set *simtvars_st = NULL; /* The gimplifier uses input_location in too many places, such as internal_get_tmp_var (). */ @@ -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, , _stmt) + && is_gimple_call (simtenter_stmt) + && gimple_call_internal_p (simtenter_stmt, IFN_GOMP_SIMT_ENTER)) +{ + simtvars_st = id->dst_simt_vars; + id->dst_simt_vars = new hash_set; +} + /* If the src function contains an IFN_VA_ARG, then so will the dst function after inlining. Likewise for IFN_GOMP_USE_SIMT. */ prop_mask = PROP_gimple_lva | PROP_gimple_lomp_dev; src_properties = id->src_cfun->curr_properties & prop_mask; if (src_properties != prop_mask) -{ - struct function *dst_cfun = DECL_STRUCT_FUNCTION (id->dst_fn); - dst_cfun->curr_properties &= src_properties | ~prop_mask; -} +dst_cfun->curr_properties &= src_properties | ~prop_mask; gcc_assert (!id->src_cfun->after_inlining); @@ -4730,6 +4746,25 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) if (cfun->gimple_df) pt_solution_reset (>gimple_df->escaped); + /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */ + if (id->dst_simt_vars) +{ + size_t nargs = gimple_call_num_args (simtenter_stmt); + hash_set *vars = id->dst_simt_vars; + auto_vec newargs (nargs + vars->elements ()); + for (size_t i = 0; i < nargs; i++) + newargs.quick_push (gimple_call_arg (simtenter_stmt, i)); + for (hash_set::iterator i = vars->begin (); i != vars->end (); ++i) + newargs.quick_push (build1 (ADDR_EXPR, + build_pointer_type (TREE_TYPE (*i)), *i)); + 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 (, g, false); + delete id->dst_simt_vars; + id->dst_simt_vars = simtvars_st; +} + /* Clean up. */ if (id->debug_map) { @@ -5453,9 +5488,19 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy) function. */ ; else -/* Ordinary automatic local variables are now in the scope of the - new function. */ -DECL_CONTEXT (copy) = id->dst_fn; +{ + /* Ordinary automatic local variables are now in the scope of the +new function. */ + DECL_CONTEXT (copy) = id->dst_fn; + if (VAR_P (copy) && id->dst_simt_vars && !is_gimple_reg (copy)) + { + if (!lookup_attribute ("omp simt private", DECL_ATTRIBUTES (copy))) + DECL_ATTRIBUTES (copy) + = tree_cons (get_identifier ("omp simt private"), NULL, + DECL_ATTRIBUTES (copy)); + id->dst_simt_vars->add (copy); + } +} return copy; } diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h index 88b3286..cf46fa5 100644 --- a/gcc/tree-inline.h +++ b/gcc/tree-inline.h @@ -145,6 +145,10 @@ struct copy_body_data equivalents in the function into which it is being inlined. */ hash_map