diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -64,51 +64,8 @@ NODE(parser, AccBeginLoopDirective) NODE(parser, AccBlockDirective) NODE(parser, AccClause) - NODE(AccClause, Auto) - NODE(AccClause, Async) - NODE(AccClause, Attach) - NODE(AccClause, Bind) - NODE(AccClause, Capture) - NODE(AccClause, Collapse) - NODE(AccClause, Copy) - NODE(AccClause, Copyin) - NODE(AccClause, Copyout) - NODE(AccClause, Create) - NODE(AccClause, Default) - NODE(AccClause, DefaultAsync) - NODE(AccClause, Delete) - NODE(AccClause, Detach) - NODE(AccClause, Device) - NODE(AccClause, DeviceNum) - NODE(AccClause, DevicePtr) - NODE(AccClause, DeviceResident) - NODE(AccClause, DeviceType) - NODE(AccClause, Finalize) - NODE(AccClause, FirstPrivate) - NODE(AccClause, Gang) - NODE(AccClause, Host) - NODE(AccClause, If) - NODE(AccClause, IfPresent) - NODE(AccClause, Independent) - NODE(AccClause, Link) - NODE(AccClause, NoCreate) - NODE(AccClause, NoHost) - NODE(AccClause, NumGangs) - NODE(AccClause, NumWorkers) - NODE(AccClause, Present) - NODE(AccClause, Private) - NODE(AccClause, Tile) - NODE(AccClause, UseDevice) - NODE(AccClause, Read) - NODE(AccClause, Reduction) - NODE(AccClause, Self) - NODE(AccClause, Seq) - NODE(AccClause, Vector) - NODE(AccClause, VectorLength) - NODE(AccClause, Wait) - NODE(AccClause, Worker) - NODE(AccClause, Write) - NODE(AccClause, Unknown) +#define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES +#include "llvm/Frontend/OpenACC/ACC.cpp.inc" NODE(parser, AccDefaultClause) NODE_ENUM(parser::AccDefaultClause, Arg) NODE(parser, AccClauseList) @@ -501,38 +458,8 @@ NODE_ENUM(OmpCancelType, Type) NODE(parser, OmpClause) NODE(parser, OmpClauseList) - NODE(OmpClause, Collapse) - NODE(OmpClause, Copyin) - NODE(OmpClause, Copyprivate) - NODE(OmpClause, Device) - NODE(OmpClause, DistSchedule) - NODE(OmpClause, Final) - NODE(OmpClause, Firstprivate) - NODE(OmpClause, From) - NODE(OmpClause, Grainsize) - NODE(OmpClause, Inbranch) - NODE(OmpClause, Lastprivate) - NODE(OmpClause, Mergeable) - NODE(OmpClause, Nogroup) - NODE(OmpClause, Notinbranch) - NODE(OmpClause, Threads) - NODE(OmpClause, Simd) - NODE(OmpClause, NumTasks) - NODE(OmpClause, NumTeams) - NODE(OmpClause, NumThreads) - NODE(OmpClause, Ordered) - NODE(OmpClause, Priority) - NODE(OmpClause, Private) - NODE(OmpClause, Safelen) - NODE(OmpClause, Shared) - NODE(OmpClause, Simdlen) - NODE(OmpClause, ThreadLimit) - NODE(OmpClause, To) - NODE(OmpClause, Link) - NODE(OmpClause, Uniform) - NODE(OmpClause, Untied) - NODE(OmpClause, UseDevicePtr) - NODE(OmpClause, IsDevicePtr) +#define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES +#include "llvm/Frontend/OpenMP/OMP.cpp.inc" NODE(parser, OmpCriticalDirective) NODE(OmpCriticalDirective, Hint) NODE(parser, OmpDeclareTargetSpecifier) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3459,47 +3459,16 @@ // OpenMP Clauses struct OmpClause { UNION_CLASS_BOILERPLATE(OmpClause); - EMPTY_CLASS(Inbranch); - EMPTY_CLASS(Mergeable); - EMPTY_CLASS(Nogroup); - EMPTY_CLASS(Notinbranch); - EMPTY_CLASS(Simd); - EMPTY_CLASS(Threads); - EMPTY_CLASS(Untied); - WRAPPER_CLASS(Collapse, ScalarIntConstantExpr); - WRAPPER_CLASS(Copyin, OmpObjectList); - WRAPPER_CLASS(Copyprivate, OmpObjectList); - WRAPPER_CLASS(Device, ScalarIntExpr); - WRAPPER_CLASS(DistSchedule, std::optional); - WRAPPER_CLASS(Final, ScalarLogicalExpr); - WRAPPER_CLASS(Firstprivate, OmpObjectList); - WRAPPER_CLASS(From, OmpObjectList); - WRAPPER_CLASS(Grainsize, ScalarIntExpr); - WRAPPER_CLASS(IsDevicePtr, std::list); - WRAPPER_CLASS(Lastprivate, OmpObjectList); - WRAPPER_CLASS(Link, OmpObjectList); - WRAPPER_CLASS(NumTasks, ScalarIntExpr); - WRAPPER_CLASS(NumTeams, ScalarIntExpr); - WRAPPER_CLASS(NumThreads, ScalarIntExpr); - WRAPPER_CLASS(Ordered, std::optional); - WRAPPER_CLASS(Priority, ScalarIntExpr); - WRAPPER_CLASS(Private, OmpObjectList); - WRAPPER_CLASS(Safelen, ScalarIntConstantExpr); - WRAPPER_CLASS(Shared, OmpObjectList); - WRAPPER_CLASS(Simdlen, ScalarIntConstantExpr); - WRAPPER_CLASS(ThreadLimit, ScalarIntExpr); - WRAPPER_CLASS(To, OmpObjectList); - WRAPPER_CLASS(Uniform, std::list); - WRAPPER_CLASS(UseDevicePtr, std::list); + +#define GEN_FLANG_CLAUSE_PARSER_CLASSES +#include "llvm/Frontend/OpenMP/OMP.cpp.inc" + CharBlock source; - std::variant + + std::variant< +#define GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST +#include "llvm/Frontend/OpenMP/OMP.cpp.inc" + > u; }; @@ -3895,60 +3864,15 @@ struct AccClause { UNION_CLASS_BOILERPLATE(AccClause); - EMPTY_CLASS(Auto); - WRAPPER_CLASS(Async, std::optional); - WRAPPER_CLASS(Attach, AccObjectList); - WRAPPER_CLASS(Bind, Name); - EMPTY_CLASS(Capture); - WRAPPER_CLASS(Collapse, ScalarIntConstantExpr); - WRAPPER_CLASS(Copy, AccObjectList); - WRAPPER_CLASS(Copyin, AccObjectListWithModifier); - WRAPPER_CLASS(Copyout, AccObjectListWithModifier); - WRAPPER_CLASS(Create, AccObjectListWithModifier); - WRAPPER_CLASS(Default, AccDefaultClause); - WRAPPER_CLASS(DefaultAsync, ScalarIntExpr); - WRAPPER_CLASS(Delete, AccObjectList); - WRAPPER_CLASS(Detach, AccObjectList); - WRAPPER_CLASS(Device, AccObjectList); - WRAPPER_CLASS(DeviceNum, ScalarIntConstantExpr); - WRAPPER_CLASS(DevicePtr, AccObjectList); - WRAPPER_CLASS(DeviceResident, AccObjectList); - WRAPPER_CLASS(DeviceType, std::optional>); - EMPTY_CLASS(Finalize); - WRAPPER_CLASS(FirstPrivate, AccObjectList); - WRAPPER_CLASS(Gang, std::optional); - WRAPPER_CLASS(Host, AccObjectList); - WRAPPER_CLASS(If, ScalarLogicalExpr); - EMPTY_CLASS(IfPresent); - EMPTY_CLASS(Independent); - WRAPPER_CLASS(Link, AccObjectList); - WRAPPER_CLASS(NoCreate, AccObjectList); - EMPTY_CLASS(NoHost); - WRAPPER_CLASS(NumGangs, ScalarIntExpr); - WRAPPER_CLASS(NumWorkers, ScalarIntExpr); - WRAPPER_CLASS(Present, AccObjectList); - WRAPPER_CLASS(Private, AccObjectList); - WRAPPER_CLASS(Tile, AccSizeExprList); - WRAPPER_CLASS(UseDevice, AccObjectList); - EMPTY_CLASS(Read); - WRAPPER_CLASS(Reduction, AccObjectListWithReduction); - WRAPPER_CLASS(Self, std::optional); - EMPTY_CLASS(Seq); - WRAPPER_CLASS(Vector, std::optional); - WRAPPER_CLASS(VectorLength, ScalarIntExpr); - WRAPPER_CLASS(Wait, std::optional); - WRAPPER_CLASS(Worker, std::optional); - EMPTY_CLASS(Write); - EMPTY_CLASS(Unknown); +#define GEN_FLANG_CLAUSE_PARSER_CLASSES +#include "llvm/Frontend/OpenACC/ACC.cpp.inc" CharBlock source; - std::variant + std::variant< +#define GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST +#include "llvm/Frontend/OpenACC/ACC.cpp.inc" + > u; }; diff --git a/flang/lib/Evaluate/CMakeLists.txt b/flang/lib/Evaluate/CMakeLists.txt --- a/flang/lib/Evaluate/CMakeLists.txt +++ b/flang/lib/Evaluate/CMakeLists.txt @@ -45,6 +45,7 @@ ${LIBPGMATH} DEPENDS + acc_gen omp_gen ) diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -55,7 +55,7 @@ parenthesized(Parser{}))) || "DEVICE" >> construct(construct( parenthesized(Parser{}))) || - "DEVICEPTR" >> construct(construct( + "DEVICEPTR" >> construct(construct( parenthesized(Parser{}))) || "DEVICENUM" >> construct(construct( parenthesized(scalarIntConstantExpr))) || @@ -69,7 +69,7 @@ construct(construct( parenthesized(maybe(nonemptyList(name))))) || "FINALIZE" >> construct(construct()) || - "FIRSTPRIVATE" >> construct(construct( + "FIRSTPRIVATE" >> construct(construct( parenthesized(Parser{}))) || "GANG" >> construct(construct( maybe(parenthesized(Parser{})))) || @@ -84,7 +84,7 @@ parenthesized(Parser{}))) || "NO_CREATE" >> construct(construct( parenthesized(Parser{}))) || - "NOHOST" >> construct(construct()) || + "NOHOST" >> construct(construct()) || "NUM_GANGS" >> construct(construct( parenthesized(scalarIntExpr))) || "NUM_WORKERS" >> construct(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -1835,7 +1835,7 @@ void Before(const AccClause::Finalize &) { Word("FINALIZE"); } void Before(const AccClause::IfPresent &) { Word("IF_PRESENT"); } void Before(const AccClause::Independent &) { Word("INDEPENDENT"); } - void Before(const AccClause::NoHost &) { Word("NOHOST"); } + void Before(const AccClause::Nohost &) { Word("NOHOST"); } void Before(const AccClause::Read &) { Word("READ"); } void Before(const AccClause::Seq &) { Word("SEQ"); } void Before(const AccClause::Write &) { Word("WRITE"); } @@ -1906,7 +1906,7 @@ Walk(x.v); Put(")"); } - void Unparse(const AccClause::DevicePtr &x) { + void Unparse(const AccClause::Deviceptr &x) { Word("DEVICEPTR"); Put("("); Walk(x.v); @@ -1918,7 +1918,7 @@ Walk(x.v); Put(")"); } - void Unparse(const AccClause::FirstPrivate &x) { + void Unparse(const AccClause::Firstprivate &x) { Word("FIRSTPRIVATE"); Put("("); Walk(x.v); diff --git a/flang/lib/Semantics/CMakeLists.txt b/flang/lib/Semantics/CMakeLists.txt --- a/flang/lib/Semantics/CMakeLists.txt +++ b/flang/lib/Semantics/CMakeLists.txt @@ -44,6 +44,7 @@ unparse-with-symbols.cpp DEPENDS + acc_gen omp_gen LINK_LIBS diff --git a/flang/lib/Semantics/check-acc-structure.h b/flang/lib/Semantics/check-acc-structure.h --- a/flang/lib/Semantics/check-acc-structure.h +++ b/flang/lib/Semantics/check-acc-structure.h @@ -76,11 +76,11 @@ void Enter(const parser::AccClause::Detach &); void Enter(const parser::AccClause::Device &); void Enter(const parser::AccClause::DeviceNum &); - void Enter(const parser::AccClause::DevicePtr &); + void Enter(const parser::AccClause::Deviceptr &); void Enter(const parser::AccClause::DeviceResident &); void Enter(const parser::AccClause::DeviceType &); void Enter(const parser::AccClause::Finalize &); - void Enter(const parser::AccClause::FirstPrivate &); + void Enter(const parser::AccClause::Firstprivate &); void Enter(const parser::AccClause::Gang &); void Enter(const parser::AccClause::Host &); void Enter(const parser::AccClause::If &); @@ -88,7 +88,7 @@ void Enter(const parser::AccClause::Independent &); void Enter(const parser::AccClause::Link &); void Enter(const parser::AccClause::NoCreate &); - void Enter(const parser::AccClause::NoHost &); + void Enter(const parser::AccClause::Nohost &); void Enter(const parser::AccClause::NumGangs &); void Enter(const parser::AccClause::NumWorkers &); void Enter(const parser::AccClause::Present &); diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -263,11 +263,11 @@ CHECK_SIMPLE_CLAUSE(Detach, ACCC_detach) CHECK_SIMPLE_CLAUSE(Device, ACCC_device) CHECK_SIMPLE_CLAUSE(DeviceNum, ACCC_device_num) -CHECK_SIMPLE_CLAUSE(DevicePtr, ACCC_deviceptr) +CHECK_SIMPLE_CLAUSE(Deviceptr, ACCC_deviceptr) CHECK_SIMPLE_CLAUSE(DeviceResident, ACCC_device_resident) CHECK_SIMPLE_CLAUSE(DeviceType, ACCC_device_type) CHECK_SIMPLE_CLAUSE(Finalize, ACCC_finalize) -CHECK_SIMPLE_CLAUSE(FirstPrivate, ACCC_firstprivate) +CHECK_SIMPLE_CLAUSE(Firstprivate, ACCC_firstprivate) CHECK_SIMPLE_CLAUSE(Gang, ACCC_gang) CHECK_SIMPLE_CLAUSE(Host, ACCC_host) CHECK_SIMPLE_CLAUSE(If, ACCC_if) @@ -275,7 +275,7 @@ CHECK_SIMPLE_CLAUSE(Independent, ACCC_independent) CHECK_SIMPLE_CLAUSE(Link, ACCC_link) CHECK_SIMPLE_CLAUSE(NoCreate, ACCC_no_create) -CHECK_SIMPLE_CLAUSE(NoHost, ACCC_nohost) +CHECK_SIMPLE_CLAUSE(Nohost, ACCC_nohost) CHECK_SIMPLE_CLAUSE(NumGangs, ACCC_num_gangs) CHECK_SIMPLE_CLAUSE(NumWorkers, ACCC_num_workers) CHECK_SIMPLE_CLAUSE(Present, ACCC_present) diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -173,7 +173,7 @@ ResolveAccObjectList(x.v, Symbol::Flag::AccPrivate); return false; } - bool Pre(const parser::AccClause::FirstPrivate &x) { + bool Pre(const parser::AccClause::Firstprivate &x) { ResolveAccObjectList(x.v, Symbol::Flag::AccFirstPrivate); return false; } diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td --- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td +++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td @@ -46,6 +46,9 @@ // EnumSet class name used for clauses to generated the allowed clauses map. string clauseEnumSetClass = ""; + + // Class holding the clauses in the flang parse-tree. + string flangClauseBaseClass = ""; } // Information about a specific clause. @@ -57,10 +60,20 @@ string alternativeName = ""; // Optional class holding value of the clause in clang AST. - string clangClass = ?; + string clangClass = ""; + + // Optional class holding the clause in flang AST. If left blank, the class + // is assumed to be the name of the clause with capitalized word and + // underscores removed. + // ex: async -> Async + // num_threads -> NumThreads + string flangClass = ""; // Optional class holding value of the clause in flang AST. - string flangClass = ?; + string flangClassValue = ""; + + // If set to 1, value is optional. Not optional by default. + bit isValueOptional = 0; // Is clause implicit? If clause is set as implicit, the default kind will // be return in getClauseKind instead of their own kind. diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -25,28 +25,30 @@ let enableBitmaskEnumInNamespace = 1; let includeHeader = "llvm/Frontend/OpenACC/ACC.h.inc"; let clauseEnumSetClass = "AccClauseSet"; + let flangClauseBaseClass = "AccClause"; } //===----------------------------------------------------------------------===// // Definition of OpenACC clauses //===----------------------------------------------------------------------===// -// 2.9.6 -def ACCC_Auto : Clause<"auto"> {} - // 2.16.1 def ACCC_Async : Clause<"async"> { - let flangClass = "std::optional"; + let flangClassValue = "ScalarIntExpr"; + let isValueOptional = 1; } +// 2.9.6 +def ACCC_Auto : Clause<"auto"> {} + // 2.7.11 def ACCC_Attach : Clause<"attach"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.15.1 def ACCC_Bind : Clause<"bind"> { - let flangClass = "Name"; + let flangClassValue = "Name"; } // 2.12 @@ -55,72 +57,73 @@ // 2.9.1 def ACCC_Collapse : Clause<"collapse"> { - let flangClass = "ScalarIntConstantExpr"; + let flangClassValue = "ScalarIntConstantExpr"; } // 2.7.5 def ACCC_Copy : Clause<"copy"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.7.6 def ACCC_Copyin : Clause<"copyin"> { - let flangClass = "AccObjectListWithModifier"; + let flangClassValue = "AccObjectListWithModifier"; } // 2.7.7 def ACCC_Copyout : Clause<"copyout"> { - let flangClass = "AccObjectListWithModifier"; + let flangClassValue = "AccObjectListWithModifier"; } // 2.7.8 def ACCC_Create : Clause<"create"> { - let flangClass = "AccObjectListWithModifier"; + let flangClassValue = "AccObjectListWithModifier"; } // 2.5.14 def ACCC_Default : Clause<"default"> { - let flangClass = "AccDefaultClause"; + let flangClassValue = "AccDefaultClause"; } // 2.4.12 def ACCC_DefaultAsync : Clause<"default_async"> { - let flangClass = "ScalarIntExpr"; + let flangClassValue = "ScalarIntExpr"; } // 2.7.10 def ACCC_Delete : Clause<"delete"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.7.12 def ACCC_Detach : Clause<"detach"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.14.4 def ACCC_Device : Clause<"device"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.14.1 def ACCC_DeviceNum : Clause<"device_num"> { - let flangClass = "ScalarIntConstantExpr"; + let flangClassValue = "ScalarIntConstantExpr"; } // 2.7.3 def ACCC_DevicePtr : Clause<"deviceptr"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.13 def ACCC_DeviceResident : Clause<"device_resident"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.4 def ACCC_DeviceType : Clause<"device_type"> { // (DeviceType, "*" - let flangClass = "std::optional>"; + let flangClassValue = "std::list"; + let isValueOptional = 1; } // 2.6.6 @@ -128,22 +131,23 @@ // 2.5.12 def ACCC_FirstPrivate : Clause<"firstprivate"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.9.2 def ACCC_Gang : Clause<"gang"> { - let flangClass = "std::optional"; + let flangClassValue = "AccGangArgument"; + let isValueOptional = 1; } // 2.14.4 def ACCC_Host : Clause<"host"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.5.4 def ACCC_If : Clause <"if"> { - let flangClass = "ScalarLogicalExpr"; + let flangClassValue = "ScalarLogicalExpr"; } // 2.14.4 @@ -154,12 +158,12 @@ // 2.13 def ACCC_Link : Clause<"link"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.7.9 def ACCC_NoCreate : Clause<"no_create"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.15.1 @@ -167,32 +171,32 @@ // 2.5.8 def ACCC_NumGangs : Clause<"num_gangs"> { - let flangClass = "ScalarIntExpr"; + let flangClassValue = "ScalarIntExpr"; } // 2.5.9 def ACCC_NumWorkers : Clause<"num_workers"> { - let flangClass = "ScalarIntExpr"; + let flangClassValue = "ScalarIntExpr"; } // 2.7.4 def ACCC_Present : Clause<"present"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.5.11 def ACCC_Private : Clause<"private"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.9.7 def ACCC_Tile : Clause <"tile"> { - let flangClass = "AccSizeExprList"; + let flangClassValue = "AccSizeExprList"; } // 2.8.1 def ACCC_UseDevice : Clause <"use_device"> { - let flangClass = "AccObjectList"; + let flangClassValue = "AccObjectList"; } // 2.12 @@ -200,12 +204,13 @@ // 2.5.13 def ACCC_Reduction : Clause<"reduction"> { - let flangClass = "AccObjectListWithReduction"; + let flangClassValue = "AccObjectListWithReduction"; } // 2.5.5 def ACCC_Self : Clause<"self"> { - let flangClass = "std::optional"; + let flangClassValue = "ScalarLogicalExpr"; + let isValueOptional = 1; } // 2.9.5 @@ -213,22 +218,25 @@ // 2.9.4 def ACCC_Vector : Clause<"vector"> { - let flangClass = "std::optional"; + let flangClassValue = "ScalarIntExpr"; + let isValueOptional = 1; } // 2.5.10 def ACCC_VectorLength : Clause<"vector_length"> { - let flangClass = "ScalarIntExpr"; + let flangClassValue = "ScalarIntExpr"; } // 2.16.2 def ACCC_Wait : Clause<"wait"> { - let flangClass = "std::optional"; + let flangClassValue = "AccWaitArgument"; + let isValueOptional = 1; } // 2.9.3 def ACCC_Worker: Clause<"worker"> { - let flangClass = "std::optional"; + let flangClassValue = "ScalarIntExpr"; + let isValueOptional = 1; } // 2.12 diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -25,6 +25,7 @@ let enableBitmaskEnumInNamespace = 1; let includeHeader = "llvm/Frontend/OpenMP/OMP.h.inc"; let clauseEnumSetClass = "OmpClauseSet"; + let flangClauseBaseClass = "OmpClause"; } //===----------------------------------------------------------------------===// @@ -34,38 +35,87 @@ def OMPC_Allocator : Clause<"allocator"> { let clangClass = "OMPAllocatorClause"; } -def OMPC_If : Clause<"if"> { let clangClass = "OMPIfClause"; } -def OMPC_Final : Clause<"final"> { let clangClass = "OMPFinalClause"; } +def OMPC_If : Clause<"if"> { + let clangClass = "OMPIfClause"; + let flangClass = "OmpIfClause"; +} +def OMPC_Final : Clause<"final"> { + let clangClass = "OMPFinalClause"; + let flangClassValue = "ScalarLogicalExpr"; +} def OMPC_NumThreads : Clause<"num_threads"> { let clangClass = "OMPNumThreadsClause"; + let flangClassValue = "ScalarIntExpr"; +} +def OMPC_SafeLen : Clause<"safelen"> { + let clangClass = "OMPSafelenClause"; + let flangClassValue = "ScalarIntConstantExpr"; +} +def OMPC_SimdLen : Clause<"simdlen"> { + let clangClass = "OMPSimdlenClause"; + let flangClassValue = "ScalarIntConstantExpr"; +} +def OMPC_Collapse : Clause<"collapse"> { + let clangClass = "OMPCollapseClause"; + let flangClassValue = "ScalarIntConstantExpr"; +} +def OMPC_Default : Clause<"default"> { + let clangClass = "OMPDefaultClause"; + let flangClass = "OmpDefaultClause"; +} +def OMPC_Private : Clause<"private"> { + let clangClass = "OMPPrivateClause"; + let flangClassValue = "OmpObjectList"; } -def OMPC_SafeLen : Clause<"safelen"> { let clangClass = "OMPSafelenClause"; } -def OMPC_SimdLen : Clause<"simdlen"> { let clangClass = "OMPSimdlenClause"; } -def OMPC_Collapse : Clause<"collapse"> { let clangClass = "OMPCollapseClause"; } -def OMPC_Default : Clause<"default"> { let clangClass = "OMPDefaultClause"; } -def OMPC_Private : Clause<"private"> { let clangClass = "OMPPrivateClause"; } def OMPC_FirstPrivate : Clause<"firstprivate"> { let clangClass = "OMPFirstprivateClause"; + let flangClassValue = "OmpObjectList"; } def OMPC_LastPrivate : Clause<"lastprivate"> { let clangClass = "OMPLastprivateClause"; + let flangClassValue = "OmpObjectList"; +} +def OMPC_Shared : Clause<"shared"> { + let clangClass = "OMPSharedClause"; + let flangClassValue = "OmpObjectList"; } -def OMPC_Shared : Clause<"shared"> { let clangClass = "OMPSharedClause"; } def OMPC_Reduction : Clause<"reduction"> { let clangClass = "OMPReductionClause"; + let flangClass = "OmpReductionClause"; +} +def OMPC_Linear : Clause<"linear"> { + let clangClass = "OMPLinearClause"; + let flangClass = "OmpLinearClause"; +} +def OMPC_Aligned : Clause<"aligned"> { + let clangClass = "OMPAlignedClause"; + let flangClass = "OmpAlignedClause"; +} +def OMPC_Copyin : Clause<"copyin"> { + let clangClass = "OMPCopyinClause"; + let flangClassValue = "OmpObjectList"; } -def OMPC_Linear : Clause<"linear"> { let clangClass = "OMPLinearClause"; } -def OMPC_Aligned : Clause<"aligned"> { let clangClass = "OMPAlignedClause"; } -def OMPC_Copyin : Clause<"copyin"> { let clangClass = "OMPCopyinClause"; } def OMPC_CopyPrivate : Clause<"copyprivate"> { let clangClass = "OMPCopyprivateClause"; + let flangClassValue = "OmpObjectList"; } def OMPC_ProcBind : Clause<"proc_bind"> { let clangClass = "OMPProcBindClause"; + let flangClass = "OmpProcBindClause"; +} +def OMPC_Schedule : Clause<"schedule"> { + let clangClass = "OMPScheduleClause"; + let flangClass = "OmpScheduleClause"; +} +def OMPC_Ordered : Clause<"ordered"> { + let clangClass = "OMPOrderedClause"; + let flangClassValue = "ScalarIntConstantExpr"; + let isValueOptional = 1; +} +def OMPC_NoWait : Clause<"nowait"> { + let clangClass = "OMPNowaitClause"; + let flangClass = "OmpNowait"; } -def OMPC_Schedule : Clause<"schedule"> { let clangClass = "OMPScheduleClause"; } -def OMPC_Ordered : Clause<"ordered"> { let clangClass = "OMPOrderedClause"; } -def OMPC_NoWait : Clause<"nowait"> { let clangClass = "OMPNowaitClause"; } def OMPC_Untied : Clause<"untied"> { let clangClass = "OMPUntiedClause"; } def OMPC_Mergeable : Clause<"mergeable"> { let clangClass = "OMPMergeableClause"; @@ -79,47 +129,70 @@ def OMPC_Acquire : Clause<"acquire"> { let clangClass = "OMPAcquireClause"; } def OMPC_Release : Clause<"release"> { let clangClass = "OMPReleaseClause"; } def OMPC_Relaxed : Clause<"relaxed"> { let clangClass = "OMPRelaxedClause"; } -def OMPC_Depend : Clause<"depend"> { let clangClass = "OMPDependClause"; } -def OMPC_Device : Clause<"device"> { let clangClass = "OMPDeviceClause"; } +def OMPC_Depend : Clause<"depend"> { + let clangClass = "OMPDependClause"; + let flangClass = "OmpDependClause"; +} +def OMPC_Device : Clause<"device"> { + let clangClass = "OMPDeviceClause"; + let flangClassValue = "ScalarIntExpr"; +} def OMPC_Threads : Clause<"threads"> { let clangClass = "OMPThreadsClause"; } def OMPC_Simd : Clause<"simd"> { let clangClass = "OMPSIMDClause"; } -def OMPC_Map : Clause<"map"> { let clangClass = "OMPMapClause"; } +def OMPC_Map : Clause<"map"> { + let clangClass = "OMPMapClause"; + let flangClass = "OmpMapClause"; +} def OMPC_NumTeams : Clause<"num_teams"> { let clangClass = "OMPNumTeamsClause"; + let flangClassValue = "ScalarIntExpr"; } def OMPC_ThreadLimit : Clause<"thread_limit"> { let clangClass = "OMPThreadLimitClause"; + let flangClassValue = "ScalarIntExpr"; } def OMPC_Priority : Clause<"priority"> { let clangClass = "OMPPriorityClause"; + let flangClassValue = "ScalarIntExpr"; } def OMPC_GrainSize : Clause<"grainsize"> { let clangClass = "OMPGrainsizeClause"; + let flangClassValue = "ScalarIntExpr"; } def OMPC_NoGroup : Clause<"nogroup"> { let clangClass = "OMPNogroupClause"; } def OMPC_NumTasks : Clause<"num_tasks"> { let clangClass = "OMPNumTasksClause"; + let flangClassValue = "ScalarIntExpr"; } def OMPC_Hint : Clause<"hint"> { let clangClass = "OMPHintClause"; } def OMPC_DistSchedule : Clause<"dist_schedule"> { let clangClass = "OMPDistScheduleClause"; + let flangClassValue = "ScalarIntExpr"; + let isValueOptional = 1; } def OMPC_DefaultMap : Clause<"defaultmap"> { let clangClass = "OMPDefaultmapClause"; + let flangClass = "OmpDefaultmapClause"; } def OMPC_To : Clause<"to"> { let clangClass = "OMPToClause"; + let flangClassValue = "OmpObjectList"; +} +def OMPC_From : Clause<"from"> { + let clangClass = "OMPFromClause"; + let flangClassValue = "OmpObjectList"; } -def OMPC_From : Clause<"from"> { let clangClass = "OMPFromClause"; } def OMPC_UseDevicePtr : Clause<"use_device_ptr"> { let clangClass = "OMPUseDevicePtrClause"; + let flangClassValue = "std::list"; } def OMPC_IsDevicePtr : Clause<"is_device_ptr"> { let clangClass = "OMPIsDevicePtrClause"; + let flangClassValue = "std::list"; } def OMPC_TaskReduction : Clause<"task_reduction"> { let clangClass = "OMPTaskReductionClause"; @@ -144,6 +217,7 @@ } def OMPC_Allocate : Clause<"allocate"> { let clangClass = "OMPAllocateClause"; + let flangClass = "OmpAllocateClause"; } def OMPC_NonTemporal : Clause<"nontemporal"> { let clangClass = "OMPNontemporalClause"; @@ -172,7 +246,9 @@ def OMPC_UseDeviceAddr : Clause<"use_device_addr"> { let clangClass = "OMPUseDeviceAddrClause"; } -def OMPC_Uniform : Clause<"uniform"> {} +def OMPC_Uniform : Clause<"uniform"> { + let flangClassValue = "std::list"; +} def OMPC_DeviceType : Clause<"device_type"> {} def OMPC_Match : Clause<"match"> {} def OMPC_Depobj : Clause<"depobj"> { @@ -191,7 +267,9 @@ let isImplicit = 1; let isDefault = 1; } -def OMPC_Link : Clause<"link"> {} +def OMPC_Link : Clause<"link"> { + let flangClassValue = "OmpObjectList"; +} def OMPC_Inbranch : Clause<"inbranch"> {} def OMPC_Notinbranch : Clause<"notinbranch"> {} diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td --- a/llvm/test/TableGen/directive1.td +++ b/llvm/test/TableGen/directive1.td @@ -12,10 +12,15 @@ let clausePrefix = "TDLC_"; let makeEnumAvailableInNamespace = 1; let enableBitmaskEnumInNamespace = 1; + let flangClauseBaseClass = "TdlClause"; } -def TDLC_ClauseA : Clause<"clausea"> {} +def TDLC_ClauseA : Clause<"clausea"> { + let flangClass = "TdlClauseA"; +} def TDLC_ClauseB : Clause<"clauseb"> { + let flangClassValue = "IntExpr"; + let isValueOptional = 1; let isDefault = 1; } @@ -173,4 +178,27 @@ // GEN-NEXT: } // GEN-EMPTY: // GEN-NEXT: #endif // GEN_FLANG_DIRECTIVE_CLAUSE_MAP +// GEN-EMPTY: +// GEN-NEXT: #ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES +// GEN-NEXT: #undef GEN_FLANG_CLAUSE_PARSER_CLASSES +// GEN-EMPTY: +// GEN-NEXT: WRAPPER_CLASS(Clauseb, std::optional); +// GEN-EMPTY: +// GEN-NEXT: #endif // GEN_FLANG_CLAUSE_PARSER_CLASSES +// GEN-EMPTY: +// GEN-NEXT: #ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST +// GEN-NEXT: #undef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST +// GEN-EMPTY: +// GEN-NEXT: TdlClauseA +// GEN-NEXT: , Clauseb +// GEN-EMPTY: +// GEN-NEXT: #endif // GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST +// GEN-EMPTY: +// GEN-NEXT: #ifdef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES +// GEN-NEXT: #undef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES +// GEN-EMPTY: +// GEN-NEXT: NODE(TdlClause, Clauseb) +// GEN-EMPTY: +// GEN-NEXT: #endif // GEN_FLANG_DUMP_PARSE_TREE_CLAUSES + diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td --- a/llvm/test/TableGen/directive2.td +++ b/llvm/test/TableGen/directive2.td @@ -11,6 +11,7 @@ let directivePrefix = "TDLD_"; let clausePrefix = "TDLC_"; let includeHeader = "tdl.h.inc"; + let flangClauseBaseClass = "TdlClause"; } def TDLC_ClauseA : Clause<"clausea"> { @@ -18,6 +19,7 @@ } def TDLC_ClauseB : Clause<"clauseb"> { let isDefault = 1; + let flangClassValue = "IntExpr"; } def TDL_DirA : Directive<"dira"> { @@ -164,3 +166,27 @@ // GEN-NEXT: } // GEN-EMPTY: // GEN-NEXT: #endif // GEN_FLANG_DIRECTIVE_CLAUSE_MAP +// GEN-EMPTY: +// GEN-NEXT: #ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES +// GEN-NEXT: #undef GEN_FLANG_CLAUSE_PARSER_CLASSES +// GEN-EMPTY: +// GEN-NEXT: EMPTY_CLASS(Clausea); +// GEN-NEXT: WRAPPER_CLASS(Clauseb, IntExpr); +// GEN-EMPTY: +// GEN-NEXT: #endif // GEN_FLANG_CLAUSE_PARSER_CLASSES +// GEN-EMPTY: +// GEN-NEXT: #ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST +// GEN-NEXT: #undef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST +// GEN-EMPTY: +// GEN-NEXT: Clausea +// GEN-NEXT: , Clauseb +// GEN-EMPTY: +// GEN-NEXT: #endif // GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST +// GEN-EMPTY: +// GEN-NEXT: #ifdef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES +// GEN-NEXT: #undef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES +// GEN-EMPTY: +// GEN-NEXT: NODE(TdlClause, Clausea) +// GEN-NEXT: NODE(TdlClause, Clauseb) +// GEN-EMPTY: +// GEN-NEXT: #endif // GEN_FLANG_DUMP_PARSE_TREE_CLAUSES \ No newline at end of file diff --git a/llvm/utils/TableGen/DirectiveEmitter.cpp b/llvm/utils/TableGen/DirectiveEmitter.cpp --- a/llvm/utils/TableGen/DirectiveEmitter.cpp +++ b/llvm/utils/TableGen/DirectiveEmitter.cpp @@ -19,6 +19,7 @@ #include "llvm/TableGen/Record.h" #include "llvm/TableGen/TableGenBackend.h" + using namespace llvm; namespace { @@ -68,6 +69,10 @@ return Def->getValueAsString("clauseEnumSetClass"); } + StringRef getFlangClauseBaseClass() const { + return Def->getValueAsString("flangClauseBaseClass"); + } + bool hasMakeEnumAvailableInNamespace() const { return Def->getValueAsBit("makeEnumAvailableInNamespace"); } @@ -146,6 +151,35 @@ return Def->getValueAsString("flangClass"); } + // Optional field. + StringRef getFlangClassValue() const { + return Def->getValueAsString("flangClassValue"); + } + + // Get the formatted name for Flang parser class. The generic formatted class + // name is constructed from the name were the first letter of each word is + // captitalized and the underscores are removed. + // ex: async -> Async + // num_threads -> NumThreads + std::string getFormattedParserClassName() { + StringRef Name = Def->getValueAsString("name"); + std::string N = Name.str(); + bool Cap = true; + std::transform(N.begin(), N.end(), N.begin(), [&Cap](unsigned char C) { + if (Cap == true) { + C = llvm::toUpper(C); + Cap = false; + } else if (C == '_') { + Cap = true; + } + return C; + }); + N.erase(std::remove(N.begin(), N.end(), '_'), N.end()); + return N; + } + + bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); } + bool isImplict() const { return Def->getValueAsBit("isImplicit"); } }; @@ -489,15 +523,89 @@ OS << "}\n"; } +// Generate classes entry for Flang clauses in the Flang parse-tree +// If the clause as a non-generic class, no entry is generated. +// If the clause does not hold a value, an EMPTY_CLASS is used. +// If the clause class is generic then a WRAPPER_CLASS is used. When the value +// is optional, the value class is wrapped into a std::optional. +void GenerateFlangClauseParserClass(const std::vector &Clauses, + raw_ostream &OS) { + + IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES", OS); + + OS << "\n"; + + for (const auto &C : Clauses) { + Clause Clause{C}; + // Clause has a non generic class. + if (!Clause.getFlangClass().empty()) + continue; + // G + if (!Clause.getFlangClassValue().empty()) { + if (Clause.isValueOptional()) { + OS << "WRAPPER_CLASS(" << Clause.getFormattedParserClassName() + << ", std::optional<" << Clause.getFlangClassValue() << ">);\n"; + } else { + OS << "WRAPPER_CLASS(" << Clause.getFormattedParserClassName() << ", " + << Clause.getFlangClassValue() << ");\n"; + } + } else { + OS << "EMPTY_CLASS(" << Clause.getFormattedParserClassName() << ");\n"; + } + } +} + +// Generate a list of the different clause classes for Flang. +void GenerateFlangClauseParserClassList(const std::vector &Clauses, + raw_ostream &OS) { + + IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST", OS); + + OS << "\n"; + llvm::interleaveComma(Clauses, OS, [&](Record *C) { + Clause Clause{C}; + if (Clause.getFlangClass().empty()) + OS << Clause.getFormattedParserClassName() << "\n"; + else + OS << Clause.getFlangClass() << "\n"; + }); +} + +// Generate dump node list for the clauses holding a generic class name. +void GenerateFlangClauseDump(const std::vector &Clauses, + const DirectiveLanguage &DirLang, + raw_ostream &OS) { + + IfDefScope Scope("GEN_FLANG_DUMP_PARSE_TREE_CLAUSES", OS); + + OS << "\n"; + for (const auto &C : Clauses) { + Clause Clause{C}; + // Clause has a non generic class. + if (!Clause.getFlangClass().empty()) + continue; + + OS << "NODE(" << DirLang.getFlangClauseBaseClass() << ", " + << Clause.getFormattedParserClassName() << ")\n"; + } +} + // Generate the implemenation section for the enumeration in the directive // language void EmitDirectivesFlangImpl(const std::vector &Directives, + const std::vector &Clauses, raw_ostream &OS, DirectiveLanguage &DirectiveLanguage) { GenerateDirectiveClauseSets(Directives, OS, DirectiveLanguage); GenerateDirectiveClauseMap(Directives, OS, DirectiveLanguage); + + GenerateFlangClauseParserClass(Clauses, OS); + + GenerateFlangClauseParserClassList(Clauses, OS); + + GenerateFlangClauseDump(Clauses, DirectiveLanguage, OS); } // Generate the implemenation section for the enumeration in the directive @@ -513,8 +621,9 @@ } const auto &Directives = Records.getAllDerivedDefinitions("Directive"); + const auto &Clauses = Records.getAllDerivedDefinitions("Clause"); DirectiveLanguage DirectiveLanguage{DirectiveLanguages[0]}; - EmitDirectivesFlangImpl(Directives, OS, DirectiveLanguage); + EmitDirectivesFlangImpl(Directives, Clauses, OS, DirectiveLanguage); } // Generate the implemenation for the enumeration in the directive