ping

On 8/26/26 11:08 AM, Jerry D wrote:
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.  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.

     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.
             (gfc_conv_is_contiguous_expr): Likewise.
             * trans-array.h (gfc_span_folds_into_stride): New prototype.
             * trans-array.cc (gfc_span_folds_into_stride): 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-intrinsic.cc (gfc_conv_is_contiguous_expr): Take span_only
             and, with it, test that the span of the descriptor is the element
             length without testing the strides.
             * trans-expr.cc (is_whole_span_addressed_dummy): New function.
             (dummy_accepts_strided_arg): New function.
             (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.


Reply via email to