Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 4ee889a

Browse files
committed
[OPENMP 4.0] Initial support for 'omp declare reduction' construct.
Add parsing, sema analysis and serialization/deserialization for 'declare reduction' construct. User-defined reductions are defined as #pragma omp declare reduction( reduction-identifier : typename-list : combiner ) [initializer ( initializer-expr )] These custom reductions may be used in 'reduction' clauses of OpenMP constructs. The combiner specifies how partial results can be combined into a single value. The combiner can use the special variable identifiers omp_in and omp_out that are of the type of the variables being reduced with this reduction-identifier. Each of them will denote one of the values to be combined before executing the combiner. It is assumed that the special omp_out identifier will refer to the storage that holds the resulting combined value after executing the combiner. As the initializer-expr value of a user-defined reduction is not known a priori the initializer-clause can be used to specify one. Then the contents of the initializer-clause will be used as the initializer for private copies of reduction list items where the omp_priv identifier will refer to the storage to be initialized. The special identifier omp_orig can also appear in the initializer-clause and it will refer to the storage of the original variable to be reduced. Differential Revision: http://reviews.llvm.org/D11182 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@262582 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent af3eb28 commit 4ee889a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1150
-26
lines changed

Diff for: include/clang/AST/DeclBase.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,10 @@ class Decl {
166166
/// has been declared outside any function. These act mostly like
167167
/// invisible friend declarations, but are also visible to unqualified
168168
/// lookup within the scope of the declaring function.
169-
IDNS_LocalExtern = 0x0800
169+
IDNS_LocalExtern = 0x0800,
170+
171+
/// This declaration is an OpenMP user defined reduction construction.
172+
IDNS_OMPReduction = 0x1000
170173
};
171174

172175
/// ObjCDeclQualifier - 'Qualifiers' written next to the return and
@@ -256,7 +259,7 @@ class Decl {
256259
SourceLocation Loc;
257260

258261
/// DeclKind - This indicates which class this is.
259-
unsigned DeclKind : 8;
262+
unsigned DeclKind : 7;
260263

261264
/// InvalidDecl - This indicates a semantic error occurred.
262265
unsigned InvalidDecl : 1;
@@ -296,7 +299,7 @@ class Decl {
296299
unsigned Hidden : 1;
297300

298301
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
299-
unsigned IdentifierNamespace : 12;
302+
unsigned IdentifierNamespace : 13;
300303

301304
/// \brief If 0, we have not computed the linkage of this declaration.
302305
/// Otherwise, it is the linkage + 1.
@@ -1117,6 +1120,7 @@ class DeclContextLookupResult {
11171120
/// ObjCContainerDecl
11181121
/// LinkageSpecDecl
11191122
/// BlockDecl
1123+
/// OMPDeclareReductionDecl
11201124
///
11211125
class DeclContext {
11221126
/// DeclKind - This indicates which class this is.

Diff for: include/clang/AST/DeclCXX.h

+8
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,14 @@ class CXXRecordDecl : public RecordDecl {
15701570
static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
15711571
CXXBasePath &Path, DeclarationName Name);
15721572

1573+
/// \brief Base-class lookup callback that determines whether there exists
1574+
/// an OpenMP declare reduction member with the given name.
1575+
///
1576+
/// This callback can be used with \c lookupInBases() to find members
1577+
/// of the given name within a C++ class hierarchy.
1578+
static bool FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
1579+
CXXBasePath &Path, DeclarationName Name);
1580+
15731581
/// \brief Base-class lookup callback that determines whether there exists
15741582
/// a member with the given name that can be used in a nested-name-specifier.
15751583
///

Diff for: include/clang/AST/DeclOpenMP.h

+81-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
#ifndef LLVM_CLANG_AST_DECLOPENMP_H
1616
#define LLVM_CLANG_AST_DECLOPENMP_H
1717

18-
#include "clang/AST/DeclBase.h"
18+
#include "clang/AST/Decl.h"
19+
#include "clang/AST/Expr.h"
20+
#include "clang/AST/ExternalASTSource.h"
21+
#include "clang/AST/Type.h"
1922
#include "llvm/ADT/ArrayRef.h"
2023
#include "llvm/Support/TrailingObjects.h"
2124

2225
namespace clang {
23-
class Expr;
2426

2527
/// \brief This represents '#pragma omp threadprivate ...' directive.
2628
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
@@ -87,6 +89,83 @@ class OMPThreadPrivateDecl final
8789
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
8890
};
8991

92+
/// \brief This represents '#pragma omp declare reduction ...' directive.
93+
/// For example, in the following, declared reduction 'foo' for types 'int' and
94+
/// 'float':
95+
///
96+
/// \code
97+
/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \
98+
/// initializer (omp_priv = 0)
99+
/// \endcode
100+
///
101+
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
102+
class OMPDeclareReductionDecl final : public NamedDecl, public DeclContext {
103+
private:
104+
friend class ASTDeclReader;
105+
/// \brief Combiner for declare reduction construct.
106+
Expr *Combiner;
107+
/// \brief Initializer for declare reduction construct.
108+
Expr *Initializer;
109+
/// \brief Reference to the previous declare reduction construct in the same
110+
/// scope with the same name. Required for proper templates instantiation if
111+
/// the declare reduction construct is declared inside compound statement.
112+
LazyDeclPtr PrevDeclInScope;
113+
/// \brief Type of declare reduction construct.
114+
QualType Ty;
115+
116+
virtual void anchor();
117+
118+
OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
119+
DeclarationName Name, QualType Ty,
120+
OMPDeclareReductionDecl *PrevDeclInScope)
121+
: NamedDecl(DK, DC, L, Name), DeclContext(DK), Combiner(nullptr),
122+
Initializer(nullptr), PrevDeclInScope(PrevDeclInScope), Ty(Ty) {}
123+
124+
void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
125+
PrevDeclInScope = Prev;
126+
}
127+
void setType(QualType T) { Ty = T; }
128+
129+
public:
130+
/// \brief Create declare reduction node.
131+
static OMPDeclareReductionDecl *
132+
Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
133+
QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
134+
/// \brief Create deserialized declare reduction node.
135+
static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
136+
unsigned ID);
137+
138+
/// \brief Get combiner expression of the declare reduction construct.
139+
Expr *getCombiner() { return Combiner; }
140+
const Expr *getCombiner() const { return Combiner; }
141+
/// \brief Set combiner expression for the declare reduction construct.
142+
void setCombiner(Expr *E) { Combiner = E; }
143+
144+
/// \brief Get initializer expression (if specified) of the declare reduction
145+
/// construct.
146+
Expr *getInitializer() { return Initializer; }
147+
const Expr *getInitializer() const { return Initializer; }
148+
/// \brief Set initializer expression for the declare reduction construct.
149+
void setInitializer(Expr *E) { Initializer = E; }
150+
151+
/// \brief Get reference to previous declare reduction construct in the same
152+
/// scope with the same name.
153+
OMPDeclareReductionDecl *getPrevDeclInScope();
154+
const OMPDeclareReductionDecl *getPrevDeclInScope() const;
155+
156+
QualType getType() const { return Ty; }
157+
158+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
159+
static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
160+
static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
161+
return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
162+
}
163+
static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
164+
return static_cast<OMPDeclareReductionDecl *>(
165+
const_cast<DeclContext *>(DC));
166+
}
167+
};
168+
90169
/// Pseudo declaration for capturing expressions. Also is used for capturing of
91170
/// non-static data members in non-static member functions.
92171
///

