On Fri, 12 Apr 2019, Richard Biener wrote:

> On Fri, 12 Apr 2019, Michael Matz wrote:
> 
> > Hi,
> > 
> > On Fri, 12 Apr 2019, Richard Biener wrote:
> > 
> > > > You miss PARM_DECLs and RESULT_DECLs, i.e. it's probably better to 
> > > > factor 
> > > > out tree.c:auto_var_in_fn_p and place the new auto_var_p in tree.c as 
> > > > well.
> > > 
> > > Hmm, I left the above unchanged from a different variant of the patch
> > > where for some reason I do not remember I explicitely decided
> > > parameters and results are not affected...
> > 
> > Even if that were the case the function is sufficiently general (also its 
> > name) that it should be generic infrastructure, not hidden away in 
> > structalias.
> 
> It was not fully equivalent, but yes.  So - like the following?
> I think checking DECL_CONTEXT isn't necessary given the 
> !DECL_EXTERNAL/STATIC checks.
> 
> Bootstrap / regtest running on x86_64-unknown-linux-gnu.

Aww, hits

/space/rguenther/src/svn/trunk/libgomp/testsuite/libgomp.oacc-c/../libgomp.oacc-c-c++-common/zero_length_subarrays.c:33:1:
 
internal compiler error: in fold_builtin_alloca_with_align, at 
tree-ssa-ccp.c:2186^M
0x6d7e45 fold_builtin_alloca_with_align^M

have to look/think about this.

Richard.

