This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Avoid an unwanted decl re-map in copy_gimple_seq_and_replace_locals
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>, Jan Hubicka <hubicka at ucw dot cz>
- Date: Mon, 11 Jan 2016 09:41:31 +0100
- Subject: Re: [patch] Avoid an unwanted decl re-map in copy_gimple_seq_and_replace_locals
- Authentication-results: sourceware.org; auth=none
- References: <20160108145901 dot GD3982 at virgil dot suse dot cz>
On Fri, Jan 8, 2016 at 3:59 PM, Martin Jambor <mjambor@suse.cz> wrote:
> Hi,
>
> I ran into an ICE when compiling the following function on the HSA branch:
>
> foo (int n, int m, int o, int (*a)[m][o])
> {
> int i, j, k;
> #pragma omp target teams distribute parallel for shared(a) firstprivate(n, m, o) private(i,j,k)
> for (i = 0; i < n; i++)
> for (j = 0; j < m; j++)
> for (k = 0; k < o; k++)
> a[i][j][k] = i + j + k;
> }
>
> The problem is that when I duplicate the loop with
> copy_gimple_seq_and_replace_locals, I get one extra re-mapping.
> Specifically, I feed the function this:
>
> {
> int i.2;
>
> #pragma omp teams shared(a) firstprivate(n) firstprivate(m) firstprivate(o) shared(m.1) shared(D.3275) shared(o.0)
> {
> #pragma omp distribute private(i.2)
> for (i.2 = 0; i.2 < n; i.2 = i.2 + 1)
> {
> #pragma omp parallel shared(a) firstprivate(n) firstprivate(m) firstprivate(o) private(i) private(j) private(k) shared(m.1) shared(D.3275) shared(o.0)
> {
> sizetype D.3286;
> long unsigned int D.3287;
> sizetype D.3288;
> sizetype D.3289;
> sizetype D.3290;
> long unsigned int D.3291;
> long unsigned int D.3292;
> int[0:D.3279][0:D.3271] * D.3293;
> int D.3294;
> int D.3295;
>
> #pragma omp for nowait
> for (i = 0; i < n; i = i + 1)
> {
> j = 0;
> goto <D.3244>;
> <D.3243>:
> k = 0;
> goto <D.3241>;
> <D.3240>:
> D.3286 = D.3275 /[ex] 4; <--- here I get wrog decl
> D.3287 = (long unsigned int) i;
> D.3288 = (sizetype) o.0;
> D.3289 = (sizetype) m.1;
> D.3290 = D.3288 * D.3289;
> D.3291 = D.3287 * D.3290;
> D.3292 = D.3291 * 4;
> D.3293 = a + D.3292;
> D.3294 = i + j;
> D.3295 = D.3294 + k;
> *D.3293[j]{lb: 0 sz: D.3286 * 4}[k] = D.3295;
> k = k + 1;
> <D.3241>:
> if (k < o) goto <D.3240>; else goto <D.3242>;
> <D.3242>:
> j = j + 1;
> <D.3244>:
> if (j < m) goto <D.3243>; else goto <D.3245>;
> <D.3245>:
> }
> }
> }
> }
> }
>
> and it replaces D.3275 with its new copy with undefined value. The
> mapping is created when an array type where the size is defined in
> terms of that variable declaration is copied. The comment in
> type-remapping code says that we "use the already remaped data" but
> that is not true.
>
> My solution was to prevent declaration duplication in this case with
> yet another state variable in struct copy_body_data that holds a
> special value when we are running copy_gimple_seq_and_replace_locals
> and another when we are within type-remapping.
>
> I'll be happy for any suggestion how to deal with this without
> cluttering copy_body_date even more but so far I have not found any.
> If nobody has a better idea, is the following good for trunk? (I am
> about to commit it to the hsa branch.) It has passed bootstrap and
> testing on x86_64-linux.
Hum. Can't you check id->remapping_type_depth? That said, how do
we end up recursing into remap_decl when copying the variable length
decl/type? Can't we avoid the recursion (basically avoid remapping
variable-size types at all?)
Richard.
> Thanks,
>
> Martin
>
>
> 2016-01-06 Martin Jambor <mjambor@suse.cz>
>
> * tree-inline.h (copy_body_data): New field
> decl_creation_prevention_level. Moved remap_var_for_cilk to minimize
> padding.
> * tree-inline.c (remap_decl): Return original decls if
> decl_creation_prevention_level is two or bigger.
> (remap_type_1): Increment and decrement decl_creation_prevention_level
> if appropriate.
> (copy_gimple_seq_and_replace_locals): Set
> decl_creation_prevention_level to 1.
>
> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
> index 88a6753..2df11a2 100644
> --- a/gcc/tree-inline.c
> +++ b/gcc/tree-inline.c
> @@ -340,8 +340,20 @@ remap_decl (tree decl, copy_body_data *id)
> return decl;
> }
>
> - /* If we didn't already have an equivalent for this declaration,
> - create one now. */
> + /* If decl copying is forbidden (which happens when copying a type with size
> + defined outside of the copied sequence) work with the original decl. */
> + if (!n
> + && id->decl_creation_prevention_level > 1
> + && (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL))
> + {
> + if (id->do_not_unshare)
> + return decl;
> + else
> + return unshare_expr (decl);
> + }
> +
> + /* If we didn't already have an equivalent for this declaration, create one
> + now. */
> if (!n)
> {
> /* Make a copy of the variable or label. */
> @@ -526,7 +538,10 @@ remap_type_1 (tree type, copy_body_data *id)
> gcc_unreachable ();
> }
>
> - /* All variants of type share the same size, so use the already remaped data. */
> + /* All variants of type share the same size, so use the already remaped
> + data. */
> + if (id->decl_creation_prevention_level > 0)
> + id->decl_creation_prevention_level++;
> if (TYPE_MAIN_VARIANT (new_tree) != new_tree)
> {
> gcc_checking_assert (TYPE_SIZE (type) == TYPE_SIZE (TYPE_MAIN_VARIANT (type)));
> @@ -540,6 +555,8 @@ remap_type_1 (tree type, copy_body_data *id)
> walk_tree (&TYPE_SIZE (new_tree), copy_tree_body_r, id, NULL);
> walk_tree (&TYPE_SIZE_UNIT (new_tree), copy_tree_body_r, id, NULL);
> }
> + if (id->decl_creation_prevention_level > 1)
> + id->decl_creation_prevention_level--;
>
> return new_tree;
> }
> @@ -5276,6 +5293,7 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
> id.transform_return_to_modify = false;
> id.transform_parameter = false;
> id.transform_lang_insert_block = NULL;
> + id.decl_creation_prevention_level = 1;
>
> /* Walk the tree once to find local labels. */
> memset (&wi, 0, sizeof (wi));
> diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
> index b8fb2a2..f737daf 100644
> --- a/gcc/tree-inline.h
> +++ b/gcc/tree-inline.h
> @@ -140,14 +140,21 @@ struct copy_body_data
> the originals have been mapped to a value rather than to a
> variable. */
> hash_map<tree, tree> *debug_map;
> -
> - /* Cilk keywords currently need to replace some variables that
> - ordinary nested functions do not. */
> - bool remap_var_for_cilk;
>
> /* A map from the inlined functions dependence info cliques to
> equivalents in the function into which it is being inlined. */
> hash_map<dependence_hash, unsigned short> *dependence_map;
> +
> + /* Cilk keywords currently need to replace some variables that
> + ordinary nested functions do not. */
> + bool remap_var_for_cilk;
> +
> + /* When zero, do nothing. When one or higher, increment during type
> + remapping, When two or higher, do not create new variables when remapping
> + decls. Used when remapping types with variable size, but when the size is
> + defined outside the sequence copied by
> + copy_gimple_seq_and_replace_locals. */
> + unsigned decl_creation_prevention_level;
> };
>
> /* Weights of constructions for estimate_num_insns. */