[flang-commits] [flang] [flang] Lower function/subroutine attribute to func op (PR #95468)
Valentin Clement バレンタイン クレメン via flang-commits
flang-commits at lists.llvm.org
Thu Jun 13 13:23:20 PDT 2024
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/95468
Keep track of the Fortran procedure attributes on the func operation.
>From 971ca4fdf67d5849361b79da30f5019d8f4e60aa Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 13 Jun 2024 11:58:14 -0700
Subject: [PATCH] [flang] Lower function/subroutine attribute to func op
---
.../flang/Optimizer/Dialect/FIROpsSupport.h | 12 +++++++
flang/lib/Lower/Bridge.cpp | 14 +++++++++
.../OpenMP/declare-target-func-and-subr.f90 | 4 +--
...arget-implicit-func-and-subr-cap-enter.f90 | 4 +--
...lare-target-implicit-func-and-subr-cap.f90 | 4 +--
.../declare-target-implicit-tarop-cap.f90 | 2 +-
flang/test/Lower/func-attrs.f90 | 31 +++++++++++++++++++
flang/test/Lower/host-associated.f90 | 2 +-
8 files changed, 65 insertions(+), 8 deletions(-)
create mode 100644 flang/test/Lower/func-attrs.f90
diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
index 47b80cca5d649..116c1dfea51b4 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
+++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
@@ -148,6 +148,18 @@ static constexpr llvm::StringRef getAdaptToByRefAttrName() {
return "adapt.valuebyref";
}
+static constexpr llvm::StringRef getFuncPureAttrName() {
+ return "fir.func_pure";
+}
+
+static constexpr llvm::StringRef getFuncElementAttrName() {
+ return "fir.func_elemental";
+}
+
+static constexpr llvm::StringRef getFuncRecursiveAttrName() {
+ return "fir.func_recursive";
+}
+
// Attribute for an alloca that is a trivial adaptor for converting a value to
// pass-by-ref semantics for a VALUE parameter. The optimizer may be able to
// eliminate these.
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 4dd0b7eb2a05f..46d7ac5f2016b 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -5025,6 +5025,20 @@ class FirConverter : public Fortran::lower::AbstractConverter {
new fir::FirOpBuilder(func, bridge.getKindMap(), &mlirSymbolTable);
assert(builder && "FirOpBuilder did not instantiate");
builder->setFastMathFlags(bridge.getLoweringOptions().getMathOptions());
+ // Set procedure attributes to the func op.
+ if (!funit.isMainProgram()) {
+ const Fortran::semantics::Symbol &funcSym = funit.getSubprogramSymbol();
+ if (IsPureProcedure(funcSym))
+ func.getOperation()->setAttr(fir::getFuncPureAttrName(),
+ builder->getUnitAttr());
+ if (IsElementalProcedure(funcSym))
+ func.getOperation()->setAttr(fir::getFuncElementAttrName(),
+ builder->getUnitAttr());
+ if (funcSym.attrs().test(Fortran::semantics::Attr::RECURSIVE))
+ func.getOperation()->setAttr(fir::getFuncRecursiveAttrName(),
+ builder->getUnitAttr());
+ }
+
builder->setInsertionPointToStart(&func.front());
if (funit.parent.isA<Fortran::lower::pft::FunctionLikeUnit>()) {
// Give internal linkage to internal functions. There are no name clash
diff --git a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90 b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
index 3d2c4067dab71..0d138321445ce 100644
--- a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
+++ b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
@@ -154,7 +154,7 @@ SUBROUTINE SUBR_DEFAULT_EXTENDEDLIST()
!! -----
! DEVICE-LABEL: func.func @_QPrecursive_declare_target
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET(INCREMENT) RESULT(K)
!$omp declare target to(RECURSIVE_DECLARE_TARGET) device_type(nohost)
INTEGER :: INCREMENT, K
@@ -166,7 +166,7 @@ RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET(INCREMENT) RESULT(K)
END FUNCTION RECURSIVE_DECLARE_TARGET
! DEVICE-LABEL: func.func @_QPrecursive_declare_target_enter
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET_ENTER(INCREMENT) RESULT(K)
!$omp declare target enter(RECURSIVE_DECLARE_TARGET_ENTER) device_type(nohost)
INTEGER :: INCREMENT, K
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
index ed718a485e3dd..0ca2bcbd66a96 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
@@ -105,7 +105,7 @@ end function target_function_test_host
!! -----
! DEVICE-LABEL: func.func @_QPimplicitly_captured_with_dev_type_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}}
recursive function implicitly_captured_with_dev_type_recursive(increment) result(k)
!$omp declare target enter(implicitly_captured_with_dev_type_recursive) device_type(host)
integer :: increment, k
@@ -174,7 +174,7 @@ recursive subroutine implicitly_captured_recursive(increment)
end program
! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
recursive subroutine implicitly_captured_recursive(increment)
integer :: increment
if (increment == 10) then
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
index df81c43a2fe69..ffca5c3ff2500 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
@@ -131,7 +131,7 @@ end function target_function_test_host
!! -----
! DEVICE-LABEL: func.func @_QPimplicitly_captured_with_dev_type_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
recursive function implicitly_captured_with_dev_type_recursive(increment) result(k)
!$omp declare target to(implicitly_captured_with_dev_type_recursive) device_type(host)
integer :: increment, k
@@ -200,7 +200,7 @@ recursive subroutine implicitly_captured_recursive(increment)
end program
! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
recursive subroutine implicitly_captured_recursive(increment)
integer :: increment
if (increment == 10) then
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
index 7d1ae06c80561..9b85a32036ca5 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
@@ -67,7 +67,7 @@ end function target_function_test_device
!! -----
! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
recursive function implicitly_captured_recursive(increment) result(k)
integer :: increment, k
if (increment == 10) then
diff --git a/flang/test/Lower/func-attrs.f90 b/flang/test/Lower/func-attrs.f90
new file mode 100644
index 0000000000000..7ab549a0ac7ce
--- /dev/null
+++ b/flang/test/Lower/func-attrs.f90
@@ -0,0 +1,31 @@
+! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
+
+pure subroutine sub1()
+end
+
+! CHECK: func.func @_QPsub1() attributes {fir.func_pure}
+
+elemental subroutine sub2()
+end
+
+! CHECK: func.func @_QPsub2() attributes {fir.func_elemental, fir.func_pure}
+
+recursive subroutine sub3()
+end
+
+! CHECK: func.func @_QPsub3() attributes {fir.func_recursive}
+
+pure function fct1()
+end
+
+! CHECK: func.func @_QPfct1() -> f32 attributes {fir.func_pure}
+
+elemental function fct2()
+end
+
+! CHECK: func.func @_QPfct2() -> f32 attributes {fir.func_elemental, fir.func_pure}
+
+recursive function fct3()
+end
+
+! CHECK: func.func @_QPfct3() -> f32 attributes {fir.func_recursive}
diff --git a/flang/test/Lower/host-associated.f90 b/flang/test/Lower/host-associated.f90
index cdc7e6a05288a..b0195108238d7 100644
--- a/flang/test/Lower/host-associated.f90
+++ b/flang/test/Lower/host-associated.f90
@@ -309,7 +309,7 @@ subroutine test7(j, k)
contains
! CHECK-LABEL: func private @_QFtest7Ptest7_inner(
-! CHECK-SAME: %[[i:.*]]: !fir.ref<i32>{{.*}}, %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) -> i32 attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
+! CHECK-SAME: %[[i:.*]]: !fir.ref<i32>{{.*}}, %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) -> i32 attributes {fir.func_elemental, fir.func_pure, fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
elemental integer function test7_inner(i)
implicit none
integer, intent(in) :: i
More information about the flang-commits
mailing list