skatrak updated this revision to Diff 551968.
skatrak added a comment.
Update patch.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D147219/new/
https://reviews.llvm.org/D147219
Files:
clang/lib/CodeGen/CGOpenMPRuntime.cpp
llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Target/LLVMIR/openmp-llvm.mlir
Index: mlir/test/Target/LLVMIR/openmp-llvm.mlir
===================================================================
--- mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -2661,3 +2661,12 @@
// CHECK: call void @foo_after()
// CHECK: ret void
+// -----
+
+// Check that OpenMP requires flags are registered by a global constructor.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }]
+// CHECK-SAME: [{ i32, ptr, ptr } { i32 0, ptr @[[REG_FN:.*]], ptr null }]
+// CHECK: define {{.*}} @[[REG_FN]]({{.*}})
+// CHECK-NOT: }
+// CHECK: call void @__tgt_register_requires(i64 10)
+module attributes {omp.requires = #omp<clause_requires reverse_offload|unified_shared_memory>} {}
Index: mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
===================================================================
--- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1289,32 +1289,18 @@
llvm::OpenMPIRBuilder *ModuleTranslation::getOpenMPBuilder() {
if (!ompBuilder) {
ompBuilder = std::make_unique<llvm::OpenMPIRBuilder>(*llvmModule);
+ ompBuilder->initialize();
- bool isTargetDevice = false, isGPU = false;
- llvm::StringRef hostIRFilePath = "";
-
- if (auto deviceAttr =
- mlirModule->getAttrOfType<mlir::BoolAttr>("omp.is_target_device"))
- isTargetDevice = deviceAttr.getValue();
-
- if (auto gpuAttr = mlirModule->getAttrOfType<mlir::BoolAttr>("omp.is_gpu"))
- isGPU = gpuAttr.getValue();
-
- if (auto filepathAttr =
- mlirModule->getAttrOfType<mlir::StringAttr>("omp.host_ir_filepath"))
- hostIRFilePath = filepathAttr.getValue();
-
- ompBuilder->initialize(hostIRFilePath);
-
- // TODO: set the flags when available
- llvm::OpenMPIRBuilderConfig config(
- isTargetDevice, isGPU,
+ // Flags represented as top-level OpenMP dialect attributes are set in
+ // `OpenMPDialectLLVMIRTranslationInterface::amendOperation()`. Here we set
+ // the default configuration.
+ ompBuilder->setConfig(llvm::OpenMPIRBuilderConfig(
+ /* IsTargetDevice = */ false, /* IsGPU = */ false,
/* OpenMPOffloadMandatory = */ false,
/* HasRequiresReverseOffload = */ false,
/* HasRequiresUnifiedAddress = */ false,
/* HasRequiresUnifiedSharedMemory = */ false,
- /* HasRequiresDynamicAllocators = */ false);
- ompBuilder->setConfig(config);
+ /* HasRequiresDynamicAllocators = */ false));
}
return ompBuilder.get();
}
Index: mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
===================================================================
--- mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -17,6 +17,7 @@
#include "mlir/IR/IRMapping.h"
#include "mlir/IR/Operation.h"
#include "mlir/Support/LLVM.h"
+#include "mlir/Support/LogicalResult.h"
#include "mlir/Target/LLVMIR/Dialect/OpenMPCommon.h"
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
#include "mlir/Transforms/RegionUtils.h"
@@ -28,6 +29,8 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+#include <optional>
using namespace mlir;
@@ -1165,7 +1168,7 @@
}
/// Convert an Atomic Ordering attribute to llvm::AtomicOrdering.
-llvm::AtomicOrdering
+static llvm::AtomicOrdering
convertAtomicOrdering(std::optional<omp::ClauseMemoryOrderKind> ao) {
if (!ao)
return llvm::AtomicOrdering::Monotonic; // Default Memory Ordering
@@ -1932,6 +1935,27 @@
return success();
}
+/// Converts the module-level set of OpenMP requires clauses into LLVM IR using
+/// OpenMPIRBuilder.
+static LogicalResult
+convertRequiresAttr(Operation &op, omp::ClauseRequiresAttr requiresAttr,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ auto *ompBuilder = moduleTranslation.getOpenMPBuilder();
+
+ // No need to read requiresAttr here, because it has already been done in
+ // translateModuleToLLVMIR(). There, flags are stored in the
+ // OpenMPIRBuilderConfig object, available to the OpenMPIRBuilder.
+ auto *regFn =
+ ompBuilder->createRegisterRequires(ompBuilder->createPlatformSpecificName(
+ {"omp_offloading", "requires_reg"}));
+
+ // Add registration function as global constructor
+ if (regFn)
+ llvm::appendToGlobalCtors(ompBuilder->M, regFn, /* Priority = */ 0);
+
+ return success();
+}
+
namespace {
/// Implementation of the dialect interface that converts operations belonging
@@ -1947,6 +1971,8 @@
convertOperation(Operation *op, llvm::IRBuilderBase &builder,
LLVM::ModuleTranslation &moduleTranslation) const final;
+ /// Given an OpenMP MLIR attribute, create the corresponding LLVM-IR, runtime
+ /// calls, or operation amendments
LogicalResult
amendOperation(Operation *op, NamedAttribute attribute,
LLVM::ModuleTranslation &moduleTranslation) const final;
@@ -1954,31 +1980,90 @@
} // namespace
-/// Given an OpenMP MLIR attribute, create the corresponding LLVM-IR, runtime
-/// calls, or operation amendments
LogicalResult OpenMPDialectLLVMIRTranslationInterface::amendOperation(
Operation *op, NamedAttribute attribute,
LLVM::ModuleTranslation &moduleTranslation) const {
- return llvm::TypeSwitch<Attribute, LogicalResult>(attribute.getValue())
- .Case([&](mlir::omp::FlagsAttr rtlAttr) {
- return convertFlagsAttr(op, rtlAttr, moduleTranslation);
- })
- .Case([&](mlir::omp::VersionAttr versionAttr) {
- llvm::OpenMPIRBuilder *ompBuilder =
- moduleTranslation.getOpenMPBuilder();
- ompBuilder->M.addModuleFlag(llvm::Module::Max, "openmp",
- versionAttr.getVersion());
- return success();
- })
- .Case([&](mlir::omp::DeclareTargetAttr declareTargetAttr) {
- return convertDeclareTargetAttr(op, declareTargetAttr,
- moduleTranslation);
- })
- .Default([&](Attribute attr) {
- // fall through for omp attributes that do not require lowering and/or
- // have no concrete definition and thus no type to define a case on
+ return llvm::StringSwitch<llvm::function_ref<LogicalResult(Attribute)>>(
+ attribute.getName())
+ .Case("omp.is_target_device",
+ [&](Attribute attr) {
+ if (auto deviceAttr = attr.dyn_cast<BoolAttr>()) {
+ llvm::OpenMPIRBuilderConfig &config =
+ moduleTranslation.getOpenMPBuilder()->Config;
+ config.setIsTargetDevice(deviceAttr.getValue());
+ return success();
+ }
+ return failure();
+ })
+ .Case("omp.is_gpu",
+ [&](Attribute attr) {
+ if (auto gpuAttr = attr.dyn_cast<BoolAttr>()) {
+ llvm::OpenMPIRBuilderConfig &config =
+ moduleTranslation.getOpenMPBuilder()->Config;
+ config.setIsGPU(gpuAttr.getValue());
+ return success();
+ }
+ return failure();
+ })
+ .Case("omp.host_ir_filepath",
+ [&](Attribute attr) {
+ if (auto filepathAttr = attr.dyn_cast<StringAttr>()) {
+ llvm::OpenMPIRBuilder *ompBuilder =
+ moduleTranslation.getOpenMPBuilder();
+ ompBuilder->loadOffloadInfoMetadata(filepathAttr.getValue());
+ return success();
+ }
+ return failure();
+ })
+ .Case("omp.flags",
+ [&](Attribute attr) {
+ if (auto rtlAttr = attr.dyn_cast<omp::FlagsAttr>())
+ return convertFlagsAttr(op, rtlAttr, moduleTranslation);
+ return failure();
+ })
+ .Case("omp.version",
+ [&](Attribute attr) {
+ if (auto versionAttr = attr.dyn_cast<omp::VersionAttr>()) {
+ llvm::OpenMPIRBuilder *ompBuilder =
+ moduleTranslation.getOpenMPBuilder();
+ ompBuilder->M.addModuleFlag(llvm::Module::Max, "openmp",
+ versionAttr.getVersion());
+ return success();
+ }
+ return failure();
+ })
+ .Case("omp.declare_target",
+ [&](Attribute attr) {
+ if (auto declareTargetAttr =
+ attr.dyn_cast<omp::DeclareTargetAttr>())
+ return convertDeclareTargetAttr(op, declareTargetAttr,
+ moduleTranslation);
+ return failure();
+ })
+ .Case(
+ "omp.requires",
+ [&](Attribute attr) {
+ if (auto requiresAttr = attr.dyn_cast<omp::ClauseRequiresAttr>()) {
+ using Requires = omp::ClauseRequires;
+ Requires flags = requiresAttr.getValue();
+ llvm::OpenMPIRBuilderConfig &config =
+ moduleTranslation.getOpenMPBuilder()->Config;
+ config.setHasRequiresReverseOffload(
+ bitEnumContainsAll(flags, Requires::reverse_offload));
+ config.setHasRequiresUnifiedAddress(
+ bitEnumContainsAll(flags, Requires::unified_address));
+ config.setHasRequiresUnifiedSharedMemory(
+ bitEnumContainsAll(flags, Requires::unified_shared_memory));
+ config.setHasRequiresDynamicAllocators(
+ bitEnumContainsAll(flags, Requires::dynamic_allocators));
+ return convertRequiresAttr(*op, requiresAttr, moduleTranslation);
+ }
+ return failure();
+ })
+ .Default([](Attribute) {
+ // Fall through for omp attributes that do not require lowering.
return success();
- });
+ })(attribute.getValue());
return failure();
}
Index: llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
===================================================================
--- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -577,31 +577,7 @@
return Fn;
}
-void OpenMPIRBuilder::initialize(StringRef HostFilePath) {
- initializeTypes(M);
-
- if (HostFilePath.empty())
- return;
-
- auto Buf = MemoryBuffer::getFile(HostFilePath);
- if (std::error_code Err = Buf.getError()) {
- report_fatal_error(("error opening host file from host file path inside of "
- "OpenMPIRBuilder: " +
- Err.message())
- .c_str());
- }
-
- LLVMContext Ctx;
- auto M = expectedToErrorOrAndEmitErrors(
- Ctx, parseBitcodeFile(Buf.get()->getMemBufferRef(), Ctx));
- if (std::error_code Err = M.getError()) {
- report_fatal_error(
- ("error parsing host file inside of OpenMPIRBuilder: " + Err.message())
- .c_str());
- }
-
- loadOffloadInfoMetadata(*M.get());
-}
+void OpenMPIRBuilder::initialize() { initializeTypes(M); }
void OpenMPIRBuilder::finalize(Function *Fn) {
SmallPtrSet<BasicBlock *, 32> ParallelRegionBlockSet;
@@ -6145,6 +6121,30 @@
}
}
+void OpenMPIRBuilder::loadOffloadInfoMetadata(StringRef HostFilePath) {
+ if (HostFilePath.empty())
+ return;
+
+ auto Buf = MemoryBuffer::getFile(HostFilePath);
+ if (std::error_code Err = Buf.getError()) {
+ report_fatal_error(("error opening host file from host file path inside of "
+ "OpenMPIRBuilder: " +
+ Err.message())
+ .c_str());
+ }
+
+ LLVMContext Ctx;
+ auto M = expectedToErrorOrAndEmitErrors(
+ Ctx, parseBitcodeFile(Buf.get()->getMemBufferRef(), Ctx));
+ if (std::error_code Err = M.getError()) {
+ report_fatal_error(
+ ("error parsing host file inside of OpenMPIRBuilder: " + Err.message())
+ .c_str());
+ }
+
+ loadOffloadInfoMetadata(*M.get());
+}
+
Function *OpenMPIRBuilder::createRegisterRequires(StringRef Name) {
// Skip the creation of the registration function if this is device codegen
if (Config.isTargetDevice())
Index: llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
===================================================================
--- llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -154,6 +154,7 @@
void setIsTargetDevice(bool Value) { IsTargetDevice = Value; }
void setIsGPU(bool Value) { IsGPU = Value; }
+ void setOpenMPOffloadMandatory(bool Value) { OpenMPOffloadMandatory = Value; }
void setFirstSeparator(StringRef FS) { FirstSeparator = FS; }
void setSeparator(StringRef S) { Separator = S; }
@@ -444,14 +445,9 @@
/// Initialize the internal state, this will put structures types and
/// potentially other helpers into the underlying module. Must be called
- /// before any other method and only once! This internal state includes
- /// Types used in the OpenMPIRBuilder generated from OMPKinds.def as well
- /// as loading offload metadata for device from the OpenMP host IR file
- /// passed in as the HostFilePath argument.
- /// \param HostFilePath The path to the host IR file, used to load in
- /// offload metadata for the device, allowing host and device to
- /// maintain the same metadata mapping.
- void initialize(StringRef HostFilePath = {});
+ /// before any other method and only once! This internal state includes types
+ /// used in the OpenMPIRBuilder generated from OMPKinds.def.
+ void initialize();
void setConfig(OpenMPIRBuilderConfig C) { Config = C; }
@@ -2513,6 +2509,15 @@
/// loaded from bitcode file, i.e, different from OpenMPIRBuilder::M module.
void loadOffloadInfoMetadata(Module &M);
+ /// Loads all the offload entries information from the host IR
+ /// metadata read from the file passed in as the HostFilePath argument. This
+ /// function is only meant to be used with device code generation.
+ ///
+ /// \param HostFilePath The path to the host IR file,
+ /// used to load in offload metadata for the device, allowing host and device
+ /// to maintain the same metadata mapping.
+ void loadOffloadInfoMetadata(StringRef HostFilePath);
+
/// Gets (if variable with the given name already exist) or creates
/// internal global variable with the specified Name. The created variable has
/// linkage CommonLinkage by default and is initialized by null value.
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===================================================================
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1038,9 +1038,10 @@
CGM.getLangOpts().OpenMPOffloadMandatory,
/*HasRequiresReverseOffload*/ false, /*HasRequiresUnifiedAddress*/ false,
hasRequiresUnifiedSharedMemory(), /*HasRequiresDynamicAllocators*/ false);
- OMPBuilder.initialize(CGM.getLangOpts().OpenMPIsTargetDevice
- ? CGM.getLangOpts().OMPHostIRFile
- : StringRef{});
+ OMPBuilder.initialize();
+ OMPBuilder.loadOffloadInfoMetadata(CGM.getLangOpts().OpenMPIsTargetDevice
+ ? CGM.getLangOpts().OMPHostIRFile
+ : StringRef{});
OMPBuilder.setConfig(Config);
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits