Skip to content

Commit c9ae0ce

Browse files
committed
[Flang][OpenMP] Increase detection capability for requires usm (and others)
Currently, the compiler only picks up some cases where requires is designated such as in the main program. However, it'll gloss over cases such as when it is specified by a user in a module, that's then used elsewhere. This patch attempts to amend that by searching the varying scopes in the current program module more comprehensively.
1 parent 07eeb5f commit c9ae0ce

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

flang/lib/Lower/Bridge.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
415415
// - Define module variables and OpenMP/OpenACC declarative constructs so
416416
// they are available before lowering any function that may use them.
417417
bool hasMainProgram = false;
418-
const Fortran::semantics::Symbol *globalOmpRequiresSymbol = nullptr;
418+
llvm::SmallVector<const Fortran::semantics::Symbol *>
419+
globalOmpRequiresSymbols;
419420
createBuilderOutsideOfFuncOpAndDo([&]() {
420421
for (Fortran::lower::pft::Program::Units &u : pft.getUnits()) {
421422
Fortran::common::visit(
@@ -424,21 +425,23 @@ class FirConverter : public Fortran::lower::AbstractConverter {
424425
if (f.isMainProgram())
425426
hasMainProgram = true;
426427
declareFunction(f);
427-
if (!globalOmpRequiresSymbol)
428-
globalOmpRequiresSymbol = f.getScope().symbol();
428+
globalOmpRequiresSymbols.push_back(f.getScope().symbol());
429429
},
430430
[&](Fortran::lower::pft::ModuleLikeUnit &m) {
431431
lowerModuleDeclScope(m);
432432
for (Fortran::lower::pft::ContainedUnit &unit :
433433
m.containedUnitList)
434434
if (auto *f =
435435
std::get_if<Fortran::lower::pft::FunctionLikeUnit>(
436-
&unit))
436+
&unit)) {
437437
declareFunction(*f);
438+
globalOmpRequiresSymbols.push_back(
439+
f->getScope().symbol());
440+
}
441+
globalOmpRequiresSymbols.push_back(m.getScope().symbol());
438442
},
439443
[&](Fortran::lower::pft::BlockDataUnit &b) {
440-
if (!globalOmpRequiresSymbol)
441-
globalOmpRequiresSymbol = b.symTab.symbol();
444+
globalOmpRequiresSymbols.push_back(b.symTab.symbol());
442445
},
443446
[&](Fortran::lower::pft::CompilerDirectiveUnit &d) {},
444447
[&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {},
@@ -481,7 +484,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
481484
Fortran::common::LanguageFeature::Coarray));
482485
});
483486

484-
finalizeOpenMPLowering(globalOmpRequiresSymbol);
487+
finalizeOpenMPLowering(globalOmpRequiresSymbols);
485488
}
486489

487490
/// Declare a function.
@@ -6681,7 +6684,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
66816684
/// Performing OpenMP lowering actions that were deferred to the end of
66826685
/// lowering.
66836686
void finalizeOpenMPLowering(
6684-
const Fortran::semantics::Symbol *globalOmpRequiresSymbol) {
6687+
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *>
6688+
&globalOmpRequiresSymbol) {
66856689
if (!ompDeferredDeclareTarget.empty()) {
66866690
bool deferredDeviceFuncFound =
66876691
Fortran::lower::markOpenMPDeferredDeclareTargetFunctions(
@@ -6690,9 +6694,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
66906694
}
66916695

66926696
// Set the module attribute related to OpenMP requires directives
6693-
if (ompDeviceCodeFound)
6694-
Fortran::lower::genOpenMPRequires(getModuleOp().getOperation(),
6695-
globalOmpRequiresSymbol);
6697+
if (ompDeviceCodeFound) {
6698+
for (auto sym : globalOmpRequiresSymbol)
6699+
Fortran::lower::genOpenMPRequires(getModuleOp().getOperation(), sym);
6700+
}
66966701
}
66976702

66986703
/// Record fir.dummy_scope operation for this function.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
2+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
3+
! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s
4+
! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %s -o - | FileCheck %s
5+
6+
! Verify that we pick up USM and apply it correctly when it is specified
7+
! outside of the program.
8+
9+
!CHECK: module attributes {
10+
!CHECK-SAME: omp.requires = #omp<clause_requires unified_shared_memory>
11+
module declare_mod
12+
implicit none
13+
!$omp requires unified_shared_memory
14+
contains
15+
end module
16+
17+
program main
18+
use declare_mod
19+
implicit none
20+
!$omp target
21+
!$omp end target
22+
end program

0 commit comments

Comments
 (0)