Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
8 changes: 8 additions & 0 deletions flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,13 @@ struct NodeVisitor {
READ_FEATURE(OmpScheduleClause)
READ_FEATURE(OmpScheduleClause::Kind)
READ_FEATURE(OmpScheduleClause::Modifier)
READ_FEATURE(OmpInteropRuntimeIdentifier)
READ_FEATURE(OmpInteropPreference)
READ_FEATURE(OmpInteropType)
READ_FEATURE(OmpInteropType::Value)
READ_FEATURE(OmpInitClause)
READ_FEATURE(OmpInitClause::Modifier)
READ_FEATURE(OmpUseClause)
READ_FEATURE(OmpDeviceModifier)
READ_FEATURE(OmpDeviceClause)
READ_FEATURE(OmpDeviceClause::Modifier)
Expand All @@ -542,6 +549,7 @@ struct NodeVisitor {
READ_FEATURE(OpenACCConstruct)
READ_FEATURE(OpenACCDeclarativeConstruct)
READ_FEATURE(OpenACCLoopConstruct)
READ_FEATURE(OpenMPInteropConstruct)
READ_FEATURE(OpenACCRoutineConstruct)
READ_FEATURE(OpenACCStandaloneDeclarativeConstruct)
READ_FEATURE(OpenACCStandaloneConstruct)
Expand Down
8 changes: 8 additions & 0 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,13 @@ class ParseTreeDumper {
NODE_ENUM(OmpDeviceModifier, Value)
NODE(parser, OmpDeviceTypeClause)
NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
NODE(parser, OmpInteropRuntimeIdentifier)
NODE(parser, OmpInteropPreference)
NODE(parser, OmpInteropType)
NODE_ENUM(OmpInteropType, Value)
NODE(parser, OmpInitClause)
NODE(OmpInitClause, Modifier)
NODE(parser, OmpUseClause)
NODE(parser, OmpUpdateClause)
NODE(parser, OmpChunkModifier)
NODE_ENUM(OmpChunkModifier, Value)
Expand All @@ -675,6 +682,7 @@ class ParseTreeDumper {
NODE(parser, OpenACCDeclarativeConstruct)
NODE(parser, OpenACCEndConstruct)
NODE(parser, OpenACCLoopConstruct)
NODE(parser, OpenMPInteropConstruct)
NODE(parser, OpenACCRoutineConstruct)
NODE(parser, OpenACCStandaloneDeclarativeConstruct)
NODE(parser, OpenACCStandaloneConstruct)
Expand Down
57 changes: 56 additions & 1 deletion flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3824,6 +3824,33 @@ struct OmpExpectation {
WRAPPER_CLASS_BOILERPLATE(OmpExpectation, Value);
};

// REF: [5.1:217-220], [5.2:293-294]
//
// OmpInteropRuntimeIdentifier -> // since 5.2
// CharLiteralConstant || ScalarIntConstantExpr
struct OmpInteropRuntimeIdentifier {
UNION_CLASS_BOILERPLATE(OmpInteropRuntimeIdentifier);
std::variant<CharLiteralConstant, ScalarIntConstantExpr> u;
};

// REF: [5.1:217-220], [5.2:293-294]
//
// OmpInteropPreference -> // since 5.2
// ([OmpRuntimeIdentifier, ...])
struct OmpInteropPreference {
WRAPPER_CLASS_BOILERPLATE(
OmpInteropPreference, std::list<OmpInteropRuntimeIdentifier>);
};

// REF: [5.1:217-220], [5.2:293-294]
//
// InteropType -> target || targetsync // since 5.2
// There can be at most only two interop-type.
struct OmpInteropType {
ENUM_CLASS(Value, Target, TargetSync)
WRAPPER_CLASS_BOILERPLATE(OmpInteropType, Value);
};

// Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69]
//
// iterator-modifier ->
Expand Down Expand Up @@ -4481,6 +4508,25 @@ struct OmpWhenClause {
t;
};

// REF: [5.1:217-220], [5.2:293-294]
//
// init-clause -> INIT ([interop-modifier,] [interop-type,]
// interop-type: interop-var)
// interop-modifier: prefer_type(preference-list)
// interop-type: target, targetsync
// interop-var: Ompobject
// There can be at most only two interop-type.
struct OmpInitClause {
TUPLE_CLASS_BOILERPLATE(OmpInitClause);
MODIFIER_BOILERPLATE(OmpInteropPreference, OmpInteropType);
std::tuple<MODIFIERS(), OmpObject> t;
};

// REF: [5.1:217-220], [5.2:294]
//
// 14.1.3 use-clause -> USE (interop-var)
WRAPPER_CLASS(OmpUseClause, OmpObject);

// OpenMP Clauses
struct OmpClause {
UNION_CLASS_BOILERPLATE(OmpClause);
Expand Down Expand Up @@ -4939,6 +4985,15 @@ struct OmpSimpleStandaloneDirective {
CharBlock source;
};

// Ref: [5.1:217-220], [5.2:291-292]
//
// interop -> INTEROP clause[ [ [,] clause]...]
struct OpenMPInteropConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPInteropConstruct);
CharBlock source;
std::tuple<Verbatim, OmpClauseList> t;
};

struct OpenMPSimpleStandaloneConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPSimpleStandaloneConstruct);
CharBlock source;
Expand All @@ -4950,7 +5005,7 @@ struct OpenMPStandaloneConstruct {
CharBlock source;
std::variant<OpenMPSimpleStandaloneConstruct, OpenMPFlushConstruct,
OpenMPCancelConstruct, OpenMPCancellationPointConstruct,
OpenMPDepobjConstruct, OmpMetadirectiveDirective>
OpenMPDepobjConstruct, OmpMetadirectiveDirective, OpenMPInteropConstruct>
u;
};

Expand Down
2 changes: 2 additions & 0 deletions flang/include/flang/Semantics/openmp-modifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ DECLARE_DESCRIPTOR(parser::OmpDependenceType);
DECLARE_DESCRIPTOR(parser::OmpDeviceModifier);
DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier);
DECLARE_DESCRIPTOR(parser::OmpExpectation);
DECLARE_DESCRIPTOR(parser::OmpInteropPreference);
DECLARE_DESCRIPTOR(parser::OmpInteropType);
DECLARE_DESCRIPTOR(parser::OmpIterator);
DECLARE_DESCRIPTOR(parser::OmpLastprivateModifier);
DECLARE_DESCRIPTOR(parser::OmpLinearModifier);
Expand Down
10 changes: 10 additions & 0 deletions flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@ extractOmpDirective(const parser::OpenMPConstruct &ompConstruct) {
},
[](const parser::OpenMPDepobjConstruct &c) {
return llvm::omp::OMPD_depobj;
},
[](const parser::OpenMPInteropConstruct &c) {
return llvm::omp::OMPD_interop;
}},
c.u);
},
Expand Down Expand Up @@ -3364,6 +3367,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
TODO(converter.getCurrentLocation(), "OpenMPDepobjConstruct");
}

