aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Lower/Bridge.cpp
diff options
context:
space:
mode:
authoragozillon <Andrew.Gozillon@amd.com>2024-03-05 17:27:16 +0100
committerGitHub <noreply@github.com>2024-03-05 17:27:16 +0100
commitafb05cd6469215232bd83e7cfbe59d2e1852567f (patch)
tree9c88de2c95d2ffe7a23c38af02425e7e0fec3794 /flang/lib/Lower/Bridge.cpp
parent3b84b6f1763159dbcdc487b201aa46a5c1c7b074 (diff)
downloadllvm-afb05cd6469215232bd83e7cfbe59d2e1852567f.zip
llvm-afb05cd6469215232bd83e7cfbe59d2e1852567f.tar.gz
llvm-afb05cd6469215232bd83e7cfbe59d2e1852567f.tar.bz2
[Flang][MLIR][OpenMP] Create a deferred declare target marking process for Bridge.cpp (#78502)
This patch seeks to create a process that happens on module finalization for OpenMP, in which a list of operations that had declare target directives applied to them and were not generated at the time of processing the original declare target directive are re-checked to apply the appropriate declare target semantics. This works by maintaining a vector of declare target related data inside of the FIR converter, in this case the symbol and the two relevant unsigned integers representing the enumerators. This vector is added to via a new function called from Bridge.cpp, insertDeferredDeclareTargets, which happens prior to the processing of the directive (similarly to getDeclareTargetFunctionDevice currently for requires), it effectively checks if the Operation the declare target directive is applied to currently exists, if it doesn't it appends to the vector. This is a seperate function to the processing of the declare target via the overloaded genOMP as we unfortunately do not have access to the list without passing it through every call, as the AbstractConverter we pass will not allow access to it (I've seen no other cases of casting it to a FirConverter, so I opted to not do that). The list is then processed at the end of the module in the finalizeOpenMPLowering function in Bridge by calling a new function markDelayedDeclareTargetFunctions which marks the latently generated operations. In certain cases, some still will not be generated, e.g. if an interface is defined, marked as declare target, but has no definition or usage in the module then it will not be emitted to the module, so due to these cases we must silently ignore when an operation has not been found via it's symbol. The main use-case for this (although, I imagine there is others) is for processing interfaces that have been declared in a module with a declare target directive but do not have their implementation defined in the same module. For example, inside of a seperate C++ module that will be linked in. In cases where the interface is called inside of a target region it'll be marked as used on device appropriately (although, realistically a user should explicitly mark it to match the corresponding definition), however, in cases where it's used in a non-clear manner through something like a function pointer passed to an external call we require this explicit marking, which this patch adds support for (currently will cause the compiler to crash). This patch also adds documentation on the declare target process and mechanisms within the compiler currently.
Diffstat (limited to 'flang/lib/Lower/Bridge.cpp')
-rw-r--r--flang/lib/Lower/Bridge.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 153ce06..8048693 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -2633,6 +2633,9 @@ private:
ompDeviceCodeFound ||
Fortran::lower::isOpenMPDeviceDeclareTarget(
*this, bridge.getSemanticsContext(), getEval(), ompDecl);
+ Fortran::lower::gatherOpenMPDeferredDeclareTargets(
+ *this, bridge.getSemanticsContext(), getEval(), ompDecl,
+ ompDeferredDeclareTarget);
genOpenMPDeclarativeConstruct(
*this, localSymbols, bridge.getSemanticsContext(), getEval(), ompDecl);
builder->restoreInsertionPoint(insertPt);
@@ -5171,6 +5174,13 @@ private:
/// lowering.
void finalizeOpenMPLowering(
const Fortran::semantics::Symbol *globalOmpRequiresSymbol) {
+ if (!ompDeferredDeclareTarget.empty()) {
+ bool deferredDeviceFuncFound =
+ Fortran::lower::markOpenMPDeferredDeclareTargetFunctions(
+ getModuleOp().getOperation(), ompDeferredDeclareTarget, *this);
+ ompDeviceCodeFound = ompDeviceCodeFound || deferredDeviceFuncFound;
+ }
+
// Set the module attribute related to OpenMP requires directives
if (ompDeviceCodeFound)
Fortran::lower::genOpenMPRequires(getModuleOp().getOperation(),
@@ -5227,6 +5237,13 @@ private:
/// intended for device offloading has been detected
bool ompDeviceCodeFound = false;
+ /// Keeps track of symbols defined as declare target that could not be
+ /// processed at the time of lowering the declare target construct, such
+ /// as certain cases where interfaces are declared but not defined within
+ /// a module.
+ llvm::SmallVector<Fortran::lower::OMPDeferredDeclareTargetInfo>
+ ompDeferredDeclareTarget;
+
const Fortran::lower::ExprToValueMap *exprValueOverrides{nullptr};
/// Stack of derived type under construction to avoid infinite loops when