}
}
+// Shares assinging of the OpenMP OffloadModuleInterface and its TargetCPU
+// attribute accross Flang tools (bbc/flang)
+void setOffloadModuleInterfaceTargetAttribute(mlir::ModuleOp &module,
+ llvm::StringRef targetCPU, llvm::StringRef targetFeatures) {
+ // Should be registered by the OpenMPDialect
+ if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
+ module.getOperation())) {
+ offloadMod.setTarget(targetCPU, targetFeatures);
+ }
+}
+
#endif // FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
// Fetch module from lb, so we can set
mlirModule = std::make_unique<mlir::ModuleOp>(lb.getModule());
+ if (!setUpTargetMachine())
+ return false;
+
if (ci.getInvocation().getFrontendOpts().features.IsEnabled(
Fortran::common::LanguageFeature::OpenMP)) {
setOffloadModuleInterfaceAttributes(
*mlirModule, ci.getInvocation().getLangOpts().OpenMPIsDevice);
+ setOffloadModuleInterfaceTargetAttribute(*mlirModule, tm->getTargetCPU(),
+ tm->getTargetFeatureString());
}
- if (!setUpTargetMachine())
- return false;
const llvm::DataLayout &dl = tm->createDataLayout();
setMLIRDataLayout(*mlirModule, dl);
--- /dev/null
+!REQUIRES: amdgpu-registered-target
+!RUN: %flang_fc1 -emit-fir -triple amdgcn-amd-amdhsa -target-cpu gfx908 -fopenmp %s -o - | FileCheck %s
+
+!===============================================================================
+! Target_Enter Simple
+!===============================================================================
+
+!CHECK: omp.target = #omp.target<target_cpu = "gfx908",
+!CHECK-SAME: target_features = "+dot3-insts,+dot4-insts,+s-memtime-inst,
+!CHECK-SAME: +16-bit-insts,+s-memrealtime,+dot6-insts,+dl-insts,+wavefrontsize64,
+!CHECK-SAME: +gfx9-insts,+gfx8-insts,+ci-insts,+dot10-insts,+dot7-insts,
+!CHECK-SAME: +dot1-insts,+dot5-insts,+mai-insts,+dpp,+dot2-insts">
+!CHECK-LABEL: func.func @_QPomp_target_simple() {
+subroutine omp_target_simple
+end subroutine omp_target_simple
+
let assemblyFormat = "`<` struct(params) `>`";
}
+def TargetAttr : OpenMP_Attr<"Target", "target"> {
+ let parameters = (ins
+ StringRefParameter<>:$target_cpu,
+ StringRefParameter<>:$target_features
+ );
+
+ let assemblyFormat = "`<` struct(params) `>`";
+}
+
+
class OpenMP_Op<string mnemonic, list<Trait> traits = []> :
Op<OpenMP_Dialect, mnemonic, traits>;
InterfaceMethod<
/*description=*/[{
Set the attribute IsDeviceAttr on the current module with the
- specified boolean argument.
+ specified boolean argument.
}],
/*retTy=*/"void",
- /*methodName=*/"setIsDevice",
+ /*methodName=*/"setIsDevice",
(ins "bool":$isDevice), [{}], [{
$_op->setAttr(
mlir::StringAttr::get($_op->getContext(), llvm::Twine{"omp.is_device"}),
its value, if it doesn't exit it returns false by default.
}],
/*retTy=*/"bool",
- /*methodName=*/"getIsDevice",
+ /*methodName=*/"getIsDevice",
(ins), [{}], [{
if (Attribute isDevice = $_op->getAttr("omp.is_device"))
if (isDevice.isa<mlir::omp::IsDeviceAttr>())
assumeTeamsOversubscription, assumeThreadsOversubscription,
assumeNoThreadState, assumeNoNestedParallelism));
}]>,
+ InterfaceMethod<
+ /*description=*/[{
+ Get the Target attribute on the current module if it exists
+ and return the attribute, if it doesn't exist it returns a nullptr.
+ }],
+ /*retTy=*/"mlir::omp::TargetAttr",
+ /*methodName=*/"getTarget",
+ (ins), [{}], [{
+ if (Attribute flags = $_op->getAttr("omp.target"))
+ return flags.dyn_cast_or_null<mlir::omp::TargetAttr>();
+ return nullptr;
+ }]>,
+ InterfaceMethod<
+ /*description=*/[{
+ Set the attribute target on the current module with the
+ specified string arguments - name of cpu and corresponding features.
+ }],
+ /*retTy=*/"void",
+ /*methodName=*/"setTarget",
+ (ins "llvm::StringRef":$targetCPU,
+ "llvm::StringRef":$targetFeatures), [{}], [{
+ if (targetCPU.empty())
+ return;
+ $_op->setAttr(("omp." + mlir::omp::TargetAttr::getMnemonic()).str(),
+ mlir::omp::TargetAttr::get($_op->getContext(),
+ targetCPU.str(),
+ targetFeatures.str()));
+ }]>,
];
}