[flang][llvm][openmp]Add Initializer clause to OMP.td (#129540)
Then use this in the Flang compiler for parsing the OpenMP declare reduction. This has no real functional change to the existing code, it's only moving the declaration itself around. A few tests has been updated, to reflect the new type names.
This commit is contained in:
parent
a537724069
commit
9925359fee
@ -514,7 +514,7 @@ public:
|
||||
READ_FEATURE(OmpReductionClause)
|
||||
READ_FEATURE(OmpInReductionClause)
|
||||
READ_FEATURE(OmpReductionCombiner)
|
||||
READ_FEATURE(OmpReductionInitializerClause)
|
||||
READ_FEATURE(OmpInitializerClause)
|
||||
READ_FEATURE(OmpReductionIdentifier)
|
||||
READ_FEATURE(OmpAllocateClause)
|
||||
READ_FEATURE(OmpAllocateClause::Modifier)
|
||||
|
@ -638,9 +638,9 @@ public:
|
||||
NODE(parser, OmpReductionCombiner)
|
||||
NODE(parser, OmpTaskReductionClause)
|
||||
NODE(OmpTaskReductionClause, Modifier)
|
||||
NODE(parser, OmpReductionInitializerProc)
|
||||
NODE(parser, OmpReductionInitializerExpr)
|
||||
NODE(parser, OmpReductionInitializerClause)
|
||||
NODE(parser, OmpInitializerProc)
|
||||
NODE(parser, OmpInitializerExpr)
|
||||
NODE(parser, OmpInitializerClause)
|
||||
NODE(parser, OmpReductionIdentifier)
|
||||
NODE(parser, OmpAllocateClause)
|
||||
NODE(OmpAllocateClause, Modifier)
|
||||
|
@ -4246,6 +4246,20 @@ struct OmpInReductionClause {
|
||||
std::tuple<MODIFIERS(), OmpObjectList> t;
|
||||
};
|
||||
|
||||
// declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
|
||||
// : combiner) [initializer-clause]
|
||||
struct OmpInitializerProc {
|
||||
TUPLE_CLASS_BOILERPLATE(OmpInitializerProc);
|
||||
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
|
||||
};
|
||||
WRAPPER_CLASS(OmpInitializerExpr, Expr);
|
||||
|
||||
// Initialization for declare reduction construct
|
||||
struct OmpInitializerClause {
|
||||
UNION_CLASS_BOILERPLATE(OmpInitializerClause);
|
||||
std::variant<OmpInitializerProc, OmpInitializerExpr> u;
|
||||
};
|
||||
|
||||
// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]
|
||||
//
|
||||
// lastprivate-clause ->
|
||||
@ -4627,24 +4641,14 @@ struct OpenMPDeclareMapperConstruct {
|
||||
std::tuple<Verbatim, OmpMapperSpecifier, OmpClauseList> t;
|
||||
};
|
||||
|
||||
// ref: 5.2: Section 5.5.11 139-141
|
||||
// 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
|
||||
// : combiner) [initializer-clause]
|
||||
struct OmpReductionInitializerProc {
|
||||
TUPLE_CLASS_BOILERPLATE(OmpReductionInitializerProc);
|
||||
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
|
||||
};
|
||||
WRAPPER_CLASS(OmpReductionInitializerExpr, Expr);
|
||||
|
||||
struct OmpReductionInitializerClause {
|
||||
UNION_CLASS_BOILERPLATE(OmpReductionInitializerClause);
|
||||
std::variant<OmpReductionInitializerProc, OmpReductionInitializerExpr> u;
|
||||
};
|
||||
|
||||
struct OpenMPDeclareReductionConstruct {
|
||||
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);
|
||||
CharBlock source;
|
||||
std::tuple<Verbatim, common::Indirection<OmpReductionSpecifier>,
|
||||
std::optional<OmpReductionInitializerClause>>
|
||||
std::optional<OmpClauseList>>
|
||||
t;
|
||||
};
|
||||
|
||||
|
@ -863,7 +863,10 @@ Init make(const parser::OmpClause::Init &inp,
|
||||
llvm_unreachable("Empty: init");
|
||||
}
|
||||
|
||||
// Initializer: missing-in-parser
|
||||
Initializer make(const parser::OmpClause::Initializer &inp,
|
||||
semantics::SemanticsContext &semaCtx) {
|
||||
llvm_unreachable("Empty: initializer");
|
||||
}
|
||||
|
||||
InReduction make(const parser::OmpClause::InReduction &inp,
|
||||
semantics::SemanticsContext &semaCtx) {
|
||||
|
@ -231,6 +231,7 @@ using Inbranch = tomp::clause::InbranchT<TypeTy, IdTy, ExprTy>;
|
||||
using Inclusive = tomp::clause::InclusiveT<TypeTy, IdTy, ExprTy>;
|
||||
using Indirect = tomp::clause::IndirectT<TypeTy, IdTy, ExprTy>;
|
||||
using Init = tomp::clause::InitT<TypeTy, IdTy, ExprTy>;
|
||||
using Initializer = tomp::clause::InitializerT<TypeTy, IdTy, ExprTy>;
|
||||
using InReduction = tomp::clause::InReductionT<TypeTy, IdTy, ExprTy>;
|
||||
using IsDevicePtr = tomp::clause::IsDevicePtrT<TypeTy, IdTy, ExprTy>;
|
||||
using Lastprivate = tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>;
|
||||
|
@ -855,6 +855,8 @@ TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
|
||||
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
|
||||
"INCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Inclusive>(
|
||||
parenthesized(Parser<OmpObjectList>{}))) ||
|
||||
"INITIALIZER" >> construct<OmpClause>(construct<OmpClause::Initializer>(
|
||||
parenthesized(Parser<OmpInitializerClause>{}))) ||
|
||||
"IS_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::IsDevicePtr>(
|
||||
parenthesized(Parser<OmpObjectList>{}))) ||
|
||||
"LASTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Lastprivate>(
|
||||
@ -1174,22 +1176,19 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
|
||||
TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>(
|
||||
sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{})))
|
||||
|
||||
TYPE_PARSER(construct<OmpReductionInitializerExpr>("OMP_PRIV =" >> expr))
|
||||
TYPE_PARSER(
|
||||
construct<OmpReductionInitializerProc>(Parser<ProcedureDesignator>{},
|
||||
parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
|
||||
TYPE_PARSER(construct<OmpInitializerExpr>("OMP_PRIV =" >> expr))
|
||||
TYPE_PARSER(construct<OmpInitializerProc>(Parser<ProcedureDesignator>{},
|
||||
parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
|
||||
|
||||
TYPE_PARSER(construct<OmpReductionInitializerClause>(
|
||||
"INITIALIZER" >> parenthesized(construct<OmpReductionInitializerClause>(
|
||||
Parser<OmpReductionInitializerExpr>{}) ||
|
||||
construct<OmpReductionInitializerClause>(
|
||||
Parser<OmpReductionInitializerProc>{}))))
|
||||
TYPE_PARSER(construct<OmpInitializerClause>(
|
||||
construct<OmpInitializerClause>(Parser<OmpInitializerExpr>{}) ||
|
||||
construct<OmpInitializerClause>(Parser<OmpInitializerProc>{})))
|
||||
|
||||
// 2.16 Declare Reduction Construct
|
||||
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
|
||||
verbatim("DECLARE REDUCTION"_tok),
|
||||
"(" >> indirect(Parser<OmpReductionSpecifier>{}) / ")",
|
||||
maybe(Parser<OmpReductionInitializerClause>{}))))
|
||||
maybe(Parser<OmpClauseList>{}))))
|
||||
|
||||
// declare-target with list
|
||||
TYPE_PARSER(sourced(construct<OmpDeclareTargetWithList>(
|
||||
|
@ -2699,28 +2699,24 @@ public:
|
||||
void Unparse(const OmpDeclareTargetWithList &x) {
|
||||
Put("("), Walk(x.v), Put(")");
|
||||
}
|
||||
void Unparse(const OmpReductionInitializerProc &x) {
|
||||
void Unparse(const OmpInitializerProc &x) {
|
||||
Walk(std::get<ProcedureDesignator>(x.t));
|
||||
Put("(");
|
||||
Walk(std::get<std::list<ActualArgSpec>>(x.t));
|
||||
Put(")");
|
||||
}
|
||||
void Unparse(const OmpReductionInitializerExpr &x) {
|
||||
void Unparse(const OmpInitializerExpr &x) {
|
||||
Word("OMP_PRIV = ");
|
||||
Walk(x.v);
|
||||
}
|
||||
void Unparse(const OmpReductionInitializerClause &x) {
|
||||
Word(" INITIALIZER(");
|
||||
Walk(x.u);
|
||||
Put(")");
|
||||
}
|
||||
void Unparse(const OmpInitializerClause &x) { Walk(x.u); }
|
||||
void Unparse(const OpenMPDeclareReductionConstruct &x) {
|
||||
BeginOpenMP();
|
||||
Word("!$OMP DECLARE REDUCTION ");
|
||||
Put("(");
|
||||
Walk(std::get<common::Indirection<OmpReductionSpecifier>>(x.t));
|
||||
Put(")");
|
||||
Walk(std::get<std::optional<OmpReductionInitializerClause>>(x.t));
|
||||
Walk(std::get<std::optional<OmpClauseList>>(x.t));
|
||||
Put("\n");
|
||||
EndOpenMP();
|
||||
}
|
||||
|
@ -1678,6 +1678,18 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) {
|
||||
dirContext_.pop_back();
|
||||
}
|
||||
|
||||
void OmpStructureChecker::Enter(
|
||||
const parser::OpenMPDeclareReductionConstruct &x) {
|
||||
const auto &dir{std::get<parser::Verbatim>(x.t)};
|
||||
PushContextAndClauseSets(
|
||||
dir.source, llvm::omp::Directive::OMPD_declare_reduction);
|
||||
}
|
||||
|
||||
void OmpStructureChecker::Leave(
|
||||
const parser::OpenMPDeclareReductionConstruct &) {
|
||||
dirContext_.pop_back();
|
||||
}
|
||||
|
||||
void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
|
||||
const auto &dir{std::get<parser::Verbatim>(x.t)};
|
||||
PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target);
|
||||
@ -2990,6 +3002,7 @@ CHECK_SIMPLE_CLAUSE(Grainsize, OMPC_grainsize)
|
||||
CHECK_SIMPLE_CLAUSE(Hint, OMPC_hint)
|
||||
CHECK_SIMPLE_CLAUSE(Holds, OMPC_holds)
|
||||
CHECK_SIMPLE_CLAUSE(Inclusive, OMPC_inclusive)
|
||||
CHECK_SIMPLE_CLAUSE(Initializer, OMPC_initializer)
|
||||
CHECK_SIMPLE_CLAUSE(Match, OMPC_match)
|
||||
CHECK_SIMPLE_CLAUSE(Nontemporal, OMPC_nontemporal)
|
||||
CHECK_SIMPLE_CLAUSE(NumTasks, OMPC_num_tasks)
|
||||
|
@ -102,6 +102,8 @@ public:
|
||||
void Leave(const parser::OpenMPDeclarativeAllocate &);
|
||||
void Enter(const parser::OpenMPDeclareMapperConstruct &);
|
||||
void Leave(const parser::OpenMPDeclareMapperConstruct &);
|
||||
void Enter(const parser::OpenMPDeclareReductionConstruct &);
|
||||
void Leave(const parser::OpenMPDeclareReductionConstruct &);
|
||||
void Enter(const parser::OpenMPDeclareTargetConstruct &);
|
||||
void Leave(const parser::OpenMPDeclareTargetConstruct &);
|
||||
void Enter(const parser::OpenMPDepobjConstruct &);
|
||||
|
@ -1482,7 +1482,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Pre(const parser::OmpReductionInitializerProc &x) {
|
||||
bool Pre(const parser::OmpInitializerProc &x) {
|
||||
auto &procDes = std::get<parser::ProcedureDesignator>(x.t);
|
||||
auto &name = std::get<parser::Name>(procDes.u);
|
||||
auto *symbol{FindSymbol(NonDerivedTypeScope(), name)};
|
||||
@ -1496,13 +1496,9 @@ public:
|
||||
|
||||
bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
|
||||
AddOmpSourceRange(x.source);
|
||||
parser::OmpClauseList emptyList{std::list<parser::OmpClause>{}};
|
||||
ProcessReductionSpecifier(
|
||||
std::get<Indirection<parser::OmpReductionSpecifier>>(x.t).value(),
|
||||
emptyList);
|
||||
auto &init =
|
||||
std::get<std::optional<parser::OmpReductionInitializerClause>>(x.t);
|
||||
Walk(init);
|
||||
std::get<std::optional<parser::OmpClauseList>>(x.t));
|
||||
return false;
|
||||
}
|
||||
bool Pre(const parser::OmpMapClause &);
|
||||
@ -1659,7 +1655,7 @@ private:
|
||||
void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
|
||||
const parser::OmpClauseList &clauses);
|
||||
void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec,
|
||||
const parser::OmpClauseList &clauses);
|
||||
const std::optional<parser::OmpClauseList> &clauses);
|
||||
};
|
||||
|
||||
bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
|
||||
@ -1754,7 +1750,7 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
|
||||
|
||||
void OmpVisitor::ProcessReductionSpecifier(
|
||||
const parser::OmpReductionSpecifier &spec,
|
||||
const parser::OmpClauseList &clauses) {
|
||||
const std::optional<parser::OmpClauseList> &clauses) {
|
||||
const auto &id{std::get<parser::OmpReductionIdentifier>(spec.t)};
|
||||
if (auto procDes{std::get_if<parser::ProcedureDesignator>(&id.u)}) {
|
||||
if (auto *name{std::get_if<parser::Name>(&procDes->u)}) {
|
||||
@ -1796,7 +1792,7 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
|
||||
if (maybeArgs && maybeClauses) {
|
||||
const parser::OmpArgument &first{maybeArgs->front()};
|
||||
if (auto *spec{std::get_if<parser::OmpReductionSpecifier>(&first.u)}) {
|
||||
ProcessReductionSpecifier(*spec, *maybeClauses);
|
||||
ProcessReductionSpecifier(*spec, maybeClauses);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -23,7 +23,7 @@ function func(x, n, init)
|
||||
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
|
||||
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
|
||||
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
|
||||
!PARSE-TREE: OmpReductionInitializerClause -> OmpReductionInitializerProc
|
||||
!PARSE-TREE: OmpInitializerClause -> OmpInitializerProc
|
||||
!PARSE-TREE-NEXT: ProcedureDesignator -> Name = 'initme'
|
||||
res=init
|
||||
!$omp simd reduction(red_add:res)
|
||||
@ -58,4 +58,4 @@ end program main
|
||||
!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red'
|
||||
!PARSE-TREE: DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec
|
||||
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
|
||||
!PARSE-TREE: OmpReductionInitializerClause -> OmpReductionInitializerExpr -> Expr = '0_4'
|
||||
!PARSE-TREE: OmpInitializerClause -> OmpInitializerExpr -> Expr = '0_4'
|
||||
|
@ -244,6 +244,9 @@ def OMPC_Indirect : Clause<"indirect"> {
|
||||
def OMPC_Init : Clause<"init"> {
|
||||
let clangClass = "OMPInitClause";
|
||||
}
|
||||
def OMPC_Initializer : Clause<"initializer"> {
|
||||
let flangClass = "OmpInitializerClause";
|
||||
}
|
||||
def OMPC_InReduction : Clause<"in_reduction"> {
|
||||
let clangClass = "OMPInReductionClause";
|
||||
let flangClass = "OmpInReductionClause";
|
||||
@ -668,6 +671,9 @@ def OMP_DeclareMapper : Directive<"declare mapper"> {
|
||||
let category = CA_Declarative;
|
||||
}
|
||||
def OMP_DeclareReduction : Directive<"declare reduction"> {
|
||||
let allowedOnceClauses = [
|
||||
VersionedClause<OMPC_Initializer>,
|
||||
];
|
||||
let association = AS_None;
|
||||
let category = CA_Declarative;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user