This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR32921, prune virtual operands of memory accesses based on TBAA


On 10/18/07, Richard Guenther <rguenther@suse.de> wrote:
> On Thu, 18 Oct 2007, Richard Guenther wrote:
>
> >
> > Now, I was totally suprised to see that while we prune virtual operands
> > (in the case of PR32921 a bunch of SFTs) based on the offset of the access
> > but not based on TBAA.  Duh.  Fixed with the following patch that will
> > do so for all alias symbols (apart from MPTs, those would need more
> > special treatment).  I also took the liberty to re-shuffle things a bit
> > in access_can_touch_variable.
> >
> > Maybe I'm missing something obvious here, but a slightly less invasive
> > patch (just pruning SFTs) bootstrapped & tested fine.
> >
> > This patch is currently bootstrapping and testing on
> > x86_64-unknown-linux-gnu for all languages including Ada.
> >
> > Danny?  Am I just crazy this day?
>
> Of course things are never that easy.  As for now we only miscompiled
> the fortran frontend I at least found a new alias stressing testcase ;)
> (HEAP variables do not have a type meaningful for TBAA)
>
> I expect maybe similar fallout for NMTs, but I'm sure SMTs and SFTs
> are correct in this respect.
>
> So the following is bootstrapping & testing now.
This looks fine to me.

Yes, HEAP vars have no real type, and can't be pruned.
NMT's should always be the correct type.