> Richard.
> 
> 2019-04-12  Richard Biener  <rguent...@suse.de>
> 
>       PR ipa/88936
>       * tree.h (auto_var_p): Declare.
>       * tree.c (auto_var_p): New function, split out from ...
>       (auto_var_in_fn_p): ... here.
>       * tree-ssa-structalias.c (struct variable_info): Add shadow_var_uid
>       member.
>       (new_var_info): Initialize it.
>       (set_uids_in_ptset): Also set the shadow variable uid if required.
>       (ipa_pta_execute): Postprocess points-to solutions assigning
>       shadow variable uids for locals that may reach their containing
>       function recursively.
> 
>       * gcc.dg/torture/pr88936-1.c: New testcase.
>       * gcc.dg/torture/pr88936-2.c: Likewise.
>       * gcc.dg/torture/pr88936-3.c: Likewise.
> 
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c        (revision 270306)
> +++ gcc/tree.c        (working copy)
> @@ -9268,17 +9268,25 @@ get_type_static_bounds (const_tree type,
>      }
>  }
>  
> +/* Return true if VAR is an automatic variable.  */
> +
> +bool
> +auto_var_p (const_tree var)
> +{
> +  return ((((VAR_P (var) && ! DECL_EXTERNAL (var))
> +         || TREE_CODE (var) == PARM_DECL)
> +        && ! TREE_STATIC (var))
> +       || TREE_CODE (var) == RESULT_DECL);
> +}
> +
>  /* Return true if VAR is an automatic variable defined in function FN.  */
>  
>  bool
>  auto_var_in_fn_p (const_tree var, const_tree fn)
>  {
>    return (DECL_P (var) && DECL_CONTEXT (var) == fn
> -       && ((((VAR_P (var) && ! DECL_EXTERNAL (var))
> -             || TREE_CODE (var) == PARM_DECL)
> -            && ! TREE_STATIC (var))
> -           || TREE_CODE (var) == LABEL_DECL
> -           || TREE_CODE (var) == RESULT_DECL));
> +       && (auto_var_p (var)
> +           || TREE_CODE (var) == LABEL_DECL));
>  }
>  
>  /* Subprogram of following function.  Called by walk_tree.
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h        (revision 270306)
> +++ gcc/tree.h        (working copy)
> @@ -4893,6 +4893,7 @@ extern bool stdarg_p (const_tree);
>  extern bool prototype_p (const_tree);
>  extern bool is_typedef_decl (const_tree x);
>  extern bool typedef_variant_p (const_tree);
> +extern bool auto_var_p (const_tree);
>  extern bool auto_var_in_fn_p (const_tree, const_tree);
>  extern tree build_low_bits_mask (tree, unsigned);
>  extern bool tree_nop_conversion_p (const_tree, const_tree);
> Index: gcc/tree-ssa-structalias.c
> ===================================================================
> --- gcc/tree-ssa-structalias.c        (revision 270306)
> +++ gcc/tree-ssa-structalias.c        (working copy)
> @@ -299,6 +299,11 @@ struct variable_info
>    /* Full size of the base variable, in bits.  */
>    unsigned HOST_WIDE_INT fullsize;
>  
> +  /* In IPA mode the shadow UID in case the variable needs to be duplicated 
> in
> +     the final points-to solution because it reaches its containing
> +     function recursively.  Zero if none is needed.  */
> +  unsigned int shadow_var_uid;
> +
>    /* Name of this variable */
>    const char *name;
>  
> @@ -397,6 +402,7 @@ new_var_info (tree t, const char *name,
>    ret->solution = BITMAP_ALLOC (&pta_obstack);
>    ret->oldsolution = NULL;
>    ret->next = 0;
> +  ret->shadow_var_uid = 0;
>    ret->head = ret->id;
>  
>    stats.total_vars++;
> @@ -6452,6 +6458,16 @@ set_uids_in_ptset (bitmap into, bitmap f
>             && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl))
>             && ! decl_binds_to_current_def_p (vi->decl))
>           pt->vars_contains_interposable = true;
> +
> +       /* If this is a local variable we can have overlapping lifetime
> +          of different function invocations through recursion duplicate
> +          it with its shadow variable.  */
> +       if (in_ipa_mode
> +           && vi->shadow_var_uid != 0)
> +         {
> +           bitmap_set_bit (into, vi->shadow_var_uid);
> +           pt->vars_contains_nonlocal = true;
> +         }
>       }
>  
>        else if (TREE_CODE (vi->decl) == FUNCTION_DECL
> @@ -8076,6 +8095,62 @@ ipa_pta_execute (void)
>    /* From the constraints compute the points-to sets.  */
>    solve_constraints ();
>  
> +  /* Now post-process solutions to handle locals from different
> +     runtime instantiations coming in through recursive invocations.  */
> +  unsigned shadow_var_cnt = 0;
> +  for (unsigned i = 1; i < varmap.length (); ++i)
> +    {
> +      varinfo_t fi = get_varinfo (i);
> +      if (fi->is_fn_info
> +       && fi->decl)
> +     /* Automatic variables pointed to by their containing functions
> +        parameters need this treatment.  */
> +     for (varinfo_t ai = first_vi_for_offset (fi, fi_parm_base);
> +          ai; ai = vi_next (ai))
> +       {
> +         varinfo_t vi = get_varinfo (find (ai->id));
> +         bitmap_iterator bi;
> +         unsigned j;
> +         EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
> +           {
> +             varinfo_t pt = get_varinfo (j);
> +             if (pt->shadow_var_uid == 0
> +                 && pt->decl
> +                 && auto_var_in_fn_p (pt->decl, fi->decl))
> +               {
> +                 pt->shadow_var_uid = allocate_decl_uid ();
> +                 shadow_var_cnt++;
> +               }
> +           }
> +       }
> +      /* As well as global variables which are another way of passing
> +         arguments to recursive invocations.  */
> +      else if (fi->is_global_var)
> +     {
> +       for (varinfo_t ai = fi; ai; ai = vi_next (ai))
> +         {
> +           varinfo_t vi = get_varinfo (find (ai->id));
> +           bitmap_iterator bi;
> +           unsigned j;
> +           EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
> +             {
> +               varinfo_t pt = get_varinfo (j);
> +               if (pt->shadow_var_uid == 0
> +                   && pt->decl
> +                   && auto_var_p (pt->decl))
> +                 {
> +                   pt->shadow_var_uid = allocate_decl_uid ();
> +                   shadow_var_cnt++;
> +                 }
> +             }
> +         }
> +     }
> +    }
> +  if (shadow_var_cnt && dump_file && (dump_flags & TDF_DETAILS))
> +    fprintf (dump_file, "Allocated %u shadow variables for locals "
> +          "maybe leaking into recursive invocations of their containing "
> +          "functions\n", shadow_var_cnt);
> +
>    /* Compute the global points-to sets for ESCAPED.
>       ???  Note that the computed escape set is not correct
>       for the whole unit as we fail to consider graph edges to
> Index: gcc/testsuite/gcc.dg/torture/pr88936-1.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/pr88936-1.c  (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/pr88936-1.c  (working copy)
> @@ -0,0 +1,27 @@
> +/* { dg-do run } */
> +/* { dg-additional-options "-fipa-pta" } */
> +
> +static long bug (long depth, long * v)
> +{
> +  if (depth == 0)
> +    {
> +      *v = 0;
> +      return 1;
> +    }
> +
> +  long r = 1;
> +  long val = bug(depth - 1, &r);
> +  return 2 * r + val;
> +}
> +
> +static long ff (long depth)
> +{
> +  return bug(depth, (long*)0);
> +}
> +
> +int main()
> +{
> +  if (ff(1) != 1)
> +    __builtin_abort ();
> +  return 0;
> +}
> Index: gcc/testsuite/gcc.dg/torture/pr88936-2.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/pr88936-2.c  (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/pr88936-2.c  (working copy)
> @@ -0,0 +1,22 @@
> +/* { dg-do run } */
> +/* { dg-additional-options "-fipa-pta" } */
> +
> +static int *p;
> +void bar(int cnt)
> +{
> +  int i = 0;
> +  if (cnt == 0)
> +    {
> +      p = &i;
> +      bar (1);
> +      if (i != 1)
> +     __builtin_abort ();
> +    }
> +  else if (cnt == 1)
> +    *p = 1;
> +}
> +int main()
> +{
> +  bar (0);
> +  return 0;
> +}
> Index: gcc/testsuite/gcc.dg/torture/pr88936-3.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/pr88936-3.c  (nonexistent)
> +++ gcc/testsuite/gcc.dg/torture/pr88936-3.c  (working copy)
> @@ -0,0 +1,21 @@
> +/* { dg-do run } */
> +/* { dg-additional-options "-fipa-pta" } */
> +
> +static int *p;
> +void bar(int cnt)
> +{
> +  if (cnt == 0)
> +    {
> +      p = &cnt;
> +      bar (1);
> +      if (cnt != 1)
> +     __builtin_abort ();
> +    }
> +  else if (cnt == 1)
> +    *p = 1;
> +}
> +int main()
> +{
> +  bar (0);
> +  return 0;
> +}
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)

Reply via email to