On 9/1/26 6:38 AM, Mikael Morin wrote:
Le 01/09/2026 à 00:14, Jerry DeLisle a écrit :
Attached is my attempt to address all of Mikael's comments.

Regression tested on x86_64. I also rechecked performance with a local benchmark here.

OK for mainline?

Regards,

Jerry

---

[PATCH v2] 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, 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.

Second, 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.

     PR fortran/126964

gcc/fortran/ChangeLog:

     * 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_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.
     (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.
     (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_span_1.f90: New test.
     * gfortran.dg/gomp/target-span-1.f90: New test.
     * gfortran.dg/c_loc_test_22.f90: Update for addressing by the
     element length.
     * gfortran.dg/class_to_type_9.f90: Likewise, and expect an
     assumed shape dummy to take no copy of a strided actual argument.
---

On 8/31/26 7:12 AM, Mikael Morin wrote:
Le 26/08/2026 à 20:08, Jerry D a écrit :
Hi all,

The attached patch recovers most of the slowdown identified in the subject PR. Test results from the original version of tonto SPEC benchmark are also described in the PR126964 Comment #7:

"For the configuration in the initial report, I am getting roughly 2% slower than the baseline before the blamed commit, meaning that most of the performance has been recovered."

To develop this patch I used claude to analyze an archived open source copy of tonto and generate an input "deck" to produce a local bench mark. This was couple by multiple runs using callgrind to identify the "hot paths"

With the patch applied for a rank two dummy passed on from a loop calling it 120000 times, with a non-contiguous actual argument, the instructions executed fall from 17151636793 to 11676814, against 10478570 before r17-3342.

As I stated above, this recovers most of the performance regression. It also has peaked my curiosity so I plan some followup explorations.

Regression tested with full testsuite on x86_64.

OK for mainline?

Regards,

Jerry

---
     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, 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.
Not exactly.  What is not supported is a span that is not divisible by the element length.  Checking for equality between the span and element length gives a stronger condition than strictly necessary. But not a wrong condition of course.  I expect subojects of larger elements to possibly work if the divisibility condition holds.

     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.
I think it works, but the second part of the fix (your next paragraph) should avoid the need to do a runtime check.  If the type is numeric, the array is flagged as "normalized" instead of "pointer", and it's using array indexing with stride instead of span.  What's missing is gfc_is_span_addressed_dummy should return false for it I suppose, and then is_subref_array would return false.
You didn't do anything for this, did you?
Anyway, the patch is good enough, so OK to push.  I'll open a new PR for this. I think the runtime span check can be avoided, and the span_only business as well.



Let me dig on this some more. It is not so obvious how to do this. I will get back to you if I can figure it out. (Obviously it would be preferred to avoid any runtime cycles)

Jerry

Reply via email to