[flang-commits] [flang] [Flang][OpenMp] Fix to threadprivate not working with host-association. (PR #74966)
via flang-commits
flang-commits at lists.llvm.org
Sat Mar 9 09:50:28 PST 2024
https://github.com/harishch4 updated https://github.com/llvm/llvm-project/pull/74966
>From 521dff8746e73b06dcef4883d4ecc90dd31e8d46 Mon Sep 17 00:00:00 2001
From: Harish Chambeti <harishcse44 at gmail.com>
Date: Sun, 10 Dec 2023 10:44:18 +0530
Subject: [PATCH 1/3] [Flang][OpenMp] Fix to threadprivate not working with
host-association.
---
flang/lib/Lower/HostAssociations.cpp | 14 +++++-
flang/lib/Lower/OpenMP/OpenMP.cpp | 15 +++++--
.../threadprivate-host-association-2.f90 | 44 +++++++++++++++++++
.../OpenMP/threadprivate-host-association.f90 | 42 ++++++++++++++++++
4 files changed, 110 insertions(+), 5 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/threadprivate-host-association-2.f90
create mode 100644 flang/test/Lower/OpenMP/threadprivate-host-association.f90
diff --git a/flang/lib/Lower/HostAssociations.cpp b/flang/lib/Lower/HostAssociations.cpp
index b9e13ccad1c929..f6e289bb7ceb20 100644
--- a/flang/lib/Lower/HostAssociations.cpp
+++ b/flang/lib/Lower/HostAssociations.cpp
@@ -16,6 +16,7 @@
#include "flang/Lower/ConvertVariable.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/SymbolMap.h"
+#include "flang/Lower/OpenMP.h"
#include "flang/Optimizer/Builder/Character.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
@@ -542,7 +543,10 @@ void Fortran::lower::HostAssociations::addSymbolsToBind(
"must be initially empty");
this->hostScope = &hostScope;
for (const auto *s : symbols)
- if (Fortran::lower::symbolIsGlobal(*s)) {
+ // GlobalOp are created for non-global threadprivate variable,
+ // so considering them as globals.
+ if (Fortran::lower::symbolIsGlobal(*s) ||
+ (*s).test(Fortran::semantics::Symbol::Flag::OmpThreadprivate)) {
// The ultimate symbol is stored here so that global symbols from the
// host scope can later be searched in this set.
globalSymbols.insert(&s->GetUltimate());
@@ -590,9 +594,15 @@ void Fortran::lower::HostAssociations::internalProcedureBindings(
for (auto &hostVariable : pft::getScopeVariableList(*hostScope))
if ((hostVariable.isAggregateStore() && hostVariable.isGlobal()) ||
(hostVariable.hasSymbol() &&
- globalSymbols.contains(&hostVariable.getSymbol().GetUltimate())))
+ globalSymbols.contains(&hostVariable.getSymbol().GetUltimate()))) {
Fortran::lower::instantiateVariable(converter, hostVariable, symMap,
storeMap);
+ // Generate threadprivate Op for host associated variables.
+ if (hostVariable.hasSymbol() &&
+ hostVariable.getSymbol().test(
+ Fortran::semantics::Symbol::Flag::OmpThreadprivate))
+ Fortran::lower::genThreadprivateOp(converter, hostVariable);
+ }
}
if (tupleSymbols.empty())
return;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 5cff95c7d125b0..6db086cfd26ca2 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -172,7 +172,9 @@ static void threadPrivatizeVars(Fortran::lower::AbstractConverter &converter,
llvm::SetVector<const Fortran::semantics::Symbol *> threadprivateSyms;
converter.collectSymbolSet(
eval, threadprivateSyms,
- Fortran::semantics::Symbol::Flag::OmpThreadprivate);
+ Fortran::semantics::Symbol::Flag::OmpThreadprivate,
+ /*collectSymbols=*/true,
+ /*collectHostAssociatedSymbols=*/true);
std::set<Fortran::semantics::SourceName> threadprivateSymNames;
// For a COMMON block, the ThreadprivateOp is generated for itself instead of
@@ -2276,8 +2278,15 @@ void Fortran::lower::genThreadprivateOp(
// variable in main program, and it has implicit SAVE attribute. Take it as
// with SAVE attribute, so to create GlobalOp for it to simplify the
// translation to LLVM IR.
- fir::GlobalOp global = globalInitialization(converter, firOpBuilder, sym,
- var, currentLocation);
+ // Avoids performing multiple globalInitializations.
+ fir::GlobalOp global;
+ auto module = converter.getModuleOp();
+ std::string globalName = converter.mangleName(sym);
+ if (module.lookupSymbol<fir::GlobalOp>(globalName))
+ global = module.lookupSymbol<fir::GlobalOp>(globalName);
+ else
+ global = globalInitialization(converter, firOpBuilder, sym, var,
+ currentLocation);
mlir::Value symValue = firOpBuilder.create<fir::AddrOfOp>(
currentLocation, global.resultType(), global.getSymbol());
diff --git a/flang/test/Lower/OpenMP/threadprivate-host-association-2.f90 b/flang/test/Lower/OpenMP/threadprivate-host-association-2.f90
new file mode 100644
index 00000000000000..b47bff5bebb0b2
--- /dev/null
+++ b/flang/test/Lower/OpenMP/threadprivate-host-association-2.f90
@@ -0,0 +1,44 @@
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for threadprivate variable in host association.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+!CHECK: func.func @_QQmain() attributes {fir.bindc_name = "main"} {
+!CHECK: %[[A:.*]] = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFEa"}
+!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[A_ADDR:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
+!CHECK: %[[TP_A:.*]] = omp.threadprivate %[[A_ADDR]] : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK: %[[TP_A_DECL:.*]]:2 = hlfir.declare %[[TP_A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: fir.call @_QFPsub() fastmath<contract> : () -> ()
+!CHECK: return
+!CHECK: }
+!CHECK: func.func private @_QFPsub() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
+!CHECK: %[[A:.*]] = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFEa"}
+!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[A_ADDR:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
+!CHECK: %[[TP_A:.*]] = omp.threadprivate %[[A_ADDR]] : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK: %[[TP_A_DECL:.*]]:2 = hlfir.declare %[[TP_A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: omp.parallel {
+!CHECK: %[[PAR_TP_A:.*]] = omp.threadprivate %[[A_ADDR]] : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK: %[[PAR_TP_A_DECL:.*]]:2 = hlfir.declare %[[PAR_TP_A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %{{.*}} = fir.load %[[PAR_TP_A_DECL]]#0 : !fir.ref<i32>
+!CHECK: omp.terminator
+!CHECK: }
+!CHECK: return
+!CHECK: }
+!CHECK: fir.global internal @_QFEa : i32 {
+!CHECK: %[[A:.*]] = fir.undefined i32
+!CHECK: fir.has_value %[[A]] : i32
+!CHECK: }
+
+program main
+ integer :: a
+ !$omp threadprivate(a)
+ call sub()
+contains
+ subroutine sub()
+ !$omp parallel
+ print *, a
+ !$omp end parallel
+ end
+end
diff --git a/flang/test/Lower/OpenMP/threadprivate-host-association.f90 b/flang/test/Lower/OpenMP/threadprivate-host-association.f90
new file mode 100644
index 00000000000000..98f7b51bb97115
--- /dev/null
+++ b/flang/test/Lower/OpenMP/threadprivate-host-association.f90
@@ -0,0 +1,42 @@
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for threadprivate variable in host association.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+!CHECK: func.func @_QQmain() attributes {fir.bindc_name = "main"} {
+!CHECK: %[[A:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
+!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[TP_A:.*]] = omp.threadprivate %[[A_DECL]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK: %[[TP_A_DECL:.*]]:2 = hlfir.declare %[[TP_A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: fir.call @_QFPsub() fastmath<contract> : () -> ()
+!CHECK: return
+!CHECK: }
+!CHECK: func.func private @_QFPsub() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
+!CHECK: %[[A:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
+!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[TP_A:.*]] = omp.threadprivate %[[A_DECL]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK: %[[TP_A_DECL:.*]]:2 = hlfir.declare %[[TP_A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: omp.parallel {
+!CHECK: %[[PAR_TP_A:.*]] = omp.threadprivate %[[A_DECL]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK: %[[PAR_TP_A_DECL:.*]]:2 = hlfir.declare %[[PAR_TP_A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %{{.*}} = fir.load %[[PAR_TP_A_DECL]]#0 : !fir.ref<i32>
+!CHECK: omp.terminator
+!CHECK: }
+!CHECK: return
+!CHECK: }
+!CHECK: fir.global internal @_QFEa : i32 {
+!CHECK: %[[A:.*]] = fir.zero_bits i32
+!CHECK: fir.has_value %[[A]] : i32
+!CHECK: }
+
+program main
+ integer, save :: a
+ !$omp threadprivate(a)
+ call sub()
+contains
+ subroutine sub()
+ !$omp parallel
+ print *, a
+ !$omp end parallel
+ end
+end
>From 34c43928a41da0d608ca6628697fa74719702ba6 Mon Sep 17 00:00:00 2001
From: Harish Chambeti <harishcse44 at gmail.com>
Date: Sat, 9 Mar 2024 23:14:12 +0530
Subject: [PATCH 2/3] Fix code format
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6db086cfd26ca2..4f0bb80cd7fdf6 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -170,9 +170,8 @@ static void threadPrivatizeVars(Fortran::lower::AbstractConverter &converter,
};
llvm::SetVector<const Fortran::semantics::Symbol *> threadprivateSyms;
- converter.collectSymbolSet(
- eval, threadprivateSyms,
- Fortran::semantics::Symbol::Flag::OmpThreadprivate,
+ converter.collectSymbolSet(eval, threadprivateSyms,
+ Fortran::semantics::Symbol::Flag::OmpThreadprivate,
/*collectSymbols=*/true,
/*collectHostAssociatedSymbols=*/true);
std::set<Fortran::semantics::SourceName> threadprivateSymNames;
>From 06d571c10d837e41c2704463a37b774247a526ef Mon Sep 17 00:00:00 2001
From: Harish Chambeti <harishcse44 at gmail.com>
Date: Sat, 9 Mar 2024 23:20:14 +0530
Subject: [PATCH 3/3] Fix code format
---
flang/lib/Lower/HostAssociations.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Lower/HostAssociations.cpp b/flang/lib/Lower/HostAssociations.cpp
index f6e289bb7ceb20..414673b00f44ca 100644
--- a/flang/lib/Lower/HostAssociations.cpp
+++ b/flang/lib/Lower/HostAssociations.cpp
@@ -14,9 +14,9 @@
#include "flang/Lower/CallInterface.h"
#include "flang/Lower/ConvertType.h"
#include "flang/Lower/ConvertVariable.h"
+#include "flang/Lower/OpenMP.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/SymbolMap.h"
-#include "flang/Lower/OpenMP.h"
#include "flang/Optimizer/Builder/Character.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
More information about the flang-commits
mailing list