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
[flang][OpenMP] Convert unique clauses in ClauseProcessor #81622
Conversation
@llvm/pr-subscribers-flang-openmp @llvm/pr-subscribers-flang-fir-hlfir Author: Krzysztof Parzyszek (kparzysz) ChangesTemporarily rename old clause list to [Clause representation 2/6] Patch is 22.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/81622.diff 1 Files Affected:
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 24bef1d999548b..d7a93db15a4bb8 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -1669,7 +1669,8 @@ class ClauseProcessor {
ClauseProcessor(Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semaCtx,
const Fortran::parser::OmpClauseList &clauses)
- : converter(converter), semaCtx(semaCtx), clauses(clauses) {}
+ : converter(converter), semaCtx(semaCtx), clauses2(clauses),
+ clauses(omp::makeList(clauses, semaCtx)) {}
// 'Unique' clauses: They can appear at most once in the clause list.
bool
@@ -1769,7 +1770,8 @@ class ClauseProcessor {
llvm::omp::Directive directive) const;
private:
- using ClauseIterator = std::list<ClauseTy>::const_iterator;
+ using ClauseIterator = omp::List<omp::Clause>::const_iterator;
+ using ClauseIterator2 = std::list<ClauseTy>::const_iterator;
/// Utility to find a clause within a range in the clause list.
template <typename T>
@@ -1782,14 +1784,26 @@ class ClauseProcessor {
return end;
}
+ /// Utility to find a clause within a range in the clause list.
+ template <typename T>
+ static ClauseIterator2 findClause2(ClauseIterator2 begin,
+ ClauseIterator2 end) {
+ for (ClauseIterator2 it = begin; it != end; ++it) {
+ if (std::get_if<T>(&it->u))
+ return it;
+ }
+
+ return end;
+ }
+
/// Return the first instance of the given clause found in the clause list or
/// `nullptr` if not present. If more than one instance is expected, use
/// `findRepeatableClause` instead.
template <typename T>
const T *
findUniqueClause(const Fortran::parser::CharBlock **source = nullptr) const {
- ClauseIterator it = findClause<T>(clauses.v.begin(), clauses.v.end());
- if (it != clauses.v.end()) {
+ ClauseIterator it = findClause<T>(clauses.begin(), clauses.end());
+ if (it != clauses.end()) {
if (source)
*source = &it->source;
return &std::get<T>(it->u);
@@ -1804,9 +1818,9 @@ class ClauseProcessor {
std::function<void(const T *, const Fortran::parser::CharBlock &source)>
callbackFn) const {
bool found = false;
- ClauseIterator nextIt, endIt = clauses.v.end();
- for (ClauseIterator it = clauses.v.begin(); it != endIt; it = nextIt) {
- nextIt = findClause<T>(it, endIt);
+ ClauseIterator2 nextIt, endIt = clauses2.v.end();
+ for (ClauseIterator2 it = clauses2.v.begin(); it != endIt; it = nextIt) {
+ nextIt = findClause2<T>(it, endIt);
if (nextIt != endIt) {
callbackFn(&std::get<T>(nextIt->u), nextIt->source);
@@ -1829,7 +1843,8 @@ class ClauseProcessor {
Fortran::lower::AbstractConverter &converter;
Fortran::semantics::SemanticsContext &semaCtx;
- const Fortran::parser::OmpClauseList &clauses;
+ const Fortran::parser::OmpClauseList &clauses2;
+ omp::List<omp::Clause> clauses;
};
//===----------------------------------------------------------------------===//
@@ -2294,64 +2309,55 @@ class ReductionProcessor {
};
static mlir::omp::ScheduleModifier
-translateScheduleModifier(const Fortran::parser::OmpScheduleModifierType &m) {
- switch (m.v) {
- case Fortran::parser::OmpScheduleModifierType::ModType::Monotonic:
+translateScheduleModifier(const omp::clause::Schedule::ModType &m) {
+ switch (m) {
+ case omp::clause::Schedule::ModType::Monotonic:
return mlir::omp::ScheduleModifier::monotonic;
- case Fortran::parser::OmpScheduleModifierType::ModType::Nonmonotonic:
+ case omp::clause::Schedule::ModType::Nonmonotonic:
return mlir::omp::ScheduleModifier::nonmonotonic;
- case Fortran::parser::OmpScheduleModifierType::ModType::Simd:
+ case omp::clause::Schedule::ModType::Simd:
return mlir::omp::ScheduleModifier::simd;
}
return mlir::omp::ScheduleModifier::none;
}
static mlir::omp::ScheduleModifier
-getScheduleModifier(const Fortran::parser::OmpScheduleClause &x) {
- const auto &modifier =
- std::get<std::optional<Fortran::parser::OmpScheduleModifier>>(x.t);
+getScheduleModifier(const omp::clause::Schedule &clause) {
+ using ScheduleModifier = omp::clause::Schedule::ScheduleModifier;
+ const auto &modifier = std::get<std::optional<ScheduleModifier>>(clause.t);
// The input may have the modifier any order, so we look for one that isn't
// SIMD. If modifier is not set at all, fall down to the bottom and return
// "none".
if (modifier) {
- const auto &modType1 =
- std::get<Fortran::parser::OmpScheduleModifier::Modifier1>(modifier->t);
- if (modType1.v.v ==
- Fortran::parser::OmpScheduleModifierType::ModType::Simd) {
- const auto &modType2 = std::get<
- std::optional<Fortran::parser::OmpScheduleModifier::Modifier2>>(
- modifier->t);
- if (modType2 &&
- modType2->v.v !=
- Fortran::parser::OmpScheduleModifierType::ModType::Simd)
- return translateScheduleModifier(modType2->v);
-
+ using ModType = omp::clause::Schedule::ModType;
+ const auto &modType1 = std::get<ModType>(modifier->t);
+ if (modType1 == ModType::Simd) {
+ const auto &modType2 = std::get<std::optional<ModType>>(modifier->t);
+ if (modType2 && *modType2 != ModType::Simd)
+ return translateScheduleModifier(*modType2);
return mlir::omp::ScheduleModifier::none;
}
- return translateScheduleModifier(modType1.v);
+ return translateScheduleModifier(modType1);
}
return mlir::omp::ScheduleModifier::none;
}
static mlir::omp::ScheduleModifier
-getSimdModifier(const Fortran::parser::OmpScheduleClause &x) {
- const auto &modifier =
- std::get<std::optional<Fortran::parser::OmpScheduleModifier>>(x.t);
+getSimdModifier(const omp::clause::Schedule &clause) {
+ using ScheduleModifier = omp::clause::Schedule::ScheduleModifier;
+ const auto &modifier = std::get<std::optional<ScheduleModifier>>(clause.t);
// Either of the two possible modifiers in the input can be the SIMD modifier,
// so look in either one, and return simd if we find one. Not found = return
// "none".
if (modifier) {
- const auto &modType1 =
- std::get<Fortran::parser::OmpScheduleModifier::Modifier1>(modifier->t);
- if (modType1.v.v == Fortran::parser::OmpScheduleModifierType::ModType::Simd)
+ using ModType = omp::clause::Schedule::ModType;
+ const auto &modType1 = std::get<ModType>(modifier->t);
+ if (modType1 == ModType::Simd)
return mlir::omp::ScheduleModifier::simd;
- const auto &modType2 = std::get<
- std::optional<Fortran::parser::OmpScheduleModifier::Modifier2>>(
- modifier->t);
- if (modType2 && modType2->v.v ==
- Fortran::parser::OmpScheduleModifierType::ModType::Simd)
+ const auto &modType2 = std::get<std::optional<ModType>>(modifier->t);
+ if (modType2 && *modType2 == ModType::Simd)
return mlir::omp::ScheduleModifier::simd;
}
return mlir::omp::ScheduleModifier::none;
@@ -2405,21 +2411,21 @@ genAllocateClause(Fortran::lower::AbstractConverter &converter,
genObjectList(ompObjectList, converter, allocateOperands);
}
-static mlir::omp::ClauseProcBindKindAttr genProcBindKindAttr(
- fir::FirOpBuilder &firOpBuilder,
- const Fortran::parser::OmpClause::ProcBind *procBindClause) {
+static mlir::omp::ClauseProcBindKindAttr
+genProcBindKindAttr(fir::FirOpBuilder &firOpBuilder,
+ const omp::clause::ProcBind &clause) {
mlir::omp::ClauseProcBindKind procBindKind;
- switch (procBindClause->v.v) {
- case Fortran::parser::OmpProcBindClause::Type::Master:
+ switch (clause.v) {
+ case omp::clause::ProcBind::Type::Master:
procBindKind = mlir::omp::ClauseProcBindKind::Master;
break;
- case Fortran::parser::OmpProcBindClause::Type::Close:
+ case omp::clause::ProcBind::Type::Close:
procBindKind = mlir::omp::ClauseProcBindKind::Close;
break;
- case Fortran::parser::OmpProcBindClause::Type::Spread:
+ case omp::clause::ProcBind::Type::Spread:
procBindKind = mlir::omp::ClauseProcBindKind::Spread;
break;
- case Fortran::parser::OmpProcBindClause::Type::Primary:
+ case omp::clause::ProcBind::Type::Primary:
procBindKind = mlir::omp::ClauseProcBindKind::Primary;
break;
}
@@ -2517,9 +2523,8 @@ bool ClauseProcessor::processCollapse(
}
std::int64_t collapseValue = 1l;
- if (auto *collapseClause = findUniqueClause<ClauseTy::Collapse>()) {
- const auto *expr = Fortran::semantics::GetExpr(collapseClause->v);
- collapseValue = Fortran::evaluate::ToInt64(*expr).value();
+ if (auto *clause = findUniqueClause<omp::clause::Collapse>()) {
+ collapseValue = Fortran::evaluate::ToInt64(clause->v).value();
found = true;
}
@@ -2558,19 +2563,19 @@ bool ClauseProcessor::processCollapse(
}
bool ClauseProcessor::processDefault() const {
- if (auto *defaultClause = findUniqueClause<ClauseTy::Default>()) {
+ if (auto *clause = findUniqueClause<omp::clause::Default>()) {
// Private, Firstprivate, Shared, None
- switch (defaultClause->v.v) {
- case Fortran::parser::OmpDefaultClause::Type::Shared:
- case Fortran::parser::OmpDefaultClause::Type::None:
+ switch (clause->v) {
+ case omp::clause::Default::Type::Shared:
+ case omp::clause::Default::Type::None:
// Default clause with shared or none do not require any handling since
// Shared is the default behavior in the IR and None is only required
// for semantic checks.
break;
- case Fortran::parser::OmpDefaultClause::Type::Private:
+ case omp::clause::Default::Type::Private:
// TODO Support default(private)
break;
- case Fortran::parser::OmpDefaultClause::Type::Firstprivate:
+ case omp::clause::Default::Type::Firstprivate:
// TODO Support default(firstprivate)
break;
}
@@ -2582,20 +2587,17 @@ bool ClauseProcessor::processDefault() const {
bool ClauseProcessor::processDevice(Fortran::lower::StatementContext &stmtCtx,
mlir::Value &result) const {
const Fortran::parser::CharBlock *source = nullptr;
- if (auto *deviceClause = findUniqueClause<ClauseTy::Device>(&source)) {
+ if (auto *clause = findUniqueClause<omp::clause::Device>(&source)) {
mlir::Location clauseLocation = converter.genLocation(*source);
- if (auto deviceModifier = std::get<
- std::optional<Fortran::parser::OmpDeviceClause::DeviceModifier>>(
- deviceClause->v.t)) {
- if (deviceModifier ==
- Fortran::parser::OmpDeviceClause::DeviceModifier::Ancestor) {
+ if (auto deviceModifier =
+ std::get<std::optional<omp::clause::Device::DeviceModifier>>(
+ clause->t)) {
+ if (deviceModifier == omp::clause::Device::DeviceModifier::Ancestor) {
TODO(clauseLocation, "OMPD_target Device Modifier Ancestor");
}
}
- if (const auto *deviceExpr = Fortran::semantics::GetExpr(
- std::get<Fortran::parser::ScalarIntExpr>(deviceClause->v.t))) {
- result = fir::getBase(converter.genExprValue(*deviceExpr, stmtCtx));
- }
+ const auto &deviceExpr = std::get<omp::SomeExpr>(clause->t);
+ result = fir::getBase(converter.genExprValue(deviceExpr, stmtCtx));
return true;
}
return false;
@@ -2603,16 +2605,16 @@ bool ClauseProcessor::processDevice(Fortran::lower::StatementContext &stmtCtx,
bool ClauseProcessor::processDeviceType(
mlir::omp::DeclareTargetDeviceType &result) const {
- if (auto *deviceTypeClause = findUniqueClause<ClauseTy::DeviceType>()) {
+ if (auto *clause = findUniqueClause<omp::clause::DeviceType>()) {
// Case: declare target ... device_type(any | host | nohost)
- switch (deviceTypeClause->v.v) {
- case Fortran::parser::OmpDeviceTypeClause::Type::Nohost:
+ switch (clause->v) {
+ case omp::clause::DeviceType::Type::Nohost:
result = mlir::omp::DeclareTargetDeviceType::nohost;
break;
- case Fortran::parser::OmpDeviceTypeClause::Type::Host:
+ case omp::clause::DeviceType::Type::Host:
result = mlir::omp::DeclareTargetDeviceType::host;
break;
- case Fortran::parser::OmpDeviceTypeClause::Type::Any:
+ case omp::clause::DeviceType::Type::Any:
result = mlir::omp::DeclareTargetDeviceType::any;
break;
}
@@ -2624,12 +2626,12 @@ bool ClauseProcessor::processDeviceType(
bool ClauseProcessor::processFinal(Fortran::lower::StatementContext &stmtCtx,
mlir::Value &result) const {
const Fortran::parser::CharBlock *source = nullptr;
- if (auto *finalClause = findUniqueClause<ClauseTy::Final>(&source)) {
+ if (auto *clause = findUniqueClause<omp::clause::Final>(&source)) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
mlir::Location clauseLocation = converter.genLocation(*source);
- mlir::Value finalVal = fir::getBase(converter.genExprValue(
- *Fortran::semantics::GetExpr(finalClause->v), stmtCtx));
+ mlir::Value finalVal =
+ fir::getBase(converter.genExprValue(clause->v, stmtCtx));
result = firOpBuilder.createConvert(clauseLocation,
firOpBuilder.getI1Type(), finalVal);
return true;
@@ -2638,10 +2640,9 @@ bool ClauseProcessor::processFinal(Fortran::lower::StatementContext &stmtCtx,
}
bool ClauseProcessor::processHint(mlir::IntegerAttr &result) const {
- if (auto *hintClause = findUniqueClause<ClauseTy::Hint>()) {
+ if (auto *clause = findUniqueClause<omp::clause::Hint>()) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- const auto *expr = Fortran::semantics::GetExpr(hintClause->v);
- int64_t hintValue = *Fortran::evaluate::ToInt64(*expr);
+ int64_t hintValue = *Fortran::evaluate::ToInt64(clause->v);
result = firOpBuilder.getI64IntegerAttr(hintValue);
return true;
}
@@ -2649,20 +2650,19 @@ bool ClauseProcessor::processHint(mlir::IntegerAttr &result) const {
}
bool ClauseProcessor::processMergeable(mlir::UnitAttr &result) const {
- return markClauseOccurrence<ClauseTy::Mergeable>(result);
+ return markClauseOccurrence<omp::clause::Mergeable>(result);
}
bool ClauseProcessor::processNowait(mlir::UnitAttr &result) const {
- return markClauseOccurrence<ClauseTy::Nowait>(result);
+ return markClauseOccurrence<omp::clause::Nowait>(result);
}
bool ClauseProcessor::processNumTeams(Fortran::lower::StatementContext &stmtCtx,
mlir::Value &result) const {
// TODO Get lower and upper bounds for num_teams when parser is updated to
// accept both.
- if (auto *numTeamsClause = findUniqueClause<ClauseTy::NumTeams>()) {
- result = fir::getBase(converter.genExprValue(
- *Fortran::semantics::GetExpr(numTeamsClause->v), stmtCtx));
+ if (auto *clause = findUniqueClause<omp::clause::NumTeams>()) {
+ result = fir::getBase(converter.genExprValue(clause->v, stmtCtx));
return true;
}
return false;
@@ -2670,22 +2670,20 @@ bool ClauseProcessor::processNumTeams(Fortran::lower::StatementContext &stmtCtx,
bool ClauseProcessor::processNumThreads(
Fortran::lower::StatementContext &stmtCtx, mlir::Value &result) const {
- if (auto *numThreadsClause = findUniqueClause<ClauseTy::NumThreads>()) {
+ if (auto *clause = findUniqueClause<omp::clause::NumThreads>()) {
// OMPIRBuilder expects `NUM_THREADS` clause as a `Value`.
- result = fir::getBase(converter.genExprValue(
- *Fortran::semantics::GetExpr(numThreadsClause->v), stmtCtx));
+ result = fir::getBase(converter.genExprValue(clause->v, stmtCtx));
return true;
}
return false;
}
bool ClauseProcessor::processOrdered(mlir::IntegerAttr &result) const {
- if (auto *orderedClause = findUniqueClause<ClauseTy::Ordered>()) {
+ if (auto *clause = findUniqueClause<omp::clause::Ordered>()) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
int64_t orderedClauseValue = 0l;
- if (orderedClause->v.has_value()) {
- const auto *expr = Fortran::semantics::GetExpr(orderedClause->v);
- orderedClauseValue = *Fortran::evaluate::ToInt64(*expr);
+ if (clause->v.has_value()) {
+ orderedClauseValue = *Fortran::evaluate::ToInt64(*clause->v);
}
result = firOpBuilder.getI64IntegerAttr(orderedClauseValue);
return true;
@@ -2695,9 +2693,8 @@ bool ClauseProcessor::processOrdered(mlir::IntegerAttr &result) const {
bool ClauseProcessor::processPriority(Fortran::lower::StatementContext &stmtCtx,
mlir::Value &result) const {
- if (auto *priorityClause = findUniqueClause<ClauseTy::Priority>()) {
- result = fir::getBase(converter.genExprValue(
- *Fortran::semantics::GetExpr(priorityClause->v), stmtCtx));
+ if (auto *clause = findUniqueClause<omp::clause::Priority>()) {
+ result = fir::getBase(converter.genExprValue(clause->v, stmtCtx));
return true;
}
return false;
@@ -2705,20 +2702,19 @@ bool ClauseProcessor::processPriority(Fortran::lower::StatementContext &stmtCtx,
bool ClauseProcessor::processProcBind(
mlir::omp::ClauseProcBindKindAttr &result) const {
- if (auto *procBindClause = findUniqueClause<ClauseTy::ProcBind>()) {
+ if (auto *clause = findUniqueClause<omp::clause::ProcBind>()) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- result = genProcBindKindAttr(firOpBuilder, procBindClause);
+ result = genProcBindKindAttr(firOpBuilder, *clause);
return true;
}
return false;
}
bool ClauseProcessor::processSafelen(mlir::IntegerAttr &result) const {
- if (auto *safelenClause = findUniqueClause<ClauseTy::Safelen>()) {
+ if (auto *clause = findUniqueClause<omp::clause::Safelen>()) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- const auto *expr = Fortran::semantics::GetExpr(safelenClause->v);
const std::optional<std::int64_t> safelenVal =
- Fortran::evaluate::ToInt64(*expr);
+ Fortran::evaluate::ToInt64(clause->v);
result = firOpBuilder.getI64IntegerAttr(*safelenVal);
return true;
}
@@ -2729,41 +2725,38 @@ bool ClauseProcessor::processSchedule(
mlir::omp::ClauseScheduleKindAttr &valAttr,
mlir::omp::ScheduleModifierAttr &modifierAttr,
mlir::UnitAttr &simdModifierAttr) const {
- if (auto *scheduleClause = findUniqueClause<ClauseTy::Schedule>()) {
+ if (auto *clause = findUniqueClause<omp::clause::Schedule>()) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
mlir::MLIRContext *context = firOpBuilder.getContext();
- const Fortran::parser::OmpScheduleClause &scheduleType = scheduleClause->v;
- const auto &scheduleClauseKind =
- std::get<Fortran::parser::OmpScheduleClause::ScheduleType>(
- scheduleType.t);
+ const auto &scheduleType =
+ std::get<omp::clause::Schedule::ScheduleType>(clause->t);
mlir::omp::ClauseScheduleKind scheduleKind;
- switch (scheduleClauseKind) {
- case Fortran::parser::OmpScheduleClause::ScheduleType::Static:
+ switch (scheduleType) {
+ case omp::clause::Schedule::ScheduleType::Static:
scheduleKind = mlir::omp::ClauseScheduleKind::Static;
break;
- case Fortran::parser::OmpScheduleClause::ScheduleType::Dynamic:
+ case omp::clause::Schedule::ScheduleType::Dynamic:
scheduleKind = mlir::omp::ClauseScheduleKind::Dynamic;
break;
- case Fortran::parser::OmpScheduleClause::ScheduleType::Guided:
+ case omp::clause::Schedule::ScheduleType::Guided:
scheduleKind = mlir::omp::ClauseScheduleKind::Guided;
break;
- case Fortran::parser::OmpScheduleClause::ScheduleType::Auto:
+ case omp::clause::Schedule::ScheduleType::Auto:
scheduleKind = mlir::omp::ClauseScheduleKind::Auto;
break;
- case Fortran::parser::OmpScheduleClause::ScheduleType::Runtime:
+ case omp::clause::Schedule::ScheduleType::Runtime:
scheduleKind = mlir::omp::ClauseScheduleKind::Runtime;
break;
}
- mlir::omp::ScheduleModifier scheduleModifier =
- getScheduleModifier(scheduleClause->v);
+ mlir::omp::ScheduleModifier scheduleModifier = getScheduleModifier(*clause);
if (scheduleModifier != mlir::omp::ScheduleModifier::none)
modifierAttr =
mlir::om...
[truncated]
|
5e67fca
to
f0bcbbf
Compare
bdf3050
to
57c70c5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, LGTM.
668bd37
to
e37dd7d
Compare
Introduce a set of generic classes (templates) that represent OpenMP clauses in a language-agnostic manner. OpenMP clauses can contain expressions and data objects and the exact representation of each depends on the source language of the compiled program. To deal with this, the templates depend on two type parameters: - IdType: type that represent object's identity (in a way that satisfied OpenMP requirements), and - ExprType: type that can represent numeric values, as well as data references (e.g. x.y[1].z[2]). In addition to that, implement code instantiating these templates from flang's AST. This patch only introduces the new classes, they are not yet used anywhere.
e37dd7d
to
e16585a
Compare
Temporarily rename old clause list to `clauses2`, old clause iterator to `ClauseIterator2`. Change `findUniqueClause` to iterate over `omp::Clause` objects, modify all handlers to operate on 'omp::clause::xyz` equivalents.
edc050c
to
fafbd98
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly mechanical changes. LGTM. Please wait for @skatrak
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Temporarily rename old clause list to
clauses2
, old clause iterator toClauseIterator2
.Change
findUniqueClause
to iterate overomp::Clause
objects, modify all handlers to operate on 'omp::clause::xyz` equivalents.[Clause representation 2/6]