Diff for: include/clang/AST/RecursiveASTVisitor.h

+8
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,14 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
14671467
}
14681468
})
14691469

1470+
DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
1471+
TRY_TO(TraverseStmt(D->getCombiner()));
1472+
if (auto *Initializer = D->getInitializer())
1473+
TRY_TO(TraverseStmt(Initializer));
1474+
TRY_TO(TraverseType(D->getType()));
1475+
return true;
1476+
})
1477+
14701478
DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
14711479

14721480
// A helper method for TemplateDecl's children.

Diff for: include/clang/Basic/DeclNodes.td

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def Named : Decl<1>;
7575
def ObjCImplementation : DDecl<ObjCImpl>;
7676
def ObjCProperty : DDecl<Named>;
7777
def ObjCCompatibleAlias : DDecl<Named>;
78+
def OMPDeclareReduction : DDecl<Named>, DeclContext;
7879
def LinkageSpec : Decl, DeclContext;
7980
def ObjCPropertyImpl : Decl;
8081
def FileScopeAsm : Decl;

Diff for: include/clang/Basic/DiagnosticParseKinds.td

+2
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,8 @@ def err_omp_immediate_directive : Error<
939939
"'#pragma omp %0' %select{|with '%2' clause }1cannot be an immediate substatement">;
940940
def err_omp_expected_identifier_for_critical : Error<
941941
"expected identifier specifying the name of the 'omp critical' directive">;
942+
def err_omp_expected_reduction_identifier : Error<
943+
"expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'">;
942944
def err_omp_unknown_map_type : Error<
943945
"incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">;
944946
def err_omp_unknown_map_type_modifier : Error<

Diff for: include/clang/Basic/DiagnosticSemaKinds.td

