r308979 - [OPENMP] Codegen for 'task_reduction' clause.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 25 08:53:26 PDT 2017
Author: abataev
Date: Tue Jul 25 08:53:26 2017
New Revision: 308979
URL: http://llvm.org/viewvc/llvm-project?rev=308979&view=rev
Log:
[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;
}
```
Added:
cfe/trunk/test/OpenMP/taskgroup_task_reduction_codegen.cpp
Modified:
cfe/trunk/include/clang/AST/StmtOpenMP.h
cfe/trunk/lib/AST/StmtOpenMP.cpp
cfe/trunk/lib/AST/StmtProfile.cpp
cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=308979&r1=308978&r2=308979&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h Tue Jul 25 08:53:26 2017
@@ -1912,7 +1912,7 @@ class OMPTaskgroupDirective : public OMP
OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
- StartLoc, EndLoc, NumClauses, 1) {}
+ StartLoc, EndLoc, NumClauses, 2) {}
/// Build an empty directive.
/// \param NumClauses Number of clauses.
@@ -1920,7 +1920,12 @@ class OMPTaskgroupDirective : public OMP
explicit OMPTaskgroupDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
+ 2) {}
+
+ /// Sets the task_reduction return variable.
+ void setReductionRef(Expr *RR) {
+ *std::next(child_begin(), 1) = RR;
+ }
public:
/// Creates directive.
@@ -1930,10 +1935,12 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param ReductionRef Reference to the task_reduction return variable.
///
static OMPTaskgroupDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+ Expr *ReductionRef);
/// Creates an empty directive.
///
@@ -1943,6 +1950,15 @@ public:
static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
+
+ /// Returns reference to the task_reduction return variable.
+ const Expr *getReductionRef() const {
+ return static_cast<const Expr *>(*std::next(child_begin(), 1));
+ }
+ Expr *getReductionRef() {
+ return static_cast<Expr *>(*std::next(child_begin(), 1));
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskgroupDirectiveClass;
}
Modified: cfe/trunk/lib/AST/StmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtOpenMP.cpp?rev=308979&r1=308978&r2=308979&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtOpenMP.cpp (original)
+++ cfe/trunk/lib/AST/StmtOpenMP.cpp Tue Jul 25 08:53:26 2017
@@ -524,14 +524,15 @@ OMPTaskwaitDirective *OMPTaskwaitDirecti
OMPTaskgroupDirective *OMPTaskgroupDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef) {
unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective) +
sizeof(OMPClause *) * Clauses.size(),
alignof(Stmt *));
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ void *Mem = C.Allocate(Size + sizeof(Stmt *) + sizeof(Expr *));
OMPTaskgroupDirective *Dir =
new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc, Clauses.size());
Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setReductionRef(ReductionRef);
Dir->setClauses(Clauses);
return Dir;
}
@@ -542,7 +543,7 @@ OMPTaskgroupDirective *OMPTaskgroupDirec
unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective) +
sizeof(OMPClause *) * NumClauses,
alignof(Stmt *));
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ void *Mem = C.Allocate(Size + sizeof(Stmt *) + sizeof(Expr *));
return new (Mem) OMPTaskgroupDirective(NumClauses);
}
Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=308979&r1=308978&r2=308979&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Jul 25 08:53:26 2017
@@ -798,6 +798,8 @@ void StmtProfiler::VisitOMPTaskwaitDirec
void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
VisitOMPExecutableDirective(S);
+ if (const Expr *E = S->getReductionRef())
+ VisitStmt(E);
}
void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=308979&r1=308978&r2=308979&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Jul 25 08:53:26 2017
@@ -2864,6 +2864,35 @@ void CodeGenFunction::EmitOMPTaskgroupDi
const OMPTaskgroupDirective &S) {
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
Action.Enter(CGF);
+ if (const Expr *E = S.getReductionRef()) {
+ SmallVector<const Expr *, 4> LHSs;
+ SmallVector<const Expr *, 4> RHSs;
+ OMPTaskDataTy Data;
+ for (const auto *C : S.getClausesOfKind<OMPTaskReductionClause>()) {
+ auto IPriv = C->privates().begin();
+ auto IRed = C->reduction_ops().begin();
+ auto ILHS = C->lhs_exprs().begin();
+ auto IRHS = C->rhs_exprs().begin();
+ for (const auto *Ref : C->varlists()) {
+ Data.ReductionVars.emplace_back(Ref);
+ Data.ReductionCopies.emplace_back(*IPriv);
+ Data.ReductionOps.emplace_back(*IRed);
+ LHSs.emplace_back(*ILHS);
+ RHSs.emplace_back(*IRHS);
+ std::advance(IPriv, 1);
+ std::advance(IRed, 1);
+ std::advance(ILHS, 1);
+ std::advance(IRHS, 1);
+ }
+ }
+ llvm::Value *ReductionDesc =
+ CGF.CGM.getOpenMPRuntime().emitTaskReductionInit(CGF, S.getLocStart(),
+ LHSs, RHSs, Data);
+ const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
+ CGF.EmitVarDecl(*VD);
+ CGF.EmitStoreOfScalar(ReductionDesc, CGF.GetAddrOfLocalVar(VD),
+ /*Volatile=*/false, E->getType());
+ }
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
};
OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=308979&r1=308978&r2=308979&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Jul 25 08:53:26 2017
@@ -129,6 +129,8 @@ private:
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 @@ public:
/// 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 @@ public:
/// 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::addDSA(ValueDecl *D, Ex
}
}
-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 @@ void DSAStackTy::addReductionData(ValueD
"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 @@ void DSAStackTy::addReductionData(ValueD
"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 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *
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 @@ StmtResult Sema::ActOnOpenMPTaskgroupDir
getCurFunction()->setHasBranchProtectedScope();
return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
- AStmt);
+ AStmt,
+ DSAStack->getTaskgroupReductionRef());
}
StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
@@ -9639,9 +9669,10 @@ static bool ActOnOMPReductionKindClause(
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());
}
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=308979&r1=308978&r2=308979&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Jul 25 08:53:26 2017
@@ -2786,6 +2786,7 @@ void ASTStmtReader::VisitOMPTaskgroupDir
// The NumClauses field was read in ReadStmtFromStream.
Record.skipInts(1);
VisitOMPExecutableDirective(D);
+ D->setReductionRef(Record.readSubExpr());
}
void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=308979&r1=308978&r2=308979&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Jul 25 08:53:26 2017
@@ -2480,6 +2480,7 @@ void ASTStmtWriter::VisitOMPTaskgroupDir
VisitStmt(D);
Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D);
+ Record.AddStmt(D->getReductionRef());
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
}
Added: cfe/trunk/test/OpenMP/taskgroup_task_reduction_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/taskgroup_task_reduction_codegen.cpp?rev=308979&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/taskgroup_task_reduction_codegen.cpp (added)
+++ cfe/trunk/test/OpenMP/taskgroup_task_reduction_codegen.cpp Tue Jul 25 08:53:26 2017
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct S {
+ int a;
+ S() : a(0) {}
+ S(const S&) {}
+ S& operator=(const S&) {return *this;}
+ ~S() {}
+ friend S operator+(const S&a, const S&b) {return a;}
+};
+
+
+int main(int argc, char **argv) {
+ int a;
+ float b;
+ S c[5];
+ short d[argc];
+#pragma omp taskgroup task_reduction(+: a, b, argc)
+ {
+#pragma omp taskgroup task_reduction(-:c, d)
+ ;
+ }
+ return 0;
+}
+// CHECK-LABEL: @main
+// CHECK: alloca i32,
+// CHECK: [[ARGC_ADDR:%.+]] = alloca i32,
+// CHECK: [[ARGV_ADDR:%.+]] = alloca i8**,
+// CHECK: [[A:%.+]] = alloca i32,
+// CHECK: [[B:%.+]] = alloca float,
+// CHECK: [[C:%.+]] = alloca [5 x %struct.S],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* @0)
+// CHECK: [[RD_IN1:%.+]] = alloca [3 x [[T1:%[^,]+]]],
+// CHECK: [[TD1:%.+]] = alloca i8*,
+// CHECK: [[RD_IN2:%.+]] = alloca [2 x [[T2:%[^,]+]]],
+// CHECK: [[TD2:%.+]] = alloca i8*,
+
+// CHECK: [[VLA:%.+]] = alloca i16, i64 [[VLA_SIZE:%[^,]+]],
+
+// CHECK: call void @__kmpc_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK-DAG: [[BC_A:%.+]] = bitcast i32* [[A]] to i8*
+// CHECK-DAG: store i8* [[BC_A]], i8** [[A_REF:[^,]+]],
+// CHECK-DAG: [[A_REF]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPA]] = getelementptr inbounds [3 x [[T1]]], [3 x [[T1]]]* [[RD_IN1]], i64 0, i64
+// CHECK-DAG: [[TMP6:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP6]],
+// CHECK-DAG: [[TMP7:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[AINIT:@.+]] to i8*), i8** [[TMP7]],
+// CHECK-DAG: [[TMP8:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP8]],
+// CHECK-DAG: [[TMP9:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[ACOMB:@.+]] to i8*), i8** [[TMP9]],
+// CHECK-DAG: [[TMP10:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 5
+// CHECK-DAG: [[TMP11:%.+]] = bitcast i32* [[TMP10]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP11]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP13:%.+]] = bitcast float* [[B]] to i8*
+// CHECK-DAG: store i8* [[TMP13]], i8** [[TMP12:%[^,]+]],
+// CHECK-DAG: [[TMP12]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPB]] = getelementptr inbounds [3 x [[T1]]], [3 x [[T1]]]* [[RD_IN1]], i64 0, i64
+// CHECK-DAG: [[TMP14:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP14]],
+// CHECK-DAG: [[TMP15:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[BINIT:@.+]] to i8*), i8** [[TMP15]],
+// CHECK-DAG: [[TMP16:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP16]],
+// CHECK-DAG: [[TMP17:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[BCOMB:@.+]] to i8*), i8** [[TMP17]],
+// CHECK-DAG: [[TMP18:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 5
+// CHECK-DAG: [[TMP19:%.+]] = bitcast i32* [[TMP18]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP19]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP21:%.+]] = bitcast i32* [[ARGC_ADDR]] to i8*
+// CHECK-DAG: store i8* [[TMP21]], i8** [[TMP20:%[^,]+]],
+// CHECK-DAG: [[TMP20]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPARGC]] = getelementptr inbounds [3 x [[T1]]], [3 x [[T1]]]* [[RD_IN1]], i64 0, i64
+// CHECK-DAG: [[TMP22:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP22]],
+// CHECK-DAG: [[TMP23:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[ARGCINIT:@.+]] to i8*), i8** [[TMP23]],
+// CHECK-DAG: [[TMP24:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP24]],
+// CHECK-DAG: [[TMP25:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[ARGCCOMB:@.+]] to i8*), i8** [[TMP25]],
+// CHECK-DAG: [[TMP26:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 5
+// CHECK-DAG: [[TMP27:%.+]] = bitcast i32* [[TMP26]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP27]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP28:%.+]] = bitcast [3 x [[T1]]]* [[RD_IN1]] to i8*
+// CHECK-DAG: [[TMP29:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 3, i8* [[TMP28]])
+// CHECK-DAG: store i8* [[TMP29]], i8** [[TD1]],
+// CHECK-DAG: call void @__kmpc_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK-DAG: [[TMP31:%.+]] = bitcast [5 x %struct.S]* [[C]] to i8*
+// CHECK-DAG: store i8* [[TMP31]], i8** [[TMP30:%[^,]+]],
+// CHECK-DAG: [[TMP30]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPC]] = getelementptr inbounds [2 x [[T2]]], [2 x [[T2]]]* [[RD_IN2]], i64 0, i64
+// CHECK-DAG: [[TMP32:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 1
+// CHECK-DAG: store i64 20, i64* [[TMP32]],
+// CHECK-DAG: [[TMP33:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[CINIT:@.+]] to i8*), i8** [[TMP33]],
+// CHECK-DAG: [[TMP34:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 3
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[CFINI:@.+]] to i8*), i8** [[TMP34]],
+// CHECK-DAG: [[TMP35:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[CCOMB:@.+]] to i8*), i8** [[TMP35]],
+// CHECK-DAG: [[TMP36:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 5
+// CHECK-DAG: [[TMP37:%.+]] = bitcast i32* [[TMP36]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP37]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP39:%.+]] = bitcast i16* [[VLA]] to i8*
+// CHECK-DAG: store i8* [[TMP39]], i8** [[TMP38:%[^,]+]],
+// CHECK-DAG: [[TMP38]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPVLA]] = getelementptr inbounds [2 x [[T2]]], [2 x [[T2]]]* [[RD_IN2]], i64 0, i64
+// CHECK-DAG: [[TMP40:%.+]] = mul nuw i64 [[VLA_SIZE]], 2
+// CHECK-DAG: [[TMP41:%.+]] = udiv exact i64 [[TMP40]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64)
+// CHECK-DAG: [[TMP42:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 1
+// CHECK-DAG: store i64 [[TMP40]], i64* [[TMP42]],
+// CHECK-DAG: [[TMP43:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[VLAINIT:@.+]] to i8*), i8** [[TMP43]],
+// CHECK-DAG: [[TMP44:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP44]],
+// CHECK-DAG: [[TMP45:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[VLACOMB:@.+]] to i8*), i8** [[TMP45]],
+// CHECK-DAG: [[TMP46:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 5
+// CHECK-DAG: store i32 1, i32* [[TMP46]],
+// CHECK: [[TMP47:%.+]] = bitcast [2 x [[T2]]]* [[RD_IN2]] to i8*
+// CHECK: [[TMP48:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 2, i8* [[TMP47]])
+// CHECK: store i8* [[TMP48]], i8** [[TD2]],
+// CHECK: call void @__kmpc_end_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK: call void @__kmpc_end_taskgroup(%ident_t* @0, i32 [[GTID]])
+
+// CHECK-DAG: define internal void [[AINIT]](i8*)
+// CHECK-DAG: store i32 0, i32* %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[ACOMB]](i8*, i8*)
+// CHECK-DAG: add nsw i32 %
+// CHECK-DAG: store i32 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[BINIT]](i8*)
+// CHECK-DAG: store float 0.000000e+00, float* %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[BCOMB]](i8*, i8*)
+// CHECK-DAG: fadd float %
+// CHECK-DAG: store float %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[ARGCINIT]](i8*)
+// CHECK-DAG: store i32 0, i32* %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[ARGCCOMB]](i8*, i8*)
+// CHECK-DAG: add nsw i32 %
+// CHECK-DAG: store i32 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[CINIT]](i8*)
+// CHECK-DAG: phi %struct.S* [
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}})
+// CHECK-DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[CFINI]](i8*)
+// CHECK-DAG: phi %struct.S* [
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}})
+// CHECK-DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[CCOMB]](i8*, i8*)
+// CHECK-DAG: phi %struct.S* [
+// CHECK-DAG: phi %struct.S* [
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}}, %struct.S* {{.+}}, %struct.S* {{.+}})
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}}, %struct.S* {{.+}})
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}})
+// CHECK-DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK_DAG: }
+
+// CHECK-DAG: define internal void [[VLAINIT]](i8*)
+// CHECK-DAG: call i32 @__kmpc_global_thread_num(%ident_t* @0)
+// CHECK-DAG: call i8* @__kmpc_threadprivate_cached(%ident_t* @0, i32 %
+// CHECK-DAG: phi i16* [
+// CHECK-DAG: store i16 0, i16* %
+// CHECK-DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[VLACOMB]](i8*, i8*)
+// CHECK-DAG: call i32 @__kmpc_global_thread_num(%ident_t* @0)
+// CHECK-DAG: call i8* @__kmpc_threadprivate_cached(%ident_t* @0, i32 %
+// CHECK-DAG: phi i16* [
+// CHECK-DAG: phi i16* [
+// CHECK-DAG: sext i16 %{{.+}} to i32
+// CHECK-DAG: add nsw i32 %
+// CHECK-DAG: trunc i32 %{{.+}} to i16
+// CHECK-DAG: store i16 %
+// CHECK_DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+#endif
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=308979&r1=308978&r2=308979&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Jul 25 08:53:26 2017
@@ -2755,6 +2755,8 @@ void EnqueueVisitor::VisitOMPTaskwaitDir
void EnqueueVisitor::VisitOMPTaskgroupDirective(
const OMPTaskgroupDirective *D) {
VisitOMPExecutableDirective(D);
+ if (const Expr *E = D->getReductionRef())
+ VisitStmt(E);
}
void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
More information about the cfe-commits
mailing list