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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits