--- /dev/null
+//===-- Tools/CrossToolHelpers.h --------------------------------- *-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
+//
+//===----------------------------------------------------------------------===//
+// A header file for containing functionallity that is used across Flang tools,
+// such as helper functions which apply or generate information needed accross
+// tools like bbc and flang-new.
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
+#define FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
+
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/IR/BuiltinOps.h"
+
+// Shares assinging of the OpenMP OffloadModuleInterface and its assorted
+// attributes accross Flang tools (bbc/flang)
+void setOffloadModuleInterfaceAttributes(
+ mlir::ModuleOp &module, bool isDevice) {
+ // Should be registered by the OpenMPDialect
+ if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
+ module.getOperation())) {
+ offloadMod.setIsDevice(isDevice);
+ }
+}
+
+#endif // FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
#include "flang/Semantics/runtime-type-info.h"
#include "flang/Semantics/semantics.h"
#include "flang/Semantics/unparse-with-symbols.h"
+#include "flang/Tools/CrossToolHelpers.h"
#include "mlir/IR/Dialect.h"
#include "mlir/Parser/Parser.h"
if (ci.getInvocation().getFrontendOpts().features.IsEnabled(
Fortran::common::LanguageFeature::OpenMP)) {
- mlir::omp::OpenMPDialect::setIsDevice(
+ setOffloadModuleInterfaceAttributes(
*mlirModule, ci.getInvocation().getLangOpts().OpenMPIsDevice);
}
!RUN: bbc -fopenmp -emit-fir -o - %s | FileCheck %s --check-prefix=HOST
!RUN: bbc -fopenmp-is-device -emit-fir -o - %s | FileCheck %s --check-prefix=DEVICE-FLAG-ONLY
-!DEVICE: module attributes {{{.*}}, omp.is_device = true{{.*}}}
-!HOST: module attributes {{{.*}}, omp.is_device = false{{.*}}}
+!DEVICE: module attributes {{{.*}}, omp.is_device = #omp.isdevice<is_device = true>{{.*}}}
+!HOST: module attributes {{{.*}}, omp.is_device = #omp.isdevice<is_device = false>{{.*}}}
!DEVICE-FLAG-ONLY: module attributes {{{.*}}"
-!DEVICE-FLAG-ONLY-NOT: , omp.is_device = {{.*}}
+!DEVICE-FLAG-ONLY-NOT: , omp.is_device = #omp.isdevice<{{.*}}>
!DEVICE-FLAG-ONLY-SAME: }
subroutine omp_subroutine()
end subroutine omp_subroutine
#include "flang/Semantics/runtime-type-info.h"
#include "flang/Semantics/semantics.h"
#include "flang/Semantics/unparse-with-symbols.h"
+#include "flang/Tools/CrossToolHelpers.h"
#include "flang/Version.inc"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/IR/AsmState.h"
burnside.lower(parseTree, semanticsContext);
mlir::ModuleOp mlirModule = burnside.getModule();
if (enableOpenMP)
- mlir::omp::OpenMPDialect::setIsDevice(mlirModule, enableOpenMPDevice);
+ setOffloadModuleInterfaceAttributes(mlirModule, enableOpenMPDevice);
std::error_code ec;
std::string outputName = outputFilename;
if (!outputName.size())
#include "mlir/Dialect/OpenMP/OpenMPOpsDialect.h.inc"
#include "mlir/Dialect/OpenMP/OpenMPOpsEnums.h.inc"
-#include "mlir/Dialect/OpenMP/OpenMPOpsInterfaces.h.inc"
#include "mlir/Dialect/OpenMP/OpenMPTypeInterfaces.h.inc"
#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/OpenMP/OpenMPOpsAttributes.h.inc"
+#include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
+
#define GET_OP_CLASSES
#include "mlir/Dialect/OpenMP/OpenMPOps.h.inc"
--- /dev/null
+//===- OpenMPInterfaces.h - MLIR Interfaces for OpenMP ----------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares OpenMP Interface implementations for the OpenMP dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENMP_OPENMPINTERFACES_H_
+#define MLIR_DIALECT_OPENMP_OPENMPINTERFACES_H_
+
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/IR/SymbolTable.h"
+#include "mlir/Interfaces/ControlFlowInterfaces.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
+
+#include "mlir/Dialect/OpenMP/OpenMPOpsInterfaces.h.inc"
+
+namespace mlir::omp {
+// You can override defaults here or implement more complex implementations of
+// functions. Or define a completely seperate external model implementation,
+// to override the existing implementation.
+struct OffloadModuleDefaultModel
+ : public OffloadModuleInterface::ExternalModel<OffloadModuleDefaultModel,
+ mlir::ModuleOp> {};
+} // namespace mlir::omp
+
+#endif // MLIR_DIALECT_OPENMP_OPENMPINTERFACES_H_
let cppNamespace = "::mlir::omp";
let dependentDialects = ["::mlir::LLVM::LLVMDialect"];
let useDefaultAttributePrinterParser = 1;
-
- let extraClassDeclaration = [{
- // Set the omp.is_device attribute on the module with the specified boolean
- static void setIsDevice(Operation* module, bool isDevice);
-
- // Return the value of the omp.is_device attribute stored in the module if it
- // exists, otherwise return false by default
- static bool getIsDevice(Operation* module);
- }];
}
// OmpCommon requires definition of OpenACC_Dialect.
include "mlir/Dialect/OpenMP/OmpCommon.td"
+//===----------------------------------------------------------------------===//
+// OpenMP Attributes
+//===----------------------------------------------------------------------===//
+
+class OpenMP_Attr<string name, string attrMnemonic,
+ list<Trait> traits = [],
+ string baseCppClass = "::mlir::Attribute">
+ : AttrDef<OpenMP_Dialect, name, traits, baseCppClass> {
+ let mnemonic = attrMnemonic;
+}
+
+def IsDeviceAttr : OpenMP_Attr<"IsDevice", "isdevice"> {
+ let parameters = (ins
+ "bool":$is_device
+ );
+
+ let assemblyFormat = "`<` struct(params) `>`";
+}
+
class OpenMP_Op<string mnemonic, list<Trait> traits = []> :
Op<OpenMP_Dialect, mnemonic, traits>;
];
}
+def OffloadModuleInterface : OpInterface<"OffloadModuleInterface"> {
+ let description = [{
+ Operations that represent a module for offloading (host or device)
+ should have this interface.
+ }];
+
+ let cppNamespace = "::mlir::omp";
+
+ let methods = [
+ InterfaceMethod<
+ /*description=*/[{
+ Set the attribute IsDeviceAttr on the current module with the
+ specified boolean argument.
+ }],
+ /*retTy=*/"void",
+ /*methodName=*/"setIsDevice",
+ (ins "bool":$isDevice), [{}], [{
+ $_op->setAttr(
+ mlir::StringAttr::get($_op->getContext(), llvm::Twine{"omp.is_device"}),
+ mlir::omp::IsDeviceAttr::get($_op->getContext(), isDevice));
+ }]>,
+ InterfaceMethod<
+ /*description=*/[{
+ Get the IsDeviceAttr attribute on the current module if it exists and return
+ its value, if it doesn't exit it returns false by default.
+ }],
+ /*retTy=*/"bool",
+ /*methodName=*/"getIsDevice",
+ (ins), [{}], [{
+ if (Attribute isDevice = $_op->getAttr("omp.is_device"))
+ if (isDevice.isa<mlir::omp::IsDeviceAttr>())
+ return isDevice.dyn_cast<IsDeviceAttr>().getIsDevice();
+ }]>,
+ ];
+}
+
#endif // OpenMP_OPS_INTERFACES
LLVM::LLVMPointerType::attachInterface<
PointerLikeModel<LLVM::LLVMPointerType>>(*getContext());
MemRefType::attachInterface<PointerLikeModel<MemRefType>>(*getContext());
+ LLVM::LLVMPointerType::attachInterface<
+ PointerLikeModel<LLVM::LLVMPointerType>>(*getContext());
+ mlir::ModuleOp::attachInterface<mlir::omp::OffloadModuleDefaultModel>(
+ *getContext());
}
//===----------------------------------------------------------------------===//
return success();
}
-//===----------------------------------------------------------------------===//
-// OpenMPDialect helper functions
-//===----------------------------------------------------------------------===//
-
-// Set the omp.is_device attribute on the module with the specified boolean
-void OpenMPDialect::setIsDevice(Operation* module, bool isDevice) {
- module->setAttr(
- mlir::StringAttr::get(module->getContext(), llvm::Twine{"omp.is_device"}),
- mlir::BoolAttr::get(module->getContext(), isDevice));
-}
-
-// Return the value of the omp.is_device attribute stored in the module if it
-// exists, otherwise return false by default
-bool OpenMPDialect::getIsDevice(Operation* module) {
- if (Attribute isDevice = module->getAttr("omp.is_device"))
- if (isDevice.isa<mlir::BoolAttr>())
- return isDevice.dyn_cast<BoolAttr>().getValue();
- return false;
-}
-
#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/OpenMP/OpenMPOpsAttributes.cpp.inc"