Commit 0a90ffa7 authored by Valentin Clement's avatar Valentin Clement Committed by clementval
Browse files

[flang][openacc] OpenACC 3.0 parser

Summary:
This patch introduce the parser for OpenACC 3.0 in Flang. It uses the same TableGen mechanism
than OpenMP.

Reviewers: nvdatian, sscalpone, tskeith, klausler, ichoyjx, jdoerfert, DavidTruby

Reviewed By: klausler

Subscribers: MaskRay, SouraVX, mgorny, hiraditya, jfb, sstefan1, llvm-commits

Tags: #llvm, #flang

Differential Revision: https://reviews.llvm.org/D83649
parent 1254f6d5
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
    OldStyleParameter, ComplexConstructor, PercentLOC, SignedPrimary, FileName,
    Convert, Dispose, IOListLeadingComma, AbbreviatedEditDescriptor,
    ProgramParentheses, PercentRefAndVal, OmitFunctionDummies, CrayPointer,
    Hollerith, ArithmeticIF, Assign, AssignedGOTO, Pause, OpenMP,
    Hollerith, ArithmeticIF, Assign, AssignedGOTO, Pause, OpenACC, OpenMP,
    CruftAfterAmpersand, ClassicCComments, AdditionalFormats, BigIntLiterals,
    RealDoControls, EquivalenceNumericWithCharacter, AdditionalIntrinsics,
    AnonymousParents, OldLabelDoEndStatements, LogicalIntegerAssignment,
@@ -37,6 +37,7 @@ public:
  LanguageFeatureControl() {
    // These features must be explicitly enabled by command line options.
    disable_.set(LanguageFeature::OldDebugLines);
    disable_.set(LanguageFeature::OpenACC);
    disable_.set(LanguageFeature::OpenMP);
    // These features, if enabled, conflict with valid standard usage,
    // so there are disabled here by default.
@@ -50,7 +51,9 @@ public:
  void WarnOnAllNonstandard(bool yes = true) { warnAll_ = yes; }
  bool IsEnabled(LanguageFeature f) const { return !disable_.test(f); }
  bool ShouldWarn(LanguageFeature f) const {
    return (warnAll_ && f != LanguageFeature::OpenMP) || warn_.test(f);
    return (warnAll_ && f != LanguageFeature::OpenMP &&
               f != LanguageFeature::OpenACC) ||
        warn_.test(f);
  }
  // Return all spellings of operators names, depending on features enabled
  std::vector<const char *> GetNames(LogicalOperator) const;
+93 −0
Original line number Diff line number Diff line
@@ -53,6 +53,88 @@ public:
  NODE(format, IntrinsicTypeDataEditDesc)
  NODE(format::IntrinsicTypeDataEditDesc, Kind)
  NODE(parser, Abstract)
  NODE(parser, AccAtomicCapture)
  NODE(AccAtomicCapture, Stmt1)
  NODE(AccAtomicCapture, Stmt2)
  NODE(parser, AccAtomicRead)
  NODE(parser, AccAtomicUpdate)
  NODE(parser, AccAtomicWrite)
  NODE(parser, AccBeginBlockDirective)
  NODE(parser, AccBeginCombinedDirective)
  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)
  NODE(parser, AccDefaultClause)
  NODE_ENUM(parser::AccDefaultClause, Arg)
  NODE(parser, AccClauseList)
  NODE(parser, AccCombinedDirective)
  NODE(parser, AccDataModifier)
  NODE_ENUM(parser::AccDataModifier, Modifier)
  NODE(parser, AccDeclarativeDirective)
  NODE(parser, AccEndAtomic)
  NODE(parser, AccEndBlockDirective)
  NODE(parser, AccEndCombinedDirective)
  NODE(parser, AccGangArgument)
  NODE(parser, AccObject)
  NODE(parser, AccObjectList)
  NODE(parser, AccObjectListWithModifier)
  NODE(parser, AccObjectListWithReduction)
  NODE(parser, AccReductionOperator)
  NODE(parser, AccSizeExpr)
  NODE(parser, AccSizeExprList)
  NODE(parser, AccStandaloneDirective)
  NODE(parser, AccLoopDirective)
  NODE(parser, AccWaitArgument)
  static std::string GetNodeName(const llvm::acc::Directive &x) {
    return llvm::Twine(
        "llvm::acc::Directive = ", llvm::acc::getOpenACCDirectiveName(x))
        .str();
  }
  NODE(parser, AcImpliedDo)
  NODE(parser, AcImpliedDoControl)
  NODE(parser, AcValue)