static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPInteropConstruct &interopConstruct) {
TODO(converter.getCurrentLocation(), "OpenMPInteropConstruct");
}

static void
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
Expand Down
33 changes: 32 additions & 1 deletion flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,17 @@ TYPE_PARSER(construct<OmpDeviceModifier>(
TYPE_PARSER(construct<OmpExpectation>( //
"PRESENT" >> pure(OmpExpectation::Value::Present)))

TYPE_PARSER(construct<OmpInteropRuntimeIdentifier>(
construct<OmpInteropRuntimeIdentifier>(charLiteralConstant) ||
construct<OmpInteropRuntimeIdentifier>(scalarIntConstantExpr)))

TYPE_PARSER(construct<OmpInteropPreference>(verbatim("PREFER_TYPE"_tok) >>
parenthesized(nonemptyList(Parser<OmpInteropRuntimeIdentifier>{}))))

TYPE_PARSER(construct<OmpInteropType>(
"TARGETSYNC" >> pure(OmpInteropType::Value::TargetSync) ||
"TARGET" >> pure(OmpInteropType::Value::Target)))

TYPE_PARSER(construct<OmpIteratorSpecifier>(
// Using Parser<TypeDeclarationStmt> or Parser<EntityDecl> has the problem
// that they will attempt to treat what follows the '=' as initialization.
Expand Down Expand Up @@ -521,6 +532,11 @@ TYPE_PARSER(sourced(

TYPE_PARSER(sourced(construct<OmpIfClause::Modifier>(OmpDirectiveNameParser{})))

TYPE_PARSER(sourced(
construct<OmpInitClause::Modifier>(
construct<OmpInitClause::Modifier>(Parser<OmpInteropPreference>{})) ||
construct<OmpInitClause::Modifier>(Parser<OmpInteropType>{})))

TYPE_PARSER(sourced(construct<OmpInReductionClause::Modifier>(
Parser<OmpReductionIdentifier>{})))

Expand Down Expand Up @@ -757,6 +773,11 @@ TYPE_PARSER(
// OpenMPv5.2 12.5.2 detach-clause -> DETACH (event-handle)
TYPE_PARSER(construct<OmpDetachClause>(Parser<OmpObject>{}))

// init clause
TYPE_PARSER(construct<OmpInitClause>(
maybe(nonemptyList(Parser<OmpInitClause::Modifier>{}) / ":"),
Parser<OmpObject>{}))

// 2.8.1 ALIGNED (list: alignment)
TYPE_PARSER(construct<OmpAlignedClause>(Parser<OmpObjectList>{},
maybe(":" >> nonemptyList(Parser<OmpAlignedClause::Modifier>{}))))
Expand Down Expand Up @@ -896,6 +917,8 @@ TYPE_PARSER( //
"IF" >> construct<OmpClause>(construct<OmpClause::If>(
parenthesized(Parser<OmpIfClause>{}))) ||
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
"INIT" >> construct<OmpClause>(construct<OmpClause::Init>(
parenthesized(Parser<OmpInitClause>{}))) ||
"INCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Inclusive>(
parenthesized(Parser<OmpObjectList>{}))) ||
"INITIALIZER" >> construct<OmpClause>(construct<OmpClause::Initializer>(
Expand Down Expand Up @@ -985,6 +1008,8 @@ TYPE_PARSER( //
parenthesized(scalarIntExpr))) ||
"TO" >> construct<OmpClause>(construct<OmpClause::To>(
parenthesized(Parser<OmpToClause>{}))) ||
"USE" >> construct<OmpClause>(construct<OmpClause::Use>(
parenthesized(Parser<OmpObject>{}))) ||
"USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>(
parenthesized(Parser<OmpObjectList>{}))) ||
"USE_DEVICE_ADDR" >>
Expand Down Expand Up @@ -1212,6 +1237,10 @@ TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first(
TYPE_PARSER(sourced(construct<OpenMPSimpleStandaloneConstruct>(
Parser<OmpSimpleStandaloneDirective>{}, Parser<OmpClauseList>{})))

// OMP 5.2 14.1 Interop construct
TYPE_PARSER(sourced(construct<OpenMPInteropConstruct>(
verbatim("INTEROP"_tok), sourced(Parser<OmpClauseList>{}))))

// Standalone Constructs
TYPE_PARSER(
sourced(construct<OpenMPStandaloneConstruct>(
Expand All @@ -1223,7 +1252,9 @@ TYPE_PARSER(
construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
construct<OpenMPStandaloneConstruct>(
Parser<OmpMetadirectiveDirective>{}) ||
construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{})) /
construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{}) ||
construct<OpenMPStandaloneConstruct>(
Parser<OpenMPInteropConstruct>{})) /
endOfLine)

// Directives enclosing structured-block
Expand Down
34 changes: 34 additions & 0 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,30 @@ class UnparseVisitor {
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpInteropPreference &x) { Walk(x.v, ","); }
void Unparse(const OmpInitClause &x) {
using Modifier = OmpInitClause::Modifier;
auto &modifiers{std::get<std::optional<std::list<Modifier>>>(x.t)};
bool isTypeStart{true};
for (const Modifier &m : *modifiers) {
if (auto *interopPreferenceMod{
std::get_if<parser::OmpInteropPreference>(&m.u)}) {
Put("PREFER_TYPE(");
Walk(*interopPreferenceMod);
Put("),");
} else if (auto *interopTypeMod{
std::get_if<parser::OmpInteropType>(&m.u)}) {
if (isTypeStart) {
isTypeStart = false;
} else {
Put(",");
}
Walk(*interopTypeMod);
}
}
Put(": ");
Walk(std::get<OmpObject>(x.t));
}
void Unparse(const OmpMapClause &x) {
using Modifier = OmpMapClause::Modifier;
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Expand Down Expand Up @@ -2740,6 +2764,15 @@ class UnparseVisitor {
Put("\n");
EndOpenMP();
}

void Unparse(const OpenMPInteropConstruct &x) {
BeginOpenMP();
Word("!$OMP INTEROP");
Walk(std::get<OmpClauseList>(x.t));
Put("\n");
EndOpenMP();
}

void Unparse(const OpenMPDeclarativeAssumes &x) {
BeginOpenMP();
Word("!$OMP ASSUMES ");
Expand Down Expand Up @@ -3037,6 +3070,7 @@ class UnparseVisitor {
OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type
WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier
WALK_NESTED_ENUM(OmpExpectation, Value) // OMP motion-expectation
WALK_NESTED_ENUM(OmpInteropType, Value) // OMP InteropType
WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering
WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier
WALK_NESTED_ENUM(OmpPrescriptiveness, Value) // OMP prescriptiveness
Expand Down
82 changes: 82 additions & 0 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5638,6 +5638,88 @@ void OmpStructureChecker::Leave(const parser::DoConstruct &x) {
Base::Leave(x);
}

void OmpStructureChecker::Enter(const parser::OpenMPInteropConstruct &x) {
bool isDependClauseOccured{false};
int targetCount{0}, targetSyncCount{0};
const auto &dir{std::get<parser::Verbatim>(x.t)};
std::set<const Symbol *> objectSymbolList;
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_interop);
const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
for (const auto &clause : clauseList.v) {
common::visit(
common::visitors{
[&](const parser::OmpClause::Init &initClause) {
if (OmpVerifyModifiers(initClause.v, llvm::omp::OMPC_init,
GetContext().directiveSource, context_)) {

auto &modifiers{OmpGetModifiers(initClause.v)};
auto &&interopTypeModifier{
OmpGetRepeatableModifier<parser::OmpInteropType>(
modifiers)};
for (const auto &it : interopTypeModifier) {
if (it->v == parser::OmpInteropType::Value::TargetSync) {
++targetSyncCount;
} else {
++targetCount;
}
}
}
const auto &interopVar{parser::Unwrap<parser::OmpObject>(
std::get<parser::OmpObject>(initClause.v.t))};
const auto *name{parser::Unwrap<parser::Name>(interopVar)};
const auto *objectSymbol{name->symbol};
if (llvm::is_contained(objectSymbolList, objectSymbol)) {
context_.Say(GetContext().directiveSource,
"Each interop-var may be specified for at most one action-clause of each INTEROP construct."_err_en_US);
} else {
objectSymbolList.insert(objectSymbol);
}
},
[&](const parser::OmpClause::Depend &dependClause) {
isDependClauseOccured = true;
},
[&](const parser::OmpClause::Destroy &destroyClause) {
const auto &interopVar{
parser::Unwrap<parser::OmpObject>(destroyClause.v)};
const auto *name{parser::Unwrap<parser::Name>(interopVar)};
const auto *objectSymbol{name->symbol};
if (llvm::is_contained(objectSymbolList, objectSymbol)) {
context_.Say(GetContext().directiveSource,
"Each interop-var may be specified for at most one action-clause of each INTEROP construct."_err_en_US);
} else {
objectSymbolList.insert(objectSymbol);
}
},
[&](const parser::OmpClause::Use &useClause) {
const auto &interopVar{
parser::Unwrap<parser::OmpObject>(useClause.v)};
const auto *name{parser::Unwrap<parser::Name>(interopVar)};
const auto *objectSymbol{name->symbol};
if (llvm::is_contained(objectSymbolList, objectSymbol)) {
context_.Say(GetContext().directiveSource,
"Each interop-var may be specified for at most one action-clause of each INTEROP construct."_err_en_US);
} else {
objectSymbolList.insert(objectSymbol);
}
},
[&](const auto &) {},
},
clause.u);
}
if (targetCount > 1 || targetSyncCount > 1) {
context_.Say(GetContext().directiveSource,
"Each interop-type may be specified at most once."_err_en_US);
}
if (isDependClauseOccured && !targetSyncCount) {
context_.Say(GetContext().directiveSource,
"A DEPEND clause can only appear on the directive if the interop-type includes TARGETSYNC"_err_en_US);
}
}

void OmpStructureChecker::Leave(const parser::OpenMPInteropConstruct &) {
dirContext_.pop_back();
}

void OmpStructureChecker::CheckAllowedRequiresClause(llvmOmpClause clause) {
CheckAllowedClause(clause);

Expand Down
2 changes: 2 additions & 0 deletions flang/lib/Semantics/check-omp-structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class OmpStructureChecker

void Enter(const parser::OpenMPConstruct &);
void Leave(const parser::OpenMPConstruct &);
void Enter(const parser::OpenMPInteropConstruct &);
void Leave(const parser::OpenMPInteropConstruct &);
void Enter(const parser::OpenMPDeclarativeConstruct &);
void Leave(const parser::OpenMPDeclarativeConstruct &);

Expand Down
Loading