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