+3
Original file line numberDiff line numberDiff line change
@@ -7992,6 +7992,9 @@ def err_omp_parent_cancel_region_nowait : Error<
79927992
"parent region for 'omp %select{cancellation point/cancel}0' construct cannot be nowait">;
79937993
def err_omp_parent_cancel_region_ordered : Error<
79947994
"parent region for 'omp %select{cancellation point/cancel}0' construct cannot be ordered">;
7995+
def err_omp_reduction_wrong_type : Error<"reduction type cannot be %select{qualified with 'const', 'volatile' or 'restrict'|a function|a reference|an array}0 type">;
7996+
def err_omp_wrong_var_in_declare_reduction : Error<"only %select{'omp_priv' or 'omp_orig'|'omp_in' or 'omp_out'}0 variables are allowed in %select{initializer|combiner}0 expression">;
7997+
def err_omp_declare_reduction_redefinition : Error<"redefinition of user-defined reduction for type %0">;
79957998
def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">;
79967999
def err_omp_typecheck_section_value : Error<
79978000
"subscripted value is not an array or pointer">;

Diff for: include/clang/Basic/OpenMPKinds.def

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ OPENMP_DIRECTIVE_EXT(parallel_for_simd, "parallel for simd")
155155
OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
156156
OPENMP_DIRECTIVE_EXT(for_simd, "for simd")
157157
OPENMP_DIRECTIVE_EXT(cancellation_point, "cancellation point")
158+
OPENMP_DIRECTIVE_EXT(declare_reduction, "declare reduction")
158159
OPENMP_DIRECTIVE(taskloop)
159160
OPENMP_DIRECTIVE_EXT(taskloop_simd, "taskloop simd")
160161
OPENMP_DIRECTIVE(distribute)

Diff for: include/clang/Parse/Parser.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -2454,7 +2454,9 @@ class Parser : public CodeCompletionHandler {
24542454
//===--------------------------------------------------------------------===//
24552455
// OpenMP: Directives and clauses.
24562456
/// \brief Parses declarative OpenMP directives.
2457-
DeclGroupPtrTy ParseOpenMPDeclarativeDirective();
2457+
DeclGroupPtrTy ParseOpenMPDeclarativeDirective(AccessSpecifier AS);
2458+
/// \brief Parse 'omp declare reduction' construct.
2459+
DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
24582460
/// \brief Parses simple list of variables.
24592461
///
24602462
/// \param Kind Kind of the directive.

Diff for: include/clang/Sema/ScopeInfo.h

+8
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ class FunctionScopeInfo {
104104
/// \brief Whether a statement was dropped because it was invalid.
105105
bool HasDroppedStmt : 1;
106106

107+
/// \brief True if current scope is for OpenMP declare reduction combiner.
108+
bool HasOMPDeclareReductionCombiner;
109+
107110
/// A flag that is set when parsing a method that must call super's
108111
/// implementation, such as \c -dealloc, \c -finalize, or any method marked
109112
/// with \c __attribute__((objc_requires_super)).
@@ -341,6 +344,10 @@ class FunctionScopeInfo {
341344
HasDroppedStmt = true;
342345
}
343346

347+
void setHasOMPDeclareReductionCombiner() {
348+
HasOMPDeclareReductionCombiner = true;
349+
}
350+
344351
void setHasCXXTry(SourceLocation TryLoc) {
345352
setHasBranchProtectedScope();
346353
FirstCXXTryLoc = TryLoc;
@@ -363,6 +370,7 @@ class FunctionScopeInfo {
363370
HasBranchIntoScope(false),
364371
HasIndirectGoto(false),
365372
HasDroppedStmt(false),
373+
HasOMPDeclareReductionCombiner(false),
366374
ObjCShouldCallSuper(false),
367375
ObjCIsDesignatedInit(false),
368376
ObjCWarnForNoDesignatedInitChain(false),

Diff for: include/clang/Sema/Sema.h

+23
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ namespace clang {
145145
class ObjCPropertyDecl;
146146
class ObjCProtocolDecl;
147147
class OMPThreadPrivateDecl;
148+
class OMPDeclareReductionDecl;
148149
class OMPClause;
149150
struct OverloadCandidate;
150151
class OverloadCandidateSet;
@@ -2671,6 +2672,8 @@ class Sema {
26712672
LookupObjCProtocolName,
26722673
/// Look up implicit 'self' parameter of an objective-c method.
26732674
LookupObjCImplicitSelfParam,
2675+
/// \brief Look up the name of an OpenMP user-defined reduction operation.
2676+
LookupOMPReductionName,
26742677
/// \brief Look up any declaration with any name.
26752678
LookupAnyName
26762679
};
@@ -7872,6 +7875,26 @@ class Sema {
78727875
OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(
78737876
SourceLocation Loc,
78747877
ArrayRef<Expr *> VarList);
7878+
/// \brief Check if the specified type is allowed to be used in 'omp declare
7879+
/// reduction' construct.
7880+
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
7881+
TypeResult ParsedType);
7882+
/// \brief Called on start of '#pragma omp declare reduction'.
7883+
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(
7884+
Scope *S, DeclContext *DC, DeclarationName Name,
7885+
ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
7886+
AccessSpecifier AS, Decl *PrevDeclInScope = nullptr);
7887+
/// \brief Initialize declare reduction construct initializer.
7888+
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D);
7889+
/// \brief Finish current declare reduction construct initializer.
7890+
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner);
7891+
/// \brief Initialize declare reduction construct initializer.
7892+
void ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D);
7893+
/// \brief Finish current declare reduction construct initializer.
7894+
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer);
7895+
/// \brief Called at the end of '#pragma omp declare reduction'.
7896+
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(
7897+
Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid);
78757898

78767899
/// \brief Initialization of captured region for OpenMP region.
78777900
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);

