https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126964

--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jerry DeLisle <[email protected]>:

https://gcc.gnu.org/g:d6c3e489d368dacfe7958e1dbfedf8cf738a03b3

commit r17-3967-gd6c3e489d368dacfe7958e1dbfedf8cf738a03b3
Author: Jerry DeLisle <[email protected]>
Date:   Fri Aug 21 16:17:14 2026 -0700

    fortran: [PR126964] Reduce the cost of a span addressed dummy

    Assisted-by: Claude Opus 5

    r17-3342 made a TARGET assumed shape or assumed rank dummy be addressed
    through the span of its descriptor, so that a pointer to it stays valid
    when its elements are subobjects of larger ones.  That costs in two ways,
    and SPEC 465.tonto pays both.

    First, addressing every element as offset * span leaves the step of a data
    reference symbolic, so loop versioning cannot prove that the accesses stay
    aligned and the loop is never vectorized.  Fold the spacing into the
    strides and the offset on entry instead, so that the elements are
    addressed by the constant element length as usual.  The element length
    divides the spacing whenever the element size equals the element
    alignment, which covers integer, real and logical elements of an assumed
    shape dummy; elsewhere the span is still used to address them.

    A dummy whose spacing is folded that way is not addressed through its span
    at all, and the descriptor built for it holds the element length as its
    span, so is_subref_array must not be true for it: passing it on needs
    neither a copy nor a test.  The predicate is therefore split in two.  What
    lets the elements be spaced by more than the element size is that the
    actual argument of a TARGET dummy is never copied, which is now
    gfc_dummy_requires_direct_arg; gfc_is_span_addressed_dummy is that
    property less the dummies whose spacing is folded into their strides, and
    moves to trans-array.cc, the element size of the type being a back end
    property.

    Second, is_subref_array became true for such a dummy, so passing one on to
    another procedure takes the copy-in/copy-out path, with the copy made
    conditional on the actual argument being contiguous.  That is more than
    the receiving dummy needs: a dummy that has a descriptor of its own
    addresses its elements by the strides held in it, so it accepts an actual
    argument of any stride; the one thing it cannot do is address elements
    that are subobjects of larger ones, which is what a span differing from
    the element length means.  Narrow the condition to the span alone when the
    dummy has a descriptor and is not CONTIGUOUS.  A dummy that needs the
    argument packed still gets the full test.  The span test is a different
    condition from contiguity, so it is a function of its own.  This applies
    to what is left span addressed: character, complex and derived type
    elements, and an assumed rank dummy, which has no strides to fold into.

            PR fortran/126964

    gcc/fortran/ChangeLog:

            * gfortran.h (gfc_dummy_requires_direct_arg): New prototype.
            * symbol.cc (gfc_is_span_addressed_dummy): Rename to...
            (gfc_dummy_requires_direct_arg): ... this and move the addressing
            out of the description.
            * trans.h (struct lang_decl): Add span_normalized.
            (GFC_DECL_SPAN_NORMALIZED): New macro.
            (gfc_conv_subref_array_arg): Add span_only argument.
            * trans-array.h (gfc_span_folds_into_stride): New prototype.
            (gfc_conv_span_is_elem_len): Likewise.
            * trans-array.cc (gfc_span_folds_into_stride): New function.
            (gfc_is_span_addressed_dummy): New function, false for a dummy
            whose element spacing is folded into its strides.
            (gfc_conv_span_is_elem_len): New function.
            (gfc_trans_dummy_array_bias): Fold the element spacing of a span
            normalized dummy into its strides and its offset on entry.
            * trans-decl.cc (gfc_build_dummy_array_decl): Mark such a dummy
            span normalized rather than giving it a span variable.
            (gfc_get_symbol_decl): Do not set GFC_DECL_PTR_ARRAY_P for it.
            * trans-expr.cc (is_whole_span_addressed_dummy): New function.
            (dummy_accepts_strided_arg): New function.
            (copy_in_out_allowed): Use gfc_dummy_requires_direct_arg, the
            actual argument of a span normalized dummy being uncopied too.
            (gfc_conv_subref_array_arg): Take span_only and, with it, test the
            span of the descriptor instead of contiguity.
            (gfc_conv_procedure_call): Ask for the span test when a span
            addressed dummy is passed on to a dummy that has a descriptor.

    gcc/testsuite/ChangeLog:

            * gfortran.dg/target_dummy_repack_1.f90: New test.
            * gfortran.dg/target_dummy_repack_2.f90: New test.
            * gfortran.dg/target_dummy_span_1.f90: New test.
            * gfortran.dg/c_loc_test_22.f90: Update for addressing by the
            element length.
            * gfortran.dg/gomp/target-span-1.f90: Likewise.
            * gfortran.dg/class_to_type_9.f90: Likewise, and expect an
            assumed shape dummy to take no copy of a strided actual argument.

    libgomp/ChangeLog:

            * testsuite/libgomp.oacc-fortran/host_data-5.F90: Expect no copy
            of a span normalized dummy passed to a dummy without a descriptor.

Reply via email to