Skip to content

[Flang] Add parser support for AUTOMAP modifier #151511

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,13 +581,17 @@ class ParseTreeDumper {
NODE(parser, OmpDependClause)
NODE(OmpDependClause, TaskDep)
NODE(OmpDependClause::TaskDep, Modifier)
NODE(parser, OmpAutomapModifier)
NODE_ENUM(OmpAutomapModifier, Value)
NODE(parser, OmpDetachClause)
NODE(parser, OmpDoacrossClause)
NODE(parser, OmpDestroyClause)
NODE(parser, OmpEndBlockDirective)
NODE(parser, OmpEndCriticalDirective)
NODE(parser, OmpEndLoopDirective)
NODE(parser, OmpEndSectionsDirective)
NODE(parser, OmpEnterClause)
NODE(OmpEnterClause, Modifier)
NODE(parser, OmpFailClause)
NODE(parser, OmpFromClause)
NODE(OmpFromClause, Modifier)
Expand Down
21 changes: 21 additions & 0 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3769,6 +3769,16 @@ struct OmpAlwaysModifier {
WRAPPER_CLASS_BOILERPLATE(OmpAlwaysModifier, Value);
};

// Ref: [6.0:289-290]
//
// automap-modifier ->
// automap // since 6.0
//
struct OmpAutomapModifier {
ENUM_CLASS(Value, Automap);
WRAPPER_CLASS_BOILERPLATE(OmpAutomapModifier, Value);
};

// Ref: [5.2:252-254]
//
// chunk-modifier ->
Expand Down Expand Up @@ -4350,6 +4360,17 @@ struct OmpDeviceTypeClause {
WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription);
};

// Ref: [5.2:158-159], [6.0:289-290]
//
// enter-clause ->
// ENTER(locator-list) |
// ENTER(automap-modifier: locator-list) | // since 6.0
struct OmpEnterClause {
TUPLE_CLASS_BOILERPLATE(OmpEnterClause);
MODIFIER_BOILERPLATE(OmpAutomapModifier);
std::tuple<MODIFIERS(), OmpObjectList> t;
};

