[OPENMP] Codegen for 'task_reduction' clause.
Added codegen for taskgroup directive with task_reduction clause.
```
<body>
```
The next code is emitted:
```
%struct.kmp_task_red_input_t red_init[n];
void *td;
call void @__kmpc_taskgroup(%ident_t id, i32 gtid)
...
red_init[i].shar = &<item>;
red_init[i].size = sizeof(<item>);
red_init[i].init = (void*)initializer_function;
red_init[i].fini = (void*)destructor_function;
red_init[i].comb = (void*)combiner_function;
red_init[i].flags = flags;
...
td = call i8* @__kmpc_task_reduction_init(i32 gtid, i32 n, i8*
(void*)red_init);
call void @__kmpc_end_taskgroup(%ident_t id, i32 gtid)
void initializer_function(i8* priv) {
*(<type>*)priv = <red_init>;
ret void;
}
void destructor_function(i8* priv) {
(<type>*)priv->~();
ret void;
}
void combiner_function(i8* inout, i8* in) {
*(<type>*)inout = *(<type>*)inout <red_id> *(<type>*)in;
ret void;
}
```
llvm-svn: 308979
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b12dfce..d3b0f46 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -129,6 +129,8 @@
bool CancelRegion = false;
unsigned AssociatedLoops = 1;
SourceLocation InnerTeamsRegionLoc;
+ /// Reference to the taskgroup task_reduction reference expression.
+ Expr *TaskgroupReductionRef = nullptr;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
: Directive(DKind), DirectiveName(Name), CurScope(CurScope),
@@ -244,10 +246,12 @@
/// Adds additional information for the reduction items with the reduction id
/// represented as an operator.
- void addReductionData(ValueDecl *D, SourceRange SR, BinaryOperatorKind BOK);
+ void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
+ BinaryOperatorKind BOK);
/// Adds additional information for the reduction items with the reduction id
/// represented as reduction identifier.
- void addReductionData(ValueDecl *D, SourceRange SR, const Expr *ReductionRef);
+ void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
+ const Expr *ReductionRef);
/// Returns the location and reduction operation from the innermost parent
/// region for the given \p D.
DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
@@ -256,6 +260,13 @@
/// region for the given \p D.
DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
const Expr *&ReductionRef);
+ /// Return reduction reference expression for the current taskgroup.
+ Expr *getTaskgroupReductionRef() const {
+ assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
+ "taskgroup reference expression requested for non taskgroup "
+ "directive.");
+ return Stack.back().first.back().TaskgroupReductionRef;
+ }
/// \brief Returns data sharing attributes from top of the stack for the
/// specified declaration.
@@ -745,8 +756,35 @@
}
}
-void DSAStackTy::addReductionData(ValueDecl *D, SourceRange SR,
- BinaryOperatorKind BOK) {
+/// \brief Build a variable declaration for OpenMP loop iteration variable.
+static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
+ StringRef Name, const AttrVec *Attrs = nullptr) {
+ DeclContext *DC = SemaRef.CurContext;
+ IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
+ TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
+ VarDecl *Decl =
+ VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
+ if (Attrs) {
+ for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
+ I != E; ++I)
+ Decl->addAttr(*I);
+ }
+ Decl->setImplicit();
+ return Decl;
+}
+
+static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
+ SourceLocation Loc,
+ bool RefersToCapture = false) {
+ D->setReferenced();
+ D->markUsed(S.Context);
+ return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
+ SourceLocation(), D, RefersToCapture, Loc, Ty,
+ VK_LValue);
+}
+
+void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
+ BinaryOperatorKind BOK) {
D = getCanonicalDecl(D);
assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
assert(
@@ -754,13 +792,22 @@
"Additional reduction info may be specified only for reduction items.");
auto &ReductionData = Stack.back().first.back().ReductionMap[D];
assert(ReductionData.ReductionRange.isInvalid() &&
+ Stack.back().first.back().Directive == OMPD_taskgroup &&
"Additional reduction info may be specified only once for reduction "
"items.");
ReductionData.set(BOK, SR);
+ Expr *&TaskgroupReductionRef =
+ Stack.back().first.back().TaskgroupReductionRef;
+ if (!TaskgroupReductionRef) {
+ auto *VD = buildVarDecl(SemaRef, SourceLocation(),
+ SemaRef.Context.VoidPtrTy, ".task_red.");
+ TaskgroupReductionRef = buildDeclRefExpr(
+ SemaRef, VD, SemaRef.Context.VoidPtrTy, SourceLocation());
+ }
}
-void DSAStackTy::addReductionData(ValueDecl *D, SourceRange SR,
- const Expr *ReductionRef) {
+void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
+ const Expr *ReductionRef) {
D = getCanonicalDecl(D);
assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
assert(
@@ -768,9 +815,18 @@
"Additional reduction info may be specified only for reduction items.");
auto &ReductionData = Stack.back().first.back().ReductionMap[D];
assert(ReductionData.ReductionRange.isInvalid() &&
+ Stack.back().first.back().Directive == OMPD_taskgroup &&
"Additional reduction info may be specified only once for reduction "
"items.");
ReductionData.set(ReductionRef, SR);
+ Expr *&TaskgroupReductionRef =
+ Stack.back().first.back().TaskgroupReductionRef;
+ if (!TaskgroupReductionRef) {
+ auto *VD = buildVarDecl(SemaRef, SourceLocation(),
+ SemaRef.Context.VoidPtrTy, ".task_red.");
+ TaskgroupReductionRef = buildDeclRefExpr(
+ SemaRef, VD, SemaRef.Context.VoidPtrTy, SourceLocation());
+ }
}
DSAStackTy::DSAVarData
@@ -841,33 +897,6 @@
return false;
}
-/// \brief Build a variable declaration for OpenMP loop iteration variable.
-static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
- StringRef Name, const AttrVec *Attrs = nullptr) {
- DeclContext *DC = SemaRef.CurContext;
- IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
- TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
- VarDecl *Decl =
- VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
- if (Attrs) {
- for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
- I != E; ++I)
- Decl->addAttr(*I);
- }
- Decl->setImplicit();
- return Decl;
-}
-
-static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
- SourceLocation Loc,
- bool RefersToCapture = false) {
- D->setReferenced();
- D->markUsed(S.Context);
- return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
- SourceLocation(), D, RefersToCapture, Loc, Ty,
- VK_LValue);
-}
-
DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) {
D = getCanonicalDecl(D);
DSAVarData DVar;
@@ -5194,7 +5223,8 @@
getCurFunction()->setHasBranchProtectedScope();
return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
- AStmt);
+ AStmt,
+ DSAStack->getTaskgroupReductionRef());
}
StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
@@ -9639,9 +9669,10 @@
Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
if (CurrDir == OMPD_taskgroup) {
if (DeclareReductionRef.isUsable())
- Stack->addReductionData(D, ReductionIdRange, DeclareReductionRef.get());
+ Stack->addTaskgroupReductionData(D, ReductionIdRange,
+ DeclareReductionRef.get());
else
- Stack->addReductionData(D, ReductionIdRange, BOK);
+ Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
}
RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get());
}