[NFC][OpenMP][mlir][flang] Move OMP offloading module attribute handling from flang to mlir (#186409)
This patch moves the OpenMP offloding module attributes handling from flang to mlir so that it can be reused in ClangIR was well. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Michael Kruse <github@meinersbur.de>
This commit is contained in:
parent
b491bd9826
commit
d7e60d5250
@ -157,89 +157,15 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks {
|
||||
Fortran::common::FPMaxminBehavior::Legacy;
|
||||
};
|
||||
|
||||
struct OffloadModuleOpts {
|
||||
OffloadModuleOpts() {}
|
||||
OffloadModuleOpts(uint32_t OpenMPTargetDebug, bool OpenMPTeamSubscription,
|
||||
bool OpenMPThreadSubscription, bool OpenMPNoThreadState,
|
||||
bool OpenMPNoNestedParallelism, bool OpenMPIsTargetDevice,
|
||||
bool OpenMPIsGPU, bool OpenMPForceUSM, uint32_t OpenMPVersion,
|
||||
std::string OMPHostIRFile = {},
|
||||
const std::vector<llvm::Triple> &OMPTargetTriples = {},
|
||||
bool NoGPULib = false)
|
||||
: OpenMPTargetDebug(OpenMPTargetDebug),
|
||||
OpenMPTeamSubscription(OpenMPTeamSubscription),
|
||||
OpenMPThreadSubscription(OpenMPThreadSubscription),
|
||||
OpenMPNoThreadState(OpenMPNoThreadState),
|
||||
OpenMPNoNestedParallelism(OpenMPNoNestedParallelism),
|
||||
OpenMPIsTargetDevice(OpenMPIsTargetDevice), OpenMPIsGPU(OpenMPIsGPU),
|
||||
OpenMPForceUSM(OpenMPForceUSM), OpenMPVersion(OpenMPVersion),
|
||||
OMPHostIRFile(OMPHostIRFile),
|
||||
OMPTargetTriples(OMPTargetTriples.begin(), OMPTargetTriples.end()),
|
||||
NoGPULib(NoGPULib) {}
|
||||
|
||||
OffloadModuleOpts(Fortran::common::LangOptions &Opts)
|
||||
: OpenMPTargetDebug(Opts.OpenMPTargetDebug),
|
||||
OpenMPTeamSubscription(Opts.OpenMPTeamSubscription),
|
||||
OpenMPThreadSubscription(Opts.OpenMPThreadSubscription),
|
||||
OpenMPNoThreadState(Opts.OpenMPNoThreadState),
|
||||
OpenMPNoNestedParallelism(Opts.OpenMPNoNestedParallelism),
|
||||
OpenMPIsTargetDevice(Opts.OpenMPIsTargetDevice),
|
||||
OpenMPIsGPU(Opts.OpenMPIsGPU), OpenMPForceUSM(Opts.OpenMPForceUSM),
|
||||
OpenMPVersion(Opts.OpenMPVersion), OMPHostIRFile(Opts.OMPHostIRFile),
|
||||
OMPTargetTriples(Opts.OMPTargetTriples), NoGPULib(Opts.NoGPULib) {}
|
||||
|
||||
uint32_t OpenMPTargetDebug = 0;
|
||||
bool OpenMPTeamSubscription = false;
|
||||
bool OpenMPThreadSubscription = false;
|
||||
bool OpenMPNoThreadState = false;
|
||||
bool OpenMPNoNestedParallelism = false;
|
||||
bool OpenMPIsTargetDevice = false;
|
||||
bool OpenMPIsGPU = false;
|
||||
bool OpenMPForceUSM = false;
|
||||
uint32_t OpenMPVersion = 31;
|
||||
std::string OMPHostIRFile = {};
|
||||
std::vector<llvm::Triple> OMPTargetTriples = {};
|
||||
bool NoGPULib = false;
|
||||
};
|
||||
|
||||
// Shares assinging of the OpenMP OffloadModuleInterface and its assorted
|
||||
// attributes accross Flang tools (bbc/flang)
|
||||
[[maybe_unused]] static void setOffloadModuleInterfaceAttributes(
|
||||
mlir::ModuleOp module, OffloadModuleOpts Opts) {
|
||||
// Should be registered by the OpenMPDialect
|
||||
if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
|
||||
module.getOperation())) {
|
||||
offloadMod.setIsTargetDevice(Opts.OpenMPIsTargetDevice);
|
||||
offloadMod.setIsGPU(Opts.OpenMPIsGPU);
|
||||
if (Opts.OpenMPForceUSM) {
|
||||
offloadMod.setRequires(mlir::omp::ClauseRequires::unified_shared_memory);
|
||||
}
|
||||
if (Opts.OpenMPIsTargetDevice) {
|
||||
offloadMod.setFlags(Opts.OpenMPTargetDebug, Opts.OpenMPTeamSubscription,
|
||||
Opts.OpenMPThreadSubscription, Opts.OpenMPNoThreadState,
|
||||
Opts.OpenMPNoNestedParallelism, Opts.OpenMPVersion, Opts.NoGPULib);
|
||||
|
||||
if (!Opts.OMPHostIRFile.empty())
|
||||
offloadMod.setHostIRFilePath(Opts.OMPHostIRFile);
|
||||
}
|
||||
auto strTriples = llvm::to_vector(llvm::map_range(Opts.OMPTargetTriples,
|
||||
[](llvm::Triple triple) { return triple.normalize(); }));
|
||||
offloadMod.setTargetTriples(strTriples);
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void setOpenMPVersionAttribute(
|
||||
mlir::ModuleOp module, int64_t version) {
|
||||
module.getOperation()->setAttr(
|
||||
mlir::StringAttr::get(module.getContext(), llvm::Twine{"omp.version"}),
|
||||
mlir::omp::VersionAttr::get(module.getContext(), version));
|
||||
}
|
||||
|
||||
[[maybe_unused]] static int64_t getOpenMPVersionAttribute(
|
||||
mlir::ModuleOp module, int64_t fallback = -1) {
|
||||
if (mlir::Attribute verAttr = module->getAttr("omp.version"))
|
||||
return llvm::cast<mlir::omp::VersionAttr>(verAttr).getVersion();
|
||||
return fallback;
|
||||
/// Create OffloadModuleOpts from Flang LangOptions.
|
||||
[[maybe_unused]] static mlir::omp::OffloadModuleOpts makeOffloadModuleOpts(
|
||||
Fortran::common::LangOptions &Opts) {
|
||||
return mlir::omp::OffloadModuleOpts(Opts.OpenMPTargetDebug,
|
||||
Opts.OpenMPTeamSubscription, Opts.OpenMPThreadSubscription,
|
||||
Opts.OpenMPNoThreadState, Opts.OpenMPNoNestedParallelism,
|
||||
Opts.OpenMPIsTargetDevice, Opts.OpenMPIsGPU, Opts.OpenMPForceUSM,
|
||||
Opts.OpenMPVersion, Opts.OMPHostIRFile, Opts.OMPTargetTriples,
|
||||
Opts.NoGPULib);
|
||||
}
|
||||
|
||||
#endif // FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
|
||||
|
||||
@ -273,10 +273,11 @@ bool CodeGenAction::beginSourceFileAction() {
|
||||
|
||||
if (ci.getInvocation().getFrontendOpts().features.IsEnabled(
|
||||
Fortran::common::LanguageFeature::OpenMP)) {
|
||||
setOffloadModuleInterfaceAttributes(lb.getModule(),
|
||||
ci.getInvocation().getLangOpts());
|
||||
setOpenMPVersionAttribute(lb.getModule(),
|
||||
ci.getInvocation().getLangOpts().OpenMPVersion);
|
||||
mlir::omp::setOffloadModuleInterfaceAttributes(
|
||||
lb.getModule(),
|
||||
makeOffloadModuleOpts(ci.getInvocation().getLangOpts()));
|
||||
mlir::omp::setOpenMPVersionAttribute(
|
||||
lb.getModule(), ci.getInvocation().getLangOpts().OpenMPVersion);
|
||||
}
|
||||
|
||||
if (ci.getInvocation().getLangOpts().FastRealMod) {
|
||||
|
||||
@ -42,9 +42,9 @@ struct ConstructDecomposition {
|
||||
llvm::omp::Directive compound,
|
||||
const List<Clause> &clauses)
|
||||
: semaCtx(semaCtx), mod(modOp), eval(ev) {
|
||||
tomp::ConstructDecompositionT decompose(getOpenMPVersionAttribute(modOp),
|
||||
*this, compound,
|
||||
llvm::ArrayRef(clauses));
|
||||
tomp::ConstructDecompositionT decompose(
|
||||
mlir::omp::getOpenMPVersionAttribute(modOp), *this, compound,
|
||||
llvm::ArrayRef(clauses));
|
||||
output = std::move(decompose.output);
|
||||
}
|
||||
|
||||
|
||||
@ -502,13 +502,14 @@ static llvm::LogicalResult convertFortranSourceToMLIR(
|
||||
for (llvm::StringRef s : targetTriplesOpenMP)
|
||||
targetTriples.emplace_back(s);
|
||||
|
||||
auto offloadModuleOpts = OffloadModuleOpts(
|
||||
auto offloadModuleOpts = mlir::omp::OffloadModuleOpts(
|
||||
setOpenMPTargetDebug, setOpenMPTeamSubscription,
|
||||
setOpenMPThreadSubscription, setOpenMPNoThreadState,
|
||||
setOpenMPNoNestedParallelism, enableOpenMPDevice, enableOpenMPGPU,
|
||||
enableOpenMPForceUSM, setOpenMPVersion, "", targetTriples, setNoGPULib);
|
||||
setOffloadModuleInterfaceAttributes(mlirModule, offloadModuleOpts);
|
||||
setOpenMPVersionAttribute(mlirModule, setOpenMPVersion);
|
||||
mlir::omp::setOffloadModuleInterfaceAttributes(mlirModule,
|
||||
offloadModuleOpts);
|
||||
mlir::omp::setOpenMPVersionAttribute(mlirModule, setOpenMPVersion);
|
||||
}
|
||||
burnside.lower(parseTree, semanticsContext);
|
||||
std::error_code ec;
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "mlir/Dialect/OpenACCMPCommon/Interfaces/AtomicInterfaces.h"
|
||||
#include "mlir/Dialect/OpenACCMPCommon/Interfaces/OpenACCMPOpsInterfaces.h"
|
||||
#include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
|
||||
#include "mlir/Dialect/OpenMP/OpenMPOffloadUtils.h"
|
||||
#include "mlir/IR/Dialect.h"
|
||||
#include "mlir/IR/OpDefinition.h"
|
||||
#include "mlir/IR/PatternMatch.h"
|
||||
|
||||
105
mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h
Normal file
105
mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h
Normal file
@ -0,0 +1,105 @@
|
||||
//===- OpenMPOffloadUtils.h - OpenMP offload utilities ----------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// \file
|
||||
/// Shared utilities for setting OpenMP offload module interface attributes.
|
||||
/// These are used by both Flang and Clang (CIR) frontends.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef MLIR_DIALECT_OPENMP_OPENMPOFFLOADUTILS_H_
|
||||
#define MLIR_DIALECT_OPENMP_OPENMPOFFLOADUTILS_H_
|
||||
|
||||
#include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
|
||||
#include "mlir/Dialect/OpenMP/OpenMPOpsAttributes.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/TargetParser/Triple.h"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace mlir::omp {
|
||||
|
||||
struct OffloadModuleOpts {
|
||||
OffloadModuleOpts() = default;
|
||||
OffloadModuleOpts(uint32_t openMPTargetDebug, bool openMPTeamSubscription,
|
||||
bool openMPThreadSubscription, bool openMPNoThreadState,
|
||||
bool openMPNoNestedParallelism, bool openMPIsTargetDevice,
|
||||
bool openMPIsGPU, bool openMPForceUSM,
|
||||
uint32_t openMPVersion, std::string ompHostIRFile = {},
|
||||
const std::vector<llvm::Triple> &ompTargetTriples = {},
|
||||
bool noGPULib = false)
|
||||
: OpenMPTargetDebug(openMPTargetDebug),
|
||||
OpenMPTeamSubscription(openMPTeamSubscription),
|
||||
OpenMPThreadSubscription(openMPThreadSubscription),
|
||||
OpenMPNoThreadState(openMPNoThreadState),
|
||||
OpenMPNoNestedParallelism(openMPNoNestedParallelism),
|
||||
OpenMPIsTargetDevice(openMPIsTargetDevice), OpenMPIsGPU(openMPIsGPU),
|
||||
OpenMPForceUSM(openMPForceUSM), OpenMPVersion(openMPVersion),
|
||||
OMPHostIRFile(std::move(ompHostIRFile)),
|
||||
OMPTargetTriples(ompTargetTriples.begin(), ompTargetTriples.end()),
|
||||
NoGPULib(noGPULib) {}
|
||||
|
||||
uint32_t OpenMPTargetDebug = 0;
|
||||
bool OpenMPTeamSubscription = false;
|
||||
bool OpenMPThreadSubscription = false;
|
||||
bool OpenMPNoThreadState = false;
|
||||
bool OpenMPNoNestedParallelism = false;
|
||||
bool OpenMPIsTargetDevice = false;
|
||||
bool OpenMPIsGPU = false;
|
||||
bool OpenMPForceUSM = false;
|
||||
uint32_t OpenMPVersion = 31;
|
||||
std::string OMPHostIRFile = {};
|
||||
std::vector<llvm::Triple> OMPTargetTriples = {};
|
||||
bool NoGPULib = false;
|
||||
};
|
||||
|
||||
/// Sets OpenMP offload module interface attributes on a ModuleOp, shared
|
||||
/// between Flang and Clang (CIR) frontends.
|
||||
[[maybe_unused]] static void
|
||||
setOffloadModuleInterfaceAttributes(ModuleOp module, OffloadModuleOpts opts) {
|
||||
if (auto offloadMod =
|
||||
llvm::dyn_cast<OffloadModuleInterface>(module.getOperation())) {
|
||||
offloadMod.setIsTargetDevice(opts.OpenMPIsTargetDevice);
|
||||
offloadMod.setIsGPU(opts.OpenMPIsGPU);
|
||||
if (opts.OpenMPForceUSM)
|
||||
offloadMod.setRequires(ClauseRequires::unified_shared_memory);
|
||||
if (opts.OpenMPIsTargetDevice) {
|
||||
offloadMod.setFlags(
|
||||
opts.OpenMPTargetDebug, opts.OpenMPTeamSubscription,
|
||||
opts.OpenMPThreadSubscription, opts.OpenMPNoThreadState,
|
||||
opts.OpenMPNoNestedParallelism, opts.OpenMPVersion, opts.NoGPULib);
|
||||
if (!opts.OMPHostIRFile.empty())
|
||||
offloadMod.setHostIRFilePath(opts.OMPHostIRFile);
|
||||
}
|
||||
auto strTriples = llvm::to_vector(
|
||||
llvm::map_range(opts.OMPTargetTriples, [](llvm::Triple triple) {
|
||||
return triple.normalize();
|
||||
}));
|
||||
offloadMod.setTargetTriples(strTriples);
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void setOpenMPVersionAttribute(ModuleOp module,
|
||||
int64_t version) {
|
||||
module.getOperation()->setAttr(
|
||||
StringAttr::get(module.getContext(), llvm::Twine{"omp.version"}),
|
||||
VersionAttr::get(module.getContext(), version));
|
||||
}
|
||||
|
||||
[[maybe_unused]] static int64_t
|
||||
getOpenMPVersionAttribute(ModuleOp module, int64_t fallback = -1) {
|
||||
if (Attribute verAttr = module->getAttr("omp.version"))
|
||||
return llvm::cast<VersionAttr>(verAttr).getVersion();
|
||||
return fallback;
|
||||
}
|
||||
|
||||
} // namespace mlir::omp
|
||||
|
||||
#endif // MLIR_DIALECT_OPENMP_OPENMPOFFLOADUTILS_H_
|
||||
Loading…
x
Reference in New Issue
Block a user