[PATCH 2/2] Fortran: Add attribute flatten
Bernhard Reutner-Fischer
rep.dot.nop@gmail.com
Thu Nov 10 10:20:31 GMT 2022
Bootstrapped and regtested cleanly on x86_unknown-linux.
The document bits will be rewritten for rst.
Ok for trunk if the prerequisite target_clones patch is approved?
gcc/fortran/ChangeLog:
* decl.cc (gfc_match_gcc_attributes): Handle flatten.
* f95-lang.cc (gfc_attribute_table): Add flatten.
* gfortran.texi: Document attribute flatten.
gcc/testsuite/ChangeLog:
* gfortran.dg/attr_flatten-1.f90: New test.
---
gcc/fortran/decl.cc | 8 +++-
gcc/fortran/f95-lang.cc | 2 +
gcc/fortran/gfortran.texi | 8 ++++
gcc/testsuite/gfortran.dg/attr_flatten-1.f90 | 41 ++++++++++++++++++++
4 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/attr_flatten-1.f90
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index d312d4812b6..3d210c26eb5 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -11841,6 +11841,7 @@ gfc_match_gcc_attributes (void)
for(;;)
{
char ch;
+ bool known_attr0args = false;
if (gfc_match_name (name) != MATCH_YES)
return MATCH_ERROR;
@@ -11849,7 +11850,9 @@ gfc_match_gcc_attributes (void)
if (strcmp (name, ext_attr_list[id].name) == 0)
break;
- if (id == EXT_ATTR_LAST)
+ if (strcmp (name, "flatten") == 0)
+ known_attr0args = true; /* Handled below. We do not need a bit. */
+ else if (id == EXT_ATTR_LAST)
{
gfc_error ("Unknown attribute in !GCC$ ATTRIBUTES statement at %C");
return MATCH_ERROR;
@@ -11864,7 +11867,8 @@ gfc_match_gcc_attributes (void)
|| id == EXT_ATTR_DLLEXPORT
|| id == EXT_ATTR_CDECL
|| id == EXT_ATTR_STDCALL
- || id == EXT_ATTR_FASTCALL)
+ || id == EXT_ATTR_FASTCALL
+ || known_attr0args)
attr.ext_attr_args
= chainon (attr.ext_attr_args,
build_tree_list (get_identifier (name), NULL_TREE));
diff --git a/gcc/fortran/f95-lang.cc b/gcc/fortran/f95-lang.cc
index 7154568aec5..ddb5b686cf6 100644
--- a/gcc/fortran/f95-lang.cc
+++ b/gcc/fortran/f95-lang.cc
@@ -101,6 +101,8 @@ static const struct attribute_spec gfc_attribute_table[] =
gfc_handle_omp_declare_target_attribute, NULL },
{ "target_clones", 1, -1, true, false, false, false,
gfc_handle_omp_declare_target_attribute, NULL },
+ { "flatten", 0, 0, true, false, false, false,
+ gfc_handle_omp_declare_target_attribute, NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 06e4c8c00a1..be650f28b62 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -3280,6 +3280,14 @@ contains
end module mymod
@end smallexample
+@node flatten
+
+Procedures annotated with the @code{flatten} attribute have their
+callees inlined, if possible.
+Please refer to
+@ref{Top,,Common Function Attributes,gcc,Using the GNU Compiler Collection (GCC)}
+for details about the respective attribute.
+
The attributes are specified using the syntax
@code{!GCC$ ATTRIBUTES} @var{attribute-list} @code{::} @var{variable-list}
diff --git a/gcc/testsuite/gfortran.dg/attr_flatten-1.f90 b/gcc/testsuite/gfortran.dg/attr_flatten-1.f90
new file mode 100644
index 00000000000..0b72f1ba17c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/attr_flatten-1.f90
@@ -0,0 +1,41 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-optimized" }
+! Test __attribute__((flatten))
+!
+module attr_flttn_1_a
+ implicit none
+contains
+ subroutine sub1(i)
+ integer, intent(in) :: i
+ integer :: n
+ do n = 1, i
+ print *, "marker1 ", i, i+n;
+ enddo
+ end
+ subroutine sub2(i)
+ integer, intent(in) :: i
+ integer :: n
+ do n = 1, i
+ print *, "marker2 ", i, i*i-n;
+ enddo
+ end
+end module
+module attr_flttn_1_b
+ use attr_flttn_1_a
+contains
+ subroutine sub3
+!GCC$ ATTRIBUTES flatten :: sub3
+ print *, "marker3 "
+ call sub2(4711)
+ call sub1(42)
+ end
+end module
+! Without the attribute flatten we would have 1 character write for each marker.
+! That would be 3 _gfortran_transfer_character_write.*marker
+! With the attribute, we have one for each sub plus marker1 and marker2
+! which were inlined into sub3.
+! So this gives 5 _gfortran_transfer_character_write.*marker
+! and there should be no calls to sub1 (); nor sub2 ();
+! { dg-final { scan-tree-dump-times { _gfortran_transfer_character_write .*?marker} 5 "optimized" } }
+! { dg-final { scan-tree-dump-not { sub1 \([^\)][^\)]*\);} "optimized" } }
+! { dg-final { scan-tree-dump-not { sub2 \([^\)][^\)]*\);} "optimized" } }
--
2.38.1
More information about the Fortran
mailing list