[flang][OpenMP] Use new modifier code in ORDER and SCHEDULE clauses (#117081)
This actually simplifies the AST node for the schedule clause: the two allowed modifiers can be easily classified as the ordering-modifier and the chunk-modifier during parsing without the need to create additional classes.
This commit is contained in:
committed by
GitHub
parent
ab28d387fa
commit
e79cd24676
@@ -505,9 +505,9 @@ public:
|
||||
READ_FEATURE(OmpObject)
|
||||
READ_FEATURE(OmpObjectList)
|
||||
READ_FEATURE(OmpOrderClause)
|
||||
READ_FEATURE(OmpOrderClause::Type)
|
||||
READ_FEATURE(OmpOrderClause::Ordering)
|
||||
READ_FEATURE(OmpOrderModifier)
|
||||
READ_FEATURE(OmpOrderModifier::Kind)
|
||||
READ_FEATURE(OmpOrderModifier::Value)
|
||||
READ_FEATURE(OmpProcBindClause)
|
||||
READ_FEATURE(OmpProcBindClause::Type)
|
||||
READ_FEATURE(OmpReductionClause)
|
||||
@@ -522,16 +522,16 @@ public:
|
||||
READ_FEATURE(OmpAllocateClause::AllocateModifier::ComplexModifier)
|
||||
READ_FEATURE(OmpAllocateClause::AllocateModifier::Align)
|
||||
READ_FEATURE(OmpScheduleClause)
|
||||
READ_FEATURE(OmpScheduleClause::ScheduleType)
|
||||
READ_FEATURE(OmpScheduleClause::Kind)
|
||||
READ_FEATURE(OmpScheduleClause::Modifier)
|
||||
READ_FEATURE(OmpDeviceClause)
|
||||
READ_FEATURE(OmpDeviceClause::DeviceModifier)
|
||||
READ_FEATURE(OmpDeviceTypeClause)
|
||||
READ_FEATURE(OmpDeviceTypeClause::Type)
|
||||
READ_FEATURE(OmpScheduleModifier)
|
||||
READ_FEATURE(OmpScheduleModifier::Modifier1)
|
||||
READ_FEATURE(OmpScheduleModifier::Modifier2)
|
||||
READ_FEATURE(OmpScheduleModifierType)
|
||||
READ_FEATURE(OmpScheduleModifierType::ModType)
|
||||
READ_FEATURE(OmpChunkModifier)
|
||||
READ_FEATURE(OmpChunkModifier::Value)
|
||||
READ_FEATURE(OmpOrderingModifier)
|
||||
READ_FEATURE(OmpOrderingModifier::Value)
|
||||
READ_FEATURE(OmpSectionBlocks)
|
||||
READ_FEATURE(OmpSectionsDirective)
|
||||
READ_FEATURE(OmpSimpleStandaloneDirective)
|
||||
|
||||
@@ -213,14 +213,18 @@ void OpenMPCounterVisitor::Post(const OmpVariableCategory::Value &c) {
|
||||
"variable_category=" + std::string{OmpVariableCategory::EnumToString(c)} +
|
||||
";";
|
||||
}
|
||||
void OpenMPCounterVisitor::Post(const OmpScheduleModifierType::ModType &c) {
|
||||
void OpenMPCounterVisitor::Post(const OmpChunkModifier::Value &c) {
|
||||
clauseDetails +=
|
||||
"modifier=" + std::string{OmpScheduleModifierType::EnumToString(c)} + ";";
|
||||
"modifier=" + std::string{OmpChunkModifier::EnumToString(c)} + ";";
|
||||
}
|
||||
void OpenMPCounterVisitor::Post(const OmpLinearModifier::Value &c) {
|
||||
clauseDetails +=
|
||||
"modifier=" + std::string{OmpLinearModifier::EnumToString(c)} + ";";
|
||||
}
|
||||
void OpenMPCounterVisitor::Post(const OmpOrderingModifier::Value &c) {
|
||||
clauseDetails +=
|
||||
"modifier=" + std::string{OmpOrderingModifier::EnumToString(c)} + ";";
|
||||
}
|
||||
void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value &c) {
|
||||
clauseDetails +=
|
||||
"type=" + std::string{OmpTaskDependenceType::EnumToString(c)} + ";";
|
||||
@@ -228,7 +232,7 @@ void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value &c) {
|
||||
void OpenMPCounterVisitor::Post(const OmpMapClause::Type &c) {
|
||||
clauseDetails += "type=" + std::string{OmpMapClause::EnumToString(c)} + ";";
|
||||
}
|
||||
void OpenMPCounterVisitor::Post(const OmpScheduleClause::ScheduleType &c) {
|
||||
void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) {
|
||||
clauseDetails +=
|
||||
"type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";";
|
||||
}
|
||||
|
||||
@@ -71,11 +71,12 @@ struct OpenMPCounterVisitor {
|
||||
void Post(const OmpDefaultmapClause::ImplicitBehavior &c);
|
||||
void Post(const OmpVariableCategory::Value &c);
|
||||
void Post(const OmpDeviceTypeClause::Type &c);
|
||||
void Post(const OmpScheduleModifierType::ModType &c);
|
||||
void Post(const OmpChunkModifier::Value &c);
|
||||
void Post(const OmpLinearModifier::Value &c);
|
||||
void Post(const OmpOrderingModifier::Value &c);
|
||||
void Post(const OmpTaskDependenceType::Value &c);
|
||||
void Post(const OmpMapClause::Type &c);
|
||||
void Post(const OmpScheduleClause::ScheduleType &c);
|
||||
void Post(const OmpScheduleClause::Kind &c);
|
||||
void Post(const OmpIfClause::DirectiveNameModifier &c);
|
||||
void Post(const OmpCancelType::Type &c);
|
||||
void Post(const OmpClause &c);
|
||||
|
||||
@@ -559,9 +559,10 @@ public:
|
||||
NODE(parser, OmpObject)
|
||||
NODE(parser, OmpObjectList)
|
||||
NODE(parser, OmpOrderClause)
|
||||
NODE_ENUM(OmpOrderClause, Type)
|
||||
NODE(OmpOrderClause, Modifier)
|
||||
NODE_ENUM(OmpOrderClause, Ordering)
|
||||
NODE(parser, OmpOrderModifier)
|
||||
NODE_ENUM(OmpOrderModifier, Kind)
|
||||
NODE_ENUM(OmpOrderModifier, Value)
|
||||
NODE(parser, OmpGrainsizeClause)
|
||||
NODE_ENUM(OmpGrainsizeClause, Prescriptiveness)
|
||||
NODE(parser, OmpNumTasksClause)
|
||||
@@ -585,17 +586,17 @@ public:
|
||||
NODE(OmpAllocateClause::AllocateModifier, ComplexModifier)
|
||||
NODE(OmpAllocateClause::AllocateModifier, Align)
|
||||
NODE(parser, OmpScheduleClause)
|
||||
NODE_ENUM(OmpScheduleClause, ScheduleType)
|
||||
NODE(OmpScheduleClause, Modifier)
|
||||
NODE_ENUM(OmpScheduleClause, Kind)
|
||||
NODE(parser, OmpDeviceClause)
|
||||
NODE_ENUM(OmpDeviceClause, DeviceModifier)
|
||||
NODE(parser, OmpDeviceTypeClause)
|
||||
NODE_ENUM(OmpDeviceTypeClause, Type)
|
||||
NODE(parser, OmpUpdateClause)
|
||||
NODE(parser, OmpScheduleModifier)
|
||||
NODE(OmpScheduleModifier, Modifier1)
|
||||
NODE(OmpScheduleModifier, Modifier2)
|
||||
NODE(parser, OmpScheduleModifierType)
|
||||
NODE_ENUM(OmpScheduleModifierType, ModType)
|
||||
NODE(parser, OmpChunkModifier)
|
||||
NODE_ENUM(OmpChunkModifier, Value)
|
||||
NODE(parser, OmpOrderingModifier)
|
||||
NODE_ENUM(OmpOrderingModifier, Value)
|
||||
NODE(parser, OmpSectionBlocks)
|
||||
NODE(parser, OmpSectionsDirective)
|
||||
NODE(parser, OmpSimpleStandaloneDirective)
|
||||
|
||||
@@ -3457,6 +3457,17 @@ inline namespace modifier {
|
||||
// ENUM_CLASS(Value, Keyword1, Keyword2);
|
||||
// };
|
||||
|
||||
// Ref: [5.2:252-254]
|
||||
//
|
||||
// chunk-modifier ->
|
||||
// SIMD // since 5.2
|
||||
//
|
||||
// Prior to 5.2 "chunk-modifier" was a part of "modifier" on SCHEDULE clause.
|
||||
struct OmpChunkModifier {
|
||||
ENUM_CLASS(Value, Simd)
|
||||
WRAPPER_CLASS_BOILERPLATE(OmpChunkModifier, Value);
|
||||
};
|
||||
|
||||
// Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69]
|
||||
//
|
||||
// iterator-specifier ->
|
||||
@@ -3508,6 +3519,30 @@ struct OmpLinearModifier {
|
||||
WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Value);
|
||||
};
|
||||
|
||||
// Ref: [4.5:56-63], [5.0:101-109], [5.1:126-133], [5.2:252-254]
|
||||
//
|
||||
// modifier ->
|
||||
// MONOTONIC | NONMONOTONIC | SIMD // since 4.5, until 5.1
|
||||
// ordering-modifier ->
|
||||
// MONOTONIC | NONMONOTONIC // since 5.2
|
||||
//
|
||||
// Until 5.1, the SCHEDULE clause accepted up to two instances of "modifier".
|
||||
// Since 5.2 "modifier" was replaced with "ordering-modifier" and "chunk-
|
||||
// modifier".
|
||||
struct OmpOrderingModifier {
|
||||
ENUM_CLASS(Value, Monotonic, Nonmonotonic, Simd)
|
||||
WRAPPER_CLASS_BOILERPLATE(OmpOrderingModifier, Value);
|
||||
};
|
||||
|
||||
// Ref: [5.1:125-126], [5.2:233-234]
|
||||
//
|
||||
// order-modifier ->
|
||||
// REPRODUCIBLE | UNCONSTRAINED // since 5.1
|
||||
struct OmpOrderModifier {
|
||||
ENUM_CLASS(Value, Reproducible, Unconstrained)
|
||||
WRAPPER_CLASS_BOILERPLATE(OmpOrderModifier, Value);
|
||||
};
|
||||
|
||||
// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
|
||||
//
|
||||
// reduction-identifier ->
|
||||
@@ -3786,16 +3821,16 @@ struct OmpMapClause {
|
||||
t;
|
||||
};
|
||||
|
||||
// 2.9.5 order-clause -> ORDER ([order-modifier :]concurrent)
|
||||
struct OmpOrderModifier {
|
||||
ENUM_CLASS(Kind, Reproducible, Unconstrained)
|
||||
WRAPPER_CLASS_BOILERPLATE(OmpOrderModifier, Kind);
|
||||
};
|
||||
|
||||
// Ref: [5.0:101-109], [5.1:126-134], [5.2:233-234]
|
||||
//
|
||||
// order-clause ->
|
||||
// ORDER(CONCURRENT) | // since 5.0
|
||||
// ORDER([order-modifier:] CONCURRENT) // since 5.1
|
||||
struct OmpOrderClause {
|
||||
TUPLE_CLASS_BOILERPLATE(OmpOrderClause);
|
||||
ENUM_CLASS(Type, Concurrent)
|
||||
std::tuple<std::optional<OmpOrderModifier>, Type> t;
|
||||
ENUM_CLASS(Ordering, Concurrent)
|
||||
MODIFIER_BOILERPLATE(OmpOrderModifier);
|
||||
std::tuple<MODIFIERS(), Ordering> t;
|
||||
};
|
||||
|
||||
// 2.5 proc-bind-clause -> PROC_BIND (MASTER | CLOSE | SPREAD)
|
||||
@@ -3816,27 +3851,19 @@ struct OmpReductionClause {
|
||||
std::tuple<MODIFIERS(), OmpObjectList> t;
|
||||
};
|
||||
|
||||
// 2.7.1 sched-modifier -> MONOTONIC | NONMONOTONIC | SIMD
|
||||
struct OmpScheduleModifierType {
|
||||
ENUM_CLASS(ModType, Monotonic, Nonmonotonic, Simd)
|
||||
WRAPPER_CLASS_BOILERPLATE(OmpScheduleModifierType, ModType);
|
||||
};
|
||||
|
||||
struct OmpScheduleModifier {
|
||||
TUPLE_CLASS_BOILERPLATE(OmpScheduleModifier);
|
||||
WRAPPER_CLASS(Modifier1, OmpScheduleModifierType);
|
||||
WRAPPER_CLASS(Modifier2, OmpScheduleModifierType);
|
||||
std::tuple<Modifier1, std::optional<Modifier2>> t;
|
||||
};
|
||||
|
||||
// 2.7.1 schedule-clause -> SCHEDULE ([sched-modifier1] [, sched-modifier2]:]
|
||||
// kind[, chunk_size])
|
||||
// Ref: [4.5:56-63], [5.0:101-109], [5.1:126-133], [5.2:252-254]
|
||||
//
|
||||
// schedule-clause ->
|
||||
// SCHEDULE([modifier[, modifier]:]
|
||||
// kind[, chunk-size]) // since 4.5, until 5.1
|
||||
// schedule-clause ->
|
||||
// SCHEDULE([ordering-modifier], chunk-modifier],
|
||||
// kind[, chunk_size]) // since 5.2
|
||||
struct OmpScheduleClause {
|
||||
TUPLE_CLASS_BOILERPLATE(OmpScheduleClause);
|
||||
ENUM_CLASS(ScheduleType, Static, Dynamic, Guided, Auto, Runtime)
|
||||
std::tuple<std::optional<OmpScheduleModifier>, ScheduleType,
|
||||
std::optional<ScalarIntExpr>>
|
||||
t;
|
||||
ENUM_CLASS(Kind, Static, Dynamic, Guided, Auto, Runtime)
|
||||
MODIFIER_BOILERPLATE(OmpOrderingModifier, OmpChunkModifier);
|
||||
std::tuple<MODIFIERS(), Kind, std::optional<ScalarIntExpr>> t;
|
||||
};
|
||||
|
||||
// Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168]
|
||||
|
||||
@@ -61,6 +61,8 @@ struct OmpModifierDescriptor {
|
||||
|
||||
template <typename SpecificTy> const OmpModifierDescriptor &OmpGetDescriptor();
|
||||
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>();
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDependenceType>();
|
||||
template <>
|
||||
@@ -68,6 +70,10 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpIterator>();
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpLinearModifier>();
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderModifier>();
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderingModifier>();
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpReductionIdentifier>();
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpReductionModifier>();
|
||||
|
||||
@@ -1109,7 +1109,7 @@ Order make(const parser::OmpClause::Order &inp,
|
||||
using wrapped = parser::OmpOrderClause;
|
||||
|
||||
CLAUSET_ENUM_CONVERT( //
|
||||
convert1, parser::OmpOrderModifier::Kind, Order::OrderModifier,
|
||||
convert1, parser::OmpOrderModifier::Value, Order::OrderModifier,
|
||||
// clang-format off
|
||||
MS(Reproducible, Reproducible)
|
||||
MS(Unconstrained, Unconstrained)
|
||||
@@ -1117,20 +1117,18 @@ Order make(const parser::OmpClause::Order &inp,
|
||||
);
|
||||
|
||||
CLAUSET_ENUM_CONVERT( //
|
||||
convert2, wrapped::Type, Order::Ordering,
|
||||
convert2, wrapped::Ordering, Order::Ordering,
|
||||
// clang-format off
|
||||
MS(Concurrent, Concurrent)
|
||||
// clang-format on
|
||||
);
|
||||
|
||||
auto &t0 = std::get<std::optional<parser::OmpOrderModifier>>(inp.v.t);
|
||||
auto &t1 = std::get<wrapped::Type>(inp.v.t);
|
||||
auto &mods = semantics::OmpGetModifiers(inp.v);
|
||||
auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpOrderModifier>(mods);
|
||||
auto &t1 = std::get<wrapped::Ordering>(inp.v.t);
|
||||
|
||||
auto convert3 = [&](const parser::OmpOrderModifier &s) {
|
||||
return convert1(s.v);
|
||||
};
|
||||
return Order{
|
||||
{/*OrderModifier=*/maybeApply(convert3, t0), /*Ordering=*/convert2(t1)}};
|
||||
return Order{{/*OrderModifier=*/maybeApplyToV(convert1, t0),
|
||||
/*Ordering=*/convert2(t1)}};
|
||||
}
|
||||
|
||||
Ordered make(const parser::OmpClause::Ordered &inp,
|
||||
@@ -1197,10 +1195,10 @@ Reduction make(const parser::OmpClause::Reduction &inp,
|
||||
auto *t1 =
|
||||
semantics::OmpGetUniqueModifier<parser::OmpReductionIdentifier>(mods);
|
||||
auto &t2 = std::get<parser::OmpObjectList>(inp.v.t);
|
||||
assert(t1 && "OmpReductionIdentifier is required");
|
||||
|
||||
return Reduction{
|
||||
{/*ReductionModifier=*/t0
|
||||
? std::make_optional<Reduction::ReductionModifier>(convert(t0->v))
|
||||
: std::nullopt,
|
||||
{/*ReductionModifier=*/maybeApplyToV(convert, t0),
|
||||
/*ReductionIdentifiers=*/{makeReductionOperator(*t1, semaCtx)},
|
||||
/*List=*/makeObjects(t2, semaCtx)}};
|
||||
}
|
||||
@@ -1221,7 +1219,7 @@ Schedule make(const parser::OmpClause::Schedule &inp,
|
||||
using wrapped = parser::OmpScheduleClause;
|
||||
|
||||
CLAUSET_ENUM_CONVERT( //
|
||||
convert1, wrapped::ScheduleType, Schedule::Kind,
|
||||
convert1, wrapped::Kind, Schedule::Kind,
|
||||
// clang-format off
|
||||
MS(Static, Static)
|
||||
MS(Dynamic, Dynamic)
|
||||
@@ -1232,8 +1230,7 @@ Schedule make(const parser::OmpClause::Schedule &inp,
|
||||
);
|
||||
|
||||
CLAUSET_ENUM_CONVERT( //
|
||||
convert2, parser::OmpScheduleModifierType::ModType,
|
||||
Schedule::OrderingModifier,
|
||||
convert2, parser::OmpOrderingModifier::Value, Schedule::OrderingModifier,
|
||||
// clang-format off
|
||||
MS(Monotonic, Monotonic)
|
||||
MS(Nonmonotonic, Nonmonotonic)
|
||||
@@ -1241,48 +1238,22 @@ Schedule make(const parser::OmpClause::Schedule &inp,
|
||||
);
|
||||
|
||||
CLAUSET_ENUM_CONVERT( //
|
||||
convert3, parser::OmpScheduleModifierType::ModType,
|
||||
Schedule::ChunkModifier,
|
||||
convert3, parser::OmpChunkModifier::Value, Schedule::ChunkModifier,
|
||||
// clang-format off
|
||||
MS(Simd, Simd)
|
||||
// clang-format on
|
||||
);
|
||||
|
||||
auto &t0 = std::get<std::optional<parser::OmpScheduleModifier>>(inp.v.t);
|
||||
auto &t1 = std::get<wrapped::ScheduleType>(inp.v.t);
|
||||
auto &t2 = std::get<std::optional<parser::ScalarIntExpr>>(inp.v.t);
|
||||
auto &mods = semantics::OmpGetModifiers(inp.v);
|
||||
auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpOrderingModifier>(mods);
|
||||
auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpChunkModifier>(mods);
|
||||
auto &t2 = std::get<wrapped::Kind>(inp.v.t);
|
||||
auto &t3 = std::get<std::optional<parser::ScalarIntExpr>>(inp.v.t);
|
||||
|
||||
if (!t0) {
|
||||
return Schedule{{/*Kind=*/convert1(t1), /*OrderingModifier=*/std::nullopt,
|
||||
/*ChunkModifier=*/std::nullopt,
|
||||
/*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t2)}};
|
||||
}
|
||||
|
||||
// The members of parser::OmpScheduleModifier correspond to OrderingModifier,
|
||||
// and ChunkModifier, but they can appear in any order.
|
||||
auto &m1 = std::get<parser::OmpScheduleModifier::Modifier1>(t0->t);
|
||||
auto &m2 =
|
||||
std::get<std::optional<parser::OmpScheduleModifier::Modifier2>>(t0->t);
|
||||
|
||||
std::optional<Schedule::OrderingModifier> omod;
|
||||
std::optional<Schedule::ChunkModifier> cmod;
|
||||
|
||||
if (m1.v.v == parser::OmpScheduleModifierType::ModType::Simd) {
|
||||
// m1 is chunk-modifier
|
||||
cmod = convert3(m1.v.v);
|
||||
if (m2)
|
||||
omod = convert2(m2->v.v);
|
||||
} else {
|
||||
// m1 is ordering-modifier
|
||||
omod = convert2(m1.v.v);
|
||||
if (m2)
|
||||
cmod = convert3(m2->v.v);
|
||||
}
|
||||
|
||||
return Schedule{{/*Kind=*/convert1(t1),
|
||||
/*OrderingModifier=*/omod,
|
||||
/*ChunkModifier=*/cmod,
|
||||
/*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t2)}};
|
||||
return Schedule{{/*Kind=*/convert1(t2),
|
||||
/*OrderingModifier=*/maybeApplyToV(convert2, t0),
|
||||
/*ChunkModifier=*/maybeApplyToV(convert3, t1),
|
||||
/*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t3)}};
|
||||
}
|
||||
|
||||
// SeqCst: empty
|
||||
@@ -1326,6 +1297,8 @@ TaskReduction make(const parser::OmpClause::TaskReduction &inp,
|
||||
auto *t0 =
|
||||
semantics::OmpGetUniqueModifier<parser::OmpReductionIdentifier>(mods);
|
||||
auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
|
||||
assert(t0 && "OmpReductionIdentifier is required");
|
||||
|
||||
return TaskReduction{
|
||||
{/*ReductionIdentifiers=*/{makeReductionOperator(*t0, semaCtx)},
|
||||
/*List=*/makeObjects(t1, semaCtx)}};
|
||||
|
||||
@@ -150,7 +150,17 @@ std::optional<ResultTy> maybeApply(FuncTy &&func,
|
||||
const std::optional<ArgTy> &arg) {
|
||||
if (!arg)
|
||||
return std::nullopt;
|
||||
return std::move(func(*arg));
|
||||
return func(*arg);
|
||||
}
|
||||
|
||||
template <
|
||||
typename FuncTy, //
|
||||
typename ArgTy, //
|
||||
typename ResultTy = std::invoke_result_t<FuncTy, typename ArgTy::Value>>
|
||||
std::optional<ResultTy> maybeApplyToV(FuncTy &&func, const ArgTy *arg) {
|
||||
if (!arg)
|
||||
return std::nullopt;
|
||||
return func(arg->v);
|
||||
}
|
||||
|
||||
std::optional<Object> getBaseObject(const Object &object,
|
||||
|
||||
@@ -228,6 +228,18 @@ TYPE_PARSER(construct<OmpLinearModifier>( //
|
||||
TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) ||
|
||||
construct<OmpReductionIdentifier>(Parser<ProcedureDesignator>{}))
|
||||
|
||||
TYPE_PARSER(construct<OmpChunkModifier>( //
|
||||
"SIMD" >> pure(OmpChunkModifier::Value::Simd)))
|
||||
|
||||
TYPE_PARSER(construct<OmpOrderModifier>(
|
||||
"REPRODUCIBLE" >> pure(OmpOrderModifier::Value::Reproducible) ||
|
||||
"UNCONSTRAINED" >> pure(OmpOrderModifier::Value::Unconstrained)))
|
||||
|
||||
TYPE_PARSER(construct<OmpOrderingModifier>(
|
||||
"MONOTONIC" >> pure(OmpOrderingModifier::Value::Monotonic) ||
|
||||
"NONMONOTONIC" >> pure(OmpOrderingModifier::Value::Nonmonotonic) ||
|
||||
"SIMD" >> pure(OmpOrderingModifier::Value::Simd)))
|
||||
|
||||
TYPE_PARSER(construct<OmpReductionModifier>(
|
||||
"INSCAN" >> pure(OmpReductionModifier::Value::Inscan) ||
|
||||
"TASK" >> pure(OmpReductionModifier::Value::Task) ||
|
||||
@@ -241,12 +253,6 @@ TYPE_PARSER(construct<OmpTaskDependenceType>(
|
||||
"MUTEXINOUTSET" >> pure(OmpTaskDependenceType::Value::Mutexinoutset) ||
|
||||
"OUT" >> pure(OmpTaskDependenceType::Value::Out)))
|
||||
|
||||
// This could be auto-generated.
|
||||
TYPE_PARSER(sourced(construct<OmpReductionClause::Modifier>(sourced(
|
||||
construct<OmpReductionClause::Modifier>(Parser<OmpReductionModifier>{}) ||
|
||||
construct<OmpReductionClause::Modifier>(
|
||||
Parser<OmpReductionIdentifier>{})))))
|
||||
|
||||
TYPE_PARSER(construct<OmpVariableCategory>(
|
||||
"AGGREGATE" >> pure(OmpVariableCategory::Value::Aggregate) ||
|
||||
"ALL"_id >> pure(OmpVariableCategory::Value::All) ||
|
||||
@@ -254,6 +260,19 @@ TYPE_PARSER(construct<OmpVariableCategory>(
|
||||
"POINTER" >> pure(OmpVariableCategory::Value::Pointer) ||
|
||||
"SCALAR" >> pure(OmpVariableCategory::Value::Scalar)))
|
||||
|
||||
// This could be auto-generated.
|
||||
TYPE_PARSER(
|
||||
sourced(construct<OmpOrderClause::Modifier>(Parser<OmpOrderModifier>{})))
|
||||
|
||||
TYPE_PARSER(sourced(construct<OmpReductionClause::Modifier>(sourced(
|
||||
construct<OmpReductionClause::Modifier>(Parser<OmpReductionModifier>{}) ||
|
||||
construct<OmpReductionClause::Modifier>(
|
||||
Parser<OmpReductionIdentifier>{})))))
|
||||
|
||||
TYPE_PARSER(sourced(construct<OmpScheduleClause::Modifier>(sourced(
|
||||
construct<OmpScheduleClause::Modifier>(Parser<OmpChunkModifier>{}) ||
|
||||
construct<OmpScheduleClause::Modifier>(Parser<OmpOrderingModifier>{})))))
|
||||
|
||||
TYPE_PARSER(sourced(
|
||||
construct<OmpDefaultmapClause::Modifier>(Parser<OmpVariableCategory>{})))
|
||||
|
||||
@@ -336,25 +355,16 @@ TYPE_PARSER(construct<OmpDefaultmapClause>(
|
||||
"DEFAULT" >> pure(OmpDefaultmapClause::ImplicitBehavior::Default)),
|
||||
maybe(":" >> nonemptyList(Parser<OmpDefaultmapClause::Modifier>{}))))
|
||||
|
||||
// 2.7.1 SCHEDULE ([modifier1 [, modifier2]:]kind[, chunk_size])
|
||||
// Modifier -> MONITONIC | NONMONOTONIC | SIMD
|
||||
// kind -> STATIC | DYNAMIC | GUIDED | AUTO | RUNTIME
|
||||
// chunk_size -> ScalarIntExpr
|
||||
TYPE_PARSER(construct<OmpScheduleModifierType>(
|
||||
"MONOTONIC" >> pure(OmpScheduleModifierType::ModType::Monotonic) ||
|
||||
"NONMONOTONIC" >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) ||
|
||||
"SIMD" >> pure(OmpScheduleModifierType::ModType::Simd)))
|
||||
TYPE_PARSER(construct<OmpScheduleClause::Kind>(
|
||||
"STATIC" >> pure(OmpScheduleClause::Kind::Static) ||
|
||||
"DYNAMIC" >> pure(OmpScheduleClause::Kind::Dynamic) ||
|
||||
"GUIDED" >> pure(OmpScheduleClause::Kind::Guided) ||
|
||||
"AUTO" >> pure(OmpScheduleClause::Kind::Auto) ||
|
||||
"RUNTIME" >> pure(OmpScheduleClause::Kind::Runtime)))
|
||||
|
||||
TYPE_PARSER(construct<OmpScheduleModifier>(Parser<OmpScheduleModifierType>{},
|
||||
maybe("," >> Parser<OmpScheduleModifierType>{}) / ":"))
|
||||
|
||||
TYPE_PARSER(construct<OmpScheduleClause>(maybe(Parser<OmpScheduleModifier>{}),
|
||||
"STATIC" >> pure(OmpScheduleClause::ScheduleType::Static) ||
|
||||
"DYNAMIC" >> pure(OmpScheduleClause::ScheduleType::Dynamic) ||
|
||||
"GUIDED" >> pure(OmpScheduleClause::ScheduleType::Guided) ||
|
||||
"AUTO" >> pure(OmpScheduleClause::ScheduleType::Auto) ||
|
||||
"RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime),
|
||||
maybe("," >> scalarIntExpr)))
|
||||
TYPE_PARSER(construct<OmpScheduleClause>(
|
||||
maybe(nonemptyList(Parser<OmpScheduleClause::Modifier>{}) / ":"),
|
||||
Parser<OmpScheduleClause::Kind>{}, maybe("," >> scalarIntExpr)))
|
||||
|
||||
// device([ device-modifier :] scalar-integer-expression)
|
||||
TYPE_PARSER(construct<OmpDeviceClause>(
|
||||
@@ -497,14 +507,9 @@ TYPE_PARSER(construct<OmpUpdateClause>(
|
||||
construct<OmpUpdateClause>(Parser<OmpDependenceType>{}) ||
|
||||
construct<OmpUpdateClause>(Parser<OmpTaskDependenceType>{})))
|
||||
|
||||
// 2.9.5 ORDER ([order-modifier :]concurrent)
|
||||
TYPE_PARSER(construct<OmpOrderModifier>(
|
||||
"REPRODUCIBLE" >> pure(OmpOrderModifier::Kind::Reproducible)) ||
|
||||
construct<OmpOrderModifier>(
|
||||
"UNCONSTRAINED" >> pure(OmpOrderModifier::Kind::Unconstrained)))
|
||||
|
||||
TYPE_PARSER(construct<OmpOrderClause>(maybe(Parser<OmpOrderModifier>{} / ":"),
|
||||
"CONCURRENT" >> pure(OmpOrderClause::Type::Concurrent)))
|
||||
TYPE_PARSER(construct<OmpOrderClause>(
|
||||
maybe(nonemptyList(Parser<OmpOrderClause::Modifier>{}) / ":"),
|
||||
"CONCURRENT" >> pure(OmpOrderClause::Ordering::Concurrent)))
|
||||
|
||||
// OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression)
|
||||
TYPE_PARSER(construct<OmpGrainsizeClause>(
|
||||
|
||||
@@ -2133,13 +2133,10 @@ public:
|
||||
}
|
||||
Walk(std::get<OmpObjectList>(x.t));
|
||||
}
|
||||
void Unparse(const OmpScheduleModifier &x) {
|
||||
Walk(std::get<OmpScheduleModifier::Modifier1>(x.t));
|
||||
Walk(",", std::get<std::optional<OmpScheduleModifier::Modifier2>>(x.t));
|
||||
}
|
||||
void Unparse(const OmpScheduleClause &x) {
|
||||
Walk(std::get<std::optional<OmpScheduleModifier>>(x.t), ":");
|
||||
Walk(std::get<OmpScheduleClause::ScheduleType>(x.t));
|
||||
using Modifier = OmpScheduleClause::Modifier;
|
||||
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");
|
||||
Walk(std::get<OmpScheduleClause::Kind>(x.t));
|
||||
Walk(",", std::get<std::optional<ScalarIntExpr>>(x.t));
|
||||
}
|
||||
void Unparse(const OmpDeviceClause &x) {
|
||||
@@ -2230,8 +2227,9 @@ public:
|
||||
Put(")");
|
||||
}
|
||||
void Unparse(const OmpOrderClause &x) {
|
||||
Walk(std::get<std::optional<OmpOrderModifier>>(x.t), ":");
|
||||
Walk(std::get<OmpOrderClause::Type>(x.t));
|
||||
using Modifier = OmpOrderClause::Modifier;
|
||||
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");
|
||||
Walk(std::get<OmpOrderClause::Ordering>(x.t));
|
||||
}
|
||||
void Unparse(const OmpGrainsizeClause &x) {
|
||||
Walk(std::get<std::optional<OmpGrainsizeClause::Prescriptiveness>>(x.t),
|
||||
@@ -2907,18 +2905,19 @@ public:
|
||||
WALK_NESTED_ENUM(OmpVariableCategory, Value) // OMP variable-category
|
||||
WALK_NESTED_ENUM(
|
||||
OmpLastprivateClause, LastprivateModifier) // OMP lastprivate-modifier
|
||||
WALK_NESTED_ENUM(OmpScheduleModifierType, ModType) // OMP schedule-modifier
|
||||
WALK_NESTED_ENUM(OmpChunkModifier, Value) // OMP chunk-modifier
|
||||
WALK_NESTED_ENUM(OmpLinearModifier, Value) // OMP linear-modifier
|
||||
WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier
|
||||
WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type
|
||||
WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-type
|
||||
WALK_NESTED_ENUM(OmpScheduleClause, Kind) // OMP schedule-kind
|
||||
WALK_NESTED_ENUM(OmpDeviceClause, DeviceModifier) // OMP device modifier
|
||||
WALK_NESTED_ENUM(OmpDeviceTypeClause, Type) // OMP DEVICE_TYPE
|
||||
WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier
|
||||
WALK_NESTED_ENUM(OmpFromClause, Expectation) // OMP motion-expectation
|
||||
WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier
|
||||
WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
|
||||
WALK_NESTED_ENUM(OmpOrderClause, Type) // OMP order-type
|
||||
WALK_NESTED_ENUM(OmpOrderModifier, Kind) // OMP order-modifier
|
||||
WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering
|
||||
WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier
|
||||
WALK_NESTED_ENUM(
|
||||
OmpGrainsizeClause, Prescriptiveness) // OMP grainsize-modifier
|
||||
WALK_NESTED_ENUM(OmpNumTasksClause, Prescriptiveness) // OMP numtasks-modifier
|
||||
|
||||
@@ -2576,19 +2576,16 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
|
||||
if (auto *clause{FindClause(llvm::omp::Clause::OMPC_schedule)}) {
|
||||
// only one schedule clause is allowed
|
||||
const auto &schedClause{std::get<parser::OmpClause::Schedule>(clause->u)};
|
||||
if (ScheduleModifierHasType(schedClause.v,
|
||||
parser::OmpScheduleModifierType::ModType::Nonmonotonic)) {
|
||||
auto &modifiers{OmpGetModifiers(schedClause.v)};
|
||||
auto *ordering{
|
||||
OmpGetUniqueModifier<parser::OmpOrderingModifier>(modifiers)};
|
||||
if (ordering &&
|
||||
ordering->v == parser::OmpOrderingModifier::Value::Nonmonotonic) {
|
||||
if (FindClause(llvm::omp::Clause::OMPC_ordered)) {
|
||||
context_.Say(clause->source,
|
||||
"The NONMONOTONIC modifier cannot be specified "
|
||||
"if an ORDERED clause is specified"_err_en_US);
|
||||
}
|
||||
if (ScheduleModifierHasType(schedClause.v,
|
||||
parser::OmpScheduleModifierType::ModType::Monotonic)) {
|
||||
context_.Say(clause->source,
|
||||
"The MONOTONIC and NONMONOTONIC modifiers "
|
||||
"cannot be both specified"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2648,8 +2645,8 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
|
||||
if (auto *o_clause{FindClause(llvm::omp::Clause::OMPC_order)}) {
|
||||
const auto &orderClause{
|
||||
std::get<parser::OmpClause::Order>(o_clause->u)};
|
||||
if (std::get<parser::OmpOrderClause::Type>(orderClause.v.t) ==
|
||||
parser::OmpOrderClause::Type::Concurrent) {
|
||||
if (std::get<parser::OmpOrderClause::Ordering>(orderClause.v.t) ==
|
||||
parser::OmpOrderClause::Ordering::Concurrent) {
|
||||
context_.Say(sl_clause->source,
|
||||
"The `SAFELEN` clause cannot appear in the `SIMD` directive "
|
||||
"with `ORDER(CONCURRENT)` clause"_err_en_US);
|
||||
@@ -3553,34 +3550,23 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
|
||||
}
|
||||
}
|
||||
|
||||
bool OmpStructureChecker::ScheduleModifierHasType(
|
||||
const parser::OmpScheduleClause &x,
|
||||
const parser::OmpScheduleModifierType::ModType &type) {
|
||||
const auto &modifier{
|
||||
std::get<std::optional<parser::OmpScheduleModifier>>(x.t)};
|
||||
if (modifier) {
|
||||
const auto &modType1{
|
||||
std::get<parser::OmpScheduleModifier::Modifier1>(modifier->t)};
|
||||
const auto &modType2{
|
||||
std::get<std::optional<parser::OmpScheduleModifier::Modifier2>>(
|
||||
modifier->t)};
|
||||
if (modType1.v.v == type || (modType2 && modType2->v.v == type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
|
||||
CheckAllowedClause(llvm::omp::Clause::OMPC_schedule);
|
||||
const parser::OmpScheduleClause &scheduleClause = x.v;
|
||||
if (!OmpVerifyModifiers(
|
||||
scheduleClause, GetContext().clauseSource, context_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2.7 Loop Construct Restriction
|
||||
if (llvm::omp::allDoSet.test(GetContext().directive)) {
|
||||
const auto &kind{std::get<1>(scheduleClause.t)};
|
||||
const auto &chunk{std::get<2>(scheduleClause.t)};
|
||||
auto &modifiers{OmpGetModifiers(scheduleClause)};
|
||||
auto kind{std::get<parser::OmpScheduleClause::Kind>(scheduleClause.t)};
|
||||
auto &chunk{
|
||||
std::get<std::optional<parser::ScalarIntExpr>>(scheduleClause.t)};
|
||||
if (chunk) {
|
||||
if (kind == parser::OmpScheduleClause::ScheduleType::Runtime ||
|
||||
kind == parser::OmpScheduleClause::ScheduleType::Auto) {
|
||||
if (kind == parser::OmpScheduleClause::Kind::Runtime ||
|
||||
kind == parser::OmpScheduleClause::Kind::Auto) {
|
||||
context_.Say(GetContext().clauseSource,
|
||||
"When SCHEDULE clause has %s specified, "
|
||||
"it must not have chunk size specified"_err_en_US,
|
||||
@@ -3594,10 +3580,12 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
|
||||
}
|
||||
}
|
||||
|
||||
if (ScheduleModifierHasType(scheduleClause,
|
||||
parser::OmpScheduleModifierType::ModType::Nonmonotonic)) {
|
||||
if (kind != parser::OmpScheduleClause::ScheduleType::Dynamic &&
|
||||
kind != parser::OmpScheduleClause::ScheduleType::Guided) {
|
||||
auto *ordering{
|
||||
OmpGetUniqueModifier<parser::OmpOrderingModifier>(modifiers)};
|
||||
if (ordering &&
|
||||
ordering->v == parser::OmpOrderingModifier::Value::Nonmonotonic) {
|
||||
if (kind != parser::OmpScheduleClause::Kind::Dynamic &&
|
||||
kind != parser::OmpScheduleClause::Kind::Guided) {
|
||||
context_.Say(GetContext().clauseSource,
|
||||
"The NONMONOTONIC modifier can only be specified with "
|
||||
"SCHEDULE(DYNAMIC) or SCHEDULE(GUIDED)"_err_en_US);
|
||||
|
||||
@@ -161,8 +161,6 @@ private:
|
||||
void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
|
||||
void HasInvalidLoopBinding(const parser::OpenMPLoopConstruct &x);
|
||||
// specific clause related
|
||||
bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
|
||||
const parser::OmpScheduleModifierType::ModType &);
|
||||
void CheckAllowedMapTypes(const parser::OmpMapClause::Type &,
|
||||
const std::list<parser::OmpMapClause::Type> &);
|
||||
llvm::StringRef getClauseName(llvm::omp::Clause clause) override;
|
||||
|
||||
@@ -55,6 +55,22 @@ const OmpClauses &OmpModifierDescriptor::clauses(unsigned version) const {
|
||||
// Note: The intent for these functions is to have them be automatically-
|
||||
// generated in the future.
|
||||
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() {
|
||||
static const OmpModifierDescriptor desc{
|
||||
/*name=*/"chunk-modifier",
|
||||
/*props=*/
|
||||
{
|
||||
{45, {OmpProperty::Unique}},
|
||||
},
|
||||
/*clauses=*/
|
||||
{
|
||||
{45, {Clause::OMPC_schedule}},
|
||||
},
|
||||
};
|
||||
return desc;
|
||||
}
|
||||
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDependenceType>() {
|
||||
static const OmpModifierDescriptor desc{
|
||||
@@ -108,6 +124,38 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpLinearModifier>() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderModifier>() {
|
||||
static const OmpModifierDescriptor desc{
|
||||
/*name=*/"order-modifier",
|
||||
/*props=*/
|
||||
{
|
||||
{51, {OmpProperty::Unique}},
|
||||
},
|
||||
/*clauses=*/
|
||||
{
|
||||
{51, {Clause::OMPC_order}},
|
||||
},
|
||||
};
|
||||
return desc;
|
||||
}
|
||||
|
||||
template <>
|
||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderingModifier>() {
|
||||
static const OmpModifierDescriptor desc{
|
||||
/*name=*/"ordering-modifier",
|
||||
/*props=*/
|
||||
{
|
||||
{45, {OmpProperty::Unique}},
|
||||
},
|
||||
/*clauses=*/
|
||||
{
|
||||
{45, {Clause::OMPC_schedule}},
|
||||
},
|
||||
};
|
||||
return desc;
|
||||
}
|
||||
|
||||
template <>
|
||||
const OmpModifierDescriptor &
|
||||
OmpGetDescriptor<parser::OmpReductionIdentifier>() {
|
||||
|
||||
@@ -17,7 +17,7 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = do
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_simd_order_reproducible()
|
||||
integer :: i, j = 1
|
||||
@@ -33,8 +33,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Reproducible
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_do_simd_order_unconstrained()
|
||||
integer :: i, j = 1
|
||||
@@ -50,8 +50,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = do simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Unconstrained
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_parallel_do_order()
|
||||
integer :: i, j = 1
|
||||
@@ -67,7 +67,7 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = parallel do
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_parallel_do_simd_order_reproducible()
|
||||
integer :: i, j = 1
|
||||
@@ -83,8 +83,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = parallel do simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Reproducible
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_target_simd_order_unconstrained()
|
||||
integer :: i, j = 1
|
||||
@@ -100,8 +100,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Unconstrained
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_target_parallel_do_order()
|
||||
integer :: i, j = 1
|
||||
@@ -117,7 +117,7 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel do
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_target_parallel_do_simd_order_reproducible()
|
||||
integer :: i, j = 1
|
||||
@@ -133,8 +133,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel do simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Reproducible
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_teams_distribute_simd_order_unconstrained()
|
||||
integer :: i, j = 1
|
||||
@@ -150,8 +150,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Unconstrained
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_teams_distribute_parallel_do_order()
|
||||
integer :: i, j = 1
|
||||
@@ -167,7 +167,7 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute parallel do
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_teams_distribute_parallel_do_simd_order_reproducible()
|
||||
integer :: i, j = 1
|
||||
@@ -183,8 +183,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute parallel do simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Reproducible
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_target_teams_distribute_simd_order_unconstrained()
|
||||
integer :: i, j = 1
|
||||
@@ -200,8 +200,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Unconstrained
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_target_teams_distribute_parallel_do_order()
|
||||
integer :: i, j = 1
|
||||
@@ -217,7 +217,7 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_target_teams_distribute_parallel_do_simd_order_reproducible()
|
||||
integer :: i, j = 1
|
||||
@@ -233,8 +233,8 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Reproducible
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
subroutine test_taskloop_simd_order_unconstrained()
|
||||
integer :: i, j = 1
|
||||
@@ -250,5 +250,5 @@ end subroutine
|
||||
!PARSE-TREE-NEXT: OmpBeginLoopDirective
|
||||
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop simd
|
||||
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause
|
||||
!PARSE-TREE-NEXT: Kind = Unconstrained
|
||||
!PARSE-TREE-NEXT: Type = Concurrent
|
||||
!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained
|
||||
!PARSE-TREE-NEXT: Ordering = Concurrent
|
||||
|
||||
Reference in New Issue
Block a user