From: Dhruv Chawla <[email protected]> This flag causes the frontend to emit annot_expr_parallel_kind for do-concurrent loops, bypassing the PR83064 fix which would emit annot_expr_ivdep_kind. This flag is meant to be a temporary fix, and it along with patch 1 of this series recovers most of the performance gap between flang and gfortran for SPEC2026 pot3d_s (speeding it up roughly 5x), modulo libgomp performance issues.
Bootstrapped and regtested on aarch64-linux-gnu. Signed-off-by: Dhruv Chawla <[email protected]> gcc/fortran/ChangeLog: PR fortran/125717 * invoke.texi: Document the option. * lang.opt: Add -fdoconcurrent-force-parallel. * trans-stmt.cc (gfc_trans_forall_loop): Emit annot_expr_parallel_kind when flag_doconcurrent_force_parallel is set. gcc/testsuite/ChangeLog: * gfortran.dg/lto/do_concurrent_16_0.f90: New test. --- gcc/fortran/invoke.texi | 9 +++- gcc/fortran/lang.opt | 4 ++ gcc/fortran/trans-stmt.cc | 9 ++-- .../gfortran.dg/lto/do_concurrent_16_0.f90 | 53 +++++++++++++++++++ 4 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/lto/do_concurrent_16_0.f90 diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 69c4fa69cc6..55a3fe3487b 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -191,7 +191,8 @@ and warnings}. -fbounds-check -ftail-call-workaround -ftail-call-workaround=@var{n} -fcheck-array-temporaries -fcheck=<all|array-temps|bits|bounds|do|mem|pointer|recursion> --fcoarray=<none|single|shared|lib> -fexternal-blas -fexternal-blas64 -ff2c +-fcoarray=<none|single|shared|lib> -fdoconcurrent-force-parallel +-fexternal-blas -fexternal-blas64 -ff2c -ffrontend-loop-interchange -ffrontend-optimize -finit-character=@var{n} -finit-integer=@var{n} -finit-local-zero -finit-derived -finit-logical=<true|false> @@ -2070,6 +2071,12 @@ size and also compilation time may become excessive. If that is the case, it may be better to disable this option. Instances of packing can be found by using @option{-Warray-temporaries}. +@opindex fdoconcurrent-force-parallel +@item -fdoconcurrent-force-parallel +This option forces parallelization of do-concurrent loops, bypassing the +usual validity analysis done by the compiler. This can introduce correctness +issues, so it should be used with caution. + @opindex fexternal-blas @item -fexternal-blas This option makes @command{gfortran} generate calls to BLAS functions diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 6266d7f71bd..f90128a2cf3 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -554,6 +554,10 @@ fdefault-real-16 Fortran Var(flag_default_real_16) Set the default real kind to an 16 byte wide type. +fdoconcurrent-force-parallel +Fortran Var(flag_doconcurrent_force_parallel) +Force auto-parallelization of do-concurrent loops. + fdollar-ok Fortran Var(flag_dollar_ok) Allow dollar signs in entity names. diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc index 0b1a8fa6b14..b89a9347394 100644 --- a/gcc/fortran/trans-stmt.cc +++ b/gcc/fortran/trans-stmt.cc @@ -4390,11 +4390,14 @@ gfc_trans_forall_loop (forall_info *forall_tmp, tree body, count, build_int_cst (TREE_TYPE (count), 0)); /* PR 83064 means that we cannot use annot_expr_parallel_kind until - the autoparallelizer can handle this. */ + the autoparallelizer can handle this. For now, use a flag to bypass + the ivdep analysis for cases where the bug doesn't manifest itself. */ + annot_expr_kind kind = annot_expr_ivdep_kind; + if (flag_doconcurrent_force_parallel && forall_tmp->do_concurrent) + kind = annot_expr_parallel_kind; if (forall_tmp->do_concurrent || iter->annot.ivdep) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, - build_int_cst (integer_type_node, - annot_expr_ivdep_kind), + build_int_cst (integer_type_node, kind), integer_zero_node); if (iter->annot.unroll && cond != error_mark_node) diff --git a/gcc/testsuite/gfortran.dg/lto/do_concurrent_16_0.f90 b/gcc/testsuite/gfortran.dg/lto/do_concurrent_16_0.f90 new file mode 100644 index 00000000000..7b0419854cd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/do_concurrent_16_0.f90 @@ -0,0 +1,53 @@ +! { dg-lto-do link } +! { dg-require-effective-target pthread } +! { dg-lto-options { { -O2 -flto -fdoconcurrent-force-parallel -ftree-parallelize-loops=2 -fdump-tree-parloops2-details } } } +! +! Testcase taken from PR fortran/83064 + +program main + use, intrinsic :: iso_fortran_env + implicit none + + integer, parameter :: nsplit = 4 + integer(int64), parameter :: ne = 100000 + integer(int64) :: stride, low(nsplit), high(nsplit), edof(ne), i + real(real64), dimension(nsplit) :: pi + + edof(1::4) = 1 + edof(2::4) = 2 + edof(3::4) = 3 + edof(4::4) = 4 + + stride = ceiling(real(ne)/nsplit) + do i = 1, nsplit + high(i) = stride*i + end do + do i = 2, nsplit + low(i) = high(i-1) + 1 + end do + low(1) = 1 + high(nsplit) = ne + + pi = 0 + do concurrent (i = 1:nsplit) + pi(i) = sum(compute( low(i), high(i) )) + end do + print *, "PI", 4*sum(pi) + +contains + + pure function compute( low, high ) result( tmp ) + integer(int64), intent(in) :: low, high + real(real64), dimension(nsplit) :: tmp + integer(int64) :: j, k + + tmp = 0 + do j = low, high + k = edof(j) + tmp(k) = tmp(k) + (-1.0_real64)**(j+1) / real( 2*j-1 ) + end do + end function + +end program main + +! { dg-final { scan-ltrans-tree-dump "parallelizing \[^\n\r\]*loop" "parloops2" } } -- 2.43.0
