[llvm-branch-commits] [flang] [mlir] [MLIR][OpenMP] Add lowering support for AUTOMAP modifier (PR #151513)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jul 31 06:08:23 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Akash Banerjee (TIFitis)
<details>
<summary>Changes</summary>
Add Automap modifier to the MLIR op definition for the DeclareTarget directive's Enter clause. Also add lowering support in Flang.
Automap Ref: OpenMP 6.0 section 7.9.7.
---
Full diff: https://github.com/llvm/llvm-project/pull/151513.diff
10 Files Affected:
- (modified) flang/include/flang/Lower/OpenMP.h (+1)
- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+8-5)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+15-18)
- (modified) flang/lib/Lower/OpenMP/Utils.cpp (+3-2)
- (modified) flang/lib/Lower/OpenMP/Utils.h (+11-3)
- (modified) flang/lib/Optimizer/OpenMP/FunctionFiltering.cpp (+3-2)
- (modified) flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp (+13-8)
- (added) flang/test/Lower/OpenMP/declare-target-automap.f90 (+8)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td (+4-4)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td (+17-2)
``````````diff
diff --git a/flang/include/flang/Lower/OpenMP.h b/flang/include/flang/Lower/OpenMP.h
index 6e150ef4e8e82..581c93f76d627 100644
--- a/flang/include/flang/Lower/OpenMP.h
+++ b/flang/include/flang/Lower/OpenMP.h
@@ -57,6 +57,7 @@ struct Variable;
struct OMPDeferredDeclareTargetInfo {
mlir::omp::DeclareTargetCaptureClause declareTargetCaptureClause;
mlir::omp::DeclareTargetDeviceType declareTargetDeviceType;
+ bool automap = false;
const Fortran::semantics::Symbol &sym;
};
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 8eabf4f499604..ab33e089cc9e8 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1184,7 +1184,8 @@ bool ClauseProcessor::processLink(
[&](const omp::clause::Link &clause, const parser::CharBlock &) {
// Case: declare target link(var1, var2)...
gatherFuncAndVarSyms(
- clause.v, mlir::omp::DeclareTargetCaptureClause::link, result);
+ clause.v, mlir::omp::DeclareTargetCaptureClause::link, result,
+ /*automap=*/false);
});
}
@@ -1512,7 +1513,8 @@ bool ClauseProcessor::processTo(
[&](const omp::clause::To &clause, const parser::CharBlock &) {
// Case: declare target to(func, var1, var2)...
gatherFuncAndVarSyms(std::get<ObjectList>(clause.t),
- mlir::omp::DeclareTargetCaptureClause::to, result);
+ mlir::omp::DeclareTargetCaptureClause::to, result,
+ /*automap=*/false);
});
}
@@ -1521,12 +1523,13 @@ bool ClauseProcessor::processEnter(
return findRepeatableClause<omp::clause::Enter>(
[&](const omp::clause::Enter &clause, const parser::CharBlock &source) {
mlir::Location currentLocation = converter.genLocation(source);
- if (std::get<std::optional<omp::clause::Enter::Modifier>>(clause.t))
- TODO(currentLocation, "Declare target enter AUTOMAP modifier");
+ bool automap =
+ std::get<std::optional<omp::clause::Enter::Modifier>>(clause.t)
+ .has_value();
// Case: declare target enter(func, var1, var2)...
gatherFuncAndVarSyms(std::get<ObjectList>(clause.t),
mlir::omp::DeclareTargetCaptureClause::enter,
- result);
+ result, automap);
});
}
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 12089d6caa5fe..de44bfa87562b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -773,7 +773,7 @@ static void getDeclareTargetInfo(
ObjectList objects{makeObjects(*objectList, semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
- symbolAndClause);
+ symbolAndClause, /*automap=*/false);
} else if (const auto *clauseList{
parser::Unwrap<parser::OmpClauseList>(spec.u)}) {
List<Clause> clauses = makeClauses(*clauseList, semaCtx);
@@ -814,13 +814,12 @@ static void collectDeferredDeclareTargets(
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
for (const DeclareTargetCapturePair &symClause : symbolAndClause) {
- mlir::Operation *op = mod.lookupSymbol(
- converter.mangleName(std::get<const semantics::Symbol &>(symClause)));
+ mlir::Operation *op =
+ mod.lookupSymbol(converter.mangleName(symClause.symbol));
if (!op) {
- deferredDeclareTarget.push_back({std::get<0>(symClause),
- clauseOps.deviceType,
- std::get<1>(symClause)});
+ deferredDeclareTarget.push_back({symClause.clause, clauseOps.deviceType,
+ symClause.automap, symClause.symbol});
}
}
}
@@ -839,8 +838,8 @@ getDeclareTargetFunctionDevice(
// directive is a function or subroutine
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
for (const DeclareTargetCapturePair &symClause : symbolAndClause) {
- mlir::Operation *op = mod.lookupSymbol(
- converter.mangleName(std::get<const semantics::Symbol &>(symClause)));
+ mlir::Operation *op =
+ mod.lookupSymbol(converter.mangleName(symClause.symbol));
if (mlir::isa_and_nonnull<mlir::func::FuncOp>(op))
return clauseOps.deviceType;
@@ -1057,7 +1056,7 @@ getImplicitMapTypeAndKind(fir::FirOpBuilder &firOpBuilder,
static void
markDeclareTarget(mlir::Operation *op, lower::AbstractConverter &converter,
mlir::omp::DeclareTargetCaptureClause captureClause,
- mlir::omp::DeclareTargetDeviceType deviceType) {
+ mlir::omp::DeclareTargetDeviceType deviceType, bool automap) {
// TODO: Add support for program local variables with declare target applied
auto declareTargetOp = llvm::dyn_cast<mlir::omp::DeclareTargetInterface>(op);
if (!declareTargetOp)
@@ -1072,11 +1071,11 @@ markDeclareTarget(mlir::Operation *op, lower::AbstractConverter &converter,
if (declareTargetOp.isDeclareTarget()) {
if (declareTargetOp.getDeclareTargetDeviceType() != deviceType)
declareTargetOp.setDeclareTarget(mlir::omp::DeclareTargetDeviceType::any,
- captureClause);
+ captureClause, automap);
return;
}
- declareTargetOp.setDeclareTarget(deviceType, captureClause);
+ declareTargetOp.setDeclareTarget(deviceType, captureClause, automap);
}
//===----------------------------------------------------------------------===//
@@ -3536,8 +3535,8 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
clauseOps, symbolAndClause);
for (const DeclareTargetCapturePair &symClause : symbolAndClause) {
- mlir::Operation *op = mod.lookupSymbol(
- converter.mangleName(std::get<const semantics::Symbol &>(symClause)));
+ mlir::Operation *op =
+ mod.lookupSymbol(converter.mangleName(symClause.symbol));
// Some symbols are deferred until later in the module, these are handled
// upon finalization of the module for OpenMP inside of Bridge, so we simply
@@ -3545,10 +3544,8 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
if (!op)
continue;
- markDeclareTarget(
- op, converter,
- std::get<mlir::omp::DeclareTargetCaptureClause>(symClause),
- clauseOps.deviceType);
+ markDeclareTarget(op, converter, symClause.clause, clauseOps.deviceType,
+ symClause.automap);
}
}
@@ -4145,7 +4142,7 @@ bool Fortran::lower::markOpenMPDeferredDeclareTargetFunctions(
deviceCodeFound = true;
markDeclareTarget(op, converter, declTar.declareTargetCaptureClause,
- devType);
+ devType, declTar.automap);
}
return deviceCodeFound;
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index 13fda978c5369..db870fb719745 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -102,9 +102,10 @@ getIterationVariableSymbol(const lower::pft::Evaluation &eval) {
void gatherFuncAndVarSyms(
const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause,
- llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause) {
+ llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause,
+ bool automap) {
for (const Object &object : objects)
- symbolAndClause.emplace_back(clause, *object.sym());
+ symbolAndClause.emplace_back(clause, *object.sym(), automap);
}
mlir::omp::MapInfoOp
diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h
index 11641ba5e8606..c99a2b7361e95 100644
--- a/flang/lib/Lower/OpenMP/Utils.h
+++ b/flang/lib/Lower/OpenMP/Utils.h
@@ -42,8 +42,15 @@ class AbstractConverter;
namespace omp {
-using DeclareTargetCapturePair =
- std::pair<mlir::omp::DeclareTargetCaptureClause, const semantics::Symbol &>;
+struct DeclareTargetCapturePair {
+ mlir::omp::DeclareTargetCaptureClause clause;
+ bool automap = false;
+ const semantics::Symbol &symbol;
+
+ DeclareTargetCapturePair(mlir::omp::DeclareTargetCaptureClause c,
+ const semantics::Symbol &s, bool a = false)
+ : clause(c), automap(a), symbol(s) {}
+};
// A small helper structure for keeping track of a component members MapInfoOp
// and index data when lowering OpenMP map clauses. Keeps track of the
@@ -150,7 +157,8 @@ getIterationVariableSymbol(const lower::pft::Evaluation &eval);
void gatherFuncAndVarSyms(
const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause,
- llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause);
+ llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause,
+ bool automap = false);
int64_t getCollapseValue(const List<Clause> &clauses);
diff --git a/flang/lib/Optimizer/OpenMP/FunctionFiltering.cpp b/flang/lib/Optimizer/OpenMP/FunctionFiltering.cpp
index ae5c0ecc5b7f6..3031bb5da6919 100644
--- a/flang/lib/Optimizer/OpenMP/FunctionFiltering.cpp
+++ b/flang/lib/Optimizer/OpenMP/FunctionFiltering.cpp
@@ -95,8 +95,9 @@ class FunctionFilteringPass
return WalkResult::skip();
}
if (declareTargetOp)
- declareTargetOp.setDeclareTarget(declareType,
- omp::DeclareTargetCaptureClause::to);
+ declareTargetOp.setDeclareTarget(
+ declareType, omp::DeclareTargetCaptureClause::to,
+ declareTargetOp.getDeclareTargetAutomap());
}
return WalkResult::advance();
});
diff --git a/flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp b/flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp
index a7ffd5fda82b7..0b0e6bd9ecf34 100644
--- a/flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp
+++ b/flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp
@@ -33,7 +33,7 @@ class MarkDeclareTargetPass
void markNestedFuncs(mlir::omp::DeclareTargetDeviceType parentDevTy,
mlir::omp::DeclareTargetCaptureClause parentCapClause,
- mlir::Operation *currOp,
+ bool parentAutomap, mlir::Operation *currOp,
llvm::SmallPtrSet<mlir::Operation *, 16> visited) {
if (visited.contains(currOp))
return;
@@ -57,13 +57,16 @@ class MarkDeclareTargetPass
currentDt != mlir::omp::DeclareTargetDeviceType::any) {
current.setDeclareTarget(
mlir::omp::DeclareTargetDeviceType::any,
- current.getDeclareTargetCaptureClause());
+ current.getDeclareTargetCaptureClause(),
+ current.getDeclareTargetAutomap());
}
} else {
- current.setDeclareTarget(parentDevTy, parentCapClause);
+ current.setDeclareTarget(parentDevTy, parentCapClause,
+ parentAutomap);
}
- markNestedFuncs(parentDevTy, parentCapClause, currFOp, visited);
+ markNestedFuncs(parentDevTy, parentCapClause, parentAutomap,
+ currFOp, visited);
}
}
}
@@ -81,7 +84,8 @@ class MarkDeclareTargetPass
llvm::SmallPtrSet<mlir::Operation *, 16> visited;
markNestedFuncs(declareTargetOp.getDeclareTargetDeviceType(),
declareTargetOp.getDeclareTargetCaptureClause(),
- functionOp, visited);
+ declareTargetOp.getDeclareTargetAutomap(), functionOp,
+ visited);
}
}
@@ -92,9 +96,10 @@ class MarkDeclareTargetPass
// the contents of the device clause
getOperation()->walk([&](mlir::omp::TargetOp tarOp) {
llvm::SmallPtrSet<mlir::Operation *, 16> visited;
- markNestedFuncs(mlir::omp::DeclareTargetDeviceType::nohost,
- mlir::omp::DeclareTargetCaptureClause::to, tarOp,
- visited);
+ markNestedFuncs(
+ /*parentDevTy=*/mlir::omp::DeclareTargetDeviceType::nohost,
+ /*parentCapClause=*/mlir::omp::DeclareTargetCaptureClause::to,
+ /*parentAutomap=*/false, tarOp, visited);
});
}
};
diff --git a/flang/test/Lower/OpenMP/declare-target-automap.f90 b/flang/test/Lower/OpenMP/declare-target-automap.f90
new file mode 100644
index 0000000000000..40c5755c3a378
--- /dev/null
+++ b/flang/test/Lower/OpenMP/declare-target-automap.f90
@@ -0,0 +1,8 @@
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 %s -o - | FileCheck %s
+
+program automap
+ integer :: x
+ !$omp declare target enter(automap: x)
+end program
+
+!CHECK: fir.global @x {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = true>} : i32
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
index 72ce4c6a21cb3..c9e6764e7d634 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
@@ -42,10 +42,10 @@ def AtomicControlAttr : OpenMP_Attr<"AtomicControl", "atomic_control"> {
//===----------------------------------------------------------------------===//
def DeclareTargetAttr : OpenMP_Attr<"DeclareTarget", "declaretarget"> {
- let parameters = (ins
- OptionalParameter<"DeclareTargetDeviceTypeAttr">:$device_type,
- OptionalParameter<"DeclareTargetCaptureClauseAttr">:$capture_clause
- );
+ let parameters =
+ (ins OptionalParameter<"DeclareTargetDeviceTypeAttr">:$device_type,
+ OptionalParameter<"DeclareTargetCaptureClauseAttr">:$capture_clause,
+ OptionalParameter<"BoolAttr">:$automap);
let assemblyFormat = "`<` struct(params) `>`";
}
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
index 0dc385b08a823..28b8f11cdd488 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
@@ -329,14 +329,16 @@ def DeclareTargetInterface : OpInterface<"DeclareTargetInterface"> {
/*retTy=*/"void",
/*methodName=*/"setDeclareTarget",
(ins "mlir::omp::DeclareTargetDeviceType":$deviceType,
- "mlir::omp::DeclareTargetCaptureClause":$captureClause), [{}], [{
+ "mlir::omp::DeclareTargetCaptureClause":$captureClause),
+ "bool":$automap), [{}], [{
$_op->setAttr("omp.declare_target",
mlir::omp::DeclareTargetAttr::get(
$_op->getContext(),
mlir::omp::DeclareTargetDeviceTypeAttr::get(
$_op->getContext(), deviceType),
mlir::omp::DeclareTargetCaptureClauseAttr::get(
- $_op->getContext(), captureClause)));
+ $_op->getContext(), captureClause),
+ mlir::BoolAttr::get($_op->getContext(), automap)));
}]>,
InterfaceMethod<
/*description=*/[{
@@ -374,6 +376,19 @@ def DeclareTargetInterface : OpInterface<"DeclareTargetInterface"> {
if (auto dAttr = llvm::dyn_cast_or_null<mlir::omp::DeclareTargetAttr>(dTar))
return dAttr.getCaptureClause().getValue();
return {};
+ }]>,
+ InterfaceMethod<
+ /*description=*/[{
+ Return true if the DeclareTarget attribute has the AUTOMAP modifier.
+ }],
+ /*retTy=*/"bool",
+ /*methodName=*/"getDeclareTargetAutomap",
+ (ins), [{}], [{
+ if (mlir::Attribute dTar = $_op->getAttr("omp.declare_target"))
+ if (auto dAttr = llvm::dyn_cast_or_null<mlir::omp::DeclareTargetAttr>(dTar))
+ if (auto autoVal = dAttr.getAutomap())
+ return autoVal.getValue();
+ return false;
}]>
];
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/151513
More information about the llvm-branch-commits
mailing list