@@ -510,6 +592,17 @@ public:
  NODE(parser, OmpSectionsDirective)
  NODE(parser, OmpSimpleStandaloneDirective)
  NODE(parser, Only)
  NODE(parser, OpenACCAtomicConstruct)
  NODE(parser, OpenACCBlockConstruct)
  NODE(parser, OpenACCCacheConstruct)
  NODE(parser, OpenACCCombinedConstruct)
  NODE(parser, OpenACCConstruct)
  NODE(parser, OpenACCDeclarativeConstruct)
  NODE(parser, OpenACCLoopConstruct)
  NODE(parser, OpenACCRoutineConstruct)
  NODE(parser, OpenACCStandaloneDeclarativeConstruct)
  NODE(parser, OpenACCStandaloneConstruct)
  NODE(parser, OpenACCWaitConstruct)
  NODE(parser, OpenMPAtomicConstruct)
  NODE(parser, OpenMPBlockConstruct)
  NODE(parser, OpenMPCancelConstruct)
+289 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include "flang/Common/Fortran.h"
#include "flang/Common/idioms.h"
#include "flang/Common/indirection.h"
#include "llvm/Frontend/OpenACC/ACC.h.inc"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include <cinttypes>
#include <list>
@@ -256,6 +257,8 @@ struct ArithmeticIfStmt;
struct AssignStmt;
struct AssignedGotoStmt;
struct PauseStmt;
struct OpenACCConstruct;
struct OpenACCDeclarativeConstruct;
struct OpenMPConstruct;
struct OpenMPDeclarativeConstruct;
struct OmpEndLoopDirective;
@@ -386,6 +389,7 @@ struct SpecificationConstruct {
      Statement<OtherSpecificationStmt>,
      Statement<common::Indirection<TypeDeclarationStmt>>,
      common::Indirection<StructureDef>,
      common::Indirection<OpenACCDeclarativeConstruct>,
      common::Indirection<OpenMPDeclarativeConstruct>,
      common::Indirection<CompilerDirective>>
      u;
@@ -424,7 +428,8 @@ struct DeclarationConstruct {
// from the implicit part to the declaration constructs
struct SpecificationPart {
  TUPLE_CLASS_BOILERPLATE(SpecificationPart);
  std::tuple<std::list<OpenMPDeclarativeConstruct>,
  std::tuple<std::list<OpenACCDeclarativeConstruct>,
      std::list<OpenMPDeclarativeConstruct>,
      std::list<Statement<common::Indirection<UseStmt>>>,
      std::list<Statement<common::Indirection<ImportStmt>>>, ImplicitPart,
      std::list<DeclarationConstruct>>
@@ -509,6 +514,7 @@ struct ExecutableConstruct {
      common::Indirection<SelectTypeConstruct>,
      common::Indirection<WhereConstruct>, common::Indirection<ForallConstruct>,
      common::Indirection<CompilerDirective>,
      common::Indirection<OpenACCConstruct>,
      common::Indirection<OpenMPConstruct>,
      common::Indirection<OmpEndLoopDirective>>
      u;
@@ -3789,5 +3795,287 @@ struct OpenMPConstruct {
      OpenMPCriticalConstruct>
      u;
};

// Parse tree nodes for OpenACC 3.0 directives and clauses

struct AccObject {
  UNION_CLASS_BOILERPLATE(AccObject);
  std::variant<Designator, /*common block*/ Name> u;
};

WRAPPER_CLASS(AccObjectList, std::list<AccObject>);

// OpenACC directive beginning or ending a block
struct AccBlockDirective {
  WRAPPER_CLASS_BOILERPLATE(AccBlockDirective, llvm::acc::Directive);
  CharBlock source;
};

struct AccLoopDirective {
  WRAPPER_CLASS_BOILERPLATE(AccLoopDirective, llvm::acc::Directive);
  CharBlock source;
};

struct AccStandaloneDirective {
  WRAPPER_CLASS_BOILERPLATE(AccStandaloneDirective, llvm::acc::Directive);
  CharBlock source;
};

// 2.11 Combined constructs
struct AccCombinedDirective {
  WRAPPER_CLASS_BOILERPLATE(AccCombinedDirective, llvm::acc::Directive);
  CharBlock source;
};

struct AccDeclarativeDirective {
  WRAPPER_CLASS_BOILERPLATE(AccDeclarativeDirective, llvm::acc::Directive);
  CharBlock source;
};

// OpenACC Clauses
struct AccDefaultClause {
  ENUM_CLASS(Arg, None, Present)
  WRAPPER_CLASS_BOILERPLATE(AccDefaultClause, Arg);
  CharBlock source;
};

struct AccDataModifier {
  ENUM_CLASS(Modifier, ReadOnly, Zero)
  WRAPPER_CLASS_BOILERPLATE(AccDataModifier, Modifier);
  CharBlock source;
};

struct AccObjectListWithModifier {
  TUPLE_CLASS_BOILERPLATE(AccObjectListWithModifier);
  std::tuple<std::optional<AccDataModifier>, AccObjectList> t;
};

// 2.5.13: + | * | max | min | iand | ior | ieor | .and. | .or. | .eqv. | .neqv.
struct AccReductionOperator {
  UNION_CLASS_BOILERPLATE(AccReductionOperator);
  std::variant<DefinedOperator, ProcedureDesignator> u;
};

struct AccObjectListWithReduction {
  TUPLE_CLASS_BOILERPLATE(AccObjectListWithReduction);
  std::tuple<AccReductionOperator, AccObjectList> t;
};

struct AccWaitArgument {
  TUPLE_CLASS_BOILERPLATE(AccWaitArgument);
  std::tuple<std::optional<ScalarIntExpr>, std::list<ScalarIntExpr>> t;
};

struct AccSizeExpr {
  TUPLE_CLASS_BOILERPLATE(AccSizeExpr);
  CharBlock source;
  std::tuple<std::optional<ScalarIntExpr>> t; // if null then *
};

struct AccSizeExprList {
  WRAPPER_CLASS_BOILERPLATE(AccSizeExprList, std::list<AccSizeExpr>);
};

struct AccGangArgument {
  TUPLE_CLASS_BOILERPLATE(AccGangArgument);
  std::tuple<std::optional<ScalarIntExpr>, std::optional<AccSizeExpr>> t;
};

struct AccClause {
  UNION_CLASS_BOILERPLATE(AccClause);

  EMPTY_CLASS(Auto);
  WRAPPER_CLASS(Async, std::optional<ScalarIntExpr>);
  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<std::list<Name>>);
  EMPTY_CLASS(Finalize);
  WRAPPER_CLASS(FirstPrivate, AccObjectList);
  WRAPPER_CLASS(Gang, std::optional<AccGangArgument>);
  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<ScalarLogicalExpr>);
  EMPTY_CLASS(Seq);
  WRAPPER_CLASS(Vector, std::optional<ScalarIntExpr>);
  WRAPPER_CLASS(VectorLength, ScalarIntExpr);
  WRAPPER_CLASS(Wait, std::optional<AccWaitArgument>);
  WRAPPER_CLASS(Worker, std::optional<ScalarIntExpr>);
  EMPTY_CLASS(Write);
  EMPTY_CLASS(Unknown);

  CharBlock source;

  std::variant<Auto, Async, Attach, Bind, Capture, Collapse, Copy, Copyin,
      Copyout, Create, Default, DefaultAsync, Delete, Detach, Device, DeviceNum,
      DevicePtr, DeviceResident, DeviceType, Finalize, FirstPrivate, Gang, Host,
      If, IfPresent, Independent, Link, NoCreate, NoHost, NumGangs, NumWorkers,
      Present, Private, Tile, UseDevice, Read, Reduction, Self, Seq, Vector,
      VectorLength, Wait, Worker, Write, Unknown>
      u;
};

struct AccClauseList {
  WRAPPER_CLASS_BOILERPLATE(AccClauseList, std::list<AccClause>);
  CharBlock source;
};

struct OpenACCRoutineConstruct {
  TUPLE_CLASS_BOILERPLATE(OpenACCRoutineConstruct);
  CharBlock source;
  std::tuple<Verbatim, std::optional<Name>, AccClauseList> t;
};

struct OpenACCCacheConstruct {
  TUPLE_CLASS_BOILERPLATE(OpenACCCacheConstruct);
  CharBlock source;
  std::tuple<Verbatim, AccObjectListWithModifier> t;
};

struct OpenACCWaitConstruct {
  TUPLE_CLASS_BOILERPLATE(OpenACCWaitConstruct);
  CharBlock source;
  std::tuple<Verbatim, std::optional<AccWaitArgument>, AccClauseList> t;
};

struct AccBeginLoopDirective {
  TUPLE_CLASS_BOILERPLATE(AccBeginLoopDirective);
  std::tuple<AccLoopDirective, AccClauseList> t;
  CharBlock source;
};

struct AccBeginBlockDirective {
  TUPLE_CLASS_BOILERPLATE(AccBeginBlockDirective);
  CharBlock source;
  std::tuple<AccBlockDirective, AccClauseList> t;
};

struct AccEndBlockDirective {
  CharBlock source;
  WRAPPER_CLASS_BOILERPLATE(AccEndBlockDirective, AccBlockDirective);
};

// ACC END ATOMIC
EMPTY_CLASS(AccEndAtomic);

// ACC ATOMIC READ
struct AccAtomicRead {
  TUPLE_CLASS_BOILERPLATE(AccAtomicRead);
  std::tuple<Verbatim, Statement<AssignmentStmt>, std::optional<AccEndAtomic>>
      t;
};

// ACC ATOMIC WRITE
struct AccAtomicWrite {
  TUPLE_CLASS_BOILERPLATE(AccAtomicWrite);
  std::tuple<Verbatim, Statement<AssignmentStmt>, std::optional<AccEndAtomic>>
      t;
};

// ACC ATOMIC UPDATE
struct AccAtomicUpdate {
  TUPLE_CLASS_BOILERPLATE(AccAtomicUpdate);
  std::tuple<std::optional<Verbatim>, Statement<AssignmentStmt>,
      std::optional<AccEndAtomic>>
      t;
};

// ACC ATOMIC CAPTURE
struct AccAtomicCapture {
  TUPLE_CLASS_BOILERPLATE(AccAtomicCapture);
  WRAPPER_CLASS(Stmt1, Statement<AssignmentStmt>);
  WRAPPER_CLASS(Stmt2, Statement<AssignmentStmt>);
  std::tuple<Verbatim, Stmt1, Stmt2, AccEndAtomic> t;
};

struct OpenACCAtomicConstruct {
  UNION_CLASS_BOILERPLATE(OpenACCAtomicConstruct);
  std::variant<AccAtomicRead, AccAtomicWrite, AccAtomicCapture, AccAtomicUpdate>
      u;
};

struct OpenACCBlockConstruct {
  TUPLE_CLASS_BOILERPLATE(OpenACCBlockConstruct);
  std::tuple<AccBeginBlockDirective, Block, AccEndBlockDirective> t;
};

struct OpenACCStandaloneDeclarativeConstruct {
  TUPLE_CLASS_BOILERPLATE(OpenACCStandaloneDeclarativeConstruct);
  CharBlock source;
  std::tuple<AccDeclarativeDirective, AccClauseList> t;
};

struct AccBeginCombinedDirective {
  TUPLE_CLASS_BOILERPLATE(AccBeginCombinedDirective);
  std::tuple<AccCombinedDirective, AccClauseList> t;
};

struct AccEndCombinedDirective {
  WRAPPER_CLASS_BOILERPLATE(AccEndCombinedDirective, AccCombinedDirective);
  CharBlock source;
};

struct OpenACCCombinedConstruct {
  TUPLE_CLASS_BOILERPLATE(OpenACCCombinedConstruct);
  CharBlock source;
  std::tuple<AccBeginCombinedDirective, Block,
      std::optional<AccEndCombinedDirective>>
      t;
};

struct OpenACCDeclarativeConstruct {
  UNION_CLASS_BOILERPLATE(OpenACCDeclarativeConstruct);
  CharBlock source;
  std::variant<OpenACCStandaloneDeclarativeConstruct> u;
};

// OpenACC directives enclosing do loop
struct OpenACCLoopConstruct {
  TUPLE_CLASS_BOILERPLATE(OpenACCLoopConstruct);
  OpenACCLoopConstruct(AccBeginLoopDirective &&a)
      : t({std::move(a), std::nullopt}) {}
  std::tuple<AccBeginLoopDirective, std::optional<DoConstruct>> t;
};

struct OpenACCStandaloneConstruct {
  TUPLE_CLASS_BOILERPLATE(OpenACCStandaloneConstruct);
  CharBlock source;
  std::tuple<AccStandaloneDirective, AccClauseList> t;
};

struct OpenACCConstruct {
  UNION_CLASS_BOILERPLATE(OpenACCConstruct);
  std::variant<OpenACCBlockConstruct, OpenACCCombinedConstruct,
      OpenACCLoopConstruct, OpenACCStandaloneConstruct, OpenACCRoutineConstruct,
      OpenACCCacheConstruct, OpenACCWaitConstruct, OpenACCAtomicConstruct>
      u;
};

} // namespace Fortran::parser
#endif // FORTRAN_PARSER_PARSE_TREE_H_
+2 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ add_flang_library(FortranParser
  instrumented-parser.cpp
  io-parsers.cpp
  message.cpp
  openacc-parsers.cpp
  openmp-parsers.cpp
  parse-tree.cpp
  parsing.cpp
@@ -32,4 +33,5 @@ add_flang_library(FortranParser

  DEPENDS
  omp_gen
  acc_gen
)
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ constexpr auto executableConstruct{
        construct<ExecutableConstruct>(indirect(whereConstruct)),
        construct<ExecutableConstruct>(indirect(forallConstruct)),
        construct<ExecutableConstruct>(indirect(ompEndLoopDirective)),
        construct<ExecutableConstruct>(indirect(openaccConstruct)),
        construct<ExecutableConstruct>(indirect(openmpConstruct)),
        construct<ExecutableConstruct>(indirect(compilerDirective)))};

Loading