This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFA][PATCH] Minor fix to aliasing machinery
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Marc Glisse <marc dot glisse at inria dot fr>
- Cc: Jeff Law <law at redhat dot com>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 6 Nov 2013 15:34:00 +0100
- Subject: Re: [RFA][PATCH] Minor fix to aliasing machinery
- Authentication-results: sourceware.org; auth=none
- References: <52702A5D dot 6030101 at redhat dot com> <alpine dot DEB dot 2 dot 10 dot 1310292254130 dot 4124 at laptop-mg dot saclay dot inria dot fr> <CAFiYyc1KVe0y0n2CwAwdV0hKG-RpPKXEE73gcanmP4mjGpxCYg at mail dot gmail dot com> <alpine dot DEB dot 2 dot 02 dot 1310301703210 dot 3709 at stedding dot saclay dot inria dot fr> <alpine dot DEB dot 2 dot 02 dot 1311061308080 dot 20046 at stedding dot saclay dot inria dot fr> <CAFiYyc3Sa+ej51m2GrNVVcVjh1B3XskS=boo3fKamdG8odXyiA at mail dot gmail dot com> <alpine dot DEB dot 2 dot 10 dot 1311061455590 dot 16233 at stedding dot saclay dot inria dot fr>
On Wed, Nov 6, 2013 at 3:08 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Wed, 6 Nov 2013, Richard Biener wrote:
>
>> On Wed, Nov 6, 2013 at 1:19 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>>>
>>> [Discussion started in
>>> http://gcc.gnu.org/ml/gcc-patches/2013-10/msg02472.html ]
>>>
>>>
>>> On Wed, 30 Oct 2013, Marc Glisse wrote:
>>>
>>>> On Wed, 30 Oct 2013, Richard Biener wrote:
>>>>
>>>>> Btw, get_addr_base_and_unit_offset may also return an offsetted
>>>>> MEM_REF (from &MEM [p_3, 17] for example). As we are interested in
>>>>> pointers this could be handled by not requiring a memory reference
>>>>> but extracting the base address and offset, covering more cases.
>>>>
>>>>
>>>>
>>>> I tried the attached patch, and it almost worked, except for one fortran
>>>> testcase (widechar_intrinsics_10.f90):
>>>
>>>
>>>
>>> Now that ao_ref_init_from_ptr_and_size has been fixed, the following
>>> patch
>>> passes bootstrap+testsuite (default languages) on
>>> x86_64-unknown-linux-gnu.
>>>
>>> 2013-11-06 Marc Glisse <marc.glisse@inria.fr>
>>> Jeff Law <law@redhat.com>
>>>
>>> gcc/
>>> * tree-ssa-alias.c (stmt_kills_ref_p_1): Use
>>> ao_ref_init_from_ptr_and_size for builtins.
>>>
>>> gcc/testsuite/
>>> * gcc.dg/tree-ssa/alias-27.c: New testcase.
>>>
>>> --
>>> Marc Glisse
>>> Index: gcc/testsuite/gcc.dg/tree-ssa/alias-27.c
>>> ===================================================================
>>> --- gcc/testsuite/gcc.dg/tree-ssa/alias-27.c (revision 0)
>>> +++ gcc/testsuite/gcc.dg/tree-ssa/alias-27.c (working copy)
>>> @@ -0,0 +1,11 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-O1 -fdump-tree-optimized" } */
>>> +
>>> +void f (long *p) {
>>> + *p = 42;
>>> + p[4] = 42;
>>> + __builtin_memset (p, 0, 100);
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-not "= 42" "optimized" } } */
>>> +/* { dg-final { cleanup-tree-dump "optimized" } } */
>>>
>>> Property changes on: gcc/testsuite/gcc.dg/tree-ssa/alias-27.c
>>> ___________________________________________________________________
>>> Added: svn:keywords
>>> ## -0,0 +1 ##
>>> +Author Date Id Revision URL
>>> \ No newline at end of property
>>> Added: svn:eol-style
>>> ## -0,0 +1 ##
>>> +native
>>> \ No newline at end of property
>>> Index: gcc/tree-ssa-alias.c
>>> ===================================================================
>>> --- gcc/tree-ssa-alias.c (revision 204453)
>>> +++ gcc/tree-ssa-alias.c (working copy)
>>> @@ -2001,23 +2001,24 @@ stmt_may_clobber_ref_p (gimple stmt, tre
>>> return stmt_may_clobber_ref_p_1 (stmt, &r);
>>> }
>>>
>>> /* If STMT kills the memory reference REF return true, otherwise
>>> return false. */
>>>
>>> static bool
>>> stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
>>> {
>>> /* For a must-alias check we need to be able to constrain
>>> - the access properly. */
>>> - ao_ref_base (ref);
>>> - if (ref->max_size == -1)
>>> + the access properly.
>>> + FIXME: except for BUILTIN_FREE. */
>>> + if (!ao_ref_base (ref)
>>> + || ref->max_size == -1)
>>> return false;
>>>
>>> if (gimple_has_lhs (stmt)
>>> && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME
>>> /* The assignment is not necessarily carried out if it can throw
>>> and we can catch it in the current function where we could
>>> inspect
>>> the previous value.
>>> ??? We only need to care about the RHS throwing. For aggregate
>>> assignments or similar calls and non-call exceptions the LHS
>>> might throw as well. */
>>> @@ -2090,37 +2091,47 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref
>>> case BUILT_IN_MEMPCPY:
>>> case BUILT_IN_MEMMOVE:
>>> case BUILT_IN_MEMSET:
>>> case BUILT_IN_MEMCPY_CHK:
>>> case BUILT_IN_MEMPCPY_CHK:
>>> case BUILT_IN_MEMMOVE_CHK:
>>> case BUILT_IN_MEMSET_CHK:
>>> {
>>> tree dest = gimple_call_arg (stmt, 0);
>>> tree len = gimple_call_arg (stmt, 2);
>>> - tree base = NULL_TREE;
>>> - HOST_WIDE_INT offset = 0;
>>> + tree rbase = ref->base;
>>> + HOST_WIDE_INT roffset = ref->offset;
>>> if (!host_integerp (len, 0))
>>> return false;
>>> - if (TREE_CODE (dest) == ADDR_EXPR)
>>> - base = get_addr_base_and_unit_offset (TREE_OPERAND (dest,
>>> 0),
>>> - &offset);
>>> - else if (TREE_CODE (dest) == SSA_NAME)
>>> - base = dest;
>>> - if (base
>>> - && base == ao_ref_base (ref))
>>> + ao_ref dref;
>>> + ao_ref_init_from_ptr_and_size (&dref, dest, len);
>>
>>
>> What I dislike about this is that it can end up building a new tree node.
>> Not sure if that should block the patch though as it clearly allows to
>> simplify the code ...
>>
>>> + tree base = ao_ref_base (&dref);
>>> + HOST_WIDE_INT offset = dref.offset;
>>> + if (!base || dref.size == -1)
>>> + return false;
>>> + if (TREE_CODE (base) == MEM_REF)
>>> + {
>>> + if (TREE_CODE (rbase) != MEM_REF)
>>
>>
>> why's that? I think that just processing both bases separately
>> would work as well.
>
>
> If they differ, there is no point going on, we might as well break early.
> And this way we maintain the property that either base and rbase are both
> refs, or they are both pointers, not some weird mix.
One can be plain 'b' while one MEM[&b, 5], so yes, they differ, but
only in offset.
>>> + return false;
>>> + // Compare pointers.
>>> + offset += BITS_PER_UNIT
>>> + * TREE_INT_CST_LOW (TREE_OPERAND (base, 1));
>>
>>
>> Use mem_ref_offset (base).
>
>
> offset += BITS_PER_UNIT * mem_ref_offset(base).to_shwi();
Yes.
> or did you mean the computations should use double_int?
That would certainly be more correct ... (with a test at the end
whether the result fits_shwi ()).
>>> + roffset += BITS_PER_UNIT
>>> + * TREE_INT_CST_LOW (TREE_OPERAND (rbase,
>>> 1));
>>
>>
>> Likewise.
>>
>>> + base = TREE_OPERAND (base, 0);
>>> + rbase = TREE_OPERAND (rbase, 0);
>>
>>
>> Both could be &decl here, so you want
>>
>> if (TREE_CODE (base) == ADDR_EXPR)
>> base = TREE_OPERAND (base, 0);
>
>
> I rely on the ao_ref* functions to set base to decl and not MEM_REF[&decl],
> is that a wrong assumption?
Ah, I missed that, yes, that's a correct assumption which also makes
my first comment moot. It's been some time since I wrote all this code ... ;)
So the only thing that remains is the mem_ref_offset thing and yes, I guess
I'd prefer to use double-ints because we deal with bit offsets in the end.
Thanks,
Richard.
> --
> Marc Glisse