> Am 13.12.2023 um 17:07 schrieb Martin Jambor <mjam...@suse.cz>:
> 
> Hi,
> 
> sorry for getting to this only so late, my email backlog from my medical
> leave still isn't empty.
> 
>> On Mon, Oct 16 2023, Richard Biener wrote:
>> The following addresses build_reconstructed_reference failing to
>> build references with a different offset than the models and thus
>> the caller conditional being off.  This manifests when attempting
>> to build a ref with offset 160 from the model BIT_FIELD_REF <l_4827[9], 8, 0>
>> onto the same base l_4827 but the models offset being 288.  This
>> cannot work for any kind of ref I can think of, not just with
>> BIT_FIELD_REFs.
>> 
>> Bootstrapped and tested on x86_64-unknown-linux-gnu, will push
>> later.
>> 
>> Martin - do you remember which case was supposed to be allowed
>> with offset < model->offset?
>> 
> 
> It happens quite often, even in our testsuite.  In fact, the condition
> is not even supposed to be necessary and is there just an early exit in
> hopeless cases with malformed programs.
> 
> The problem is that the function is used in two contexts and in one of
> them we are not careful about ARRAY_REFs, as explained below in a commit
> message of a patch I'd like to push.  Needless to say, it has passed
> bootstrap and testing on x86_64-linux, I'm running the same on
> aarch64-linux.
> 
> What do you think

Thanks for the explanation. This wasn’t obvious.  The patch is OK from my side.

Thanks,
Richard 