// OMP 5.2 15.8.3 extended-atomic, fail-clause ->
// FAIL(memory-order)
struct OmpFailClause {
Expand Down
1 change: 1 addition & 0 deletions flang/include/flang/Semantics/openmp-modifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ DECLARE_DESCRIPTOR(parser::OmpAlignModifier);
DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier);
DECLARE_DESCRIPTOR(parser::OmpAlwaysModifier);
DECLARE_DESCRIPTOR(parser::OmpAutomapModifier);
DECLARE_DESCRIPTOR(parser::OmpChunkModifier);
DECLARE_DESCRIPTOR(parser::OmpCloseModifier);
DECLARE_DESCRIPTOR(parser::OmpContextSelector);
Expand Down
10 changes: 7 additions & 3 deletions flang/lib/Lower/OpenMP/ClauseProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1519,10 +1519,14 @@ bool ClauseProcessor::processTo(
bool ClauseProcessor::processEnter(
llvm::SmallVectorImpl<DeclareTargetCapturePair> &result) const {
return findRepeatableClause<omp::clause::Enter>(
[&](const omp::clause::Enter &clause, const parser::CharBlock &) {
[&](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");
// Case: declare target enter(func, var1, var2)...
gatherFuncAndVarSyms(
clause.v, mlir::omp::DeclareTargetCaptureClause::enter, result);
gatherFuncAndVarSyms(std::get<ObjectList>(clause.t),
mlir::omp::DeclareTargetCaptureClause::enter,
result);
});
}

Expand Down
15 changes: 13 additions & 2 deletions flang/lib/Lower/OpenMP/Clauses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -772,8 +772,19 @@ Doacross make(const parser::OmpClause::Doacross &inp,

Enter make(const parser::OmpClause::Enter &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpObjectList
return Enter{makeObjects(/*List=*/inp.v, semaCtx)};
// inp.v -> parser::OmpEnterClause
CLAUSET_ENUM_CONVERT( //
convert, parser::OmpAutomapModifier::Value, Enter::Modifier,
// clang-format off
MS(Automap, Automap)
// clang-format on
);
auto &mods = semantics::OmpGetModifiers(inp.v);
auto *mod = semantics::OmpGetUniqueModifier<parser::OmpAutomapModifier>(mods);
auto &objList = std::get<parser::OmpObjectList>(inp.v.t);

return Enter{{/*Modifier=*/maybeApplyToV(convert, mod),
/*List=*/makeObjects(objList, semaCtx)}};
}

Exclusive make(const parser::OmpClause::Exclusive &inp,
Expand Down
12 changes: 11 additions & 1 deletion flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@ TYPE_PARSER(construct<OmpAllocatorSimpleModifier>(scalarIntExpr))
TYPE_PARSER(construct<OmpAlwaysModifier>( //
"ALWAYS" >> pure(OmpAlwaysModifier::Value::Always)))

TYPE_PARSER(construct<OmpAutomapModifier>(
"AUTOMAP" >> pure(OmpAutomapModifier::Value::Automap)))

TYPE_PARSER(construct<OmpChunkModifier>( //
"SIMD" >> pure(OmpChunkModifier::Value::Simd)))

Expand Down Expand Up @@ -601,6 +604,9 @@ TYPE_PARSER(sourced(construct<OmpDependClause::TaskDep::Modifier>(sourced(
TYPE_PARSER(
sourced(construct<OmpDeviceClause::Modifier>(Parser<OmpDeviceModifier>{})))

TYPE_PARSER(
sourced(construct<OmpEnterClause::Modifier>(Parser<OmpAutomapModifier>{})))

TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
sourced(construct<OmpFromClause::Modifier>(Parser<OmpExpectation>{}) ||
construct<OmpFromClause::Modifier>(Parser<OmpMapper>{}) ||
Expand Down Expand Up @@ -735,6 +741,10 @@ TYPE_PARSER(construct<OmpDefaultClause>(
Parser<OmpDefaultClause::DataSharingAttribute>{}) ||
construct<OmpDefaultClause>(indirect(Parser<OmpDirectiveSpecification>{}))))

TYPE_PARSER(construct<OmpEnterClause>(
maybe(nonemptyList(Parser<OmpEnterClause::Modifier>{}) / ":"),
Parser<OmpObjectList>{}))

TYPE_PARSER(construct<OmpFailClause>(
"ACQ_REL" >> pure(common::OmpMemoryOrderType::Acq_Rel) ||
"ACQUIRE" >> pure(common::OmpMemoryOrderType::Acquire) ||
Expand Down Expand Up @@ -1023,7 +1033,7 @@ TYPE_PARSER( //
"DYNAMIC_ALLOCATORS" >>
construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
"ENTER" >> construct<OmpClause>(construct<OmpClause::Enter>(
parenthesized(Parser<OmpObjectList>{}))) ||
parenthesized(Parser<OmpEnterClause>{}))) ||
"EXCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Exclusive>(
parenthesized(Parser<OmpObjectList>{}))) ||
"FAIL" >> construct<OmpClause>(construct<OmpClause::Fail>(
Expand Down
6 changes: 6 additions & 0 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,11 @@ class UnparseVisitor {
Walk(std::get<OmpObjectList>(x.t));
Walk(": ", std::get<std::optional<std::list<Modifier>>>(x.t));
}
void Unparse(const OmpEnterClause &x) {
using Modifier = OmpEnterClause::Modifier;
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpFromClause &x) {
using Modifier = OmpFromClause::Modifier;
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Expand Down Expand Up @@ -2986,6 +2991,7 @@ class UnparseVisitor {
WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
WALK_NESTED_ENUM(OmpAdjustArgsClause::OmpAdjustOp, Value) // OMP adjustop
WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at
WALK_NESTED_ENUM(OmpAutomapModifier, Value) // OMP automap-modifier
WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind
WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind
WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default
Expand Down
32 changes: 19 additions & 13 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1568,9 +1568,10 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
},
[&](const parser::OmpClause::Enter &enterClause) {
enterClauseFound = true;
CheckSymbolNames(dir.source, enterClause.v);
CheckVarIsNotPartOfAnotherVar(dir.source, enterClause.v);
CheckThreadprivateOrDeclareTargetVar(enterClause.v);
auto &objList{std::get<parser::OmpObjectList>(enterClause.v.t)};
CheckSymbolNames(dir.source, objList);
CheckVarIsNotPartOfAnotherVar(dir.source, objList);
CheckThreadprivateOrDeclareTargetVar(objList);
},
[&](const parser::OmpClause::DeviceType &deviceTypeClause) {
deviceTypeClauseFound = true;
Expand Down Expand Up @@ -4028,7 +4029,11 @@ void OmpStructureChecker::Enter(const parser::OmpClause::HasDeviceAddr &x) {

void OmpStructureChecker::Enter(const parser::OmpClause::Enter &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_enter);
const parser::OmpObjectList &objList{x.v};
if (!OmpVerifyModifiers(
x.v, llvm::omp::OMPC_enter, GetContext().clauseSource, context_)) {
return;
}
const parser::OmpObjectList &objList{std::get<parser::OmpObjectList>(x.v.t)};
SymbolSourceMap symbols;
GetSymbolsInObjectList(objList, symbols);
for (const auto &[symbol, source] : symbols) {
Expand Down Expand Up @@ -4488,17 +4493,18 @@ const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList(
const parser::OmpClause &clause) {

// Clauses with OmpObjectList as its data member
using MemberObjectListClauses = std::tuple<parser::OmpClause::Copyprivate,
parser::OmpClause::Copyin, parser::OmpClause::Enter,
parser::OmpClause::Firstprivate, parser::OmpClause::Link,
parser::OmpClause::Private, parser::OmpClause::Shared,
parser::OmpClause::UseDevicePtr, parser::OmpClause::UseDeviceAddr>;
using MemberObjectListClauses =
std::tuple<parser::OmpClause::Copyprivate, parser::OmpClause::Copyin,
parser::OmpClause::Firstprivate, parser::OmpClause::Link,
parser::OmpClause::Private, parser::OmpClause::Shared,
parser::OmpClause::UseDevicePtr, parser::OmpClause::UseDeviceAddr>;

// Clauses with OmpObjectList in the tuple
using TupleObjectListClauses = std::tuple<parser::OmpClause::Aligned,
parser::OmpClause::Allocate, parser::OmpClause::From,
parser::OmpClause::Lastprivate, parser::OmpClause::Map,
parser::OmpClause::Reduction, parser::OmpClause::To>;
using TupleObjectListClauses =
std::tuple<parser::OmpClause::Aligned, parser::OmpClause::Allocate,
parser::OmpClause::From, parser::OmpClause::Lastprivate,
parser::OmpClause::Map, parser::OmpClause::Reduction,
parser::OmpClause::To, parser::OmpClause::Enter>;

// TODO:: Generate the tuples using TableGen.
// Handle other constructs with OmpObjectList such as OpenMPThreadprivate.
Expand Down
16 changes: 16 additions & 0 deletions flang/lib/Semantics/openmp-modifiers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,22 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlwaysModifier>() {
return desc;
}

template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAutomapModifier>() {
static const OmpModifierDescriptor desc{
/*name=*/"automap-modifier",
/*props=*/
{
{60, {OmpProperty::Unique}},
},
/*clauses=*/
{
{60, {Clause::OMPC_enter}},
},
};
return desc;
}

template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() {
static const OmpModifierDescriptor desc{
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2152,7 +2152,8 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) {
ResolveOmpObjectList(linkClause->v, Symbol::Flag::OmpDeclareTarget);
} else if (const auto *enterClause{
std::get_if<parser::OmpClause::Enter>(&clause.u)}) {
ResolveOmpObjectList(enterClause->v, Symbol::Flag::OmpDeclareTarget);
ResolveOmpObjectList(std::get<parser::OmpObjectList>(enterClause->v.t),
Symbol::Flag::OmpDeclareTarget);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,8 @@ class OmpVisitor : public virtual DeclarationVisitor {
populateDeclareTargetNames(linkClause->v);
} else if (const auto *enterClause{
std::get_if<parser::OmpClause::Enter>(&clause.u)}) {
populateDeclareTargetNames(enterClause->v);
populateDeclareTargetNames(
std::get<parser::OmpObjectList>(enterClause->v.t));
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions flang/test/Parser/OpenMP/enter-automap-modifier.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck %s --check-prefix=UNPARSE
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck %s --check-prefix=PARSE-TREE

program automap
integer :: x
!$omp declare target enter(automap: x)
end program

!UNPARSE: PROGRAM AUTOMAP
!UNPARSE: INTEGER x
!UNPARSE: !$OMP DECLARE TARGET ENTER(AUTOMAP: x)
!UNPARSE: END PROGRAM

!PARSE-TREE: OmpClauseList -> OmpClause -> Enter -> OmpEnterClause
!PARSE-TREE-NEXT: | Modifier -> OmpAutomapModifier -> Value = Automap
!PARSE-TREE-NEXT: | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
5 changes: 3 additions & 2 deletions llvm/include/llvm/Frontend/OpenMP/ClauseT.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,8 +578,9 @@ struct DynamicAllocatorsT {
template <typename T, typename I, typename E> //
struct EnterT {
using List = ObjectListT<I, E>;
using WrapperTrait = std::true_type;
List v;
ENUM(Modifier, Automap);
using TupleTrait = std::true_type;
std::tuple<OPT(Modifier), List> t;
};

// V5.2: [5.6.2] `exclusive` clause
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Frontend/OpenMP/OMP.td
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def OMPC_DynamicAllocators : Clause<[Spelling<"dynamic_allocators">]> {
let clangClass = "OMPDynamicAllocatorsClause";
}
def OMPC_Enter : Clause<[Spelling<"enter">]> {
let flangClass = "OmpObjectList";
let flangClass = "OmpEnterClause";
}
def OMPC_Exclusive : Clause<[Spelling<"exclusive">]> {
let clangClass = "OMPExclusiveClause";
Expand Down
Loading