[Flang][OpenMP] Extend omp requires detection in Bridge.cpp (#188106)
Currently, we do not check the module for requires directives, which means we'll miss these and not set them on the OpenMP module. Otherwise, due to the first come first serve method we currently check the symbols, there is certain formats that would mean the compiler would miss that a user had specified requires somewhere in the module. This is partially but not fully avoided by the Semantics layer pushing the requires on to the top most PFT symbol, as it is entirely possible to create a legal Fortran program where you could have two or more of these (e.g. module and main program in one file, standalone funcitons intermixed with modules or main program). Some examples of this are shown in the added Fortran test. This PR opts to resolve it by gathering all of the relevant symbols and processing them. Also removed gathering from BlockDataUnit as I don't think these symbols ever get the requires applied.
This commit is contained in:
parent
fbf484009c
commit
e55c85341d
@ -494,7 +494,8 @@ public:
|
||||
// - Define module variables and OpenMP/OpenACC declarative constructs so
|
||||
// they are available before lowering any function that may use them.
|
||||
bool hasMainProgram = false;
|
||||
const Fortran::semantics::Symbol *globalOmpRequiresSymbol = nullptr;
|
||||
llvm::SmallVector<const Fortran::semantics::Symbol *>
|
||||
globalOmpRequiresSymbols;
|
||||
createBuilderOutsideOfFuncOpAndDo([&]() {
|
||||
for (Fortran::lower::pft::Program::Units &u : pft.getUnits()) {
|
||||
Fortran::common::visit(
|
||||
@ -503,8 +504,7 @@ public:
|
||||
if (f.isMainProgram())
|
||||
hasMainProgram = true;
|
||||
declareFunction(f);
|
||||
if (!globalOmpRequiresSymbol)
|
||||
globalOmpRequiresSymbol = f.getScope().symbol();
|
||||
globalOmpRequiresSymbols.push_back(f.getScope().symbol());
|
||||
},
|
||||
[&](Fortran::lower::pft::ModuleLikeUnit &m) {
|
||||
lowerModuleDeclScope(m);
|
||||
@ -512,12 +512,15 @@ public:
|
||||
m.containedUnitList)
|
||||
if (auto *f =
|
||||
std::get_if<Fortran::lower::pft::FunctionLikeUnit>(
|
||||
&unit))
|
||||
&unit)) {
|
||||
declareFunction(*f);
|
||||
globalOmpRequiresSymbols.push_back(
|
||||
f->getScope().symbol());
|
||||
}
|
||||
globalOmpRequiresSymbols.push_back(m.getScope().symbol());
|
||||
},
|
||||
[&](Fortran::lower::pft::BlockDataUnit &b) {
|
||||
if (!globalOmpRequiresSymbol)
|
||||
globalOmpRequiresSymbol = b.symTab.symbol();
|
||||
globalOmpRequiresSymbols.push_back(b.symTab.symbol());
|
||||
},
|
||||
[&](Fortran::lower::pft::CompilerDirectiveUnit &d) {},
|
||||
[&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {},
|
||||
@ -567,7 +570,7 @@ public:
|
||||
Fortran::common::LanguageFeature::Coarray));
|
||||
});
|
||||
|
||||
finalizeOpenMPLowering(globalOmpRequiresSymbol);
|
||||
finalizeOpenMPLowering(globalOmpRequiresSymbols);
|
||||
}
|
||||
|
||||
/// Declare a function.
|
||||
@ -7201,7 +7204,8 @@ private:
|
||||
/// Performing OpenMP lowering actions that were deferred to the end of
|
||||
/// lowering.
|
||||
void finalizeOpenMPLowering(
|
||||
const Fortran::semantics::Symbol *globalOmpRequiresSymbol) {
|
||||
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *>
|
||||
&globalOmpRequiresSymbol) {
|
||||
if (!ompDeferredDeclareTarget.empty()) {
|
||||
bool deferredDeviceFuncFound =
|
||||
Fortran::lower::markOpenMPDeferredDeclareTargetFunctions(
|
||||
@ -7210,9 +7214,10 @@ private:
|
||||
}
|
||||
|
||||
// Set the module attribute related to OpenMP requires directives
|
||||
if (ompDeviceCodeFound)
|
||||
Fortran::lower::genOpenMPRequires(getModuleOp().getOperation(),
|
||||
globalOmpRequiresSymbol);
|
||||
if (ompDeviceCodeFound) {
|
||||
for (const Fortran::semantics::Symbol *sym : globalOmpRequiresSymbol)
|
||||
Fortran::lower::genOpenMPRequires(getModuleOp().getOperation(), sym);
|
||||
}
|
||||
}
|
||||
|
||||
/// Record fir.dummy_scope operation for this function.
|
||||
|
||||
56
flang/test/Lower/OpenMP/requires-usm.f90
Normal file
56
flang/test/Lower/OpenMP/requires-usm.f90
Normal file
@ -0,0 +1,56 @@
|
||||
! RUN: split-file %s %t
|
||||
|
||||
! Verify that we pick up requires USM and apply it correctly when it is specified
|
||||
! outside of the program.
|
||||
|
||||
! RUN: %flang_fc1 -emit-hlfir -fopenmp %t/requires-usm.f90 -o - | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %t/requires-usm.f90 -o - | FileCheck %s
|
||||
! RUN: bbc -fopenmp -emit-hlfir %t/requires-usm.f90 -o - | FileCheck %s
|
||||
! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %t/requires-usm.f90 -o - | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-hlfir -fopenmp %t/requires-usm-subroutine-after.f90 -o - | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %t/requires-usm-subroutine-after.f90 -o - | FileCheck %s
|
||||
! RUN: bbc -fopenmp -emit-hlfir %t/requires-usm-subroutine-after.f90 -o - | FileCheck %s
|
||||
! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %t/requires-usm-subroutine-after.f90 -o - | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-hlfir -fopenmp %t/requires-usm-program-after.f90 -o - | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %t/requires-usm-program-after.f90 -o - | FileCheck %s
|
||||
! RUN: bbc -fopenmp -emit-hlfir %t/requires-usm-program-after.f90 -o - | FileCheck %s
|
||||
! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %t/requires-usm-program-after.f90 -o - | FileCheck %s
|
||||
|
||||
! CHECK: module attributes {
|
||||
! CHECK-SAME: omp.requires = #omp<clause_requires unified_shared_memory>
|
||||
|
||||
!--- requires-usm.f90
|
||||
module declare_mod
|
||||
implicit none
|
||||
!$omp requires unified_shared_memory
|
||||
contains
|
||||
end module
|
||||
|
||||
program main
|
||||
use declare_mod
|
||||
implicit none
|
||||
!$omp target
|
||||
!$omp end target
|
||||
end program
|
||||
|
||||
!--- requires-usm-subroutine-after.f90
|
||||
program main
|
||||
implicit none
|
||||
end program main
|
||||
|
||||
subroutine test
|
||||
!$omp requires unified_shared_memory
|
||||
!$omp target
|
||||
!$omp end target
|
||||
end subroutine
|
||||
|
||||
!--- requires-usm-program-after.f90
|
||||
subroutine test
|
||||
end subroutine
|
||||
|
||||
program main
|
||||
implicit none
|
||||
!$omp requires unified_shared_memory
|
||||
!$omp target
|
||||
!$omp end target
|
||||
end program main
|
||||
Loading…
x
Reference in New Issue
Block a user