> Martin
> 
> 
> 
> Subject: [PATCH] SRA: Relax requirements to use build_reconstructed_reference 
> (PR 111807)
> 
> This patch half-reverts 3aaf704bca3e and replaces it with a fix with
> relaxed requiremets for invoking build_reconstructed_reference in
> build_ref_for_model.
> 
> build_ref_for_model/build_ref_for_offset is used in two slightly
> different contexts. The first is when we are looking at an assignment
> like
> 
>   p->field_A.field_B = s.field_B;
> 
> and we have a replacements for e.g. s.field_B.field_C.field_D and we
> want to store them directly to p->field_A.field_B.field_C.field_D (as
> opposed to going through s or using a MEM_REF based in
> p->field_A.field_B).  In this case, the offset of the
> "model" (s.field_B.field_C.field_D) within this can be different than
> offset within the LHS that we want to reach (field_C.field_D within
> the "base" p->field_A.field_B).  Patch 3aaf704bca3e has caused us to
> unnecessarily create MEM_REFs for these situations.  These uses of
> build_ref_for_model work with the relaxed condition just fine.
> 
> The second, problematic, context is when somewhere in the function we
> have an assignment
> 
>  s.field_A = t.field_A.field_B;
> 
> and we are creating an access structure to represent s.field_A.field_B
> even if it is not actually accessed in the original input.  This is
> done after scanning the entire function body and we need to construct
> a "universal" reference to s.field_A.field_B.  In this case the "base"
> is "s" and it has to be the DECL itself and not some reference for it
> because for arbitrary references we need a GSI pointing to a statement
> which we don't have, the reference is supposed to be universal.
> 
> But then using build_ref_for_model and within it
> build_reconstructed_reference misbehaves if the expression contains
> any ARRAY_REFs.  In the first case those are fine because as we
> eventually reach the aggregate type that matches a real LHS or RHS, we
> know we we can just bolt the rest of the references onto it and end up
> with the correct overall reference.  However when dealing with
> 
>   s.array[1].field_A = s.array[2].field_B;
> 
> we cannot just bolt array[2] reference when we want array[1] but that
> is exactly what happens when we use build_reconstructed_reference and
> keep it walking all the way to s.
> 
> I was considering making all users of the second kind use directly
> build_ref_for_offset instead of build_ref_for_model but the latter
> also handles COMPONENT_REFs to bit-fields which the former does not.
> Therefore I have decided to use the NULL-ness of GSI as an indicator
> how strict we need to be.  I have changed the function comment to
> reflect that.
> 
> I have been able to observe disambiguation improvements with this patch
> over current master, we do successfully manage a few more
> aliasing_component_refs_p disambiguations when compiling cc1, going
> from:
> 
>  Alias oracle query stats:
>    refs_may_alias_p: 94354287 disambiguations, 106279231 queries
>    ref_maybe_used_by_call_p: 1572511 disambiguations, 95618222 queries
>    call_may_clobber_ref_p: 649273 disambiguations, 659371 queries
>    stmt_kills_ref_p: 142342 kills, 8407309 queries
>    nonoverlapping_component_refs_p: 19 disambiguations, 10227 queries
>    nonoverlapping_refs_since_match_p: 15665 disambiguations, 52585 must 
> overlaps, 68893 queries
>    aliasing_component_refs_p: 67090 disambiguations, 3081766 queries
>    TBAA oracle: 22675296 disambiguations 61781978 queries
>                 14045969 are in alias set 0
>                 10997085 queries asked about the same object
>                 153 queries asked about the same alias set
>                 0 access volatile
>                 12485774 are dependent in the DAG
>                 1577701 are aritificially in conflict with void *
> 
>  Modref stats:
>    modref kill: 832 kills, 19399 queries
>    modref use: 50760 disambiguations, 1825109 queries
>    modref clobber: 1371014 disambiguations, 40152535 queries
>    5190238 tbaa queries (0.129263 per modref query)
>    1341663 base compares (0.033414 per modref query)
> 
>  PTA query stats:
>    pt_solution_includes: 36784427 disambiguations, 46141175 queries
>    pt_solutions_intersect: 4519387 disambiguations, 17081996 queries
> 
> to:
> 
>  Alias oracle query stats:
>    refs_may_alias_p: 94354083 disambiguations, 106278948 queries
>    ref_maybe_used_by_call_p: 1572511 disambiguations, 95618018 queries
>    call_may_clobber_ref_p: 649273 disambiguations, 659371 queries
>    stmt_kills_ref_p: 142342 kills, 8407310 queries
>    nonoverlapping_component_refs_p: 19 disambiguations, 10227 queries
>    nonoverlapping_refs_since_match_p: 15665 disambiguations, 52585 must 
> overlaps, 68893 queries
>    aliasing_component_refs_p: 67104 disambiguations, 3081781 queries
>    TBAA oracle: 22676608 disambiguations 61782455 queries
>                 14044948 are in alias set 0
>                 10998619 queries asked about the same object
>                 153 queries asked about the same alias set
>                 0 access volatile
>                 12484882 are dependent in the DAG
>                 1577245 are aritificially in conflict with void *
> 
>  Modref stats:
>    modref kill: 832 kills, 19399 queries
>    modref use: 50760 disambiguations, 1825106 queries
>    modref clobber: 1371028 disambiguations, 40152504 queries
>    5190319 tbaa queries (0.129265 per modref query)
>    1341403 base compares (0.033408 per modref query)
> 
>  PTA query stats:
>    pt_solution_includes: 36784449 disambiguations, 46141210 queries
>    pt_solutions_intersect: 4519320 disambiguations, 17082083 queries
> 
> gcc/ChangeLog:
> 
> 2023-12-13  Martin Jambor  <mjam...@suse.cz>
> 
>    PR tree-optimization/111807
>    * tree-sra.cc (build_ref_for_model): Allow offset smaller than
>    model->offset when gsi is non-NULL.  Adjust function comment.
> ---
> gcc/tree-sra.cc | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
> index 3bd0c7a9af0..1dba721be11 100644
> --- a/gcc/tree-sra.cc
> +++ b/gcc/tree-sra.cc
> @@ -1843,8 +1843,11 @@ build_reconstructed_reference (location_t, tree base, 
> struct access *model)
> /* Construct a memory reference to a part of an aggregate BASE at the given
>    OFFSET and of the same type as MODEL.  In case this is a reference to a
>    bit-field, the function will replicate the last component_ref of model's
> -   expr to access it.  GSI and INSERT_AFTER have the same meaning as in
> -   build_ref_for_offset.  */
> +   expr to access it.  INSERT_AFTER and GSI have the same meaning as in
> +   build_ref_for_offset, furthermore, when GSI is NULL, the function expects
> +   that it re-builds the entire reference from a DECL to the final access and
> +   so will create a MEM_REF when OFFSET does not exactly match offset of
> +   MODEL.  */
> 
> static tree
> build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
> @@ -1874,7 +1877,8 @@ build_ref_for_model (location_t loc, tree base, 
> HOST_WIDE_INT offset,
>      && !TREE_THIS_VOLATILE (base)
>      && (TYPE_ADDR_SPACE (TREE_TYPE (base))
>          == TYPE_ADDR_SPACE (TREE_TYPE (model->expr)))
> -      && offset == model->offset
> +      && (offset == model->offset
> +          || (gsi && offset <= model->offset))
>      /* build_reconstructed_reference can still fail if we have already
>         massaged BASE because of another type incompatibility.  */
>      && (res = build_reconstructed_reference (loc, base, model)))
> --
> 2.43.0
> 
> 
> 
> 
> 

Reply via email to