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.