>
> Richard.
>
> 2007-10-18  Richard Guenther  <rguenther@suse.de>
>
>         PR middle-end/32921
>         * tree-ssa-operands.c (access_can_touch_variable): Aliases
>         with non-conflicting alias sets with the reference do not
>         touch the access.  Re-structure function a bit.
>
>         * gfortran.dg/pr32921.f: New testcase.
>         * gcc.c-torture/execute/20071018-1.c: Likewise.
>
> Index: testsuite/gfortran.dg/pr32921.f
> ===================================================================
> --- testsuite/gfortran.dg/pr32921.f     (revision 0)
> +++ testsuite/gfortran.dg/pr32921.f     (revision 0)
> @@ -0,0 +1,49 @@
> +! { dg-do compile }
> +! { dg-options "-O2 -fdump-tree-lim" }
> +! gfortran -c -m32 -O2 -S junk.f
> +!
> +      MODULE LES3D_DATA
> +
> +      IMPLICIT REAL*8 (A-H,O-Z)
> +
> +      PARAMETER ( NSPECI = 1, ND = 7 + NSPECI )
> +
> +      INTEGER IMAX
> +
> +      DOUBLE PRECISION,ALLOCATABLE,DIMENSION(:,:,:) ::
> +     >         UAV,QAV
> +
> +
> +      END MODULE LES3D_DATA
> +!---------------------------------------------------------------------
> +!------------------------------------------------------------------------
> +      SUBROUTINE FLUXI()
> +
> +      USE LES3D_DATA
> +      IMPLICIT REAL*8(A-H,O-Z)
> +
> +      ALLOCATABLE QS(:)
> +
> +      ALLOCATE( QS(0:IMAX))
> +      QS=0D0
> +
> +      RETURN
> +      END
> +!------------------------------------------------------------------------
> +!------------------------------------------------------------------------
> +      SUBROUTINE EXTRAPI()
> +
> +      USE LES3D_DATA
> +      IMPLICIT REAL*8(A-H,O-Z)
> +
> +      I1 = 0
> +      I2 = IMAX - 1
> +
> +            DO I = I1, I2
> +               UAV(I,1,2) = QAV(I,1,2)
> +            END DO
> +
> +      RETURN
> +      END
> +! { dg-final { scan-tree-dump-times "stride" 6 "lim" } }
> +! { dg-final { cleanup-tree-dump "lim" } }
> Index: tree-ssa-operands.c
> ===================================================================
> *** tree-ssa-operands.c (revision 129439)
> --- tree-ssa-operands.c (working copy)
> *************** access_can_touch_variable (tree ref, tre
> *** 1198,1204 ****
>   {
>     bool offsetgtz = offset > 0;
>     unsigned HOST_WIDE_INT uoffset = (unsigned HOST_WIDE_INT) offset;
> !   tree base = ref ? get_base_address (ref) : NULL;
>
>     /* If ALIAS is .GLOBAL_VAR then the memory reference REF must be
>        using a call-clobbered memory tag.  By definition, call-clobbered
> --- 1198,1208 ----
>   {
>     bool offsetgtz = offset > 0;
>     unsigned HOST_WIDE_INT uoffset = (unsigned HOST_WIDE_INT) offset;
> !   tree base;
> !
> !   /* For NULL refs we cannot prune based on the unknown access.  */
> !   if (!ref)
> !     return true;
>
>     /* If ALIAS is .GLOBAL_VAR then the memory reference REF must be
>        using a call-clobbered memory tag.  By definition, call-clobbered
> *************** access_can_touch_variable (tree ref, tre
> *** 1206,1216 ****
>     if (alias == gimple_global_var (cfun))
>       return true;
>
>     /* If ref is a TARGET_MEM_REF, just return true, as we can't really
> !      disambiguate them right now.  */
> !   if (ref && TREE_CODE (ref) == TARGET_MEM_REF)
>       return true;
> !
>     /* If ALIAS is an SFT, it can't be touched if the offset
>        and size of the access is not overlapping with the SFT offset and
>        size.  This is only true if we are accessing through a pointer
> --- 1210,1247 ----
>     if (alias == gimple_global_var (cfun))
>       return true;
>
> +   /* If the alias sets of the single primitive type in an alias does
> +      not conflict with that of the memory reference then the access does
> +      not touch the alias.  Both MPTs and HEAP vars we cannot handle here.  */
> +   if (flag_strict_aliasing
> +       && TREE_CODE (alias) != MEMORY_PARTITION_TAG
> +       && !var_ann (alias)->is_heapvar
> +       && !AGGREGATE_TYPE_P (TREE_TYPE (ref))
> +       && !AGGREGATE_TYPE_P (TREE_TYPE (alias)))
> +     {
> +       tree alias_type = TREE_TYPE (alias);
> +       tree ref_type = TREE_TYPE (ref);
> +
> +       if (TREE_CODE (alias_type) == COMPLEX_TYPE
> +         || TREE_CODE (alias_type) == VECTOR_TYPE)
> +       alias_type = TREE_TYPE (alias_type);
> +
> +       if (TREE_CODE (ref_type) == COMPLEX_TYPE
> +         || TREE_CODE (ref_type) == VECTOR_TYPE)
> +       ref_type = TREE_TYPE (ref_type);
> +
> +       if (!alias_sets_conflict_p (get_alias_set (alias_type),
> +                                 get_alias_set (ref_type)))
> +       return false;
> +     }
> +
>     /* If ref is a TARGET_MEM_REF, just return true, as we can't really
> !      disambiguate them based on offsets right now.  */
> !   if (TREE_CODE (ref) == TARGET_MEM_REF)
>       return true;
> !
> !   base = get_base_address (ref);
> !
>     /* If ALIAS is an SFT, it can't be touched if the offset
>        and size of the access is not overlapping with the SFT offset and
>        size.  This is only true if we are accessing through a pointer
> *************** access_can_touch_variable (tree ref, tre
> *** 1309,1316 ****
>        my_char_ref_1 = (char[1:1] &) &my_char;
>        D.874_2 = (*my_char_ref_1)[1]{lb: 1 sz: 1};
>     */
> !   else if (ref
> !          && flag_strict_aliasing
>            && TREE_CODE (ref) != INDIRECT_REF
>            && !MTAG_P (alias)
>            && base
> --- 1340,1346 ----
>        my_char_ref_1 = (char[1:1] &) &my_char;
>        D.874_2 = (*my_char_ref_1)[1]{lb: 1 sz: 1};
>     */
> !   else if (flag_strict_aliasing
>            && TREE_CODE (ref) != INDIRECT_REF
>            && !MTAG_P (alias)
>            && base
> *************** access_can_touch_variable (tree ref, tre
> *** 1344,1351 ****
>     /* If the offset of the access is greater than the size of one of
>        the possible aliases, it can't be touching that alias, because it
>        would be past the end of the structure.  */
> !   else if (ref
> !          && flag_strict_aliasing
>            && TREE_CODE (ref) != INDIRECT_REF
>            && !MTAG_P (alias)
>            && !POINTER_TYPE_P (TREE_TYPE (alias))
> --- 1374,1380 ----
>     /* If the offset of the access is greater than the size of one of
>        the possible aliases, it can't be touching that alias, because it
>        would be past the end of the structure.  */
> !   else if (flag_strict_aliasing
>            && TREE_CODE (ref) != INDIRECT_REF
>            && !MTAG_P (alias)
>            && !POINTER_TYPE_P (TREE_TYPE (alias))
> Index: testsuite/gcc.c-torture/execute/20071018-1.c
> ===================================================================
> *** testsuite/gcc.c-torture/execute/20071018-1.c        (revision 0)
> --- testsuite/gcc.c-torture/execute/20071018-1.c        (revision 0)
> ***************
> *** 0 ****
> --- 1,31 ----
> + extern void abort(void);
> +
> + struct foo {
> +   int rank;
> +   char *name;
> + };
> +
> + struct mem {
> +   struct foo *x[4];
> + };
> +
> + void __attribute__((noinline)) bar(struct foo **f)
> + {
> +   *f = __builtin_malloc(sizeof(struct foo));
> + }
> + struct foo * foo(int rank)
> + {
> +   void *x = __builtin_malloc(sizeof(struct mem));
> +   struct mem *as = x;
> +   struct foo **upper = &as->x[rank * 8 - 1];
> +   *upper = 0;
> +   bar(upper);
> +   return *upper;
> + }
> +
> + int main()
> + {
> +   if (foo(0) == 0)
> +     abort ();
> +   return 0;
> + }
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]