Skip to content

Commit 8bbcdae

Browse files
kparzysztblah
authored andcommitted
[flang][OpenMP] Implement OpenMP stylized expressions (llvm#165049)
Consider OpenMP stylized expression to be a template to be instantiated with a series of types listed on the containing directive (currently DECLARE_REDUCTION). Create a series of instantiations in the parser, allowing OpenMP special variables to be declared separately for each type. --------- Co-authored-by: Tom Eccles <[email protected]>
1 parent 2b5ce82 commit 8bbcdae

24 files changed

+812
-234
lines changed

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ class ParseTreeDumper {
599599
NODE(parser, OmpInitClause)
600600
NODE(OmpInitClause, Modifier)
601601
NODE(parser, OmpInitializerClause)
602-
NODE(parser, OmpInitializerProc)
602+
NODE(parser, OmpInitializerExpression)
603603
NODE(parser, OmpInReductionClause)
604604
NODE(OmpInReductionClause, Modifier)
605605
NODE(parser, OmpInteropPreference)
@@ -677,6 +677,10 @@ class ParseTreeDumper {
677677
NODE_ENUM(OmpSeverityClause, Severity)
678678
NODE(parser, OmpStepComplexModifier)
679679
NODE(parser, OmpStepSimpleModifier)
680+
NODE(parser, OmpStylizedDeclaration)
681+
NODE(parser, OmpStylizedExpression)
682+
NODE(parser, OmpStylizedInstance)
683+
NODE(OmpStylizedInstance, Instance)
680684
NODE(parser, OmpTaskDependenceType)
681685
NODE_ENUM(OmpTaskDependenceType, Value)
682686
NODE(parser, OmpTaskReductionClause)

flang/include/flang/Parser/openmp-utils.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525

2626
namespace Fortran::parser::omp {
2727

28+
template <typename T> constexpr auto addr_if(std::optional<T> &x) {
29+
return x ? &*x : nullptr;
30+
}
31+
template <typename T> constexpr auto addr_if(const std::optional<T> &x) {
32+
return x ? &*x : nullptr;
33+
}
34+
2835
namespace detail {
2936
using D = llvm::omp::Directive;
3037

@@ -133,9 +140,24 @@ template <typename T> OmpDirectiveName GetOmpDirectiveName(const T &x) {
133140
}
134141

135142
const OmpObjectList *GetOmpObjectList(const OmpClause &clause);
143+
144+
template <typename T>
145+
const T *GetFirstArgument(const OmpDirectiveSpecification &spec) {
146+
for (const OmpArgument &arg : spec.Arguments().v) {
147+
if (auto *t{std::get_if<T>(&arg.u)}) {
148+
return t;
149+
}
150+
}
151+
return nullptr;
152+
}
153+
136154
const BlockConstruct *GetFortranBlockConstruct(
137155
const ExecutionPartConstruct &epc);
138156

157+
const OmpCombinerExpression *GetCombinerExpr(
158+
const OmpReductionSpecifier &rspec);
159+
const OmpInitializerExpression *GetInitializerExpr(const OmpClause &init);
160+
139161
} // namespace Fortran::parser::omp
140162

141163
#endif // FORTRAN_PARSER_OPENMP_UTILS_H

flang/include/flang/Parser/parse-tree.h

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
#include "provenance.h"
2525
#include "flang/Common/idioms.h"
2626
#include "flang/Common/indirection.h"
27+
#include "flang/Common/reference.h"
2728
#include "flang/Support/Fortran.h"
29+
#include "llvm/ADT/ArrayRef.h"
2830
#include "llvm/Frontend/OpenACC/ACC.h.inc"
2931
#include "llvm/Frontend/OpenMP/OMP.h"
3032
#include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -3510,6 +3512,8 @@ struct OmpDirectiveName {
35103512

35113513
// type-name list item
35123514
struct OmpTypeName {
3515+
CharBlock source;
3516+
mutable const semantics::DeclTypeSpec *declTypeSpec{nullptr};
35133517
UNION_CLASS_BOILERPLATE(OmpTypeName);
35143518
std::variant<TypeSpec, DeclarationTypeSpec> u;
35153519
};
@@ -3538,6 +3542,39 @@ struct OmpObjectList {
35383542
WRAPPER_CLASS_BOILERPLATE(OmpObjectList, std::list<OmpObject>);
35393543
};
35403544

3545+
struct OmpStylizedDeclaration {
3546+
COPY_AND_ASSIGN_BOILERPLATE(OmpStylizedDeclaration);
3547+
// Since "Reference" isn't handled by parse-tree-visitor, add EmptyTrait,
3548+
// and visit the members by hand when needed.
3549+
using EmptyTrait = std::true_type;
3550+
common::Reference<const OmpTypeName> type;
3551+
EntityDecl var;
3552+
};
3553+
3554+
struct OmpStylizedInstance {
3555+
struct Instance {
3556+
UNION_CLASS_BOILERPLATE(Instance);
3557+
std::variant<AssignmentStmt, CallStmt, common::Indirection<Expr>> u;
3558+
};
3559+
TUPLE_CLASS_BOILERPLATE(OmpStylizedInstance);
3560+
std::tuple<std::list<OmpStylizedDeclaration>, Instance> t;
3561+
};
3562+
3563+
class ParseState;
3564+
3565+
// Ref: [5.2:76], [6.0:185]
3566+
//
3567+
struct OmpStylizedExpression {
3568+
CharBlock source;
3569+
// Pointer to a temporary copy of the ParseState that is used to create
3570+
// additional parse subtrees for the stylized expression. This is only
3571+
// used internally during parsing and conveys no information to the
3572+
// consumers of the AST.
3573+
const ParseState *state{nullptr};
3574+
WRAPPER_CLASS_BOILERPLATE(
3575+
OmpStylizedExpression, std::list<OmpStylizedInstance>);
3576+
};
3577+
35413578
// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
35423579
//
35433580
// reduction-identifier ->
@@ -3555,9 +3592,22 @@ struct OmpReductionIdentifier {
35553592
// combiner-expression -> // since 4.5
35563593
// assignment-statement |
35573594
// function-reference
3558-
struct OmpCombinerExpression {
3559-
UNION_CLASS_BOILERPLATE(OmpCombinerExpression);
3560-
std::variant<AssignmentStmt, FunctionReference> u;
3595+
struct OmpCombinerExpression : public OmpStylizedExpression {
3596+
INHERITED_WRAPPER_CLASS_BOILERPLATE(
3597+
OmpCombinerExpression, OmpStylizedExpression);
3598+
static llvm::ArrayRef<CharBlock> Variables();
3599+
};
3600+
3601+
// Ref: [4.5:222:7-8], [5.0:305:28-29], [5.1:337:20-21], [5.2:127:6-8],
3602+
// [6.0:242:3-5]
3603+
//
3604+
// initializer-expression -> // since 4.5
3605+
// OMP_PRIV = expression |
3606+
// subroutine-name(argument-list)
3607+
struct OmpInitializerExpression : public OmpStylizedExpression {
3608+
INHERITED_WRAPPER_CLASS_BOILERPLATE(
3609+
OmpInitializerExpression, OmpStylizedExpression);
3610+
static llvm::ArrayRef<CharBlock> Variables();
35613611
};
35623612

35633613
inline namespace arguments {
@@ -4558,16 +4608,9 @@ struct OmpInReductionClause {
45584608
std::tuple<MODIFIERS(), OmpObjectList> t;
45594609
};
45604610

4561-
// declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
4562-
// : combiner) [initializer-clause]
4563-
struct OmpInitializerProc {
4564-
TUPLE_CLASS_BOILERPLATE(OmpInitializerProc);
4565-
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
4566-
};
45674611
// Initialization for declare reduction construct
45684612
struct OmpInitializerClause {
4569-
UNION_CLASS_BOILERPLATE(OmpInitializerClause);
4570-
std::variant<OmpInitializerProc, AssignmentStmt> u;
4613+
WRAPPER_CLASS_BOILERPLATE(OmpInitializerClause, OmpInitializerExpression);
45714614
};
45724615

45734616
// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]

flang/include/flang/Semantics/symbol.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,8 @@ class Symbol {
830830
OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
831831
// OpenMP data-copying attribute
832832
OmpCopyIn, OmpCopyPrivate,
833+
// OpenMP special variables
834+
OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
833835
// OpenMP miscellaneous flags
834836
OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned, OmpNontemporal,
835837
OmpAllocate, OmpDeclarativeAllocateDirective,

0 commit comments

Comments
 (0)