-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[flang][OpenMP] Fix privatization of procedure pointers #130336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-flang-fir-hlfir Author: Leandro Lupori (luporl) ChangesFixes #121720 Full diff: https://github.com/llvm/llvm-project/pull/130336.diff 4 Files Affected:
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index cc19f335cd017..425007da6b563 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -1274,6 +1274,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
[](const fir::FortranVariableOpInterface &box) {
return fir::FortranVariableOpInterface(box).isPointer();
},
+ [](const fir::AbstractBox &box) {
+ return fir::isBoxProcAddressType(box.getAddr().getType());
+ },
[](const auto &box) { return false; });
copyVarHLFIR(loc, dst, src, isBoxAllocatable, isBoxPointer, flags);
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index cc55191170c65..4bca4641a1b2e 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1842,7 +1842,7 @@ void Fortran::lower::genDeclareSymbol(
bool force) {
if (converter.getLoweringOptions().getLowerToHighLevelFIR() &&
(!Fortran::semantics::IsProcedure(sym) ||
- Fortran::semantics::IsPointer(sym)) &&
+ Fortran::semantics::IsPointer(sym.GetUltimate())) &&
!sym.detailsIf<Fortran::semantics::CommonBlockDetails>()) {
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
const mlir::Location loc = genLocation(converter, sym);
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 719cb1b9d75aa..6aa8ba4c9e7f4 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -553,70 +553,92 @@ std::string getTypeAsString(mlir::Type ty, const fir::KindMapping &kindMap,
llvm::raw_string_ostream name{buf};
if (!prefix.empty())
name << "_";
- while (ty) {
- if (fir::isa_trivial(ty)) {
- if (mlir::isa<mlir::IndexType>(ty)) {
- name << "idx";
- } else if (ty.isIntOrIndex()) {
- name << 'i' << ty.getIntOrFloatBitWidth();
- } else if (mlir::isa<mlir::FloatType>(ty)) {
- name << 'f' << ty.getIntOrFloatBitWidth();
- } else if (auto cplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(ty)) {
- name << 'z';
- auto floatTy = mlir::cast<mlir::FloatType>(cplxTy.getElementType());
- name << floatTy.getWidth();
- } else if (auto logTy = mlir::dyn_cast_or_null<fir::LogicalType>(ty)) {
- name << 'l' << kindMap.getLogicalBitsize(logTy.getFKind());
+
+ std::function<void(mlir::Type)> appendTypeName = [&](mlir::Type ty) {
+ while (ty) {
+ if (fir::isa_trivial(ty)) {
+ if (mlir::isa<mlir::IndexType>(ty)) {
+ name << "idx";
+ } else if (ty.isIntOrIndex()) {
+ name << 'i' << ty.getIntOrFloatBitWidth();
+ } else if (mlir::isa<mlir::FloatType>(ty)) {
+ name << 'f' << ty.getIntOrFloatBitWidth();
+ } else if (auto cplxTy =
+ mlir::dyn_cast_or_null<mlir::ComplexType>(ty)) {
+ name << 'z';
+ auto floatTy = mlir::cast<mlir::FloatType>(cplxTy.getElementType());
+ name << floatTy.getWidth();
+ } else if (auto logTy = mlir::dyn_cast_or_null<fir::LogicalType>(ty)) {
+ name << 'l' << kindMap.getLogicalBitsize(logTy.getFKind());
+ } else {
+ llvm::report_fatal_error("unsupported type");
+ }
+ break;
+ } else if (mlir::isa<mlir::NoneType>(ty)) {
+ name << "none";
+ break;
+ } else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(ty)) {
+ name << 'c' << kindMap.getCharacterBitsize(charTy.getFKind());
+ if (charTy.getLen() == fir::CharacterType::unknownLen())
+ name << "xU";
+ else if (charTy.getLen() != fir::CharacterType::singleton())
+ name << "x" << charTy.getLen();
+ break;
+ } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(ty)) {
+ for (auto extent : seqTy.getShape()) {
+ if (extent == fir::SequenceType::getUnknownExtent())
+ name << "Ux";
+ else
+ name << extent << 'x';
+ }
+ ty = seqTy.getEleTy();
+ } else if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
+ name << "ref_";
+ ty = refTy.getEleTy();
+ } else if (auto ptrTy = mlir::dyn_cast_or_null<fir::PointerType>(ty)) {
+ name << "ptr_";
+ ty = ptrTy.getEleTy();
+ } else if (auto ptrTy =
+ mlir::dyn_cast_or_null<fir::LLVMPointerType>(ty)) {
+ name << "llvmptr_";
+ ty = ptrTy.getEleTy();
+ } else if (auto heapTy = mlir::dyn_cast_or_null<fir::HeapType>(ty)) {
+ name << "heap_";
+ ty = heapTy.getEleTy();
+ } else if (auto classTy = mlir::dyn_cast_or_null<fir::ClassType>(ty)) {
+ name << "class_";
+ ty = classTy.getEleTy();
+ } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(ty)) {
+ name << "box_";
+ ty = boxTy.getEleTy();
+ } else if (auto boxcharTy =
+ mlir::dyn_cast_or_null<fir::BoxCharType>(ty)) {
+ name << "boxchar_";
+ ty = boxcharTy.getEleTy();
+ } else if (auto boxprocTy =
+ mlir::dyn_cast_or_null<fir::BoxProcType>(ty)) {
+ name << "boxproc_";
+ auto procTy = mlir::dyn_cast<mlir::FunctionType>(boxprocTy.getEleTy());
+ assert(procTy.getNumResults() <= 1 &&
+ "function type with more than one result");
+ for (const auto &result : procTy.getResults())
+ appendTypeName(result);
+ name << "_args";
+ for (const auto &arg : procTy.getInputs()) {
+ name << '_';
+ appendTypeName(arg);
+ }
+ break;
+ } else if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(ty)) {
+ name << "rec_" << recTy.getName();
+ break;
} else {
llvm::report_fatal_error("unsupported type");
}
- break;
- } else if (mlir::isa<mlir::NoneType>(ty)) {
- name << "none";
- break;
- } else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(ty)) {
- name << 'c' << kindMap.getCharacterBitsize(charTy.getFKind());
- if (charTy.getLen() == fir::CharacterType::unknownLen())
- name << "xU";
- else if (charTy.getLen() != fir::CharacterType::singleton())
- name << "x" << charTy.getLen();
- break;
- } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(ty)) {
- for (auto extent : seqTy.getShape()) {
- if (extent == fir::SequenceType::getUnknownExtent())
- name << "Ux";
- else
- name << extent << 'x';
- }
- ty = seqTy.getEleTy();
- } else if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
- name << "ref_";
- ty = refTy.getEleTy();
- } else if (auto ptrTy = mlir::dyn_cast_or_null<fir::PointerType>(ty)) {
- name << "ptr_";
- ty = ptrTy.getEleTy();
- } else if (auto ptrTy = mlir::dyn_cast_or_null<fir::LLVMPointerType>(ty)) {
- name << "llvmptr_";
- ty = ptrTy.getEleTy();
- } else if (auto heapTy = mlir::dyn_cast_or_null<fir::HeapType>(ty)) {
- name << "heap_";
- ty = heapTy.getEleTy();
- } else if (auto classTy = mlir::dyn_cast_or_null<fir::ClassType>(ty)) {
- name << "class_";
- ty = classTy.getEleTy();
- } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(ty)) {
- name << "box_";
- ty = boxTy.getEleTy();
- } else if (auto boxcharTy = mlir::dyn_cast_or_null<fir::BoxCharType>(ty)) {
- name << "boxchar_";
- ty = boxcharTy.getEleTy();
- } else if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(ty)) {
- name << "rec_" << recTy.getName();
- break;
- } else {
- llvm::report_fatal_error("unsupported type");
}
- }
+ };
+
+ appendTypeName(ty);
return buf;
}
diff --git a/flang/test/Lower/OpenMP/privatization-proc-ptr.f90 b/flang/test/Lower/OpenMP/privatization-proc-ptr.f90
new file mode 100644
index 0000000000000..168580edac878
--- /dev/null
+++ b/flang/test/Lower/OpenMP/privatization-proc-ptr.f90
@@ -0,0 +1,165 @@
+! Test privatization of procedure pointers.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+!RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+program proc_ptr_test
+ implicit none
+
+contains
+
+!CHECK: omp.private {type = private} @_QFFtest_namesEpf2_private_boxproc_z32_args_ref_3x4xf32_ref_z32 : !fir.boxproc<(!fir.ref<!fir.array<3x4xf32>>, !fir.ref<complex<f32>>) -> complex<f32>>
+!CHECK: omp.private {type = private} @_QFFtest_namesEpf1_private_boxproc_f32_args_ref_f32 : !fir.boxproc<(!fir.ref<f32>) -> f32>
+!CHECK: omp.private {type = private} @_QFFtest_namesEpf0_private_boxproc_i32_args : !fir.boxproc<() -> i32>
+!CHECK: omp.private {type = private} @_QFFtest_namesEps2_private_boxproc__args_ref_i32_boxchar_c8xU : !fir.boxproc<(!fir.ref<i32>, !fir.boxchar<1>) -> ()>
+!CHECK: omp.private {type = private} @_QFFtest_namesEps1_private_boxproc__args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> ()>
+!CHECK: omp.private {type = private} @_QFFtest_namesEps0_private_boxproc__args : !fir.boxproc<() -> ()>
+
+!CHECK: omp.private {type = private} @_QFFtest_lastprivateEps_private_boxproc__args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> ()>
+!CHECK: omp.private {type = private} @_QFFtest_lastprivateEpf_private_boxproc_i32_args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> i32>
+
+!CHECK: omp.private {type = firstprivate} @_QFFtest_firstprivateEps_firstprivate_boxproc__args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> ()> copy {
+!CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>, %[[ARG1:.*]]: !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>):
+!CHECK: %[[TEMP:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>
+!CHECK: fir.store %[[TEMP]] to %[[ARG1]] : !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>
+!CHECK: omp.yield(%[[ARG1]] : !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>)
+!CHECK: }
+
+!CHECK: omp.private {type = firstprivate} @_QFFtest_firstprivateEpf_firstprivate_boxproc_i32_args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> i32>
+!CHECK: omp.private {type = private} @_QFFtest_privateEps_private_boxproc__args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> ()>
+!CHECK: omp.private {type = private} @_QFFtest_privateEpf_private_boxproc_i32_args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> i32>
+
+!CHECK-LABEL: func private @_QFPtest_private
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_privateEpf"}
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_privateEps"}
+!CHECK: omp.parallel
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_privateEpf"}
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_privateEps"}
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PRIV_PF]]#0
+!CHECK: %[[PF_BOX:.*]] = fir.box_addr %[[PF_VAL]]
+!CHECK: fir.call %[[PF_BOX]]({{.*}})
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PRIV_PS]]#0
+!CHECK: %[[PS_BOX:.*]] = fir.box_addr %[[PS_VAL]]
+!CHECK: fir.call %[[PS_BOX]]({{.*}})
+subroutine test_private
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+ integer :: res
+
+ !$omp parallel private(pf, ps)
+ pf => f
+ ps => sub
+ res = pf(123)
+ call ps(456)
+ !$omp end parallel
+end subroutine
+
+!CHECK-LABEL: func private @_QFPtest_firstprivate
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_firstprivateEpf"}
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_firstprivateEps"}
+!CHECK: omp.parallel
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_firstprivateEpf"}
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_firstprivateEps"}
+subroutine test_firstprivate
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+
+ !$omp parallel firstprivate(pf, ps)
+ !$omp end parallel
+end subroutine
+
+!CHECK-LABEL: func private @_QFPtest_lastprivate
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_lastprivateEpf"}
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_lastprivateEps"}
+!CHECK: omp.parallel
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_lastprivateEpf"}
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_lastprivateEps"}
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PRIV_PF]]#0
+!CHECK: fir.store %[[PF_VAL]] to %[[PF]]#0
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PRIV_PS]]#0
+!CHECK: fir.store %[[PS_VAL]] to %[[PS]]#0
+subroutine test_lastprivate
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+ integer :: i
+
+ !$omp parallel do lastprivate(pf, ps)
+ do i = 1, 5
+ end do
+ !$omp end parallel do
+end subroutine
+
+!CHECK-LABEL: func private @_QFPtest_sections
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_sectionsEpf"}
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_sectionsEps"}
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_sectionsEpf"}
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PF]]#0
+!CHECK: fir.store %[[PF_VAL]] to %[[PRIV_PF]]#0
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_sectionsEps"}
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PS]]#0
+!CHECK: fir.store %[[PS_VAL]] to %[[PRIV_PS]]#0
+!CHECK: omp.sections
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PRIV_PF]]#0
+!CHECK: fir.store %[[PF_VAL]] to %[[PF]]#0
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PRIV_PS]]#0
+!CHECK: fir.store %[[PS_VAL]] to %[[PS]]#0
+subroutine test_sections
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+
+ !$omp sections firstprivate(pf, ps) lastprivate(pf, ps)
+ !$omp end sections
+end subroutine
+
+integer function f(arg)
+ integer :: arg
+ f = arg
+end function
+
+subroutine sub(arg)
+ integer :: arg
+end subroutine
+
+subroutine test_names
+ procedure(s0), pointer :: ps0
+ procedure(s1), pointer :: ps1
+ procedure(s2), pointer :: ps2
+
+ procedure(f0), pointer :: pf0
+ procedure(f1), pointer :: pf1
+ procedure(f2), pointer :: pf2
+
+ !$omp parallel private(ps0, ps1, ps2, pf0, pf1, pf2)
+ !$omp end parallel
+end subroutine
+
+subroutine s0
+end subroutine
+
+subroutine s1(i)
+ integer :: i
+end subroutine
+
+subroutine s2(i, j)
+ integer :: i
+ character(*) :: j
+end subroutine
+
+integer function f0
+ f0 = 0
+end function
+
+real function f1(r)
+ real :: r
+
+ f1 = 0.0
+end function
+
+function f2(a, c)
+ real :: a(3, 4)
+ complex :: f2, c
+
+ f2 = (0.0, 0.0)
+end function
+
+end program
|
|
@llvm/pr-subscribers-flang-openmp Author: Leandro Lupori (luporl) ChangesFixes #121720 Full diff: https://github.com/llvm/llvm-project/pull/130336.diff 4 Files Affected:
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index cc19f335cd017..425007da6b563 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -1274,6 +1274,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
[](const fir::FortranVariableOpInterface &box) {
return fir::FortranVariableOpInterface(box).isPointer();
},
+ [](const fir::AbstractBox &box) {
+ return fir::isBoxProcAddressType(box.getAddr().getType());
+ },
[](const auto &box) { return false; });
copyVarHLFIR(loc, dst, src, isBoxAllocatable, isBoxPointer, flags);
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index cc55191170c65..4bca4641a1b2e 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1842,7 +1842,7 @@ void Fortran::lower::genDeclareSymbol(
bool force) {
if (converter.getLoweringOptions().getLowerToHighLevelFIR() &&
(!Fortran::semantics::IsProcedure(sym) ||
- Fortran::semantics::IsPointer(sym)) &&
+ Fortran::semantics::IsPointer(sym.GetUltimate())) &&
!sym.detailsIf<Fortran::semantics::CommonBlockDetails>()) {
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
const mlir::Location loc = genLocation(converter, sym);
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 719cb1b9d75aa..6aa8ba4c9e7f4 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -553,70 +553,92 @@ std::string getTypeAsString(mlir::Type ty, const fir::KindMapping &kindMap,
llvm::raw_string_ostream name{buf};
if (!prefix.empty())
name << "_";
- while (ty) {
- if (fir::isa_trivial(ty)) {
- if (mlir::isa<mlir::IndexType>(ty)) {
- name << "idx";
- } else if (ty.isIntOrIndex()) {
- name << 'i' << ty.getIntOrFloatBitWidth();
- } else if (mlir::isa<mlir::FloatType>(ty)) {
- name << 'f' << ty.getIntOrFloatBitWidth();
- } else if (auto cplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(ty)) {
- name << 'z';
- auto floatTy = mlir::cast<mlir::FloatType>(cplxTy.getElementType());
- name << floatTy.getWidth();
- } else if (auto logTy = mlir::dyn_cast_or_null<fir::LogicalType>(ty)) {
- name << 'l' << kindMap.getLogicalBitsize(logTy.getFKind());
+
+ std::function<void(mlir::Type)> appendTypeName = [&](mlir::Type ty) {
+ while (ty) {
+ if (fir::isa_trivial(ty)) {
+ if (mlir::isa<mlir::IndexType>(ty)) {
+ name << "idx";
+ } else if (ty.isIntOrIndex()) {
+ name << 'i' << ty.getIntOrFloatBitWidth();
+ } else if (mlir::isa<mlir::FloatType>(ty)) {
+ name << 'f' << ty.getIntOrFloatBitWidth();
+ } else if (auto cplxTy =
+ mlir::dyn_cast_or_null<mlir::ComplexType>(ty)) {
+ name << 'z';
+ auto floatTy = mlir::cast<mlir::FloatType>(cplxTy.getElementType());
+ name << floatTy.getWidth();
+ } else if (auto logTy = mlir::dyn_cast_or_null<fir::LogicalType>(ty)) {
+ name << 'l' << kindMap.getLogicalBitsize(logTy.getFKind());
+ } else {
+ llvm::report_fatal_error("unsupported type");
+ }
+ break;
+ } else if (mlir::isa<mlir::NoneType>(ty)) {
+ name << "none";
+ break;
+ } else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(ty)) {
+ name << 'c' << kindMap.getCharacterBitsize(charTy.getFKind());
+ if (charTy.getLen() == fir::CharacterType::unknownLen())
+ name << "xU";
+ else if (charTy.getLen() != fir::CharacterType::singleton())
+ name << "x" << charTy.getLen();
+ break;
+ } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(ty)) {
+ for (auto extent : seqTy.getShape()) {
+ if (extent == fir::SequenceType::getUnknownExtent())
+ name << "Ux";
+ else
+ name << extent << 'x';
+ }
+ ty = seqTy.getEleTy();
+ } else if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
+ name << "ref_";
+ ty = refTy.getEleTy();
+ } else if (auto ptrTy = mlir::dyn_cast_or_null<fir::PointerType>(ty)) {
+ name << "ptr_";
+ ty = ptrTy.getEleTy();
+ } else if (auto ptrTy =
+ mlir::dyn_cast_or_null<fir::LLVMPointerType>(ty)) {
+ name << "llvmptr_";
+ ty = ptrTy.getEleTy();
+ } else if (auto heapTy = mlir::dyn_cast_or_null<fir::HeapType>(ty)) {
+ name << "heap_";
+ ty = heapTy.getEleTy();
+ } else if (auto classTy = mlir::dyn_cast_or_null<fir::ClassType>(ty)) {
+ name << "class_";
+ ty = classTy.getEleTy();
+ } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(ty)) {
+ name << "box_";
+ ty = boxTy.getEleTy();
+ } else if (auto boxcharTy =
+ mlir::dyn_cast_or_null<fir::BoxCharType>(ty)) {
+ name << "boxchar_";
+ ty = boxcharTy.getEleTy();
+ } else if (auto boxprocTy =
+ mlir::dyn_cast_or_null<fir::BoxProcType>(ty)) {
+ name << "boxproc_";
+ auto procTy = mlir::dyn_cast<mlir::FunctionType>(boxprocTy.getEleTy());
+ assert(procTy.getNumResults() <= 1 &&
+ "function type with more than one result");
+ for (const auto &result : procTy.getResults())
+ appendTypeName(result);
+ name << "_args";
+ for (const auto &arg : procTy.getInputs()) {
+ name << '_';
+ appendTypeName(arg);
+ }
+ break;
+ } else if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(ty)) {
+ name << "rec_" << recTy.getName();
+ break;
} else {
llvm::report_fatal_error("unsupported type");
}
- break;
- } else if (mlir::isa<mlir::NoneType>(ty)) {
- name << "none";
- break;
- } else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(ty)) {
- name << 'c' << kindMap.getCharacterBitsize(charTy.getFKind());
- if (charTy.getLen() == fir::CharacterType::unknownLen())
- name << "xU";
- else if (charTy.getLen() != fir::CharacterType::singleton())
- name << "x" << charTy.getLen();
- break;
- } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(ty)) {
- for (auto extent : seqTy.getShape()) {
- if (extent == fir::SequenceType::getUnknownExtent())
- name << "Ux";
- else
- name << extent << 'x';
- }
- ty = seqTy.getEleTy();
- } else if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
- name << "ref_";
- ty = refTy.getEleTy();
- } else if (auto ptrTy = mlir::dyn_cast_or_null<fir::PointerType>(ty)) {
- name << "ptr_";
- ty = ptrTy.getEleTy();
- } else if (auto ptrTy = mlir::dyn_cast_or_null<fir::LLVMPointerType>(ty)) {
- name << "llvmptr_";
- ty = ptrTy.getEleTy();
- } else if (auto heapTy = mlir::dyn_cast_or_null<fir::HeapType>(ty)) {
- name << "heap_";
- ty = heapTy.getEleTy();
- } else if (auto classTy = mlir::dyn_cast_or_null<fir::ClassType>(ty)) {
- name << "class_";
- ty = classTy.getEleTy();
- } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(ty)) {
- name << "box_";
- ty = boxTy.getEleTy();
- } else if (auto boxcharTy = mlir::dyn_cast_or_null<fir::BoxCharType>(ty)) {
- name << "boxchar_";
- ty = boxcharTy.getEleTy();
- } else if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(ty)) {
- name << "rec_" << recTy.getName();
- break;
- } else {
- llvm::report_fatal_error("unsupported type");
}
- }
+ };
+
+ appendTypeName(ty);
return buf;
}
diff --git a/flang/test/Lower/OpenMP/privatization-proc-ptr.f90 b/flang/test/Lower/OpenMP/privatization-proc-ptr.f90
new file mode 100644
index 0000000000000..168580edac878
--- /dev/null
+++ b/flang/test/Lower/OpenMP/privatization-proc-ptr.f90
@@ -0,0 +1,165 @@
+! Test privatization of procedure pointers.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+!RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+program proc_ptr_test
+ implicit none
+
+contains
+
+!CHECK: omp.private {type = private} @_QFFtest_namesEpf2_private_boxproc_z32_args_ref_3x4xf32_ref_z32 : !fir.boxproc<(!fir.ref<!fir.array<3x4xf32>>, !fir.ref<complex<f32>>) -> complex<f32>>
+!CHECK: omp.private {type = private} @_QFFtest_namesEpf1_private_boxproc_f32_args_ref_f32 : !fir.boxproc<(!fir.ref<f32>) -> f32>
+!CHECK: omp.private {type = private} @_QFFtest_namesEpf0_private_boxproc_i32_args : !fir.boxproc<() -> i32>
+!CHECK: omp.private {type = private} @_QFFtest_namesEps2_private_boxproc__args_ref_i32_boxchar_c8xU : !fir.boxproc<(!fir.ref<i32>, !fir.boxchar<1>) -> ()>
+!CHECK: omp.private {type = private} @_QFFtest_namesEps1_private_boxproc__args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> ()>
+!CHECK: omp.private {type = private} @_QFFtest_namesEps0_private_boxproc__args : !fir.boxproc<() -> ()>
+
+!CHECK: omp.private {type = private} @_QFFtest_lastprivateEps_private_boxproc__args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> ()>
+!CHECK: omp.private {type = private} @_QFFtest_lastprivateEpf_private_boxproc_i32_args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> i32>
+
+!CHECK: omp.private {type = firstprivate} @_QFFtest_firstprivateEps_firstprivate_boxproc__args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> ()> copy {
+!CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>, %[[ARG1:.*]]: !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>):
+!CHECK: %[[TEMP:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>
+!CHECK: fir.store %[[TEMP]] to %[[ARG1]] : !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>
+!CHECK: omp.yield(%[[ARG1]] : !fir.ref<!fir.boxproc<(!fir.ref<i32>) -> ()>>)
+!CHECK: }
+
+!CHECK: omp.private {type = firstprivate} @_QFFtest_firstprivateEpf_firstprivate_boxproc_i32_args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> i32>
+!CHECK: omp.private {type = private} @_QFFtest_privateEps_private_boxproc__args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> ()>
+!CHECK: omp.private {type = private} @_QFFtest_privateEpf_private_boxproc_i32_args_ref_i32 : !fir.boxproc<(!fir.ref<i32>) -> i32>
+
+!CHECK-LABEL: func private @_QFPtest_private
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_privateEpf"}
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_privateEps"}
+!CHECK: omp.parallel
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_privateEpf"}
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_privateEps"}
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PRIV_PF]]#0
+!CHECK: %[[PF_BOX:.*]] = fir.box_addr %[[PF_VAL]]
+!CHECK: fir.call %[[PF_BOX]]({{.*}})
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PRIV_PS]]#0
+!CHECK: %[[PS_BOX:.*]] = fir.box_addr %[[PS_VAL]]
+!CHECK: fir.call %[[PS_BOX]]({{.*}})
+subroutine test_private
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+ integer :: res
+
+ !$omp parallel private(pf, ps)
+ pf => f
+ ps => sub
+ res = pf(123)
+ call ps(456)
+ !$omp end parallel
+end subroutine
+
+!CHECK-LABEL: func private @_QFPtest_firstprivate
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_firstprivateEpf"}
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_firstprivateEps"}
+!CHECK: omp.parallel
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_firstprivateEpf"}
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_firstprivateEps"}
+subroutine test_firstprivate
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+
+ !$omp parallel firstprivate(pf, ps)
+ !$omp end parallel
+end subroutine
+
+!CHECK-LABEL: func private @_QFPtest_lastprivate
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_lastprivateEpf"}
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_lastprivateEps"}
+!CHECK: omp.parallel
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_lastprivateEpf"}
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_lastprivateEps"}
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PRIV_PF]]#0
+!CHECK: fir.store %[[PF_VAL]] to %[[PF]]#0
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PRIV_PS]]#0
+!CHECK: fir.store %[[PS_VAL]] to %[[PS]]#0
+subroutine test_lastprivate
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+ integer :: i
+
+ !$omp parallel do lastprivate(pf, ps)
+ do i = 1, 5
+ end do
+ !$omp end parallel do
+end subroutine
+
+!CHECK-LABEL: func private @_QFPtest_sections
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_sectionsEpf"}
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_sectionsEps"}
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_sectionsEpf"}
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PF]]#0
+!CHECK: fir.store %[[PF_VAL]] to %[[PRIV_PF]]#0
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %{{.*}} {{{.*}}uniq_name = "_QFFtest_sectionsEps"}
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PS]]#0
+!CHECK: fir.store %[[PS_VAL]] to %[[PRIV_PS]]#0
+!CHECK: omp.sections
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PRIV_PF]]#0
+!CHECK: fir.store %[[PF_VAL]] to %[[PF]]#0
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PRIV_PS]]#0
+!CHECK: fir.store %[[PS_VAL]] to %[[PS]]#0
+subroutine test_sections
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+
+ !$omp sections firstprivate(pf, ps) lastprivate(pf, ps)
+ !$omp end sections
+end subroutine
+
+integer function f(arg)
+ integer :: arg
+ f = arg
+end function
+
+subroutine sub(arg)
+ integer :: arg
+end subroutine
+
+subroutine test_names
+ procedure(s0), pointer :: ps0
+ procedure(s1), pointer :: ps1
+ procedure(s2), pointer :: ps2
+
+ procedure(f0), pointer :: pf0
+ procedure(f1), pointer :: pf1
+ procedure(f2), pointer :: pf2
+
+ !$omp parallel private(ps0, ps1, ps2, pf0, pf1, pf2)
+ !$omp end parallel
+end subroutine
+
+subroutine s0
+end subroutine
+
+subroutine s1(i)
+ integer :: i
+end subroutine
+
+subroutine s2(i, j)
+ integer :: i
+ character(*) :: j
+end subroutine
+
+integer function f0
+ f0 = 0
+end function
+
+real function f1(r)
+ real :: r
+
+ f1 = 0.0
+end function
+
+function f2(a, c)
+ real :: a(3, 4)
+ complex :: f2, c
+
+ f2 = (0.0, 0.0)
+end function
+
+end program
|
jeanPerier
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
ergawy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thanks!
tblah
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Fixes #121720