Diff for: include/clang/Serialization/ASTBitCodes.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,9 @@ namespace clang {
11741174
/// \brief A PragmaCommentDecl record.
11751175
DECL_PRAGMA_COMMENT,
11761176
/// \brief A PragmaDetectMismatchDecl record.
1177-
DECL_PRAGMA_DETECT_MISMATCH
1177+
DECL_PRAGMA_DETECT_MISMATCH,
1178+
/// \brief An OMPDeclareReductionDecl record.
1179+
DECL_OMP_DECLARE_REDUCTION,
11781180
};
11791181

11801182
/// \brief Record codes for each kind of statement or expression.

Diff for: lib/AST/CXXInheritance.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,21 @@ bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
405405
return false;
406406
}
407407

408+
bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
409+
CXXBasePath &Path,
410+
DeclarationName Name) {
411+
RecordDecl *BaseRecord =
412+
Specifier->getType()->castAs<RecordType>()->getDecl();
413+
414+
for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty();
415+
Path.Decls = Path.Decls.slice(1)) {
416+
if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPReduction))
417+
return true;
418+
}
419+
420+
return false;
421+
}
422+
408423
bool CXXRecordDecl::
409424
FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
410425
CXXBasePath &Path,

Diff for: lib/AST/Decl.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/AST/Attr.h"
1919
#include "clang/AST/DeclCXX.h"
2020
#include "clang/AST/DeclObjC.h"
21+
#include "clang/AST/DeclOpenMP.h"
2122
#include "clang/AST/DeclTemplate.h"
2223
#include "clang/AST/Expr.h"
2324
#include "clang/AST/ExprCXX.h"

Diff for: lib/AST/DeclBase.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,9 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
633633
case TemplateTemplateParm:
634634
return IDNS_Ordinary | IDNS_Tag | IDNS_Type;
635635

636+
case OMPDeclareReduction:
637+
return IDNS_OMPReduction;
638+
636639
// Never have names.
637640
case Friend:
638641
case FriendTemplate:
@@ -963,6 +966,7 @@ DeclContext *DeclContext::getPrimaryContext() {
963966
case Decl::LinkageSpec:
964967
case Decl::Block:
965968
case Decl::Captured:
969+
case Decl::OMPDeclareReduction:
966970
// There is only one DeclContext for these entities.
967971
return this;
968972

Diff for: lib/AST/DeclOpenMP.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,36 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
5353
std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
5454
}
5555

56+
//===----------------------------------------------------------------------===//
57+
// OMPDeclareReductionDecl Implementation.
58+
//===----------------------------------------------------------------------===//
59+
60+
void OMPDeclareReductionDecl::anchor() {}
61+
62+
OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create(
63+
ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
64+
QualType T, OMPDeclareReductionDecl *PrevDeclInScope) {
65+
return new (C, DC) OMPDeclareReductionDecl(OMPDeclareReduction, DC, L, Name,
66+
T, PrevDeclInScope);
67+
}
68+
69+
OMPDeclareReductionDecl *
70+
OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
71+
return new (C, ID) OMPDeclareReductionDecl(
72+
OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(),
73+
QualType(), /*PrevDeclInScope=*/nullptr);
74+
}
75+
76+
OMPDeclareReductionDecl *OMPDeclareReductionDecl::getPrevDeclInScope() {
77+
return cast_or_null<OMPDeclareReductionDecl>(
78+
PrevDeclInScope.get(getASTContext().getExternalSource()));
79+
}
80+
const OMPDeclareReductionDecl *
81+
OMPDeclareReductionDecl::getPrevDeclInScope() const {
82+
return cast_or_null<OMPDeclareReductionDecl>(
83+
PrevDeclInScope.get(getASTContext().getExternalSource()));
84+
}
85+
5686
//===----------------------------------------------------------------------===//
5787
// OMPCapturedExprDecl Implementation.
5888
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)