Home | History | Annotate | Line # | Download | only in CodeGen
      1      1.1  joerg //===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
      2      1.1  joerg //
      3      1.1  joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4      1.1  joerg // See https://llvm.org/LICENSE.txt for license information.
      5      1.1  joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6      1.1  joerg //
      7      1.1  joerg //===----------------------------------------------------------------------===//
      8      1.1  joerg //
      9      1.1  joerg // This contains code to emit OpenMP nodes as LLVM code.
     10      1.1  joerg //
     11      1.1  joerg //===----------------------------------------------------------------------===//
     12      1.1  joerg 
     13      1.1  joerg #include "CGCleanup.h"
     14      1.1  joerg #include "CGOpenMPRuntime.h"
     15      1.1  joerg #include "CodeGenFunction.h"
     16      1.1  joerg #include "CodeGenModule.h"
     17      1.1  joerg #include "TargetInfo.h"
     18  1.1.1.2  joerg #include "clang/AST/ASTContext.h"
     19  1.1.1.2  joerg #include "clang/AST/Attr.h"
     20  1.1.1.2  joerg #include "clang/AST/DeclOpenMP.h"
     21  1.1.1.2  joerg #include "clang/AST/OpenMPClause.h"
     22      1.1  joerg #include "clang/AST/Stmt.h"
     23      1.1  joerg #include "clang/AST/StmtOpenMP.h"
     24  1.1.1.2  joerg #include "clang/AST/StmtVisitor.h"
     25  1.1.1.2  joerg #include "clang/Basic/OpenMPKinds.h"
     26  1.1.1.2  joerg #include "clang/Basic/PrettyStackTrace.h"
     27  1.1.1.2  joerg #include "llvm/Frontend/OpenMP/OMPConstants.h"
     28  1.1.1.2  joerg #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
     29  1.1.1.2  joerg #include "llvm/IR/Constants.h"
     30  1.1.1.2  joerg #include "llvm/IR/Instructions.h"
     31  1.1.1.2  joerg #include "llvm/Support/AtomicOrdering.h"
     32      1.1  joerg using namespace clang;
     33      1.1  joerg using namespace CodeGen;
     34  1.1.1.2  joerg using namespace llvm::omp;
     35  1.1.1.2  joerg 
     36  1.1.1.2  joerg static const VarDecl *getBaseDecl(const Expr *Ref);
     37      1.1  joerg 
     38      1.1  joerg namespace {
     39      1.1  joerg /// Lexical scope for OpenMP executable constructs, that handles correct codegen
     40      1.1  joerg /// for captured expressions.
     41      1.1  joerg class OMPLexicalScope : public CodeGenFunction::LexicalScope {
     42      1.1  joerg   void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
     43      1.1  joerg     for (const auto *C : S.clauses()) {
     44      1.1  joerg       if (const auto *CPI = OMPClauseWithPreInit::get(C)) {
     45      1.1  joerg         if (const auto *PreInit =
     46      1.1  joerg                 cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
     47      1.1  joerg           for (const auto *I : PreInit->decls()) {
     48      1.1  joerg             if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
     49      1.1  joerg               CGF.EmitVarDecl(cast<VarDecl>(*I));
     50      1.1  joerg             } else {
     51      1.1  joerg               CodeGenFunction::AutoVarEmission Emission =
     52      1.1  joerg                   CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
     53      1.1  joerg               CGF.EmitAutoVarCleanups(Emission);
     54      1.1  joerg             }
     55      1.1  joerg           }
     56      1.1  joerg         }
     57      1.1  joerg       }
     58      1.1  joerg     }
     59      1.1  joerg   }
     60      1.1  joerg   CodeGenFunction::OMPPrivateScope InlinedShareds;
     61      1.1  joerg 
     62      1.1  joerg   static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
     63      1.1  joerg     return CGF.LambdaCaptureFields.lookup(VD) ||
     64      1.1  joerg            (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
     65  1.1.1.2  joerg            (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) &&
     66  1.1.1.2  joerg             cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD));
     67      1.1  joerg   }
     68      1.1  joerg 
     69      1.1  joerg public:
     70      1.1  joerg   OMPLexicalScope(
     71      1.1  joerg       CodeGenFunction &CGF, const OMPExecutableDirective &S,
     72      1.1  joerg       const llvm::Optional<OpenMPDirectiveKind> CapturedRegion = llvm::None,
     73      1.1  joerg       const bool EmitPreInitStmt = true)
     74      1.1  joerg       : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
     75      1.1  joerg         InlinedShareds(CGF) {
     76      1.1  joerg     if (EmitPreInitStmt)
     77      1.1  joerg       emitPreInitStmt(CGF, S);
     78      1.1  joerg     if (!CapturedRegion.hasValue())
     79      1.1  joerg       return;
     80      1.1  joerg     assert(S.hasAssociatedStmt() &&
     81      1.1  joerg            "Expected associated statement for inlined directive.");
     82      1.1  joerg     const CapturedStmt *CS = S.getCapturedStmt(*CapturedRegion);
     83      1.1  joerg     for (const auto &C : CS->captures()) {
     84      1.1  joerg       if (C.capturesVariable() || C.capturesVariableByCopy()) {
     85      1.1  joerg         auto *VD = C.getCapturedVar();
     86      1.1  joerg         assert(VD == VD->getCanonicalDecl() &&
     87      1.1  joerg                "Canonical decl must be captured.");
     88      1.1  joerg         DeclRefExpr DRE(
     89      1.1  joerg             CGF.getContext(), const_cast<VarDecl *>(VD),
     90      1.1  joerg             isCapturedVar(CGF, VD) || (CGF.CapturedStmtInfo &&
     91      1.1  joerg                                        InlinedShareds.isGlobalVarCaptured(VD)),
     92      1.1  joerg             VD->getType().getNonReferenceType(), VK_LValue, C.getLocation());
     93      1.1  joerg         InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
     94  1.1.1.2  joerg           return CGF.EmitLValue(&DRE).getAddress(CGF);
     95      1.1  joerg         });
     96      1.1  joerg       }
     97      1.1  joerg     }
     98      1.1  joerg     (void)InlinedShareds.Privatize();
     99      1.1  joerg   }
    100      1.1  joerg };
    101      1.1  joerg 
    102      1.1  joerg /// Lexical scope for OpenMP parallel construct, that handles correct codegen
    103      1.1  joerg /// for captured expressions.
    104      1.1  joerg class OMPParallelScope final : public OMPLexicalScope {
    105      1.1  joerg   bool EmitPreInitStmt(const OMPExecutableDirective &S) {
    106      1.1  joerg     OpenMPDirectiveKind Kind = S.getDirectiveKind();
    107      1.1  joerg     return !(isOpenMPTargetExecutionDirective(Kind) ||
    108      1.1  joerg              isOpenMPLoopBoundSharingDirective(Kind)) &&
    109      1.1  joerg            isOpenMPParallelDirective(Kind);
    110      1.1  joerg   }
    111      1.1  joerg 
    112      1.1  joerg public:
    113      1.1  joerg   OMPParallelScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
    114      1.1  joerg       : OMPLexicalScope(CGF, S, /*CapturedRegion=*/llvm::None,
    115      1.1  joerg                         EmitPreInitStmt(S)) {}
    116      1.1  joerg };
    117      1.1  joerg 
    118      1.1  joerg /// Lexical scope for OpenMP teams construct, that handles correct codegen
    119      1.1  joerg /// for captured expressions.
    120      1.1  joerg class OMPTeamsScope final : public OMPLexicalScope {
    121      1.1  joerg   bool EmitPreInitStmt(const OMPExecutableDirective &S) {
    122      1.1  joerg     OpenMPDirectiveKind Kind = S.getDirectiveKind();
    123      1.1  joerg     return !isOpenMPTargetExecutionDirective(Kind) &&
    124      1.1  joerg            isOpenMPTeamsDirective(Kind);
    125      1.1  joerg   }
    126      1.1  joerg 
    127      1.1  joerg public:
    128      1.1  joerg   OMPTeamsScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
    129      1.1  joerg       : OMPLexicalScope(CGF, S, /*CapturedRegion=*/llvm::None,
    130      1.1  joerg                         EmitPreInitStmt(S)) {}
    131      1.1  joerg };
    132      1.1  joerg 
    133      1.1  joerg /// Private scope for OpenMP loop-based directives, that supports capturing
    134      1.1  joerg /// of used expression from loop statement.
    135      1.1  joerg class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {
    136  1.1.1.2  joerg   void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopBasedDirective &S) {
    137  1.1.1.2  joerg     const DeclStmt *PreInits;
    138      1.1  joerg     CodeGenFunction::OMPMapVars PreCondVars;
    139  1.1.1.2  joerg     if (auto *LD = dyn_cast<OMPLoopDirective>(&S)) {
    140  1.1.1.2  joerg       llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
    141  1.1.1.2  joerg       for (const auto *E : LD->counters()) {
    142  1.1.1.2  joerg         const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
    143  1.1.1.2  joerg         EmittedAsPrivate.insert(VD->getCanonicalDecl());
    144  1.1.1.2  joerg         (void)PreCondVars.setVarAddr(
    145  1.1.1.2  joerg             CGF, VD, CGF.CreateMemTemp(VD->getType().getNonReferenceType()));
    146  1.1.1.2  joerg       }
    147  1.1.1.2  joerg       // Mark private vars as undefs.
    148  1.1.1.2  joerg       for (const auto *C : LD->getClausesOfKind<OMPPrivateClause>()) {
    149  1.1.1.2  joerg         for (const Expr *IRef : C->varlists()) {
    150  1.1.1.2  joerg           const auto *OrigVD =
    151  1.1.1.2  joerg               cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
    152  1.1.1.2  joerg           if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
    153  1.1.1.2  joerg             (void)PreCondVars.setVarAddr(
    154  1.1.1.2  joerg                 CGF, OrigVD,
    155  1.1.1.2  joerg                 Address(llvm::UndefValue::get(CGF.ConvertTypeForMem(
    156  1.1.1.2  joerg                             CGF.getContext().getPointerType(
    157  1.1.1.2  joerg                                 OrigVD->getType().getNonReferenceType()))),
    158  1.1.1.2  joerg                         CGF.getContext().getDeclAlign(OrigVD)));
    159  1.1.1.2  joerg           }
    160      1.1  joerg         }
    161      1.1  joerg       }
    162  1.1.1.2  joerg       (void)PreCondVars.apply(CGF);
    163  1.1.1.2  joerg       // Emit init, __range and __end variables for C++ range loops.
    164  1.1.1.2  joerg       (void)OMPLoopBasedDirective::doForAllLoops(
    165  1.1.1.2  joerg           LD->getInnermostCapturedStmt()->getCapturedStmt(),
    166  1.1.1.2  joerg           /*TryImperfectlyNestedLoops=*/true, LD->getLoopsNumber(),
    167  1.1.1.2  joerg           [&CGF](unsigned Cnt, const Stmt *CurStmt) {
    168  1.1.1.2  joerg             if (const auto *CXXFor = dyn_cast<CXXForRangeStmt>(CurStmt)) {
    169  1.1.1.2  joerg               if (const Stmt *Init = CXXFor->getInit())
    170  1.1.1.2  joerg                 CGF.EmitStmt(Init);
    171  1.1.1.2  joerg               CGF.EmitStmt(CXXFor->getRangeStmt());
    172  1.1.1.2  joerg               CGF.EmitStmt(CXXFor->getEndStmt());
    173  1.1.1.2  joerg             }
    174  1.1.1.2  joerg             return false;
    175  1.1.1.2  joerg           });
    176  1.1.1.2  joerg       PreInits = cast_or_null<DeclStmt>(LD->getPreInits());
    177  1.1.1.2  joerg     } else if (const auto *Tile = dyn_cast<OMPTileDirective>(&S)) {
    178  1.1.1.2  joerg       PreInits = cast_or_null<DeclStmt>(Tile->getPreInits());
    179  1.1.1.2  joerg     } else {
    180  1.1.1.2  joerg       llvm_unreachable("Unknown loop-based directive kind.");
    181      1.1  joerg     }
    182  1.1.1.2  joerg     if (PreInits) {
    183      1.1  joerg       for (const auto *I : PreInits->decls())
    184      1.1  joerg         CGF.EmitVarDecl(cast<VarDecl>(*I));
    185      1.1  joerg     }
    186      1.1  joerg     PreCondVars.restore(CGF);
    187      1.1  joerg   }
    188      1.1  joerg 
    189      1.1  joerg public:
    190  1.1.1.2  joerg   OMPLoopScope(CodeGenFunction &CGF, const OMPLoopBasedDirective &S)
    191      1.1  joerg       : CodeGenFunction::RunCleanupsScope(CGF) {
    192      1.1  joerg     emitPreInitStmt(CGF, S);
    193      1.1  joerg   }
    194      1.1  joerg };
    195      1.1  joerg 
    196      1.1  joerg class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope {
    197      1.1  joerg   CodeGenFunction::OMPPrivateScope InlinedShareds;
    198      1.1  joerg 
    199      1.1  joerg   static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
    200      1.1  joerg     return CGF.LambdaCaptureFields.lookup(VD) ||
    201      1.1  joerg            (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
    202      1.1  joerg            (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) &&
    203      1.1  joerg             cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD));
    204      1.1  joerg   }
    205      1.1  joerg 
    206      1.1  joerg public:
    207      1.1  joerg   OMPSimdLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
    208      1.1  joerg       : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
    209      1.1  joerg         InlinedShareds(CGF) {
    210      1.1  joerg     for (const auto *C : S.clauses()) {
    211      1.1  joerg       if (const auto *CPI = OMPClauseWithPreInit::get(C)) {
    212      1.1  joerg         if (const auto *PreInit =
    213      1.1  joerg                 cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
    214      1.1  joerg           for (const auto *I : PreInit->decls()) {
    215      1.1  joerg             if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
    216      1.1  joerg               CGF.EmitVarDecl(cast<VarDecl>(*I));
    217      1.1  joerg             } else {
    218      1.1  joerg               CodeGenFunction::AutoVarEmission Emission =
    219      1.1  joerg                   CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
    220      1.1  joerg               CGF.EmitAutoVarCleanups(Emission);
    221      1.1  joerg             }
    222      1.1  joerg           }
    223      1.1  joerg         }
    224      1.1  joerg       } else if (const auto *UDP = dyn_cast<OMPUseDevicePtrClause>(C)) {
    225      1.1  joerg         for (const Expr *E : UDP->varlists()) {
    226      1.1  joerg           const Decl *D = cast<DeclRefExpr>(E)->getDecl();
    227      1.1  joerg           if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(D))
    228      1.1  joerg             CGF.EmitVarDecl(*OED);
    229      1.1  joerg         }
    230  1.1.1.2  joerg       } else if (const auto *UDP = dyn_cast<OMPUseDeviceAddrClause>(C)) {
    231  1.1.1.2  joerg         for (const Expr *E : UDP->varlists()) {
    232  1.1.1.2  joerg           const Decl *D = getBaseDecl(E);
    233  1.1.1.2  joerg           if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(D))
    234  1.1.1.2  joerg             CGF.EmitVarDecl(*OED);
    235  1.1.1.2  joerg         }
    236      1.1  joerg       }
    237      1.1  joerg     }
    238      1.1  joerg     if (!isOpenMPSimdDirective(S.getDirectiveKind()))
    239      1.1  joerg       CGF.EmitOMPPrivateClause(S, InlinedShareds);
    240      1.1  joerg     if (const auto *TG = dyn_cast<OMPTaskgroupDirective>(&S)) {
    241      1.1  joerg       if (const Expr *E = TG->getReductionRef())
    242      1.1  joerg         CGF.EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()));
    243      1.1  joerg     }
    244  1.1.1.2  joerg     // Temp copy arrays for inscan reductions should not be emitted as they are
    245  1.1.1.2  joerg     // not used in simd only mode.
    246  1.1.1.2  joerg     llvm::DenseSet<CanonicalDeclPtr<const Decl>> CopyArrayTemps;
    247  1.1.1.2  joerg     for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
    248  1.1.1.2  joerg       if (C->getModifier() != OMPC_REDUCTION_inscan)
    249  1.1.1.2  joerg         continue;
    250  1.1.1.2  joerg       for (const Expr *E : C->copy_array_temps())
    251  1.1.1.2  joerg         CopyArrayTemps.insert(cast<DeclRefExpr>(E)->getDecl());
    252  1.1.1.2  joerg     }
    253      1.1  joerg     const auto *CS = cast_or_null<CapturedStmt>(S.getAssociatedStmt());
    254      1.1  joerg     while (CS) {
    255      1.1  joerg       for (auto &C : CS->captures()) {
    256      1.1  joerg         if (C.capturesVariable() || C.capturesVariableByCopy()) {
    257      1.1  joerg           auto *VD = C.getCapturedVar();
    258  1.1.1.2  joerg           if (CopyArrayTemps.contains(VD))
    259  1.1.1.2  joerg             continue;
    260      1.1  joerg           assert(VD == VD->getCanonicalDecl() &&
    261      1.1  joerg                  "Canonical decl must be captured.");
    262      1.1  joerg           DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD),
    263      1.1  joerg                           isCapturedVar(CGF, VD) ||
    264      1.1  joerg                               (CGF.CapturedStmtInfo &&
    265      1.1  joerg                                InlinedShareds.isGlobalVarCaptured(VD)),
    266      1.1  joerg                           VD->getType().getNonReferenceType(), VK_LValue,
    267      1.1  joerg                           C.getLocation());
    268      1.1  joerg           InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
    269  1.1.1.2  joerg             return CGF.EmitLValue(&DRE).getAddress(CGF);
    270      1.1  joerg           });
    271      1.1  joerg         }
    272      1.1  joerg       }
    273      1.1  joerg       CS = dyn_cast<CapturedStmt>(CS->getCapturedStmt());
    274      1.1  joerg     }
    275      1.1  joerg     (void)InlinedShareds.Privatize();
    276      1.1  joerg   }
    277      1.1  joerg };
    278      1.1  joerg 
    279      1.1  joerg } // namespace
    280      1.1  joerg 
    281      1.1  joerg static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
    282      1.1  joerg                                          const OMPExecutableDirective &S,
    283      1.1  joerg                                          const RegionCodeGenTy &CodeGen);
    284      1.1  joerg 
    285      1.1  joerg LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) {
    286      1.1  joerg   if (const auto *OrigDRE = dyn_cast<DeclRefExpr>(E)) {
    287      1.1  joerg     if (const auto *OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) {
    288      1.1  joerg       OrigVD = OrigVD->getCanonicalDecl();
    289      1.1  joerg       bool IsCaptured =
    290      1.1  joerg           LambdaCaptureFields.lookup(OrigVD) ||
    291      1.1  joerg           (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) ||
    292      1.1  joerg           (CurCodeDecl && isa<BlockDecl>(CurCodeDecl));
    293      1.1  joerg       DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), IsCaptured,
    294      1.1  joerg                       OrigDRE->getType(), VK_LValue, OrigDRE->getExprLoc());
    295      1.1  joerg       return EmitLValue(&DRE);
    296      1.1  joerg     }
    297      1.1  joerg   }
    298      1.1  joerg   return EmitLValue(E);
    299      1.1  joerg }
    300      1.1  joerg 
    301      1.1  joerg llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
    302      1.1  joerg   ASTContext &C = getContext();
    303      1.1  joerg   llvm::Value *Size = nullptr;
    304      1.1  joerg   auto SizeInChars = C.getTypeSizeInChars(Ty);
    305      1.1  joerg   if (SizeInChars.isZero()) {
    306      1.1  joerg     // getTypeSizeInChars() returns 0 for a VLA.
    307      1.1  joerg     while (const VariableArrayType *VAT = C.getAsVariableArrayType(Ty)) {
    308      1.1  joerg       VlaSizePair VlaSize = getVLASize(VAT);
    309      1.1  joerg       Ty = VlaSize.Type;
    310      1.1  joerg       Size = Size ? Builder.CreateNUWMul(Size, VlaSize.NumElts)
    311      1.1  joerg                   : VlaSize.NumElts;
    312      1.1  joerg     }
    313      1.1  joerg     SizeInChars = C.getTypeSizeInChars(Ty);
    314      1.1  joerg     if (SizeInChars.isZero())
    315      1.1  joerg       return llvm::ConstantInt::get(SizeTy, /*V=*/0);
    316      1.1  joerg     return Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars));
    317      1.1  joerg   }
    318      1.1  joerg   return CGM.getSize(SizeInChars);
    319      1.1  joerg }
    320      1.1  joerg 
    321      1.1  joerg void CodeGenFunction::GenerateOpenMPCapturedVars(
    322      1.1  joerg     const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {
    323      1.1  joerg   const RecordDecl *RD = S.getCapturedRecordDecl();
    324      1.1  joerg   auto CurField = RD->field_begin();
    325      1.1  joerg   auto CurCap = S.captures().begin();
    326      1.1  joerg   for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
    327      1.1  joerg                                                  E = S.capture_init_end();
    328      1.1  joerg        I != E; ++I, ++CurField, ++CurCap) {
    329      1.1  joerg     if (CurField->hasCapturedVLAType()) {
    330      1.1  joerg       const VariableArrayType *VAT = CurField->getCapturedVLAType();
    331      1.1  joerg       llvm::Value *Val = VLASizeMap[VAT->getSizeExpr()];
    332      1.1  joerg       CapturedVars.push_back(Val);
    333      1.1  joerg     } else if (CurCap->capturesThis()) {
    334      1.1  joerg       CapturedVars.push_back(CXXThisValue);
    335      1.1  joerg     } else if (CurCap->capturesVariableByCopy()) {
    336      1.1  joerg       llvm::Value *CV = EmitLoadOfScalar(EmitLValue(*I), CurCap->getLocation());
    337      1.1  joerg 
    338      1.1  joerg       // If the field is not a pointer, we need to save the actual value
    339      1.1  joerg       // and load it as a void pointer.
    340      1.1  joerg       if (!CurField->getType()->isAnyPointerType()) {
    341      1.1  joerg         ASTContext &Ctx = getContext();
    342      1.1  joerg         Address DstAddr = CreateMemTemp(
    343      1.1  joerg             Ctx.getUIntPtrType(),
    344      1.1  joerg             Twine(CurCap->getCapturedVar()->getName(), ".casted"));
    345      1.1  joerg         LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType());
    346      1.1  joerg 
    347      1.1  joerg         llvm::Value *SrcAddrVal = EmitScalarConversion(
    348      1.1  joerg             DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()),
    349      1.1  joerg             Ctx.getPointerType(CurField->getType()), CurCap->getLocation());
    350      1.1  joerg         LValue SrcLV =
    351      1.1  joerg             MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
    352      1.1  joerg 
    353      1.1  joerg         // Store the value using the source type pointer.
    354      1.1  joerg         EmitStoreThroughLValue(RValue::get(CV), SrcLV);
    355      1.1  joerg 
    356      1.1  joerg         // Load the value using the destination type pointer.
    357      1.1  joerg         CV = EmitLoadOfScalar(DstLV, CurCap->getLocation());
    358      1.1  joerg       }
    359      1.1  joerg       CapturedVars.push_back(CV);
    360      1.1  joerg     } else {
    361      1.1  joerg       assert(CurCap->capturesVariable() && "Expected capture by reference.");
    362  1.1.1.2  joerg       CapturedVars.push_back(EmitLValue(*I).getAddress(*this).getPointer());
    363      1.1  joerg     }
    364      1.1  joerg   }
    365      1.1  joerg }
    366      1.1  joerg 
    367      1.1  joerg static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc,
    368      1.1  joerg                                     QualType DstType, StringRef Name,
    369      1.1  joerg                                     LValue AddrLV) {
    370      1.1  joerg   ASTContext &Ctx = CGF.getContext();
    371      1.1  joerg 
    372      1.1  joerg   llvm::Value *CastedPtr = CGF.EmitScalarConversion(
    373  1.1.1.2  joerg       AddrLV.getAddress(CGF).getPointer(), Ctx.getUIntPtrType(),
    374      1.1  joerg       Ctx.getPointerType(DstType), Loc);
    375      1.1  joerg   Address TmpAddr =
    376      1.1  joerg       CGF.MakeNaturalAlignAddrLValue(CastedPtr, Ctx.getPointerType(DstType))
    377  1.1.1.2  joerg           .getAddress(CGF);
    378      1.1  joerg   return TmpAddr;
    379      1.1  joerg }
    380      1.1  joerg 
    381      1.1  joerg static QualType getCanonicalParamType(ASTContext &C, QualType T) {
    382      1.1  joerg   if (T->isLValueReferenceType())
    383      1.1  joerg     return C.getLValueReferenceType(
    384      1.1  joerg         getCanonicalParamType(C, T.getNonReferenceType()),
    385      1.1  joerg         /*SpelledAsLValue=*/false);
    386      1.1  joerg   if (T->isPointerType())
    387      1.1  joerg     return C.getPointerType(getCanonicalParamType(C, T->getPointeeType()));
    388      1.1  joerg   if (const ArrayType *A = T->getAsArrayTypeUnsafe()) {
    389      1.1  joerg     if (const auto *VLA = dyn_cast<VariableArrayType>(A))
    390      1.1  joerg       return getCanonicalParamType(C, VLA->getElementType());
    391      1.1  joerg     if (!A->isVariablyModifiedType())
    392      1.1  joerg       return C.getCanonicalType(T);
    393      1.1  joerg   }
    394      1.1  joerg   return C.getCanonicalParamType(T);
    395      1.1  joerg }
    396      1.1  joerg 
    397      1.1  joerg namespace {
    398  1.1.1.2  joerg /// Contains required data for proper outlined function codegen.
    399  1.1.1.2  joerg struct FunctionOptions {
    400  1.1.1.2  joerg   /// Captured statement for which the function is generated.
    401  1.1.1.2  joerg   const CapturedStmt *S = nullptr;
    402  1.1.1.2  joerg   /// true if cast to/from  UIntPtr is required for variables captured by
    403  1.1.1.2  joerg   /// value.
    404  1.1.1.2  joerg   const bool UIntPtrCastRequired = true;
    405  1.1.1.2  joerg   /// true if only casted arguments must be registered as local args or VLA
    406  1.1.1.2  joerg   /// sizes.
    407  1.1.1.2  joerg   const bool RegisterCastedArgsOnly = false;
    408  1.1.1.2  joerg   /// Name of the generated function.
    409  1.1.1.2  joerg   const StringRef FunctionName;
    410  1.1.1.2  joerg   /// Location of the non-debug version of the outlined function.
    411  1.1.1.2  joerg   SourceLocation Loc;
    412  1.1.1.2  joerg   explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired,
    413  1.1.1.2  joerg                            bool RegisterCastedArgsOnly, StringRef FunctionName,
    414  1.1.1.2  joerg                            SourceLocation Loc)
    415  1.1.1.2  joerg       : S(S), UIntPtrCastRequired(UIntPtrCastRequired),
    416  1.1.1.2  joerg         RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
    417  1.1.1.2  joerg         FunctionName(FunctionName), Loc(Loc) {}
    418  1.1.1.2  joerg };
    419  1.1.1.2  joerg } // namespace
    420      1.1  joerg 
    421      1.1  joerg static llvm::Function *emitOutlinedFunctionPrologue(
    422      1.1  joerg     CodeGenFunction &CGF, FunctionArgList &Args,
    423      1.1  joerg     llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>>
    424      1.1  joerg         &LocalAddrs,
    425      1.1  joerg     llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
    426      1.1  joerg         &VLASizes,
    427      1.1  joerg     llvm::Value *&CXXThisValue, const FunctionOptions &FO) {
    428      1.1  joerg   const CapturedDecl *CD = FO.S->getCapturedDecl();
    429      1.1  joerg   const RecordDecl *RD = FO.S->getCapturedRecordDecl();
    430      1.1  joerg   assert(CD->hasBody() && "missing CapturedDecl body");
    431      1.1  joerg 
    432      1.1  joerg   CXXThisValue = nullptr;
    433      1.1  joerg   // Build the argument list.
    434      1.1  joerg   CodeGenModule &CGM = CGF.CGM;
    435      1.1  joerg   ASTContext &Ctx = CGM.getContext();
    436      1.1  joerg   FunctionArgList TargetArgs;
    437      1.1  joerg   Args.append(CD->param_begin(),
    438      1.1  joerg               std::next(CD->param_begin(), CD->getContextParamPosition()));
    439      1.1  joerg   TargetArgs.append(
    440      1.1  joerg       CD->param_begin(),
    441      1.1  joerg       std::next(CD->param_begin(), CD->getContextParamPosition()));
    442      1.1  joerg   auto I = FO.S->captures().begin();
    443      1.1  joerg   FunctionDecl *DebugFunctionDecl = nullptr;
    444      1.1  joerg   if (!FO.UIntPtrCastRequired) {
    445      1.1  joerg     FunctionProtoType::ExtProtoInfo EPI;
    446      1.1  joerg     QualType FunctionTy = Ctx.getFunctionType(Ctx.VoidTy, llvm::None, EPI);
    447      1.1  joerg     DebugFunctionDecl = FunctionDecl::Create(
    448      1.1  joerg         Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(),
    449      1.1  joerg         SourceLocation(), DeclarationName(), FunctionTy,
    450      1.1  joerg         Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static,
    451      1.1  joerg         /*isInlineSpecified=*/false, /*hasWrittenPrototype=*/false);
    452      1.1  joerg   }
    453      1.1  joerg   for (const FieldDecl *FD : RD->fields()) {
    454      1.1  joerg     QualType ArgType = FD->getType();
    455      1.1  joerg     IdentifierInfo *II = nullptr;
    456      1.1  joerg     VarDecl *CapVar = nullptr;
    457      1.1  joerg 
    458      1.1  joerg     // If this is a capture by copy and the type is not a pointer, the outlined
    459      1.1  joerg     // function argument type should be uintptr and the value properly casted to
    460      1.1  joerg     // uintptr. This is necessary given that the runtime library is only able to
    461      1.1  joerg     // deal with pointers. We can pass in the same way the VLA type sizes to the
    462      1.1  joerg     // outlined function.
    463      1.1  joerg     if (FO.UIntPtrCastRequired &&
    464      1.1  joerg         ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
    465      1.1  joerg          I->capturesVariableArrayType()))
    466      1.1  joerg       ArgType = Ctx.getUIntPtrType();
    467      1.1  joerg 
    468      1.1  joerg     if (I->capturesVariable() || I->capturesVariableByCopy()) {
    469      1.1  joerg       CapVar = I->getCapturedVar();
    470      1.1  joerg       II = CapVar->getIdentifier();
    471      1.1  joerg     } else if (I->capturesThis()) {
    472      1.1  joerg       II = &Ctx.Idents.get("this");
    473      1.1  joerg     } else {
    474      1.1  joerg       assert(I->capturesVariableArrayType());
    475      1.1  joerg       II = &Ctx.Idents.get("vla");
    476      1.1  joerg     }
    477      1.1  joerg     if (ArgType->isVariablyModifiedType())
    478      1.1  joerg       ArgType = getCanonicalParamType(Ctx, ArgType);
    479      1.1  joerg     VarDecl *Arg;
    480      1.1  joerg     if (DebugFunctionDecl && (CapVar || I->capturesThis())) {
    481      1.1  joerg       Arg = ParmVarDecl::Create(
    482      1.1  joerg           Ctx, DebugFunctionDecl,
    483      1.1  joerg           CapVar ? CapVar->getBeginLoc() : FD->getBeginLoc(),
    484      1.1  joerg           CapVar ? CapVar->getLocation() : FD->getLocation(), II, ArgType,
    485      1.1  joerg           /*TInfo=*/nullptr, SC_None, /*DefArg=*/nullptr);
    486      1.1  joerg     } else {
    487      1.1  joerg       Arg = ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(),
    488      1.1  joerg                                       II, ArgType, ImplicitParamDecl::Other);
    489      1.1  joerg     }
    490      1.1  joerg     Args.emplace_back(Arg);
    491      1.1  joerg     // Do not cast arguments if we emit function with non-original types.
    492      1.1  joerg     TargetArgs.emplace_back(
    493      1.1  joerg         FO.UIntPtrCastRequired
    494      1.1  joerg             ? Arg
    495      1.1  joerg             : CGM.getOpenMPRuntime().translateParameter(FD, Arg));
    496      1.1  joerg     ++I;
    497      1.1  joerg   }
    498      1.1  joerg   Args.append(
    499      1.1  joerg       std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
    500      1.1  joerg       CD->param_end());
    501      1.1  joerg   TargetArgs.append(
    502      1.1  joerg       std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
    503      1.1  joerg       CD->param_end());
    504      1.1  joerg 
    505      1.1  joerg   // Create the function declaration.
    506      1.1  joerg   const CGFunctionInfo &FuncInfo =
    507      1.1  joerg       CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, TargetArgs);
    508      1.1  joerg   llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
    509      1.1  joerg 
    510      1.1  joerg   auto *F =
    511      1.1  joerg       llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
    512      1.1  joerg                              FO.FunctionName, &CGM.getModule());
    513      1.1  joerg   CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
    514      1.1  joerg   if (CD->isNothrow())
    515      1.1  joerg     F->setDoesNotThrow();
    516      1.1  joerg   F->setDoesNotRecurse();
    517      1.1  joerg 
    518      1.1  joerg   // Generate the function.
    519      1.1  joerg   CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs,
    520  1.1.1.2  joerg                     FO.UIntPtrCastRequired ? FO.Loc : FO.S->getBeginLoc(),
    521  1.1.1.2  joerg                     FO.UIntPtrCastRequired ? FO.Loc
    522  1.1.1.2  joerg                                            : CD->getBody()->getBeginLoc());
    523      1.1  joerg   unsigned Cnt = CD->getContextParamPosition();
    524      1.1  joerg   I = FO.S->captures().begin();
    525      1.1  joerg   for (const FieldDecl *FD : RD->fields()) {
    526      1.1  joerg     // Do not map arguments if we emit function with non-original types.
    527      1.1  joerg     Address LocalAddr(Address::invalid());
    528      1.1  joerg     if (!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) {
    529      1.1  joerg       LocalAddr = CGM.getOpenMPRuntime().getParameterAddress(CGF, Args[Cnt],
    530      1.1  joerg                                                              TargetArgs[Cnt]);
    531      1.1  joerg     } else {
    532      1.1  joerg       LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]);
    533      1.1  joerg     }
    534      1.1  joerg     // If we are capturing a pointer by copy we don't need to do anything, just
    535      1.1  joerg     // use the value that we get from the arguments.
    536      1.1  joerg     if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
    537      1.1  joerg       const VarDecl *CurVD = I->getCapturedVar();
    538      1.1  joerg       if (!FO.RegisterCastedArgsOnly)
    539      1.1  joerg         LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
    540      1.1  joerg       ++Cnt;
    541      1.1  joerg       ++I;
    542      1.1  joerg       continue;
    543      1.1  joerg     }
    544      1.1  joerg 
    545      1.1  joerg     LValue ArgLVal = CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(),
    546      1.1  joerg                                         AlignmentSource::Decl);
    547      1.1  joerg     if (FD->hasCapturedVLAType()) {
    548      1.1  joerg       if (FO.UIntPtrCastRequired) {
    549      1.1  joerg         ArgLVal = CGF.MakeAddrLValue(
    550      1.1  joerg             castValueFromUintptr(CGF, I->getLocation(), FD->getType(),
    551      1.1  joerg                                  Args[Cnt]->getName(), ArgLVal),
    552      1.1  joerg             FD->getType(), AlignmentSource::Decl);
    553      1.1  joerg       }
    554      1.1  joerg       llvm::Value *ExprArg = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation());
    555      1.1  joerg       const VariableArrayType *VAT = FD->getCapturedVLAType();
    556      1.1  joerg       VLASizes.try_emplace(Args[Cnt], VAT->getSizeExpr(), ExprArg);
    557      1.1  joerg     } else if (I->capturesVariable()) {
    558      1.1  joerg       const VarDecl *Var = I->getCapturedVar();
    559      1.1  joerg       QualType VarTy = Var->getType();
    560  1.1.1.2  joerg       Address ArgAddr = ArgLVal.getAddress(CGF);
    561      1.1  joerg       if (ArgLVal.getType()->isLValueReferenceType()) {
    562      1.1  joerg         ArgAddr = CGF.EmitLoadOfReference(ArgLVal);
    563      1.1  joerg       } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
    564      1.1  joerg         assert(ArgLVal.getType()->isPointerType());
    565      1.1  joerg         ArgAddr = CGF.EmitLoadOfPointer(
    566      1.1  joerg             ArgAddr, ArgLVal.getType()->castAs<PointerType>());
    567      1.1  joerg       }
    568      1.1  joerg       if (!FO.RegisterCastedArgsOnly) {
    569      1.1  joerg         LocalAddrs.insert(
    570      1.1  joerg             {Args[Cnt],
    571      1.1  joerg              {Var, Address(ArgAddr.getPointer(), Ctx.getDeclAlign(Var))}});
    572      1.1  joerg       }
    573      1.1  joerg     } else if (I->capturesVariableByCopy()) {
    574      1.1  joerg       assert(!FD->getType()->isAnyPointerType() &&
    575      1.1  joerg              "Not expecting a captured pointer.");
    576      1.1  joerg       const VarDecl *Var = I->getCapturedVar();
    577      1.1  joerg       LocalAddrs.insert({Args[Cnt],
    578      1.1  joerg                          {Var, FO.UIntPtrCastRequired
    579      1.1  joerg                                    ? castValueFromUintptr(
    580      1.1  joerg                                          CGF, I->getLocation(), FD->getType(),
    581      1.1  joerg                                          Args[Cnt]->getName(), ArgLVal)
    582  1.1.1.2  joerg                                    : ArgLVal.getAddress(CGF)}});
    583      1.1  joerg     } else {
    584      1.1  joerg       // If 'this' is captured, load it into CXXThisValue.
    585      1.1  joerg       assert(I->capturesThis());
    586      1.1  joerg       CXXThisValue = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation());
    587  1.1.1.2  joerg       LocalAddrs.insert({Args[Cnt], {nullptr, ArgLVal.getAddress(CGF)}});
    588      1.1  joerg     }
    589      1.1  joerg     ++Cnt;
    590      1.1  joerg     ++I;
    591      1.1  joerg   }
    592      1.1  joerg 
    593      1.1  joerg   return F;
    594      1.1  joerg }
    595      1.1  joerg 
    596      1.1  joerg llvm::Function *
    597  1.1.1.2  joerg CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
    598  1.1.1.2  joerg                                                     SourceLocation Loc) {
    599      1.1  joerg   assert(
    600      1.1  joerg       CapturedStmtInfo &&
    601      1.1  joerg       "CapturedStmtInfo should be set when generating the captured function");
    602      1.1  joerg   const CapturedDecl *CD = S.getCapturedDecl();
    603      1.1  joerg   // Build the argument list.
    604      1.1  joerg   bool NeedWrapperFunction =
    605  1.1.1.2  joerg       getDebugInfo() && CGM.getCodeGenOpts().hasReducedDebugInfo();
    606      1.1  joerg   FunctionArgList Args;
    607      1.1  joerg   llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
    608      1.1  joerg   llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
    609      1.1  joerg   SmallString<256> Buffer;
    610      1.1  joerg   llvm::raw_svector_ostream Out(Buffer);
    611      1.1  joerg   Out << CapturedStmtInfo->getHelperName();
    612      1.1  joerg   if (NeedWrapperFunction)
    613      1.1  joerg     Out << "_debug__";
    614      1.1  joerg   FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false,
    615  1.1.1.2  joerg                      Out.str(), Loc);
    616      1.1  joerg   llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs,
    617      1.1  joerg                                                    VLASizes, CXXThisValue, FO);
    618      1.1  joerg   CodeGenFunction::OMPPrivateScope LocalScope(*this);
    619      1.1  joerg   for (const auto &LocalAddrPair : LocalAddrs) {
    620      1.1  joerg     if (LocalAddrPair.second.first) {
    621      1.1  joerg       LocalScope.addPrivate(LocalAddrPair.second.first, [&LocalAddrPair]() {
    622      1.1  joerg         return LocalAddrPair.second.second;
    623      1.1  joerg       });
    624      1.1  joerg     }
    625      1.1  joerg   }
    626      1.1  joerg   (void)LocalScope.Privatize();
    627      1.1  joerg   for (const auto &VLASizePair : VLASizes)
    628      1.1  joerg     VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
    629      1.1  joerg   PGO.assignRegionCounters(GlobalDecl(CD), F);
    630      1.1  joerg   CapturedStmtInfo->EmitBody(*this, CD->getBody());
    631      1.1  joerg   (void)LocalScope.ForceCleanup();
    632      1.1  joerg   FinishFunction(CD->getBodyRBrace());
    633      1.1  joerg   if (!NeedWrapperFunction)
    634      1.1  joerg     return F;
    635      1.1  joerg 
    636      1.1  joerg   FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true,
    637      1.1  joerg                             /*RegisterCastedArgsOnly=*/true,
    638  1.1.1.2  joerg                             CapturedStmtInfo->getHelperName(), Loc);
    639      1.1  joerg   CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true);
    640      1.1  joerg   WrapperCGF.CapturedStmtInfo = CapturedStmtInfo;
    641      1.1  joerg   Args.clear();
    642      1.1  joerg   LocalAddrs.clear();
    643      1.1  joerg   VLASizes.clear();
    644      1.1  joerg   llvm::Function *WrapperF =
    645      1.1  joerg       emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes,
    646      1.1  joerg                                    WrapperCGF.CXXThisValue, WrapperFO);
    647      1.1  joerg   llvm::SmallVector<llvm::Value *, 4> CallArgs;
    648  1.1.1.2  joerg   auto *PI = F->arg_begin();
    649      1.1  joerg   for (const auto *Arg : Args) {
    650      1.1  joerg     llvm::Value *CallArg;
    651      1.1  joerg     auto I = LocalAddrs.find(Arg);
    652      1.1  joerg     if (I != LocalAddrs.end()) {
    653      1.1  joerg       LValue LV = WrapperCGF.MakeAddrLValue(
    654      1.1  joerg           I->second.second,
    655      1.1  joerg           I->second.first ? I->second.first->getType() : Arg->getType(),
    656      1.1  joerg           AlignmentSource::Decl);
    657  1.1.1.2  joerg       if (LV.getType()->isAnyComplexType())
    658  1.1.1.2  joerg         LV.setAddress(WrapperCGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
    659  1.1.1.2  joerg             LV.getAddress(WrapperCGF),
    660  1.1.1.2  joerg             PI->getType()->getPointerTo(
    661  1.1.1.2  joerg                 LV.getAddress(WrapperCGF).getAddressSpace())));
    662      1.1  joerg       CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
    663      1.1  joerg     } else {
    664      1.1  joerg       auto EI = VLASizes.find(Arg);
    665      1.1  joerg       if (EI != VLASizes.end()) {
    666      1.1  joerg         CallArg = EI->second.second;
    667      1.1  joerg       } else {
    668      1.1  joerg         LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),
    669      1.1  joerg                                               Arg->getType(),
    670      1.1  joerg                                               AlignmentSource::Decl);
    671      1.1  joerg         CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
    672      1.1  joerg       }
    673      1.1  joerg     }
    674      1.1  joerg     CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType()));
    675  1.1.1.2  joerg     ++PI;
    676      1.1  joerg   }
    677  1.1.1.2  joerg   CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, Loc, F, CallArgs);
    678      1.1  joerg   WrapperCGF.FinishFunction();
    679      1.1  joerg   return WrapperF;
    680      1.1  joerg }
    681      1.1  joerg 
    682      1.1  joerg //===----------------------------------------------------------------------===//
    683      1.1  joerg //                              OpenMP Directive Emission
    684      1.1  joerg //===----------------------------------------------------------------------===//
    685      1.1  joerg void CodeGenFunction::EmitOMPAggregateAssign(
    686      1.1  joerg     Address DestAddr, Address SrcAddr, QualType OriginalType,
    687      1.1  joerg     const llvm::function_ref<void(Address, Address)> CopyGen) {
    688      1.1  joerg   // Perform element-by-element initialization.
    689      1.1  joerg   QualType ElementTy;
    690      1.1  joerg 
    691      1.1  joerg   // Drill down to the base element type on both arrays.
    692      1.1  joerg   const ArrayType *ArrayTy = OriginalType->getAsArrayTypeUnsafe();
    693      1.1  joerg   llvm::Value *NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr);
    694      1.1  joerg   SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
    695      1.1  joerg 
    696      1.1  joerg   llvm::Value *SrcBegin = SrcAddr.getPointer();
    697      1.1  joerg   llvm::Value *DestBegin = DestAddr.getPointer();
    698      1.1  joerg   // Cast from pointer to array type to pointer to single element.
    699      1.1  joerg   llvm::Value *DestEnd = Builder.CreateGEP(DestBegin, NumElements);
    700      1.1  joerg   // The basic structure here is a while-do loop.
    701      1.1  joerg   llvm::BasicBlock *BodyBB = createBasicBlock("omp.arraycpy.body");
    702      1.1  joerg   llvm::BasicBlock *DoneBB = createBasicBlock("omp.arraycpy.done");
    703      1.1  joerg   llvm::Value *IsEmpty =
    704      1.1  joerg       Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
    705      1.1  joerg   Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
    706      1.1  joerg 
    707      1.1  joerg   // Enter the loop body, making that address the current address.
    708      1.1  joerg   llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
    709      1.1  joerg   EmitBlock(BodyBB);
    710      1.1  joerg 
    711      1.1  joerg   CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy);
    712      1.1  joerg 
    713      1.1  joerg   llvm::PHINode *SrcElementPHI =
    714      1.1  joerg     Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast");
    715      1.1  joerg   SrcElementPHI->addIncoming(SrcBegin, EntryBB);
    716      1.1  joerg   Address SrcElementCurrent =
    717      1.1  joerg       Address(SrcElementPHI,
    718      1.1  joerg               SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
    719      1.1  joerg 
    720      1.1  joerg   llvm::PHINode *DestElementPHI =
    721      1.1  joerg     Builder.CreatePHI(DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
    722      1.1  joerg   DestElementPHI->addIncoming(DestBegin, EntryBB);
    723      1.1  joerg   Address DestElementCurrent =
    724      1.1  joerg     Address(DestElementPHI,
    725      1.1  joerg             DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
    726      1.1  joerg 
    727      1.1  joerg   // Emit copy.
    728      1.1  joerg   CopyGen(DestElementCurrent, SrcElementCurrent);
    729      1.1  joerg 
    730      1.1  joerg   // Shift the address forward by one element.
    731      1.1  joerg   llvm::Value *DestElementNext = Builder.CreateConstGEP1_32(
    732      1.1  joerg       DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
    733      1.1  joerg   llvm::Value *SrcElementNext = Builder.CreateConstGEP1_32(
    734      1.1  joerg       SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
    735      1.1  joerg   // Check whether we've reached the end.
    736      1.1  joerg   llvm::Value *Done =
    737      1.1  joerg       Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
    738      1.1  joerg   Builder.CreateCondBr(Done, DoneBB, BodyBB);
    739      1.1  joerg   DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock());
    740      1.1  joerg   SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock());
    741      1.1  joerg 
    742      1.1  joerg   // Done.
    743      1.1  joerg   EmitBlock(DoneBB, /*IsFinished=*/true);
    744      1.1  joerg }
    745      1.1  joerg 
    746      1.1  joerg void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,
    747      1.1  joerg                                   Address SrcAddr, const VarDecl *DestVD,
    748      1.1  joerg                                   const VarDecl *SrcVD, const Expr *Copy) {
    749      1.1  joerg   if (OriginalType->isArrayType()) {
    750      1.1  joerg     const auto *BO = dyn_cast<BinaryOperator>(Copy);
    751      1.1  joerg     if (BO && BO->getOpcode() == BO_Assign) {
    752      1.1  joerg       // Perform simple memcpy for simple copying.
    753      1.1  joerg       LValue Dest = MakeAddrLValue(DestAddr, OriginalType);
    754      1.1  joerg       LValue Src = MakeAddrLValue(SrcAddr, OriginalType);
    755      1.1  joerg       EmitAggregateAssign(Dest, Src, OriginalType);
    756      1.1  joerg     } else {
    757      1.1  joerg       // For arrays with complex element types perform element by element
    758      1.1  joerg       // copying.
    759      1.1  joerg       EmitOMPAggregateAssign(
    760      1.1  joerg           DestAddr, SrcAddr, OriginalType,
    761      1.1  joerg           [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) {
    762      1.1  joerg             // Working with the single array element, so have to remap
    763      1.1  joerg             // destination and source variables to corresponding array
    764      1.1  joerg             // elements.
    765      1.1  joerg             CodeGenFunction::OMPPrivateScope Remap(*this);
    766      1.1  joerg             Remap.addPrivate(DestVD, [DestElement]() { return DestElement; });
    767      1.1  joerg             Remap.addPrivate(SrcVD, [SrcElement]() { return SrcElement; });
    768      1.1  joerg             (void)Remap.Privatize();
    769      1.1  joerg             EmitIgnoredExpr(Copy);
    770      1.1  joerg           });
    771      1.1  joerg     }
    772      1.1  joerg   } else {
    773      1.1  joerg     // Remap pseudo source variable to private copy.
    774      1.1  joerg     CodeGenFunction::OMPPrivateScope Remap(*this);
    775      1.1  joerg     Remap.addPrivate(SrcVD, [SrcAddr]() { return SrcAddr; });
    776      1.1  joerg     Remap.addPrivate(DestVD, [DestAddr]() { return DestAddr; });
    777      1.1  joerg     (void)Remap.Privatize();
    778      1.1  joerg     // Emit copying of the whole variable.
    779      1.1  joerg     EmitIgnoredExpr(Copy);
    780      1.1  joerg   }
    781      1.1  joerg }
    782      1.1  joerg 
    783      1.1  joerg bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
    784      1.1  joerg                                                 OMPPrivateScope &PrivateScope) {
    785      1.1  joerg   if (!HaveInsertPoint())
    786      1.1  joerg     return false;
    787      1.1  joerg   bool DeviceConstTarget =
    788      1.1  joerg       getLangOpts().OpenMPIsDevice &&
    789      1.1  joerg       isOpenMPTargetExecutionDirective(D.getDirectiveKind());
    790      1.1  joerg   bool FirstprivateIsLastprivate = false;
    791  1.1.1.2  joerg   llvm::DenseMap<const VarDecl *, OpenMPLastprivateModifier> Lastprivates;
    792      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
    793      1.1  joerg     for (const auto *D : C->varlists())
    794  1.1.1.2  joerg       Lastprivates.try_emplace(
    795  1.1.1.2  joerg           cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl(),
    796  1.1.1.2  joerg           C->getKind());
    797      1.1  joerg   }
    798      1.1  joerg   llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;
    799      1.1  joerg   llvm::SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
    800      1.1  joerg   getOpenMPCaptureRegions(CaptureRegions, D.getDirectiveKind());
    801      1.1  joerg   // Force emission of the firstprivate copy if the directive does not emit
    802      1.1  joerg   // outlined function, like omp for, omp simd, omp distribute etc.
    803      1.1  joerg   bool MustEmitFirstprivateCopy =
    804      1.1  joerg       CaptureRegions.size() == 1 && CaptureRegions.back() == OMPD_unknown;
    805      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
    806  1.1.1.2  joerg     const auto *IRef = C->varlist_begin();
    807  1.1.1.2  joerg     const auto *InitsRef = C->inits().begin();
    808      1.1  joerg     for (const Expr *IInit : C->private_copies()) {
    809      1.1  joerg       const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
    810      1.1  joerg       bool ThisFirstprivateIsLastprivate =
    811      1.1  joerg           Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
    812      1.1  joerg       const FieldDecl *FD = CapturedStmtInfo->lookup(OrigVD);
    813      1.1  joerg       const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
    814      1.1  joerg       if (!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD &&
    815      1.1  joerg           !FD->getType()->isReferenceType() &&
    816      1.1  joerg           (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) {
    817      1.1  joerg         EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
    818      1.1  joerg         ++IRef;
    819      1.1  joerg         ++InitsRef;
    820      1.1  joerg         continue;
    821      1.1  joerg       }
    822      1.1  joerg       // Do not emit copy for firstprivate constant variables in target regions,
    823      1.1  joerg       // captured by reference.
    824      1.1  joerg       if (DeviceConstTarget && OrigVD->getType().isConstant(getContext()) &&
    825      1.1  joerg           FD && FD->getType()->isReferenceType() &&
    826      1.1  joerg           (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) {
    827      1.1  joerg         (void)CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(*this,
    828      1.1  joerg                                                                     OrigVD);
    829      1.1  joerg         ++IRef;
    830      1.1  joerg         ++InitsRef;
    831      1.1  joerg         continue;
    832      1.1  joerg       }
    833      1.1  joerg       FirstprivateIsLastprivate =
    834      1.1  joerg           FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
    835      1.1  joerg       if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
    836      1.1  joerg         const auto *VDInit =
    837      1.1  joerg             cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
    838      1.1  joerg         bool IsRegistered;
    839      1.1  joerg         DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
    840      1.1  joerg                         /*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
    841      1.1  joerg                         (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
    842      1.1  joerg         LValue OriginalLVal;
    843      1.1  joerg         if (!FD) {
    844      1.1  joerg           // Check if the firstprivate variable is just a constant value.
    845      1.1  joerg           ConstantEmission CE = tryEmitAsConstant(&DRE);
    846      1.1  joerg           if (CE && !CE.isReference()) {
    847      1.1  joerg             // Constant value, no need to create a copy.
    848      1.1  joerg             ++IRef;
    849      1.1  joerg             ++InitsRef;
    850      1.1  joerg             continue;
    851      1.1  joerg           }
    852      1.1  joerg           if (CE && CE.isReference()) {
    853      1.1  joerg             OriginalLVal = CE.getReferenceLValue(*this, &DRE);
    854      1.1  joerg           } else {
    855      1.1  joerg             assert(!CE && "Expected non-constant firstprivate.");
    856      1.1  joerg             OriginalLVal = EmitLValue(&DRE);
    857      1.1  joerg           }
    858      1.1  joerg         } else {
    859      1.1  joerg           OriginalLVal = EmitLValue(&DRE);
    860      1.1  joerg         }
    861      1.1  joerg         QualType Type = VD->getType();
    862      1.1  joerg         if (Type->isArrayType()) {
    863      1.1  joerg           // Emit VarDecl with copy init for arrays.
    864      1.1  joerg           // Get the address of the original variable captured in current
    865      1.1  joerg           // captured region.
    866      1.1  joerg           IsRegistered = PrivateScope.addPrivate(
    867      1.1  joerg               OrigVD, [this, VD, Type, OriginalLVal, VDInit]() {
    868      1.1  joerg                 AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
    869      1.1  joerg                 const Expr *Init = VD->getInit();
    870      1.1  joerg                 if (!isa<CXXConstructExpr>(Init) ||
    871      1.1  joerg                     isTrivialInitializer(Init)) {
    872      1.1  joerg                   // Perform simple memcpy.
    873      1.1  joerg                   LValue Dest =
    874      1.1  joerg                       MakeAddrLValue(Emission.getAllocatedAddress(), Type);
    875      1.1  joerg                   EmitAggregateAssign(Dest, OriginalLVal, Type);
    876      1.1  joerg                 } else {
    877      1.1  joerg                   EmitOMPAggregateAssign(
    878  1.1.1.2  joerg                       Emission.getAllocatedAddress(),
    879  1.1.1.2  joerg                       OriginalLVal.getAddress(*this), Type,
    880      1.1  joerg                       [this, VDInit, Init](Address DestElement,
    881      1.1  joerg                                            Address SrcElement) {
    882      1.1  joerg                         // Clean up any temporaries needed by the
    883      1.1  joerg                         // initialization.
    884      1.1  joerg                         RunCleanupsScope InitScope(*this);
    885      1.1  joerg                         // Emit initialization for single element.
    886      1.1  joerg                         setAddrOfLocalVar(VDInit, SrcElement);
    887      1.1  joerg                         EmitAnyExprToMem(Init, DestElement,
    888      1.1  joerg                                          Init->getType().getQualifiers(),
    889      1.1  joerg                                          /*IsInitializer*/ false);
    890      1.1  joerg                         LocalDeclMap.erase(VDInit);
    891      1.1  joerg                       });
    892      1.1  joerg                 }
    893      1.1  joerg                 EmitAutoVarCleanups(Emission);
    894      1.1  joerg                 return Emission.getAllocatedAddress();
    895      1.1  joerg               });
    896      1.1  joerg         } else {
    897  1.1.1.2  joerg           Address OriginalAddr = OriginalLVal.getAddress(*this);
    898  1.1.1.2  joerg           IsRegistered =
    899  1.1.1.2  joerg               PrivateScope.addPrivate(OrigVD, [this, VDInit, OriginalAddr, VD,
    900  1.1.1.2  joerg                                                ThisFirstprivateIsLastprivate,
    901  1.1.1.2  joerg                                                OrigVD, &Lastprivates, IRef]() {
    902      1.1  joerg                 // Emit private VarDecl with copy init.
    903      1.1  joerg                 // Remap temp VDInit variable to the address of the original
    904      1.1  joerg                 // variable (for proper handling of captured global variables).
    905      1.1  joerg                 setAddrOfLocalVar(VDInit, OriginalAddr);
    906      1.1  joerg                 EmitDecl(*VD);
    907      1.1  joerg                 LocalDeclMap.erase(VDInit);
    908  1.1.1.2  joerg                 if (ThisFirstprivateIsLastprivate &&
    909  1.1.1.2  joerg                     Lastprivates[OrigVD->getCanonicalDecl()] ==
    910  1.1.1.2  joerg                         OMPC_LASTPRIVATE_conditional) {
    911  1.1.1.2  joerg                   // Create/init special variable for lastprivate conditionals.
    912  1.1.1.2  joerg                   Address VDAddr =
    913  1.1.1.2  joerg                       CGM.getOpenMPRuntime().emitLastprivateConditionalInit(
    914  1.1.1.2  joerg                           *this, OrigVD);
    915  1.1.1.2  joerg                   llvm::Value *V = EmitLoadOfScalar(
    916  1.1.1.2  joerg                       MakeAddrLValue(GetAddrOfLocalVar(VD), (*IRef)->getType(),
    917  1.1.1.2  joerg                                      AlignmentSource::Decl),
    918  1.1.1.2  joerg                       (*IRef)->getExprLoc());
    919  1.1.1.2  joerg                   EmitStoreOfScalar(V,
    920  1.1.1.2  joerg                                     MakeAddrLValue(VDAddr, (*IRef)->getType(),
    921  1.1.1.2  joerg                                                    AlignmentSource::Decl));
    922  1.1.1.2  joerg                   LocalDeclMap.erase(VD);
    923  1.1.1.2  joerg                   setAddrOfLocalVar(VD, VDAddr);
    924  1.1.1.2  joerg                   return VDAddr;
    925  1.1.1.2  joerg                 }
    926      1.1  joerg                 return GetAddrOfLocalVar(VD);
    927      1.1  joerg               });
    928      1.1  joerg         }
    929      1.1  joerg         assert(IsRegistered &&
    930      1.1  joerg                "firstprivate var already registered as private");
    931      1.1  joerg         // Silence the warning about unused variable.
    932      1.1  joerg         (void)IsRegistered;
    933      1.1  joerg       }
    934      1.1  joerg       ++IRef;
    935      1.1  joerg       ++InitsRef;
    936      1.1  joerg     }
    937      1.1  joerg   }
    938      1.1  joerg   return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
    939      1.1  joerg }
    940      1.1  joerg 
    941      1.1  joerg void CodeGenFunction::EmitOMPPrivateClause(
    942      1.1  joerg     const OMPExecutableDirective &D,
    943      1.1  joerg     CodeGenFunction::OMPPrivateScope &PrivateScope) {
    944      1.1  joerg   if (!HaveInsertPoint())
    945      1.1  joerg     return;
    946      1.1  joerg   llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
    947      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) {
    948      1.1  joerg     auto IRef = C->varlist_begin();
    949      1.1  joerg     for (const Expr *IInit : C->private_copies()) {
    950      1.1  joerg       const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
    951      1.1  joerg       if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
    952      1.1  joerg         const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
    953      1.1  joerg         bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD]() {
    954      1.1  joerg           // Emit private VarDecl with copy init.
    955      1.1  joerg           EmitDecl(*VD);
    956      1.1  joerg           return GetAddrOfLocalVar(VD);
    957      1.1  joerg         });
    958      1.1  joerg         assert(IsRegistered && "private var already registered as private");
    959      1.1  joerg         // Silence the warning about unused variable.
    960      1.1  joerg         (void)IsRegistered;
    961      1.1  joerg       }
    962      1.1  joerg       ++IRef;
    963      1.1  joerg     }
    964      1.1  joerg   }
    965      1.1  joerg }
    966      1.1  joerg 
    967      1.1  joerg bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {
    968      1.1  joerg   if (!HaveInsertPoint())
    969      1.1  joerg     return false;
    970      1.1  joerg   // threadprivate_var1 = master_threadprivate_var1;
    971      1.1  joerg   // operator=(threadprivate_var2, master_threadprivate_var2);
    972      1.1  joerg   // ...
    973      1.1  joerg   // __kmpc_barrier(&loc, global_tid);
    974      1.1  joerg   llvm::DenseSet<const VarDecl *> CopiedVars;
    975      1.1  joerg   llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr;
    976      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) {
    977      1.1  joerg     auto IRef = C->varlist_begin();
    978      1.1  joerg     auto ISrcRef = C->source_exprs().begin();
    979      1.1  joerg     auto IDestRef = C->destination_exprs().begin();
    980      1.1  joerg     for (const Expr *AssignOp : C->assignment_ops()) {
    981      1.1  joerg       const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
    982      1.1  joerg       QualType Type = VD->getType();
    983      1.1  joerg       if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
    984      1.1  joerg         // Get the address of the master variable. If we are emitting code with
    985      1.1  joerg         // TLS support, the address is passed from the master as field in the
    986      1.1  joerg         // captured declaration.
    987      1.1  joerg         Address MasterAddr = Address::invalid();
    988      1.1  joerg         if (getLangOpts().OpenMPUseTLS &&
    989      1.1  joerg             getContext().getTargetInfo().isTLSSupported()) {
    990      1.1  joerg           assert(CapturedStmtInfo->lookup(VD) &&
    991      1.1  joerg                  "Copyin threadprivates should have been captured!");
    992      1.1  joerg           DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD), true,
    993      1.1  joerg                           (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
    994  1.1.1.2  joerg           MasterAddr = EmitLValue(&DRE).getAddress(*this);
    995      1.1  joerg           LocalDeclMap.erase(VD);
    996      1.1  joerg         } else {
    997      1.1  joerg           MasterAddr =
    998      1.1  joerg             Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD)
    999      1.1  joerg                                         : CGM.GetAddrOfGlobal(VD),
   1000      1.1  joerg                     getContext().getDeclAlign(VD));
   1001      1.1  joerg         }
   1002      1.1  joerg         // Get the address of the threadprivate variable.
   1003  1.1.1.2  joerg         Address PrivateAddr = EmitLValue(*IRef).getAddress(*this);
   1004      1.1  joerg         if (CopiedVars.size() == 1) {
   1005      1.1  joerg           // At first check if current thread is a master thread. If it is, no
   1006      1.1  joerg           // need to copy data.
   1007      1.1  joerg           CopyBegin = createBasicBlock("copyin.not.master");
   1008      1.1  joerg           CopyEnd = createBasicBlock("copyin.not.master.end");
   1009  1.1.1.2  joerg           // TODO: Avoid ptrtoint conversion.
   1010  1.1.1.2  joerg           auto *MasterAddrInt =
   1011  1.1.1.2  joerg               Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy);
   1012  1.1.1.2  joerg           auto *PrivateAddrInt =
   1013  1.1.1.2  joerg               Builder.CreatePtrToInt(PrivateAddr.getPointer(), CGM.IntPtrTy);
   1014      1.1  joerg           Builder.CreateCondBr(
   1015  1.1.1.2  joerg               Builder.CreateICmpNE(MasterAddrInt, PrivateAddrInt), CopyBegin,
   1016  1.1.1.2  joerg               CopyEnd);
   1017      1.1  joerg           EmitBlock(CopyBegin);
   1018      1.1  joerg         }
   1019      1.1  joerg         const auto *SrcVD =
   1020      1.1  joerg             cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
   1021      1.1  joerg         const auto *DestVD =
   1022      1.1  joerg             cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
   1023      1.1  joerg         EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
   1024      1.1  joerg       }
   1025      1.1  joerg       ++IRef;
   1026      1.1  joerg       ++ISrcRef;
   1027      1.1  joerg       ++IDestRef;
   1028      1.1  joerg     }
   1029      1.1  joerg   }
   1030      1.1  joerg   if (CopyEnd) {
   1031      1.1  joerg     // Exit out of copying procedure for non-master thread.
   1032      1.1  joerg     EmitBlock(CopyEnd, /*IsFinished=*/true);
   1033      1.1  joerg     return true;
   1034      1.1  joerg   }
   1035      1.1  joerg   return false;
   1036      1.1  joerg }
   1037      1.1  joerg 
   1038      1.1  joerg bool CodeGenFunction::EmitOMPLastprivateClauseInit(
   1039      1.1  joerg     const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) {
   1040      1.1  joerg   if (!HaveInsertPoint())
   1041      1.1  joerg     return false;
   1042      1.1  joerg   bool HasAtLeastOneLastprivate = false;
   1043      1.1  joerg   llvm::DenseSet<const VarDecl *> SIMDLCVs;
   1044      1.1  joerg   if (isOpenMPSimdDirective(D.getDirectiveKind())) {
   1045      1.1  joerg     const auto *LoopDirective = cast<OMPLoopDirective>(&D);
   1046      1.1  joerg     for (const Expr *C : LoopDirective->counters()) {
   1047      1.1  joerg       SIMDLCVs.insert(
   1048      1.1  joerg           cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
   1049      1.1  joerg     }
   1050      1.1  joerg   }
   1051      1.1  joerg   llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
   1052      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
   1053      1.1  joerg     HasAtLeastOneLastprivate = true;
   1054      1.1  joerg     if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
   1055      1.1  joerg         !getLangOpts().OpenMPSimd)
   1056      1.1  joerg       break;
   1057  1.1.1.2  joerg     const auto *IRef = C->varlist_begin();
   1058  1.1.1.2  joerg     const auto *IDestRef = C->destination_exprs().begin();
   1059      1.1  joerg     for (const Expr *IInit : C->private_copies()) {
   1060      1.1  joerg       // Keep the address of the original variable for future update at the end
   1061      1.1  joerg       // of the loop.
   1062      1.1  joerg       const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
   1063      1.1  joerg       // Taskloops do not require additional initialization, it is done in
   1064      1.1  joerg       // runtime support library.
   1065      1.1  joerg       if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
   1066      1.1  joerg         const auto *DestVD =
   1067      1.1  joerg             cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
   1068      1.1  joerg         PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() {
   1069      1.1  joerg           DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
   1070      1.1  joerg                           /*RefersToEnclosingVariableOrCapture=*/
   1071      1.1  joerg                               CapturedStmtInfo->lookup(OrigVD) != nullptr,
   1072      1.1  joerg                           (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
   1073  1.1.1.2  joerg           return EmitLValue(&DRE).getAddress(*this);
   1074      1.1  joerg         });
   1075      1.1  joerg         // Check if the variable is also a firstprivate: in this case IInit is
   1076      1.1  joerg         // not generated. Initialization of this variable will happen in codegen
   1077      1.1  joerg         // for 'firstprivate' clause.
   1078      1.1  joerg         if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
   1079      1.1  joerg           const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
   1080  1.1.1.2  joerg           bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD, C,
   1081  1.1.1.2  joerg                                                                OrigVD]() {
   1082  1.1.1.2  joerg             if (C->getKind() == OMPC_LASTPRIVATE_conditional) {
   1083  1.1.1.2  joerg               Address VDAddr =
   1084  1.1.1.2  joerg                   CGM.getOpenMPRuntime().emitLastprivateConditionalInit(*this,
   1085  1.1.1.2  joerg                                                                         OrigVD);
   1086  1.1.1.2  joerg               setAddrOfLocalVar(VD, VDAddr);
   1087  1.1.1.2  joerg               return VDAddr;
   1088  1.1.1.2  joerg             }
   1089      1.1  joerg             // Emit private VarDecl with copy init.
   1090      1.1  joerg             EmitDecl(*VD);
   1091      1.1  joerg             return GetAddrOfLocalVar(VD);
   1092      1.1  joerg           });
   1093      1.1  joerg           assert(IsRegistered &&
   1094      1.1  joerg                  "lastprivate var already registered as private");
   1095      1.1  joerg           (void)IsRegistered;
   1096      1.1  joerg         }
   1097      1.1  joerg       }
   1098      1.1  joerg       ++IRef;
   1099      1.1  joerg       ++IDestRef;
   1100      1.1  joerg     }
   1101      1.1  joerg   }
   1102      1.1  joerg   return HasAtLeastOneLastprivate;
   1103      1.1  joerg }
   1104      1.1  joerg 
   1105      1.1  joerg void CodeGenFunction::EmitOMPLastprivateClauseFinal(
   1106      1.1  joerg     const OMPExecutableDirective &D, bool NoFinals,
   1107      1.1  joerg     llvm::Value *IsLastIterCond) {
   1108      1.1  joerg   if (!HaveInsertPoint())
   1109      1.1  joerg     return;
   1110      1.1  joerg   // Emit following code:
   1111      1.1  joerg   // if (<IsLastIterCond>) {
   1112      1.1  joerg   //   orig_var1 = private_orig_var1;
   1113      1.1  joerg   //   ...
   1114      1.1  joerg   //   orig_varn = private_orig_varn;
   1115      1.1  joerg   // }
   1116      1.1  joerg   llvm::BasicBlock *ThenBB = nullptr;
   1117      1.1  joerg   llvm::BasicBlock *DoneBB = nullptr;
   1118      1.1  joerg   if (IsLastIterCond) {
   1119  1.1.1.2  joerg     // Emit implicit barrier if at least one lastprivate conditional is found
   1120  1.1.1.2  joerg     // and this is not a simd mode.
   1121  1.1.1.2  joerg     if (!getLangOpts().OpenMPSimd &&
   1122  1.1.1.2  joerg         llvm::any_of(D.getClausesOfKind<OMPLastprivateClause>(),
   1123  1.1.1.2  joerg                      [](const OMPLastprivateClause *C) {
   1124  1.1.1.2  joerg                        return C->getKind() == OMPC_LASTPRIVATE_conditional;
   1125  1.1.1.2  joerg                      })) {
   1126  1.1.1.2  joerg       CGM.getOpenMPRuntime().emitBarrierCall(*this, D.getBeginLoc(),
   1127  1.1.1.2  joerg                                              OMPD_unknown,
   1128  1.1.1.2  joerg                                              /*EmitChecks=*/false,
   1129  1.1.1.2  joerg                                              /*ForceSimpleCall=*/true);
   1130  1.1.1.2  joerg     }
   1131      1.1  joerg     ThenBB = createBasicBlock(".omp.lastprivate.then");
   1132      1.1  joerg     DoneBB = createBasicBlock(".omp.lastprivate.done");
   1133      1.1  joerg     Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
   1134      1.1  joerg     EmitBlock(ThenBB);
   1135      1.1  joerg   }
   1136      1.1  joerg   llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
   1137      1.1  joerg   llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
   1138      1.1  joerg   if (const auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
   1139      1.1  joerg     auto IC = LoopDirective->counters().begin();
   1140      1.1  joerg     for (const Expr *F : LoopDirective->finals()) {
   1141      1.1  joerg       const auto *D =
   1142      1.1  joerg           cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl();
   1143      1.1  joerg       if (NoFinals)
   1144      1.1  joerg         AlreadyEmittedVars.insert(D);
   1145      1.1  joerg       else
   1146      1.1  joerg         LoopCountersAndUpdates[D] = F;
   1147      1.1  joerg       ++IC;
   1148      1.1  joerg     }
   1149      1.1  joerg   }
   1150      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
   1151      1.1  joerg     auto IRef = C->varlist_begin();
   1152      1.1  joerg     auto ISrcRef = C->source_exprs().begin();
   1153      1.1  joerg     auto IDestRef = C->destination_exprs().begin();
   1154      1.1  joerg     for (const Expr *AssignOp : C->assignment_ops()) {
   1155      1.1  joerg       const auto *PrivateVD =
   1156      1.1  joerg           cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
   1157      1.1  joerg       QualType Type = PrivateVD->getType();
   1158      1.1  joerg       const auto *CanonicalVD = PrivateVD->getCanonicalDecl();
   1159      1.1  joerg       if (AlreadyEmittedVars.insert(CanonicalVD).second) {
   1160      1.1  joerg         // If lastprivate variable is a loop control variable for loop-based
   1161      1.1  joerg         // directive, update its value before copyin back to original
   1162      1.1  joerg         // variable.
   1163      1.1  joerg         if (const Expr *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
   1164      1.1  joerg           EmitIgnoredExpr(FinalExpr);
   1165      1.1  joerg         const auto *SrcVD =
   1166      1.1  joerg             cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
   1167      1.1  joerg         const auto *DestVD =
   1168      1.1  joerg             cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
   1169      1.1  joerg         // Get the address of the private variable.
   1170      1.1  joerg         Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
   1171      1.1  joerg         if (const auto *RefTy = PrivateVD->getType()->getAs<ReferenceType>())
   1172      1.1  joerg           PrivateAddr =
   1173      1.1  joerg               Address(Builder.CreateLoad(PrivateAddr),
   1174  1.1.1.2  joerg                       CGM.getNaturalTypeAlignment(RefTy->getPointeeType()));
   1175  1.1.1.2  joerg         // Store the last value to the private copy in the last iteration.
   1176  1.1.1.2  joerg         if (C->getKind() == OMPC_LASTPRIVATE_conditional)
   1177  1.1.1.2  joerg           CGM.getOpenMPRuntime().emitLastprivateConditionalFinalUpdate(
   1178  1.1.1.2  joerg               *this, MakeAddrLValue(PrivateAddr, (*IRef)->getType()), PrivateVD,
   1179  1.1.1.2  joerg               (*IRef)->getExprLoc());
   1180  1.1.1.2  joerg         // Get the address of the original variable.
   1181  1.1.1.2  joerg         Address OriginalAddr = GetAddrOfLocalVar(DestVD);
   1182      1.1  joerg         EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
   1183      1.1  joerg       }
   1184      1.1  joerg       ++IRef;
   1185      1.1  joerg       ++ISrcRef;
   1186      1.1  joerg       ++IDestRef;
   1187      1.1  joerg     }
   1188      1.1  joerg     if (const Expr *PostUpdate = C->getPostUpdateExpr())
   1189      1.1  joerg       EmitIgnoredExpr(PostUpdate);
   1190      1.1  joerg   }
   1191      1.1  joerg   if (IsLastIterCond)
   1192      1.1  joerg     EmitBlock(DoneBB, /*IsFinished=*/true);
   1193      1.1  joerg }
   1194      1.1  joerg 
   1195      1.1  joerg void CodeGenFunction::EmitOMPReductionClauseInit(
   1196      1.1  joerg     const OMPExecutableDirective &D,
   1197  1.1.1.2  joerg     CodeGenFunction::OMPPrivateScope &PrivateScope, bool ForInscan) {
   1198      1.1  joerg   if (!HaveInsertPoint())
   1199      1.1  joerg     return;
   1200      1.1  joerg   SmallVector<const Expr *, 4> Shareds;
   1201      1.1  joerg   SmallVector<const Expr *, 4> Privates;
   1202      1.1  joerg   SmallVector<const Expr *, 4> ReductionOps;
   1203      1.1  joerg   SmallVector<const Expr *, 4> LHSs;
   1204      1.1  joerg   SmallVector<const Expr *, 4> RHSs;
   1205  1.1.1.2  joerg   OMPTaskDataTy Data;
   1206  1.1.1.2  joerg   SmallVector<const Expr *, 4> TaskLHSs;
   1207  1.1.1.2  joerg   SmallVector<const Expr *, 4> TaskRHSs;
   1208      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
   1209  1.1.1.2  joerg     if (ForInscan != (C->getModifier() == OMPC_REDUCTION_inscan))
   1210  1.1.1.2  joerg       continue;
   1211  1.1.1.2  joerg     Shareds.append(C->varlist_begin(), C->varlist_end());
   1212  1.1.1.2  joerg     Privates.append(C->privates().begin(), C->privates().end());
   1213  1.1.1.2  joerg     ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
   1214  1.1.1.2  joerg     LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
   1215  1.1.1.2  joerg     RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
   1216  1.1.1.2  joerg     if (C->getModifier() == OMPC_REDUCTION_task) {
   1217  1.1.1.2  joerg       Data.ReductionVars.append(C->privates().begin(), C->privates().end());
   1218  1.1.1.2  joerg       Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end());
   1219  1.1.1.2  joerg       Data.ReductionCopies.append(C->privates().begin(), C->privates().end());
   1220  1.1.1.2  joerg       Data.ReductionOps.append(C->reduction_ops().begin(),
   1221  1.1.1.2  joerg                                C->reduction_ops().end());
   1222  1.1.1.2  joerg       TaskLHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
   1223  1.1.1.2  joerg       TaskRHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
   1224      1.1  joerg     }
   1225      1.1  joerg   }
   1226  1.1.1.2  joerg   ReductionCodeGen RedCG(Shareds, Shareds, Privates, ReductionOps);
   1227      1.1  joerg   unsigned Count = 0;
   1228  1.1.1.2  joerg   auto *ILHS = LHSs.begin();
   1229  1.1.1.2  joerg   auto *IRHS = RHSs.begin();
   1230  1.1.1.2  joerg   auto *IPriv = Privates.begin();
   1231      1.1  joerg   for (const Expr *IRef : Shareds) {
   1232      1.1  joerg     const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
   1233      1.1  joerg     // Emit private VarDecl with reduction init.
   1234  1.1.1.2  joerg     RedCG.emitSharedOrigLValue(*this, Count);
   1235      1.1  joerg     RedCG.emitAggregateType(*this, Count);
   1236      1.1  joerg     AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
   1237      1.1  joerg     RedCG.emitInitialization(*this, Count, Emission.getAllocatedAddress(),
   1238      1.1  joerg                              RedCG.getSharedLValue(Count),
   1239      1.1  joerg                              [&Emission](CodeGenFunction &CGF) {
   1240      1.1  joerg                                CGF.EmitAutoVarInit(Emission);
   1241      1.1  joerg                                return true;
   1242      1.1  joerg                              });
   1243      1.1  joerg     EmitAutoVarCleanups(Emission);
   1244      1.1  joerg     Address BaseAddr = RedCG.adjustPrivateAddress(
   1245      1.1  joerg         *this, Count, Emission.getAllocatedAddress());
   1246      1.1  joerg     bool IsRegistered = PrivateScope.addPrivate(
   1247      1.1  joerg         RedCG.getBaseDecl(Count), [BaseAddr]() { return BaseAddr; });
   1248      1.1  joerg     assert(IsRegistered && "private var already registered as private");
   1249      1.1  joerg     // Silence the warning about unused variable.
   1250      1.1  joerg     (void)IsRegistered;
   1251      1.1  joerg 
   1252      1.1  joerg     const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
   1253      1.1  joerg     const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
   1254      1.1  joerg     QualType Type = PrivateVD->getType();
   1255      1.1  joerg     bool isaOMPArraySectionExpr = isa<OMPArraySectionExpr>(IRef);
   1256      1.1  joerg     if (isaOMPArraySectionExpr && Type->isVariablyModifiedType()) {
   1257      1.1  joerg       // Store the address of the original variable associated with the LHS
   1258      1.1  joerg       // implicit variable.
   1259  1.1.1.2  joerg       PrivateScope.addPrivate(LHSVD, [&RedCG, Count, this]() {
   1260  1.1.1.2  joerg         return RedCG.getSharedLValue(Count).getAddress(*this);
   1261      1.1  joerg       });
   1262      1.1  joerg       PrivateScope.addPrivate(
   1263      1.1  joerg           RHSVD, [this, PrivateVD]() { return GetAddrOfLocalVar(PrivateVD); });
   1264      1.1  joerg     } else if ((isaOMPArraySectionExpr && Type->isScalarType()) ||
   1265      1.1  joerg                isa<ArraySubscriptExpr>(IRef)) {
   1266      1.1  joerg       // Store the address of the original variable associated with the LHS
   1267      1.1  joerg       // implicit variable.
   1268  1.1.1.2  joerg       PrivateScope.addPrivate(LHSVD, [&RedCG, Count, this]() {
   1269  1.1.1.2  joerg         return RedCG.getSharedLValue(Count).getAddress(*this);
   1270      1.1  joerg       });
   1271      1.1  joerg       PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() {
   1272      1.1  joerg         return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD),
   1273      1.1  joerg                                             ConvertTypeForMem(RHSVD->getType()),
   1274      1.1  joerg                                             "rhs.begin");
   1275      1.1  joerg       });
   1276      1.1  joerg     } else {
   1277      1.1  joerg       QualType Type = PrivateVD->getType();
   1278      1.1  joerg       bool IsArray = getContext().getAsArrayType(Type) != nullptr;
   1279  1.1.1.2  joerg       Address OriginalAddr = RedCG.getSharedLValue(Count).getAddress(*this);
   1280      1.1  joerg       // Store the address of the original variable associated with the LHS
   1281      1.1  joerg       // implicit variable.
   1282      1.1  joerg       if (IsArray) {
   1283      1.1  joerg         OriginalAddr = Builder.CreateElementBitCast(
   1284      1.1  joerg             OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");
   1285      1.1  joerg       }
   1286      1.1  joerg       PrivateScope.addPrivate(LHSVD, [OriginalAddr]() { return OriginalAddr; });
   1287      1.1  joerg       PrivateScope.addPrivate(
   1288      1.1  joerg           RHSVD, [this, PrivateVD, RHSVD, IsArray]() {
   1289      1.1  joerg             return IsArray
   1290      1.1  joerg                        ? Builder.CreateElementBitCast(
   1291      1.1  joerg                              GetAddrOfLocalVar(PrivateVD),
   1292      1.1  joerg                              ConvertTypeForMem(RHSVD->getType()), "rhs.begin")
   1293      1.1  joerg                        : GetAddrOfLocalVar(PrivateVD);
   1294      1.1  joerg           });
   1295      1.1  joerg     }
   1296      1.1  joerg     ++ILHS;
   1297      1.1  joerg     ++IRHS;
   1298      1.1  joerg     ++IPriv;
   1299      1.1  joerg     ++Count;
   1300      1.1  joerg   }
   1301  1.1.1.2  joerg   if (!Data.ReductionVars.empty()) {
   1302  1.1.1.2  joerg     Data.IsReductionWithTaskMod = true;
   1303  1.1.1.2  joerg     Data.IsWorksharingReduction =
   1304  1.1.1.2  joerg         isOpenMPWorksharingDirective(D.getDirectiveKind());
   1305  1.1.1.2  joerg     llvm::Value *ReductionDesc = CGM.getOpenMPRuntime().emitTaskReductionInit(
   1306  1.1.1.2  joerg         *this, D.getBeginLoc(), TaskLHSs, TaskRHSs, Data);
   1307  1.1.1.2  joerg     const Expr *TaskRedRef = nullptr;
   1308  1.1.1.2  joerg     switch (D.getDirectiveKind()) {
   1309  1.1.1.2  joerg     case OMPD_parallel:
   1310  1.1.1.2  joerg       TaskRedRef = cast<OMPParallelDirective>(D).getTaskReductionRefExpr();
   1311  1.1.1.2  joerg       break;
   1312  1.1.1.2  joerg     case OMPD_for:
   1313  1.1.1.2  joerg       TaskRedRef = cast<OMPForDirective>(D).getTaskReductionRefExpr();
   1314  1.1.1.2  joerg       break;
   1315  1.1.1.2  joerg     case OMPD_sections:
   1316  1.1.1.2  joerg       TaskRedRef = cast<OMPSectionsDirective>(D).getTaskReductionRefExpr();
   1317  1.1.1.2  joerg       break;
   1318  1.1.1.2  joerg     case OMPD_parallel_for:
   1319  1.1.1.2  joerg       TaskRedRef = cast<OMPParallelForDirective>(D).getTaskReductionRefExpr();
   1320  1.1.1.2  joerg       break;
   1321  1.1.1.2  joerg     case OMPD_parallel_master:
   1322  1.1.1.2  joerg       TaskRedRef =
   1323  1.1.1.2  joerg           cast<OMPParallelMasterDirective>(D).getTaskReductionRefExpr();
   1324  1.1.1.2  joerg       break;
   1325  1.1.1.2  joerg     case OMPD_parallel_sections:
   1326  1.1.1.2  joerg       TaskRedRef =
   1327  1.1.1.2  joerg           cast<OMPParallelSectionsDirective>(D).getTaskReductionRefExpr();
   1328  1.1.1.2  joerg       break;
   1329  1.1.1.2  joerg     case OMPD_target_parallel:
   1330  1.1.1.2  joerg       TaskRedRef =
   1331  1.1.1.2  joerg           cast<OMPTargetParallelDirective>(D).getTaskReductionRefExpr();
   1332  1.1.1.2  joerg       break;
   1333  1.1.1.2  joerg     case OMPD_target_parallel_for:
   1334  1.1.1.2  joerg       TaskRedRef =
   1335  1.1.1.2  joerg           cast<OMPTargetParallelForDirective>(D).getTaskReductionRefExpr();
   1336  1.1.1.2  joerg       break;
   1337  1.1.1.2  joerg     case OMPD_distribute_parallel_for:
   1338  1.1.1.2  joerg       TaskRedRef =
   1339  1.1.1.2  joerg           cast<OMPDistributeParallelForDirective>(D).getTaskReductionRefExpr();
   1340  1.1.1.2  joerg       break;
   1341  1.1.1.2  joerg     case OMPD_teams_distribute_parallel_for:
   1342  1.1.1.2  joerg       TaskRedRef = cast<OMPTeamsDistributeParallelForDirective>(D)
   1343  1.1.1.2  joerg                        .getTaskReductionRefExpr();
   1344  1.1.1.2  joerg       break;
   1345  1.1.1.2  joerg     case OMPD_target_teams_distribute_parallel_for:
   1346  1.1.1.2  joerg       TaskRedRef = cast<OMPTargetTeamsDistributeParallelForDirective>(D)
   1347  1.1.1.2  joerg                        .getTaskReductionRefExpr();
   1348  1.1.1.2  joerg       break;
   1349  1.1.1.2  joerg     case OMPD_simd:
   1350  1.1.1.2  joerg     case OMPD_for_simd:
   1351  1.1.1.2  joerg     case OMPD_section:
   1352  1.1.1.2  joerg     case OMPD_single:
   1353  1.1.1.2  joerg     case OMPD_master:
   1354  1.1.1.2  joerg     case OMPD_critical:
   1355  1.1.1.2  joerg     case OMPD_parallel_for_simd:
   1356  1.1.1.2  joerg     case OMPD_task:
   1357  1.1.1.2  joerg     case OMPD_taskyield:
   1358  1.1.1.2  joerg     case OMPD_barrier:
   1359  1.1.1.2  joerg     case OMPD_taskwait:
   1360  1.1.1.2  joerg     case OMPD_taskgroup:
   1361  1.1.1.2  joerg     case OMPD_flush:
   1362  1.1.1.2  joerg     case OMPD_depobj:
   1363  1.1.1.2  joerg     case OMPD_scan:
   1364  1.1.1.2  joerg     case OMPD_ordered:
   1365  1.1.1.2  joerg     case OMPD_atomic:
   1366  1.1.1.2  joerg     case OMPD_teams:
   1367  1.1.1.2  joerg     case OMPD_target:
   1368  1.1.1.2  joerg     case OMPD_cancellation_point:
   1369  1.1.1.2  joerg     case OMPD_cancel:
   1370  1.1.1.2  joerg     case OMPD_target_data:
   1371  1.1.1.2  joerg     case OMPD_target_enter_data:
   1372  1.1.1.2  joerg     case OMPD_target_exit_data:
   1373  1.1.1.2  joerg     case OMPD_taskloop:
   1374  1.1.1.2  joerg     case OMPD_taskloop_simd:
   1375  1.1.1.2  joerg     case OMPD_master_taskloop:
   1376  1.1.1.2  joerg     case OMPD_master_taskloop_simd:
   1377  1.1.1.2  joerg     case OMPD_parallel_master_taskloop:
   1378  1.1.1.2  joerg     case OMPD_parallel_master_taskloop_simd:
   1379  1.1.1.2  joerg     case OMPD_distribute:
   1380  1.1.1.2  joerg     case OMPD_target_update:
   1381  1.1.1.2  joerg     case OMPD_distribute_parallel_for_simd:
   1382  1.1.1.2  joerg     case OMPD_distribute_simd:
   1383  1.1.1.2  joerg     case OMPD_target_parallel_for_simd:
   1384  1.1.1.2  joerg     case OMPD_target_simd:
   1385  1.1.1.2  joerg     case OMPD_teams_distribute:
   1386  1.1.1.2  joerg     case OMPD_teams_distribute_simd:
   1387  1.1.1.2  joerg     case OMPD_teams_distribute_parallel_for_simd:
   1388  1.1.1.2  joerg     case OMPD_target_teams:
   1389  1.1.1.2  joerg     case OMPD_target_teams_distribute:
   1390  1.1.1.2  joerg     case OMPD_target_teams_distribute_parallel_for_simd:
   1391  1.1.1.2  joerg     case OMPD_target_teams_distribute_simd:
   1392  1.1.1.2  joerg     case OMPD_declare_target:
   1393  1.1.1.2  joerg     case OMPD_end_declare_target:
   1394  1.1.1.2  joerg     case OMPD_threadprivate:
   1395  1.1.1.2  joerg     case OMPD_allocate:
   1396  1.1.1.2  joerg     case OMPD_declare_reduction:
   1397  1.1.1.2  joerg     case OMPD_declare_mapper:
   1398  1.1.1.2  joerg     case OMPD_declare_simd:
   1399  1.1.1.2  joerg     case OMPD_requires:
   1400  1.1.1.2  joerg     case OMPD_declare_variant:
   1401  1.1.1.2  joerg     case OMPD_begin_declare_variant:
   1402  1.1.1.2  joerg     case OMPD_end_declare_variant:
   1403  1.1.1.2  joerg     case OMPD_unknown:
   1404  1.1.1.2  joerg     default:
   1405  1.1.1.2  joerg       llvm_unreachable("Enexpected directive with task reductions.");
   1406  1.1.1.2  joerg     }
   1407  1.1.1.2  joerg 
   1408  1.1.1.2  joerg     const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(TaskRedRef)->getDecl());
   1409  1.1.1.2  joerg     EmitVarDecl(*VD);
   1410  1.1.1.2  joerg     EmitStoreOfScalar(ReductionDesc, GetAddrOfLocalVar(VD),
   1411  1.1.1.2  joerg                       /*Volatile=*/false, TaskRedRef->getType());
   1412  1.1.1.2  joerg   }
   1413      1.1  joerg }
   1414      1.1  joerg 
   1415      1.1  joerg void CodeGenFunction::EmitOMPReductionClauseFinal(
   1416      1.1  joerg     const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) {
   1417      1.1  joerg   if (!HaveInsertPoint())
   1418      1.1  joerg     return;
   1419      1.1  joerg   llvm::SmallVector<const Expr *, 8> Privates;
   1420      1.1  joerg   llvm::SmallVector<const Expr *, 8> LHSExprs;
   1421      1.1  joerg   llvm::SmallVector<const Expr *, 8> RHSExprs;
   1422      1.1  joerg   llvm::SmallVector<const Expr *, 8> ReductionOps;
   1423      1.1  joerg   bool HasAtLeastOneReduction = false;
   1424  1.1.1.2  joerg   bool IsReductionWithTaskMod = false;
   1425      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
   1426  1.1.1.2  joerg     // Do not emit for inscan reductions.
   1427  1.1.1.2  joerg     if (C->getModifier() == OMPC_REDUCTION_inscan)
   1428  1.1.1.2  joerg       continue;
   1429      1.1  joerg     HasAtLeastOneReduction = true;
   1430      1.1  joerg     Privates.append(C->privates().begin(), C->privates().end());
   1431      1.1  joerg     LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
   1432      1.1  joerg     RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
   1433      1.1  joerg     ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
   1434  1.1.1.2  joerg     IsReductionWithTaskMod =
   1435  1.1.1.2  joerg         IsReductionWithTaskMod || C->getModifier() == OMPC_REDUCTION_task;
   1436      1.1  joerg   }
   1437      1.1  joerg   if (HasAtLeastOneReduction) {
   1438  1.1.1.2  joerg     if (IsReductionWithTaskMod) {
   1439  1.1.1.2  joerg       CGM.getOpenMPRuntime().emitTaskReductionFini(
   1440  1.1.1.2  joerg           *this, D.getBeginLoc(),
   1441  1.1.1.2  joerg           isOpenMPWorksharingDirective(D.getDirectiveKind()));
   1442  1.1.1.2  joerg     }
   1443      1.1  joerg     bool WithNowait = D.getSingleClause<OMPNowaitClause>() ||
   1444      1.1  joerg                       isOpenMPParallelDirective(D.getDirectiveKind()) ||
   1445      1.1  joerg                       ReductionKind == OMPD_simd;
   1446      1.1  joerg     bool SimpleReduction = ReductionKind == OMPD_simd;
   1447      1.1  joerg     // Emit nowait reduction if nowait clause is present or directive is a
   1448      1.1  joerg     // parallel directive (it always has implicit barrier).
   1449      1.1  joerg     CGM.getOpenMPRuntime().emitReduction(
   1450      1.1  joerg         *this, D.getEndLoc(), Privates, LHSExprs, RHSExprs, ReductionOps,
   1451      1.1  joerg         {WithNowait, SimpleReduction, ReductionKind});
   1452      1.1  joerg   }
   1453      1.1  joerg }
   1454      1.1  joerg 
   1455      1.1  joerg static void emitPostUpdateForReductionClause(
   1456      1.1  joerg     CodeGenFunction &CGF, const OMPExecutableDirective &D,
   1457      1.1  joerg     const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
   1458      1.1  joerg   if (!CGF.HaveInsertPoint())
   1459      1.1  joerg     return;
   1460      1.1  joerg   llvm::BasicBlock *DoneBB = nullptr;
   1461      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
   1462      1.1  joerg     if (const Expr *PostUpdate = C->getPostUpdateExpr()) {
   1463      1.1  joerg       if (!DoneBB) {
   1464      1.1  joerg         if (llvm::Value *Cond = CondGen(CGF)) {
   1465      1.1  joerg           // If the first post-update expression is found, emit conditional
   1466      1.1  joerg           // block if it was requested.
   1467      1.1  joerg           llvm::BasicBlock *ThenBB = CGF.createBasicBlock(".omp.reduction.pu");
   1468      1.1  joerg           DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done");
   1469      1.1  joerg           CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB);
   1470      1.1  joerg           CGF.EmitBlock(ThenBB);
   1471      1.1  joerg         }
   1472      1.1  joerg       }
   1473      1.1  joerg       CGF.EmitIgnoredExpr(PostUpdate);
   1474      1.1  joerg     }
   1475      1.1  joerg   }
   1476      1.1  joerg   if (DoneBB)
   1477      1.1  joerg     CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
   1478      1.1  joerg }
   1479      1.1  joerg 
   1480      1.1  joerg namespace {
   1481      1.1  joerg /// Codegen lambda for appending distribute lower and upper bounds to outlined
   1482      1.1  joerg /// parallel function. This is necessary for combined constructs such as
   1483      1.1  joerg /// 'distribute parallel for'
   1484      1.1  joerg typedef llvm::function_ref<void(CodeGenFunction &,
   1485      1.1  joerg                                 const OMPExecutableDirective &,
   1486      1.1  joerg                                 llvm::SmallVectorImpl<llvm::Value *> &)>
   1487      1.1  joerg     CodeGenBoundParametersTy;
   1488      1.1  joerg } // anonymous namespace
   1489      1.1  joerg 
   1490  1.1.1.2  joerg static void
   1491  1.1.1.2  joerg checkForLastprivateConditionalUpdate(CodeGenFunction &CGF,
   1492  1.1.1.2  joerg                                      const OMPExecutableDirective &S) {
   1493  1.1.1.2  joerg   if (CGF.getLangOpts().OpenMP < 50)
   1494  1.1.1.2  joerg     return;
   1495  1.1.1.2  joerg   llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> PrivateDecls;
   1496  1.1.1.2  joerg   for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
   1497  1.1.1.2  joerg     for (const Expr *Ref : C->varlists()) {
   1498  1.1.1.2  joerg       if (!Ref->getType()->isScalarType())
   1499  1.1.1.2  joerg         continue;
   1500  1.1.1.2  joerg       const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
   1501  1.1.1.2  joerg       if (!DRE)
   1502  1.1.1.2  joerg         continue;
   1503  1.1.1.2  joerg       PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
   1504  1.1.1.2  joerg       CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref);
   1505  1.1.1.2  joerg     }
   1506  1.1.1.2  joerg   }
   1507  1.1.1.2  joerg   for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
   1508  1.1.1.2  joerg     for (const Expr *Ref : C->varlists()) {
   1509  1.1.1.2  joerg       if (!Ref->getType()->isScalarType())
   1510  1.1.1.2  joerg         continue;
   1511  1.1.1.2  joerg       const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
   1512  1.1.1.2  joerg       if (!DRE)
   1513  1.1.1.2  joerg         continue;
   1514  1.1.1.2  joerg       PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
   1515  1.1.1.2  joerg       CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref);
   1516  1.1.1.2  joerg     }
   1517  1.1.1.2  joerg   }
   1518  1.1.1.2  joerg   for (const auto *C : S.getClausesOfKind<OMPLinearClause>()) {
   1519  1.1.1.2  joerg     for (const Expr *Ref : C->varlists()) {
   1520  1.1.1.2  joerg       if (!Ref->getType()->isScalarType())
   1521  1.1.1.2  joerg         continue;
   1522  1.1.1.2  joerg       const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
   1523  1.1.1.2  joerg       if (!DRE)
   1524  1.1.1.2  joerg         continue;
   1525  1.1.1.2  joerg       PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
   1526  1.1.1.2  joerg       CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref);
   1527  1.1.1.2  joerg     }
   1528  1.1.1.2  joerg   }
   1529  1.1.1.2  joerg   // Privates should ne analyzed since they are not captured at all.
   1530  1.1.1.2  joerg   // Task reductions may be skipped - tasks are ignored.
   1531  1.1.1.2  joerg   // Firstprivates do not return value but may be passed by reference - no need
   1532  1.1.1.2  joerg   // to check for updated lastprivate conditional.
   1533  1.1.1.2  joerg   for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
   1534  1.1.1.2  joerg     for (const Expr *Ref : C->varlists()) {
   1535  1.1.1.2  joerg       if (!Ref->getType()->isScalarType())
   1536  1.1.1.2  joerg         continue;
   1537  1.1.1.2  joerg       const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
   1538  1.1.1.2  joerg       if (!DRE)
   1539  1.1.1.2  joerg         continue;
   1540  1.1.1.2  joerg       PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
   1541  1.1.1.2  joerg     }
   1542  1.1.1.2  joerg   }
   1543  1.1.1.2  joerg   CGF.CGM.getOpenMPRuntime().checkAndEmitSharedLastprivateConditional(
   1544  1.1.1.2  joerg       CGF, S, PrivateDecls);
   1545  1.1.1.2  joerg }
   1546  1.1.1.2  joerg 
   1547      1.1  joerg static void emitCommonOMPParallelDirective(
   1548      1.1  joerg     CodeGenFunction &CGF, const OMPExecutableDirective &S,
   1549      1.1  joerg     OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
   1550      1.1  joerg     const CodeGenBoundParametersTy &CodeGenBoundParameters) {
   1551      1.1  joerg   const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
   1552      1.1  joerg   llvm::Function *OutlinedFn =
   1553      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
   1554      1.1  joerg           S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
   1555      1.1  joerg   if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
   1556      1.1  joerg     CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
   1557      1.1  joerg     llvm::Value *NumThreads =
   1558      1.1  joerg         CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
   1559      1.1  joerg                            /*IgnoreResultAssign=*/true);
   1560      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
   1561      1.1  joerg         CGF, NumThreads, NumThreadsClause->getBeginLoc());
   1562      1.1  joerg   }
   1563      1.1  joerg   if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) {
   1564      1.1  joerg     CodeGenFunction::RunCleanupsScope ProcBindScope(CGF);
   1565      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitProcBindClause(
   1566      1.1  joerg         CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getBeginLoc());
   1567      1.1  joerg   }
   1568      1.1  joerg   const Expr *IfCond = nullptr;
   1569      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
   1570      1.1  joerg     if (C->getNameModifier() == OMPD_unknown ||
   1571      1.1  joerg         C->getNameModifier() == OMPD_parallel) {
   1572      1.1  joerg       IfCond = C->getCondition();
   1573      1.1  joerg       break;
   1574      1.1  joerg     }
   1575      1.1  joerg   }
   1576      1.1  joerg 
   1577      1.1  joerg   OMPParallelScope Scope(CGF, S);
   1578      1.1  joerg   llvm::SmallVector<llvm::Value *, 16> CapturedVars;
   1579      1.1  joerg   // Combining 'distribute' with 'for' requires sharing each 'distribute' chunk
   1580      1.1  joerg   // lower and upper bounds with the pragma 'for' chunking mechanism.
   1581      1.1  joerg   // The following lambda takes care of appending the lower and upper bound
   1582      1.1  joerg   // parameters when necessary
   1583      1.1  joerg   CodeGenBoundParameters(CGF, S, CapturedVars);
   1584      1.1  joerg   CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
   1585      1.1  joerg   CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getBeginLoc(), OutlinedFn,
   1586      1.1  joerg                                               CapturedVars, IfCond);
   1587      1.1  joerg }
   1588      1.1  joerg 
   1589  1.1.1.2  joerg static bool isAllocatableDecl(const VarDecl *VD) {
   1590  1.1.1.2  joerg   const VarDecl *CVD = VD->getCanonicalDecl();
   1591  1.1.1.2  joerg   if (!CVD->hasAttr<OMPAllocateDeclAttr>())
   1592  1.1.1.2  joerg     return false;
   1593  1.1.1.2  joerg   const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
   1594  1.1.1.2  joerg   // Use the default allocation.
   1595  1.1.1.2  joerg   return !((AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc ||
   1596  1.1.1.2  joerg             AA->getAllocatorType() == OMPAllocateDeclAttr::OMPNullMemAlloc) &&
   1597  1.1.1.2  joerg            !AA->getAllocator());
   1598  1.1.1.2  joerg }
   1599  1.1.1.2  joerg 
   1600      1.1  joerg static void emitEmptyBoundParameters(CodeGenFunction &,
   1601      1.1  joerg                                      const OMPExecutableDirective &,
   1602      1.1  joerg                                      llvm::SmallVectorImpl<llvm::Value *> &) {}
   1603      1.1  joerg 
   1604  1.1.1.2  joerg Address CodeGenFunction::OMPBuilderCBHelpers::getAddressOfLocalVariable(
   1605  1.1.1.2  joerg     CodeGenFunction &CGF, const VarDecl *VD) {
   1606  1.1.1.2  joerg   CodeGenModule &CGM = CGF.CGM;
   1607  1.1.1.2  joerg   auto &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   1608  1.1.1.2  joerg 
   1609  1.1.1.2  joerg   if (!VD)
   1610  1.1.1.2  joerg     return Address::invalid();
   1611  1.1.1.2  joerg   const VarDecl *CVD = VD->getCanonicalDecl();
   1612  1.1.1.2  joerg   if (!isAllocatableDecl(CVD))
   1613  1.1.1.2  joerg     return Address::invalid();
   1614  1.1.1.2  joerg   llvm::Value *Size;
   1615  1.1.1.2  joerg   CharUnits Align = CGM.getContext().getDeclAlign(CVD);
   1616  1.1.1.2  joerg   if (CVD->getType()->isVariablyModifiedType()) {
   1617  1.1.1.2  joerg     Size = CGF.getTypeSize(CVD->getType());
   1618  1.1.1.2  joerg     // Align the size: ((size + align - 1) / align) * align
   1619  1.1.1.2  joerg     Size = CGF.Builder.CreateNUWAdd(
   1620  1.1.1.2  joerg         Size, CGM.getSize(Align - CharUnits::fromQuantity(1)));
   1621  1.1.1.2  joerg     Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align));
   1622  1.1.1.2  joerg     Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align));
   1623  1.1.1.2  joerg   } else {
   1624  1.1.1.2  joerg     CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType());
   1625  1.1.1.2  joerg     Size = CGM.getSize(Sz.alignTo(Align));
   1626  1.1.1.2  joerg   }
   1627  1.1.1.2  joerg 
   1628  1.1.1.2  joerg   const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
   1629  1.1.1.2  joerg   assert(AA->getAllocator() &&
   1630  1.1.1.2  joerg          "Expected allocator expression for non-default allocator.");
   1631  1.1.1.2  joerg   llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator());
   1632  1.1.1.2  joerg   // According to the standard, the original allocator type is a enum (integer).
   1633  1.1.1.2  joerg   // Convert to pointer type, if required.
   1634  1.1.1.2  joerg   if (Allocator->getType()->isIntegerTy())
   1635  1.1.1.2  joerg     Allocator = CGF.Builder.CreateIntToPtr(Allocator, CGM.VoidPtrTy);
   1636  1.1.1.2  joerg   else if (Allocator->getType()->isPointerTy())
   1637  1.1.1.2  joerg     Allocator = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Allocator,
   1638  1.1.1.2  joerg                                                                 CGM.VoidPtrTy);
   1639  1.1.1.2  joerg 
   1640  1.1.1.2  joerg   llvm::Value *Addr = OMPBuilder.createOMPAlloc(
   1641  1.1.1.2  joerg       CGF.Builder, Size, Allocator,
   1642  1.1.1.2  joerg       getNameWithSeparators({CVD->getName(), ".void.addr"}, ".", "."));
   1643  1.1.1.2  joerg   llvm::CallInst *FreeCI =
   1644  1.1.1.2  joerg       OMPBuilder.createOMPFree(CGF.Builder, Addr, Allocator);
   1645  1.1.1.2  joerg 
   1646  1.1.1.2  joerg   CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>(NormalAndEHCleanup, FreeCI);
   1647  1.1.1.2  joerg   Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
   1648  1.1.1.2  joerg       Addr,
   1649  1.1.1.2  joerg       CGF.ConvertTypeForMem(CGM.getContext().getPointerType(CVD->getType())),
   1650  1.1.1.2  joerg       getNameWithSeparators({CVD->getName(), ".addr"}, ".", "."));
   1651  1.1.1.2  joerg   return Address(Addr, Align);
   1652  1.1.1.2  joerg }
   1653  1.1.1.2  joerg 
   1654  1.1.1.2  joerg Address CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate(
   1655  1.1.1.2  joerg     CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr,
   1656  1.1.1.2  joerg     SourceLocation Loc) {
   1657  1.1.1.2  joerg   CodeGenModule &CGM = CGF.CGM;
   1658  1.1.1.2  joerg   if (CGM.getLangOpts().OpenMPUseTLS &&
   1659  1.1.1.2  joerg       CGM.getContext().getTargetInfo().isTLSSupported())
   1660  1.1.1.2  joerg     return VDAddr;
   1661  1.1.1.2  joerg 
   1662  1.1.1.2  joerg   llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   1663  1.1.1.2  joerg 
   1664  1.1.1.2  joerg   llvm::Type *VarTy = VDAddr.getElementType();
   1665  1.1.1.2  joerg   llvm::Value *Data =
   1666  1.1.1.2  joerg       CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.Int8PtrTy);
   1667  1.1.1.2  joerg   llvm::ConstantInt *Size = CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy));
   1668  1.1.1.2  joerg   std::string Suffix = getNameWithSeparators({"cache", ""});
   1669  1.1.1.2  joerg   llvm::Twine CacheName = Twine(CGM.getMangledName(VD)).concat(Suffix);
   1670  1.1.1.2  joerg 
   1671  1.1.1.2  joerg   llvm::CallInst *ThreadPrivateCacheCall =
   1672  1.1.1.2  joerg       OMPBuilder.createCachedThreadPrivate(CGF.Builder, Data, Size, CacheName);
   1673  1.1.1.2  joerg 
   1674  1.1.1.2  joerg   return Address(ThreadPrivateCacheCall, VDAddr.getAlignment());
   1675  1.1.1.2  joerg }
   1676  1.1.1.2  joerg 
   1677  1.1.1.2  joerg std::string CodeGenFunction::OMPBuilderCBHelpers::getNameWithSeparators(
   1678  1.1.1.2  joerg     ArrayRef<StringRef> Parts, StringRef FirstSeparator, StringRef Separator) {
   1679  1.1.1.2  joerg   SmallString<128> Buffer;
   1680  1.1.1.2  joerg   llvm::raw_svector_ostream OS(Buffer);
   1681  1.1.1.2  joerg   StringRef Sep = FirstSeparator;
   1682  1.1.1.2  joerg   for (StringRef Part : Parts) {
   1683  1.1.1.2  joerg     OS << Sep << Part;
   1684  1.1.1.2  joerg     Sep = Separator;
   1685  1.1.1.2  joerg   }
   1686  1.1.1.2  joerg   return OS.str().str();
   1687  1.1.1.2  joerg }
   1688      1.1  joerg void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
   1689  1.1.1.2  joerg   if (CGM.getLangOpts().OpenMPIRBuilder) {
   1690  1.1.1.2  joerg     llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   1691  1.1.1.2  joerg     // Check if we have any if clause associated with the directive.
   1692  1.1.1.2  joerg     llvm::Value *IfCond = nullptr;
   1693  1.1.1.2  joerg     if (const auto *C = S.getSingleClause<OMPIfClause>())
   1694  1.1.1.2  joerg       IfCond = EmitScalarExpr(C->getCondition(),
   1695  1.1.1.2  joerg                               /*IgnoreResultAssign=*/true);
   1696  1.1.1.2  joerg 
   1697  1.1.1.2  joerg     llvm::Value *NumThreads = nullptr;
   1698  1.1.1.2  joerg     if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>())
   1699  1.1.1.2  joerg       NumThreads = EmitScalarExpr(NumThreadsClause->getNumThreads(),
   1700  1.1.1.2  joerg                                   /*IgnoreResultAssign=*/true);
   1701  1.1.1.2  joerg 
   1702  1.1.1.2  joerg     ProcBindKind ProcBind = OMP_PROC_BIND_default;
   1703  1.1.1.2  joerg     if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>())
   1704  1.1.1.2  joerg       ProcBind = ProcBindClause->getProcBindKind();
   1705  1.1.1.2  joerg 
   1706  1.1.1.2  joerg     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
   1707  1.1.1.2  joerg 
   1708  1.1.1.2  joerg     // The cleanup callback that finalizes all variabels at the given location,
   1709  1.1.1.2  joerg     // thus calls destructors etc.
   1710  1.1.1.2  joerg     auto FiniCB = [this](InsertPointTy IP) {
   1711  1.1.1.2  joerg       OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
   1712  1.1.1.2  joerg     };
   1713  1.1.1.2  joerg 
   1714  1.1.1.2  joerg     // Privatization callback that performs appropriate action for
   1715  1.1.1.2  joerg     // shared/private/firstprivate/lastprivate/copyin/... variables.
   1716  1.1.1.2  joerg     //
   1717  1.1.1.2  joerg     // TODO: This defaults to shared right now.
   1718  1.1.1.2  joerg     auto PrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
   1719  1.1.1.2  joerg                      llvm::Value &, llvm::Value &Val, llvm::Value *&ReplVal) {
   1720  1.1.1.2  joerg       // The next line is appropriate only for variables (Val) with the
   1721  1.1.1.2  joerg       // data-sharing attribute "shared".
   1722  1.1.1.2  joerg       ReplVal = &Val;
   1723  1.1.1.2  joerg 
   1724  1.1.1.2  joerg       return CodeGenIP;
   1725  1.1.1.2  joerg     };
   1726  1.1.1.2  joerg 
   1727  1.1.1.2  joerg     const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
   1728  1.1.1.2  joerg     const Stmt *ParallelRegionBodyStmt = CS->getCapturedStmt();
   1729  1.1.1.2  joerg 
   1730  1.1.1.2  joerg     auto BodyGenCB = [ParallelRegionBodyStmt,
   1731  1.1.1.2  joerg                       this](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
   1732  1.1.1.2  joerg                             llvm::BasicBlock &ContinuationBB) {
   1733  1.1.1.2  joerg       OMPBuilderCBHelpers::OutlinedRegionBodyRAII ORB(*this, AllocaIP,
   1734  1.1.1.2  joerg                                                       ContinuationBB);
   1735  1.1.1.2  joerg       OMPBuilderCBHelpers::EmitOMPRegionBody(*this, ParallelRegionBodyStmt,
   1736  1.1.1.2  joerg                                              CodeGenIP, ContinuationBB);
   1737  1.1.1.2  joerg     };
   1738  1.1.1.2  joerg 
   1739  1.1.1.2  joerg     CGCapturedStmtInfo CGSI(*CS, CR_OpenMP);
   1740  1.1.1.2  joerg     CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI);
   1741  1.1.1.2  joerg     llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
   1742  1.1.1.2  joerg         AllocaInsertPt->getParent(), AllocaInsertPt->getIterator());
   1743  1.1.1.2  joerg     Builder.restoreIP(
   1744  1.1.1.2  joerg         OMPBuilder.createParallel(Builder, AllocaIP, BodyGenCB, PrivCB, FiniCB,
   1745  1.1.1.2  joerg                                   IfCond, NumThreads, ProcBind, S.hasCancel()));
   1746  1.1.1.2  joerg     return;
   1747  1.1.1.2  joerg   }
   1748  1.1.1.2  joerg 
   1749      1.1  joerg   // Emit parallel region as a standalone region.
   1750      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   1751      1.1  joerg     Action.Enter(CGF);
   1752      1.1  joerg     OMPPrivateScope PrivateScope(CGF);
   1753      1.1  joerg     bool Copyins = CGF.EmitOMPCopyinClause(S);
   1754      1.1  joerg     (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
   1755      1.1  joerg     if (Copyins) {
   1756      1.1  joerg       // Emit implicit barrier to synchronize threads and avoid data races on
   1757      1.1  joerg       // propagation master's thread values of threadprivate variables to local
   1758      1.1  joerg       // instances of that variables of all other implicit threads.
   1759      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitBarrierCall(
   1760      1.1  joerg           CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
   1761      1.1  joerg           /*ForceSimpleCall=*/true);
   1762      1.1  joerg     }
   1763      1.1  joerg     CGF.EmitOMPPrivateClause(S, PrivateScope);
   1764      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   1765      1.1  joerg     (void)PrivateScope.Privatize();
   1766      1.1  joerg     CGF.EmitStmt(S.getCapturedStmt(OMPD_parallel)->getCapturedStmt());
   1767      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
   1768      1.1  joerg   };
   1769  1.1.1.2  joerg   {
   1770  1.1.1.2  joerg     auto LPCRegion =
   1771  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   1772  1.1.1.2  joerg     emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen,
   1773  1.1.1.2  joerg                                    emitEmptyBoundParameters);
   1774  1.1.1.2  joerg     emitPostUpdateForReductionClause(*this, S,
   1775  1.1.1.2  joerg                                      [](CodeGenFunction &) { return nullptr; });
   1776  1.1.1.2  joerg   }
   1777  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   1778  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   1779  1.1.1.2  joerg }
   1780  1.1.1.2  joerg 
   1781  1.1.1.2  joerg namespace {
   1782  1.1.1.2  joerg /// RAII to handle scopes for loop transformation directives.
   1783  1.1.1.2  joerg class OMPTransformDirectiveScopeRAII {
   1784  1.1.1.2  joerg   OMPLoopScope *Scope = nullptr;
   1785  1.1.1.2  joerg   CodeGenFunction::CGCapturedStmtInfo *CGSI = nullptr;
   1786  1.1.1.2  joerg   CodeGenFunction::CGCapturedStmtRAII *CapInfoRAII = nullptr;
   1787  1.1.1.2  joerg 
   1788  1.1.1.2  joerg public:
   1789  1.1.1.2  joerg   OMPTransformDirectiveScopeRAII(CodeGenFunction &CGF, const Stmt *S) {
   1790  1.1.1.2  joerg     if (const auto *Dir = dyn_cast<OMPLoopBasedDirective>(S)) {
   1791  1.1.1.2  joerg       Scope = new OMPLoopScope(CGF, *Dir);
   1792  1.1.1.2  joerg       CGSI = new CodeGenFunction::CGCapturedStmtInfo(CR_OpenMP);
   1793  1.1.1.2  joerg       CapInfoRAII = new CodeGenFunction::CGCapturedStmtRAII(CGF, CGSI);
   1794  1.1.1.2  joerg     }
   1795  1.1.1.2  joerg   }
   1796  1.1.1.2  joerg   ~OMPTransformDirectiveScopeRAII() {
   1797  1.1.1.2  joerg     if (!Scope)
   1798  1.1.1.2  joerg       return;
   1799  1.1.1.2  joerg     delete CapInfoRAII;
   1800  1.1.1.2  joerg     delete CGSI;
   1801  1.1.1.2  joerg     delete Scope;
   1802  1.1.1.2  joerg   }
   1803  1.1.1.2  joerg };
   1804  1.1.1.2  joerg } // namespace
   1805  1.1.1.2  joerg 
   1806  1.1.1.2  joerg static void emitBody(CodeGenFunction &CGF, const Stmt *S, const Stmt *NextLoop,
   1807  1.1.1.2  joerg                      int MaxLevel, int Level = 0) {
   1808  1.1.1.2  joerg   assert(Level < MaxLevel && "Too deep lookup during loop body codegen.");
   1809  1.1.1.2  joerg   const Stmt *SimplifiedS = S->IgnoreContainers();
   1810  1.1.1.2  joerg   if (const auto *CS = dyn_cast<CompoundStmt>(SimplifiedS)) {
   1811  1.1.1.2  joerg     PrettyStackTraceLoc CrashInfo(
   1812  1.1.1.2  joerg         CGF.getContext().getSourceManager(), CS->getLBracLoc(),
   1813  1.1.1.2  joerg         "LLVM IR generation of compound statement ('{}')");
   1814  1.1.1.2  joerg 
   1815  1.1.1.2  joerg     // Keep track of the current cleanup stack depth, including debug scopes.
   1816  1.1.1.2  joerg     CodeGenFunction::LexicalScope Scope(CGF, S->getSourceRange());
   1817  1.1.1.2  joerg     for (const Stmt *CurStmt : CS->body())
   1818  1.1.1.2  joerg       emitBody(CGF, CurStmt, NextLoop, MaxLevel, Level);
   1819  1.1.1.2  joerg     return;
   1820  1.1.1.2  joerg   }
   1821  1.1.1.2  joerg   if (SimplifiedS == NextLoop) {
   1822  1.1.1.2  joerg     OMPTransformDirectiveScopeRAII PossiblyTransformDirectiveScope(CGF,
   1823  1.1.1.2  joerg                                                                    SimplifiedS);
   1824  1.1.1.2  joerg     if (auto *Dir = dyn_cast<OMPTileDirective>(SimplifiedS))
   1825  1.1.1.2  joerg       SimplifiedS = Dir->getTransformedStmt();
   1826  1.1.1.2  joerg     if (const auto *CanonLoop = dyn_cast<OMPCanonicalLoop>(SimplifiedS))
   1827  1.1.1.2  joerg       SimplifiedS = CanonLoop->getLoopStmt();
   1828  1.1.1.2  joerg     if (const auto *For = dyn_cast<ForStmt>(SimplifiedS)) {
   1829  1.1.1.2  joerg       S = For->getBody();
   1830  1.1.1.2  joerg     } else {
   1831  1.1.1.2  joerg       assert(isa<CXXForRangeStmt>(SimplifiedS) &&
   1832  1.1.1.2  joerg              "Expected canonical for loop or range-based for loop.");
   1833  1.1.1.2  joerg       const auto *CXXFor = cast<CXXForRangeStmt>(SimplifiedS);
   1834  1.1.1.2  joerg       CGF.EmitStmt(CXXFor->getLoopVarStmt());
   1835  1.1.1.2  joerg       S = CXXFor->getBody();
   1836  1.1.1.2  joerg     }
   1837  1.1.1.2  joerg     if (Level + 1 < MaxLevel) {
   1838  1.1.1.2  joerg       NextLoop = OMPLoopDirective::tryToFindNextInnerLoop(
   1839  1.1.1.2  joerg           S, /*TryImperfectlyNestedLoops=*/true);
   1840  1.1.1.2  joerg       emitBody(CGF, S, NextLoop, MaxLevel, Level + 1);
   1841  1.1.1.2  joerg       return;
   1842  1.1.1.2  joerg     }
   1843  1.1.1.2  joerg   }
   1844  1.1.1.2  joerg   CGF.EmitStmt(S);
   1845      1.1  joerg }
   1846      1.1  joerg 
   1847      1.1  joerg void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
   1848      1.1  joerg                                       JumpDest LoopExit) {
   1849      1.1  joerg   RunCleanupsScope BodyScope(*this);
   1850      1.1  joerg   // Update counters values on current iteration.
   1851      1.1  joerg   for (const Expr *UE : D.updates())
   1852      1.1  joerg     EmitIgnoredExpr(UE);
   1853      1.1  joerg   // Update the linear variables.
   1854      1.1  joerg   // In distribute directives only loop counters may be marked as linear, no
   1855      1.1  joerg   // need to generate the code for them.
   1856      1.1  joerg   if (!isOpenMPDistributeDirective(D.getDirectiveKind())) {
   1857      1.1  joerg     for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
   1858      1.1  joerg       for (const Expr *UE : C->updates())
   1859      1.1  joerg         EmitIgnoredExpr(UE);
   1860      1.1  joerg     }
   1861      1.1  joerg   }
   1862      1.1  joerg 
   1863      1.1  joerg   // On a continue in the body, jump to the end.
   1864      1.1  joerg   JumpDest Continue = getJumpDestInCurrentScope("omp.body.continue");
   1865      1.1  joerg   BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
   1866      1.1  joerg   for (const Expr *E : D.finals_conditions()) {
   1867      1.1  joerg     if (!E)
   1868      1.1  joerg       continue;
   1869      1.1  joerg     // Check that loop counter in non-rectangular nest fits into the iteration
   1870      1.1  joerg     // space.
   1871      1.1  joerg     llvm::BasicBlock *NextBB = createBasicBlock("omp.body.next");
   1872      1.1  joerg     EmitBranchOnBoolExpr(E, NextBB, Continue.getBlock(),
   1873      1.1  joerg                          getProfileCount(D.getBody()));
   1874      1.1  joerg     EmitBlock(NextBB);
   1875      1.1  joerg   }
   1876  1.1.1.2  joerg 
   1877  1.1.1.2  joerg   OMPPrivateScope InscanScope(*this);
   1878  1.1.1.2  joerg   EmitOMPReductionClauseInit(D, InscanScope, /*ForInscan=*/true);
   1879  1.1.1.2  joerg   bool IsInscanRegion = InscanScope.Privatize();
   1880  1.1.1.2  joerg   if (IsInscanRegion) {
   1881  1.1.1.2  joerg     // Need to remember the block before and after scan directive
   1882  1.1.1.2  joerg     // to dispatch them correctly depending on the clause used in
   1883  1.1.1.2  joerg     // this directive, inclusive or exclusive. For inclusive scan the natural
   1884  1.1.1.2  joerg     // order of the blocks is used, for exclusive clause the blocks must be
   1885  1.1.1.2  joerg     // executed in reverse order.
   1886  1.1.1.2  joerg     OMPBeforeScanBlock = createBasicBlock("omp.before.scan.bb");
   1887  1.1.1.2  joerg     OMPAfterScanBlock = createBasicBlock("omp.after.scan.bb");
   1888  1.1.1.2  joerg     // No need to allocate inscan exit block, in simd mode it is selected in the
   1889  1.1.1.2  joerg     // codegen for the scan directive.
   1890  1.1.1.2  joerg     if (D.getDirectiveKind() != OMPD_simd && !getLangOpts().OpenMPSimd)
   1891  1.1.1.2  joerg       OMPScanExitBlock = createBasicBlock("omp.exit.inscan.bb");
   1892  1.1.1.2  joerg     OMPScanDispatch = createBasicBlock("omp.inscan.dispatch");
   1893  1.1.1.2  joerg     EmitBranch(OMPScanDispatch);
   1894  1.1.1.2  joerg     EmitBlock(OMPBeforeScanBlock);
   1895  1.1.1.2  joerg   }
   1896  1.1.1.2  joerg 
   1897      1.1  joerg   // Emit loop variables for C++ range loops.
   1898      1.1  joerg   const Stmt *Body =
   1899      1.1  joerg       D.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
   1900      1.1  joerg   // Emit loop body.
   1901  1.1.1.2  joerg   emitBody(*this, Body,
   1902  1.1.1.2  joerg            OMPLoopBasedDirective::tryToFindNextInnerLoop(
   1903  1.1.1.2  joerg                Body, /*TryImperfectlyNestedLoops=*/true),
   1904  1.1.1.2  joerg            D.getLoopsNumber());
   1905  1.1.1.2  joerg 
   1906  1.1.1.2  joerg   // Jump to the dispatcher at the end of the loop body.
   1907  1.1.1.2  joerg   if (IsInscanRegion)
   1908  1.1.1.2  joerg     EmitBranch(OMPScanExitBlock);
   1909  1.1.1.2  joerg 
   1910      1.1  joerg   // The end (updates/cleanups).
   1911      1.1  joerg   EmitBlock(Continue.getBlock());
   1912      1.1  joerg   BreakContinueStack.pop_back();
   1913      1.1  joerg }
   1914      1.1  joerg 
   1915  1.1.1.2  joerg using EmittedClosureTy = std::pair<llvm::Function *, llvm::Value *>;
   1916  1.1.1.2  joerg 
   1917  1.1.1.2  joerg /// Emit a captured statement and return the function as well as its captured
   1918  1.1.1.2  joerg /// closure context.
   1919  1.1.1.2  joerg static EmittedClosureTy emitCapturedStmtFunc(CodeGenFunction &ParentCGF,
   1920  1.1.1.2  joerg                                              const CapturedStmt *S) {
   1921  1.1.1.2  joerg   LValue CapStruct = ParentCGF.InitCapturedStruct(*S);
   1922  1.1.1.2  joerg   CodeGenFunction CGF(ParentCGF.CGM, /*suppressNewContext=*/true);
   1923  1.1.1.2  joerg   std::unique_ptr<CodeGenFunction::CGCapturedStmtInfo> CSI =
   1924  1.1.1.2  joerg       std::make_unique<CodeGenFunction::CGCapturedStmtInfo>(*S);
   1925  1.1.1.2  joerg   CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, CSI.get());
   1926  1.1.1.2  joerg   llvm::Function *F = CGF.GenerateCapturedStmtFunction(*S);
   1927  1.1.1.2  joerg 
   1928  1.1.1.2  joerg   return {F, CapStruct.getPointer(ParentCGF)};
   1929  1.1.1.2  joerg }
   1930  1.1.1.2  joerg 
   1931  1.1.1.2  joerg /// Emit a call to a previously captured closure.
   1932  1.1.1.2  joerg static llvm::CallInst *
   1933  1.1.1.2  joerg emitCapturedStmtCall(CodeGenFunction &ParentCGF, EmittedClosureTy Cap,
   1934  1.1.1.2  joerg                      llvm::ArrayRef<llvm::Value *> Args) {
   1935  1.1.1.2  joerg   // Append the closure context to the argument.
   1936  1.1.1.2  joerg   SmallVector<llvm::Value *> EffectiveArgs;
   1937  1.1.1.2  joerg   EffectiveArgs.reserve(Args.size() + 1);
   1938  1.1.1.2  joerg   llvm::append_range(EffectiveArgs, Args);
   1939  1.1.1.2  joerg   EffectiveArgs.push_back(Cap.second);
   1940  1.1.1.2  joerg 
   1941  1.1.1.2  joerg   return ParentCGF.Builder.CreateCall(Cap.first, EffectiveArgs);
   1942  1.1.1.2  joerg }
   1943  1.1.1.2  joerg 
   1944  1.1.1.2  joerg llvm::CanonicalLoopInfo *
   1945  1.1.1.2  joerg CodeGenFunction::EmitOMPCollapsedCanonicalLoopNest(const Stmt *S, int Depth) {
   1946  1.1.1.2  joerg   assert(Depth == 1 && "Nested loops with OpenMPIRBuilder not yet implemented");
   1947  1.1.1.2  joerg 
   1948  1.1.1.2  joerg   EmitStmt(S);
   1949  1.1.1.2  joerg   assert(OMPLoopNestStack.size() >= (size_t)Depth && "Found too few loops");
   1950  1.1.1.2  joerg 
   1951  1.1.1.2  joerg   // The last added loop is the outermost one.
   1952  1.1.1.2  joerg   return OMPLoopNestStack.back();
   1953  1.1.1.2  joerg }
   1954  1.1.1.2  joerg 
   1955  1.1.1.2  joerg void CodeGenFunction::EmitOMPCanonicalLoop(const OMPCanonicalLoop *S) {
   1956  1.1.1.2  joerg   const Stmt *SyntacticalLoop = S->getLoopStmt();
   1957  1.1.1.2  joerg   if (!getLangOpts().OpenMPIRBuilder) {
   1958  1.1.1.2  joerg     // Ignore if OpenMPIRBuilder is not enabled.
   1959  1.1.1.2  joerg     EmitStmt(SyntacticalLoop);
   1960  1.1.1.2  joerg     return;
   1961  1.1.1.2  joerg   }
   1962  1.1.1.2  joerg 
   1963  1.1.1.2  joerg   LexicalScope ForScope(*this, S->getSourceRange());
   1964  1.1.1.2  joerg 
   1965  1.1.1.2  joerg   // Emit init statements. The Distance/LoopVar funcs may reference variable
   1966  1.1.1.2  joerg   // declarations they contain.
   1967  1.1.1.2  joerg   const Stmt *BodyStmt;
   1968  1.1.1.2  joerg   if (const auto *For = dyn_cast<ForStmt>(SyntacticalLoop)) {
   1969  1.1.1.2  joerg     if (const Stmt *InitStmt = For->getInit())
   1970  1.1.1.2  joerg       EmitStmt(InitStmt);
   1971  1.1.1.2  joerg     BodyStmt = For->getBody();
   1972  1.1.1.2  joerg   } else if (const auto *RangeFor =
   1973  1.1.1.2  joerg                  dyn_cast<CXXForRangeStmt>(SyntacticalLoop)) {
   1974  1.1.1.2  joerg     if (const DeclStmt *RangeStmt = RangeFor->getRangeStmt())
   1975  1.1.1.2  joerg       EmitStmt(RangeStmt);
   1976  1.1.1.2  joerg     if (const DeclStmt *BeginStmt = RangeFor->getBeginStmt())
   1977  1.1.1.2  joerg       EmitStmt(BeginStmt);
   1978  1.1.1.2  joerg     if (const DeclStmt *EndStmt = RangeFor->getEndStmt())
   1979  1.1.1.2  joerg       EmitStmt(EndStmt);
   1980  1.1.1.2  joerg     if (const DeclStmt *LoopVarStmt = RangeFor->getLoopVarStmt())
   1981  1.1.1.2  joerg       EmitStmt(LoopVarStmt);
   1982  1.1.1.2  joerg     BodyStmt = RangeFor->getBody();
   1983  1.1.1.2  joerg   } else
   1984  1.1.1.2  joerg     llvm_unreachable("Expected for-stmt or range-based for-stmt");
   1985  1.1.1.2  joerg 
   1986  1.1.1.2  joerg   // Emit closure for later use. By-value captures will be captured here.
   1987  1.1.1.2  joerg   const CapturedStmt *DistanceFunc = S->getDistanceFunc();
   1988  1.1.1.2  joerg   EmittedClosureTy DistanceClosure = emitCapturedStmtFunc(*this, DistanceFunc);
   1989  1.1.1.2  joerg   const CapturedStmt *LoopVarFunc = S->getLoopVarFunc();
   1990  1.1.1.2  joerg   EmittedClosureTy LoopVarClosure = emitCapturedStmtFunc(*this, LoopVarFunc);
   1991  1.1.1.2  joerg 
   1992  1.1.1.2  joerg   // Call the distance function to get the number of iterations of the loop to
   1993  1.1.1.2  joerg   // come.
   1994  1.1.1.2  joerg   QualType LogicalTy = DistanceFunc->getCapturedDecl()
   1995  1.1.1.2  joerg                            ->getParam(0)
   1996  1.1.1.2  joerg                            ->getType()
   1997  1.1.1.2  joerg                            .getNonReferenceType();
   1998  1.1.1.2  joerg   Address CountAddr = CreateMemTemp(LogicalTy, ".count.addr");
   1999  1.1.1.2  joerg   emitCapturedStmtCall(*this, DistanceClosure, {CountAddr.getPointer()});
   2000  1.1.1.2  joerg   llvm::Value *DistVal = Builder.CreateLoad(CountAddr, ".count");
   2001  1.1.1.2  joerg 
   2002  1.1.1.2  joerg   // Emit the loop structure.
   2003  1.1.1.2  joerg   llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   2004  1.1.1.2  joerg   auto BodyGen = [&, this](llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP,
   2005  1.1.1.2  joerg                            llvm::Value *IndVar) {
   2006  1.1.1.2  joerg     Builder.restoreIP(CodeGenIP);
   2007  1.1.1.2  joerg 
   2008  1.1.1.2  joerg     // Emit the loop body: Convert the logical iteration number to the loop
   2009  1.1.1.2  joerg     // variable and emit the body.
   2010  1.1.1.2  joerg     const DeclRefExpr *LoopVarRef = S->getLoopVarRef();
   2011  1.1.1.2  joerg     LValue LCVal = EmitLValue(LoopVarRef);
   2012  1.1.1.2  joerg     Address LoopVarAddress = LCVal.getAddress(*this);
   2013  1.1.1.2  joerg     emitCapturedStmtCall(*this, LoopVarClosure,
   2014  1.1.1.2  joerg                          {LoopVarAddress.getPointer(), IndVar});
   2015  1.1.1.2  joerg 
   2016  1.1.1.2  joerg     RunCleanupsScope BodyScope(*this);
   2017  1.1.1.2  joerg     EmitStmt(BodyStmt);
   2018  1.1.1.2  joerg   };
   2019  1.1.1.2  joerg   llvm::CanonicalLoopInfo *CL =
   2020  1.1.1.2  joerg       OMPBuilder.createCanonicalLoop(Builder, BodyGen, DistVal);
   2021  1.1.1.2  joerg 
   2022  1.1.1.2  joerg   // Finish up the loop.
   2023  1.1.1.2  joerg   Builder.restoreIP(CL->getAfterIP());
   2024  1.1.1.2  joerg   ForScope.ForceCleanup();
   2025  1.1.1.2  joerg 
   2026  1.1.1.2  joerg   // Remember the CanonicalLoopInfo for parent AST nodes consuming it.
   2027  1.1.1.2  joerg   OMPLoopNestStack.push_back(CL);
   2028  1.1.1.2  joerg }
   2029  1.1.1.2  joerg 
   2030      1.1  joerg void CodeGenFunction::EmitOMPInnerLoop(
   2031  1.1.1.2  joerg     const OMPExecutableDirective &S, bool RequiresCleanup, const Expr *LoopCond,
   2032      1.1  joerg     const Expr *IncExpr,
   2033      1.1  joerg     const llvm::function_ref<void(CodeGenFunction &)> BodyGen,
   2034      1.1  joerg     const llvm::function_ref<void(CodeGenFunction &)> PostIncGen) {
   2035      1.1  joerg   auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
   2036      1.1  joerg 
   2037      1.1  joerg   // Start the loop with a block that tests the condition.
   2038      1.1  joerg   auto CondBlock = createBasicBlock("omp.inner.for.cond");
   2039      1.1  joerg   EmitBlock(CondBlock);
   2040      1.1  joerg   const SourceRange R = S.getSourceRange();
   2041  1.1.1.2  joerg 
   2042  1.1.1.2  joerg   // If attributes are attached, push to the basic block with them.
   2043  1.1.1.2  joerg   const auto &OMPED = cast<OMPExecutableDirective>(S);
   2044  1.1.1.2  joerg   const CapturedStmt *ICS = OMPED.getInnermostCapturedStmt();
   2045  1.1.1.2  joerg   const Stmt *SS = ICS->getCapturedStmt();
   2046  1.1.1.2  joerg   const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(SS);
   2047  1.1.1.2  joerg   OMPLoopNestStack.clear();
   2048  1.1.1.2  joerg   if (AS)
   2049  1.1.1.2  joerg     LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(),
   2050  1.1.1.2  joerg                    AS->getAttrs(), SourceLocToDebugLoc(R.getBegin()),
   2051  1.1.1.2  joerg                    SourceLocToDebugLoc(R.getEnd()));
   2052  1.1.1.2  joerg   else
   2053  1.1.1.2  joerg     LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
   2054  1.1.1.2  joerg                    SourceLocToDebugLoc(R.getEnd()));
   2055      1.1  joerg 
   2056      1.1  joerg   // If there are any cleanups between here and the loop-exit scope,
   2057      1.1  joerg   // create a block to stage a loop exit along.
   2058      1.1  joerg   llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
   2059      1.1  joerg   if (RequiresCleanup)
   2060      1.1  joerg     ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
   2061      1.1  joerg 
   2062      1.1  joerg   llvm::BasicBlock *LoopBody = createBasicBlock("omp.inner.for.body");
   2063      1.1  joerg 
   2064      1.1  joerg   // Emit condition.
   2065      1.1  joerg   EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S));
   2066      1.1  joerg   if (ExitBlock != LoopExit.getBlock()) {
   2067      1.1  joerg     EmitBlock(ExitBlock);
   2068      1.1  joerg     EmitBranchThroughCleanup(LoopExit);
   2069      1.1  joerg   }
   2070      1.1  joerg 
   2071      1.1  joerg   EmitBlock(LoopBody);
   2072      1.1  joerg   incrementProfileCounter(&S);
   2073      1.1  joerg 
   2074      1.1  joerg   // Create a block for the increment.
   2075      1.1  joerg   JumpDest Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
   2076      1.1  joerg   BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
   2077      1.1  joerg 
   2078      1.1  joerg   BodyGen(*this);
   2079      1.1  joerg 
   2080      1.1  joerg   // Emit "IV = IV + 1" and a back-edge to the condition block.
   2081      1.1  joerg   EmitBlock(Continue.getBlock());
   2082      1.1  joerg   EmitIgnoredExpr(IncExpr);
   2083      1.1  joerg   PostIncGen(*this);
   2084      1.1  joerg   BreakContinueStack.pop_back();
   2085      1.1  joerg   EmitBranch(CondBlock);
   2086      1.1  joerg   LoopStack.pop();
   2087      1.1  joerg   // Emit the fall-through block.
   2088      1.1  joerg   EmitBlock(LoopExit.getBlock());
   2089      1.1  joerg }
   2090      1.1  joerg 
   2091      1.1  joerg bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
   2092      1.1  joerg   if (!HaveInsertPoint())
   2093      1.1  joerg     return false;
   2094      1.1  joerg   // Emit inits for the linear variables.
   2095      1.1  joerg   bool HasLinears = false;
   2096      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
   2097      1.1  joerg     for (const Expr *Init : C->inits()) {
   2098      1.1  joerg       HasLinears = true;
   2099      1.1  joerg       const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
   2100      1.1  joerg       if (const auto *Ref =
   2101      1.1  joerg               dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) {
   2102      1.1  joerg         AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
   2103      1.1  joerg         const auto *OrigVD = cast<VarDecl>(Ref->getDecl());
   2104      1.1  joerg         DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
   2105      1.1  joerg                         CapturedStmtInfo->lookup(OrigVD) != nullptr,
   2106      1.1  joerg                         VD->getInit()->getType(), VK_LValue,
   2107      1.1  joerg                         VD->getInit()->getExprLoc());
   2108      1.1  joerg         EmitExprAsInit(&DRE, VD, MakeAddrLValue(Emission.getAllocatedAddress(),
   2109      1.1  joerg                                                 VD->getType()),
   2110      1.1  joerg                        /*capturedByInit=*/false);
   2111      1.1  joerg         EmitAutoVarCleanups(Emission);
   2112      1.1  joerg       } else {
   2113      1.1  joerg         EmitVarDecl(*VD);
   2114      1.1  joerg       }
   2115      1.1  joerg     }
   2116      1.1  joerg     // Emit the linear steps for the linear clauses.
   2117      1.1  joerg     // If a step is not constant, it is pre-calculated before the loop.
   2118      1.1  joerg     if (const auto *CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
   2119      1.1  joerg       if (const auto *SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
   2120      1.1  joerg         EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl()));
   2121      1.1  joerg         // Emit calculation of the linear step.
   2122      1.1  joerg         EmitIgnoredExpr(CS);
   2123      1.1  joerg       }
   2124      1.1  joerg   }
   2125      1.1  joerg   return HasLinears;
   2126      1.1  joerg }
   2127      1.1  joerg 
   2128      1.1  joerg void CodeGenFunction::EmitOMPLinearClauseFinal(
   2129      1.1  joerg     const OMPLoopDirective &D,
   2130      1.1  joerg     const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
   2131      1.1  joerg   if (!HaveInsertPoint())
   2132      1.1  joerg     return;
   2133      1.1  joerg   llvm::BasicBlock *DoneBB = nullptr;
   2134      1.1  joerg   // Emit the final values of the linear variables.
   2135      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
   2136      1.1  joerg     auto IC = C->varlist_begin();
   2137      1.1  joerg     for (const Expr *F : C->finals()) {
   2138      1.1  joerg       if (!DoneBB) {
   2139      1.1  joerg         if (llvm::Value *Cond = CondGen(*this)) {
   2140      1.1  joerg           // If the first post-update expression is found, emit conditional
   2141      1.1  joerg           // block if it was requested.
   2142      1.1  joerg           llvm::BasicBlock *ThenBB = createBasicBlock(".omp.linear.pu");
   2143      1.1  joerg           DoneBB = createBasicBlock(".omp.linear.pu.done");
   2144      1.1  joerg           Builder.CreateCondBr(Cond, ThenBB, DoneBB);
   2145      1.1  joerg           EmitBlock(ThenBB);
   2146      1.1  joerg         }
   2147      1.1  joerg       }
   2148      1.1  joerg       const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
   2149      1.1  joerg       DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
   2150      1.1  joerg                       CapturedStmtInfo->lookup(OrigVD) != nullptr,
   2151      1.1  joerg                       (*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
   2152  1.1.1.2  joerg       Address OrigAddr = EmitLValue(&DRE).getAddress(*this);
   2153      1.1  joerg       CodeGenFunction::OMPPrivateScope VarScope(*this);
   2154      1.1  joerg       VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; });
   2155      1.1  joerg       (void)VarScope.Privatize();
   2156      1.1  joerg       EmitIgnoredExpr(F);
   2157      1.1  joerg       ++IC;
   2158      1.1  joerg     }
   2159      1.1  joerg     if (const Expr *PostUpdate = C->getPostUpdateExpr())
   2160      1.1  joerg       EmitIgnoredExpr(PostUpdate);
   2161      1.1  joerg   }
   2162      1.1  joerg   if (DoneBB)
   2163      1.1  joerg     EmitBlock(DoneBB, /*IsFinished=*/true);
   2164      1.1  joerg }
   2165      1.1  joerg 
   2166      1.1  joerg static void emitAlignedClause(CodeGenFunction &CGF,
   2167      1.1  joerg                               const OMPExecutableDirective &D) {
   2168      1.1  joerg   if (!CGF.HaveInsertPoint())
   2169      1.1  joerg     return;
   2170      1.1  joerg   for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) {
   2171      1.1  joerg     llvm::APInt ClauseAlignment(64, 0);
   2172      1.1  joerg     if (const Expr *AlignmentExpr = Clause->getAlignment()) {
   2173      1.1  joerg       auto *AlignmentCI =
   2174      1.1  joerg           cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
   2175      1.1  joerg       ClauseAlignment = AlignmentCI->getValue();
   2176      1.1  joerg     }
   2177      1.1  joerg     for (const Expr *E : Clause->varlists()) {
   2178      1.1  joerg       llvm::APInt Alignment(ClauseAlignment);
   2179      1.1  joerg       if (Alignment == 0) {
   2180      1.1  joerg         // OpenMP [2.8.1, Description]
   2181      1.1  joerg         // If no optional parameter is specified, implementation-defined default
   2182      1.1  joerg         // alignments for SIMD instructions on the target platforms are assumed.
   2183      1.1  joerg         Alignment =
   2184      1.1  joerg             CGF.getContext()
   2185      1.1  joerg                 .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
   2186      1.1  joerg                     E->getType()->getPointeeType()))
   2187      1.1  joerg                 .getQuantity();
   2188      1.1  joerg       }
   2189      1.1  joerg       assert((Alignment == 0 || Alignment.isPowerOf2()) &&
   2190      1.1  joerg              "alignment is not power of 2");
   2191      1.1  joerg       if (Alignment != 0) {
   2192      1.1  joerg         llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
   2193  1.1.1.2  joerg         CGF.emitAlignmentAssumption(
   2194      1.1  joerg             PtrValue, E, /*No second loc needed*/ SourceLocation(),
   2195      1.1  joerg             llvm::ConstantInt::get(CGF.getLLVMContext(), Alignment));
   2196      1.1  joerg       }
   2197      1.1  joerg     }
   2198      1.1  joerg   }
   2199      1.1  joerg }
   2200      1.1  joerg 
   2201      1.1  joerg void CodeGenFunction::EmitOMPPrivateLoopCounters(
   2202      1.1  joerg     const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) {
   2203      1.1  joerg   if (!HaveInsertPoint())
   2204      1.1  joerg     return;
   2205      1.1  joerg   auto I = S.private_counters().begin();
   2206      1.1  joerg   for (const Expr *E : S.counters()) {
   2207      1.1  joerg     const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   2208      1.1  joerg     const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
   2209      1.1  joerg     // Emit var without initialization.
   2210      1.1  joerg     AutoVarEmission VarEmission = EmitAutoVarAlloca(*PrivateVD);
   2211      1.1  joerg     EmitAutoVarCleanups(VarEmission);
   2212      1.1  joerg     LocalDeclMap.erase(PrivateVD);
   2213      1.1  joerg     (void)LoopScope.addPrivate(VD, [&VarEmission]() {
   2214      1.1  joerg       return VarEmission.getAllocatedAddress();
   2215      1.1  joerg     });
   2216      1.1  joerg     if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) ||
   2217      1.1  joerg         VD->hasGlobalStorage()) {
   2218      1.1  joerg       (void)LoopScope.addPrivate(PrivateVD, [this, VD, E]() {
   2219      1.1  joerg         DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD),
   2220      1.1  joerg                         LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD),
   2221      1.1  joerg                         E->getType(), VK_LValue, E->getExprLoc());
   2222  1.1.1.2  joerg         return EmitLValue(&DRE).getAddress(*this);
   2223      1.1  joerg       });
   2224      1.1  joerg     } else {
   2225      1.1  joerg       (void)LoopScope.addPrivate(PrivateVD, [&VarEmission]() {
   2226      1.1  joerg         return VarEmission.getAllocatedAddress();
   2227      1.1  joerg       });
   2228      1.1  joerg     }
   2229      1.1  joerg     ++I;
   2230      1.1  joerg   }
   2231      1.1  joerg   // Privatize extra loop counters used in loops for ordered(n) clauses.
   2232      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPOrderedClause>()) {
   2233      1.1  joerg     if (!C->getNumForLoops())
   2234      1.1  joerg       continue;
   2235  1.1.1.2  joerg     for (unsigned I = S.getLoopsNumber(), E = C->getLoopNumIterations().size();
   2236      1.1  joerg          I < E; ++I) {
   2237      1.1  joerg       const auto *DRE = cast<DeclRefExpr>(C->getLoopCounter(I));
   2238      1.1  joerg       const auto *VD = cast<VarDecl>(DRE->getDecl());
   2239      1.1  joerg       // Override only those variables that can be captured to avoid re-emission
   2240      1.1  joerg       // of the variables declared within the loops.
   2241      1.1  joerg       if (DRE->refersToEnclosingVariableOrCapture()) {
   2242      1.1  joerg         (void)LoopScope.addPrivate(VD, [this, DRE, VD]() {
   2243      1.1  joerg           return CreateMemTemp(DRE->getType(), VD->getName());
   2244      1.1  joerg         });
   2245      1.1  joerg       }
   2246      1.1  joerg     }
   2247      1.1  joerg   }
   2248      1.1  joerg }
   2249      1.1  joerg 
   2250      1.1  joerg static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
   2251      1.1  joerg                         const Expr *Cond, llvm::BasicBlock *TrueBlock,
   2252      1.1  joerg                         llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
   2253      1.1  joerg   if (!CGF.HaveInsertPoint())
   2254      1.1  joerg     return;
   2255      1.1  joerg   {
   2256      1.1  joerg     CodeGenFunction::OMPPrivateScope PreCondScope(CGF);
   2257      1.1  joerg     CGF.EmitOMPPrivateLoopCounters(S, PreCondScope);
   2258      1.1  joerg     (void)PreCondScope.Privatize();
   2259      1.1  joerg     // Get initial values of real counters.
   2260      1.1  joerg     for (const Expr *I : S.inits()) {
   2261      1.1  joerg       CGF.EmitIgnoredExpr(I);
   2262      1.1  joerg     }
   2263      1.1  joerg   }
   2264      1.1  joerg   // Create temp loop control variables with their init values to support
   2265      1.1  joerg   // non-rectangular loops.
   2266      1.1  joerg   CodeGenFunction::OMPMapVars PreCondVars;
   2267      1.1  joerg   for (const Expr * E: S.dependent_counters()) {
   2268      1.1  joerg     if (!E)
   2269      1.1  joerg       continue;
   2270      1.1  joerg     assert(!E->getType().getNonReferenceType()->isRecordType() &&
   2271      1.1  joerg            "dependent counter must not be an iterator.");
   2272      1.1  joerg     const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   2273      1.1  joerg     Address CounterAddr =
   2274      1.1  joerg         CGF.CreateMemTemp(VD->getType().getNonReferenceType());
   2275      1.1  joerg     (void)PreCondVars.setVarAddr(CGF, VD, CounterAddr);
   2276      1.1  joerg   }
   2277      1.1  joerg   (void)PreCondVars.apply(CGF);
   2278      1.1  joerg   for (const Expr *E : S.dependent_inits()) {
   2279      1.1  joerg     if (!E)
   2280      1.1  joerg       continue;
   2281      1.1  joerg     CGF.EmitIgnoredExpr(E);
   2282      1.1  joerg   }
   2283      1.1  joerg   // Check that loop is executed at least one time.
   2284      1.1  joerg   CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount);
   2285      1.1  joerg   PreCondVars.restore(CGF);
   2286      1.1  joerg }
   2287      1.1  joerg 
   2288      1.1  joerg void CodeGenFunction::EmitOMPLinearClause(
   2289      1.1  joerg     const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) {
   2290      1.1  joerg   if (!HaveInsertPoint())
   2291      1.1  joerg     return;
   2292      1.1  joerg   llvm::DenseSet<const VarDecl *> SIMDLCVs;
   2293      1.1  joerg   if (isOpenMPSimdDirective(D.getDirectiveKind())) {
   2294      1.1  joerg     const auto *LoopDirective = cast<OMPLoopDirective>(&D);
   2295      1.1  joerg     for (const Expr *C : LoopDirective->counters()) {
   2296      1.1  joerg       SIMDLCVs.insert(
   2297      1.1  joerg           cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
   2298      1.1  joerg     }
   2299      1.1  joerg   }
   2300      1.1  joerg   for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
   2301      1.1  joerg     auto CurPrivate = C->privates().begin();
   2302      1.1  joerg     for (const Expr *E : C->varlists()) {
   2303      1.1  joerg       const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   2304      1.1  joerg       const auto *PrivateVD =
   2305      1.1  joerg           cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
   2306      1.1  joerg       if (!SIMDLCVs.count(VD->getCanonicalDecl())) {
   2307      1.1  joerg         bool IsRegistered = PrivateScope.addPrivate(VD, [this, PrivateVD]() {
   2308      1.1  joerg           // Emit private VarDecl with copy init.
   2309      1.1  joerg           EmitVarDecl(*PrivateVD);
   2310      1.1  joerg           return GetAddrOfLocalVar(PrivateVD);
   2311      1.1  joerg         });
   2312      1.1  joerg         assert(IsRegistered && "linear var already registered as private");
   2313      1.1  joerg         // Silence the warning about unused variable.
   2314      1.1  joerg         (void)IsRegistered;
   2315      1.1  joerg       } else {
   2316      1.1  joerg         EmitVarDecl(*PrivateVD);
   2317      1.1  joerg       }
   2318      1.1  joerg       ++CurPrivate;
   2319      1.1  joerg     }
   2320      1.1  joerg   }
   2321      1.1  joerg }
   2322      1.1  joerg 
   2323      1.1  joerg static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
   2324      1.1  joerg                                      const OMPExecutableDirective &D,
   2325      1.1  joerg                                      bool IsMonotonic) {
   2326      1.1  joerg   if (!CGF.HaveInsertPoint())
   2327      1.1  joerg     return;
   2328      1.1  joerg   if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) {
   2329      1.1  joerg     RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(),
   2330      1.1  joerg                                  /*ignoreResult=*/true);
   2331      1.1  joerg     auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
   2332      1.1  joerg     CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
   2333      1.1  joerg     // In presence of finite 'safelen', it may be unsafe to mark all
   2334      1.1  joerg     // the memory instructions parallel, because loop-carried
   2335      1.1  joerg     // dependences of 'safelen' iterations are possible.
   2336      1.1  joerg     if (!IsMonotonic)
   2337      1.1  joerg       CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>());
   2338      1.1  joerg   } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) {
   2339      1.1  joerg     RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(),
   2340      1.1  joerg                                  /*ignoreResult=*/true);
   2341      1.1  joerg     auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
   2342      1.1  joerg     CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
   2343      1.1  joerg     // In presence of finite 'safelen', it may be unsafe to mark all
   2344      1.1  joerg     // the memory instructions parallel, because loop-carried
   2345      1.1  joerg     // dependences of 'safelen' iterations are possible.
   2346      1.1  joerg     CGF.LoopStack.setParallel(/*Enable=*/false);
   2347      1.1  joerg   }
   2348      1.1  joerg }
   2349      1.1  joerg 
   2350      1.1  joerg void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D,
   2351      1.1  joerg                                       bool IsMonotonic) {
   2352      1.1  joerg   // Walk clauses and process safelen/lastprivate.
   2353      1.1  joerg   LoopStack.setParallel(!IsMonotonic);
   2354      1.1  joerg   LoopStack.setVectorizeEnable();
   2355      1.1  joerg   emitSimdlenSafelenClause(*this, D, IsMonotonic);
   2356  1.1.1.2  joerg   if (const auto *C = D.getSingleClause<OMPOrderClause>())
   2357  1.1.1.2  joerg     if (C->getKind() == OMPC_ORDER_concurrent)
   2358  1.1.1.2  joerg       LoopStack.setParallel(/*Enable=*/true);
   2359  1.1.1.2  joerg   if ((D.getDirectiveKind() == OMPD_simd ||
   2360  1.1.1.2  joerg        (getLangOpts().OpenMPSimd &&
   2361  1.1.1.2  joerg         isOpenMPSimdDirective(D.getDirectiveKind()))) &&
   2362  1.1.1.2  joerg       llvm::any_of(D.getClausesOfKind<OMPReductionClause>(),
   2363  1.1.1.2  joerg                    [](const OMPReductionClause *C) {
   2364  1.1.1.2  joerg                      return C->getModifier() == OMPC_REDUCTION_inscan;
   2365  1.1.1.2  joerg                    }))
   2366  1.1.1.2  joerg     // Disable parallel access in case of prefix sum.
   2367  1.1.1.2  joerg     LoopStack.setParallel(/*Enable=*/false);
   2368      1.1  joerg }
   2369      1.1  joerg 
   2370      1.1  joerg void CodeGenFunction::EmitOMPSimdFinal(
   2371      1.1  joerg     const OMPLoopDirective &D,
   2372      1.1  joerg     const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
   2373      1.1  joerg   if (!HaveInsertPoint())
   2374      1.1  joerg     return;
   2375      1.1  joerg   llvm::BasicBlock *DoneBB = nullptr;
   2376      1.1  joerg   auto IC = D.counters().begin();
   2377      1.1  joerg   auto IPC = D.private_counters().begin();
   2378      1.1  joerg   for (const Expr *F : D.finals()) {
   2379      1.1  joerg     const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
   2380      1.1  joerg     const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
   2381      1.1  joerg     const auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD);
   2382      1.1  joerg     if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) ||
   2383      1.1  joerg         OrigVD->hasGlobalStorage() || CED) {
   2384      1.1  joerg       if (!DoneBB) {
   2385      1.1  joerg         if (llvm::Value *Cond = CondGen(*this)) {
   2386      1.1  joerg           // If the first post-update expression is found, emit conditional
   2387      1.1  joerg           // block if it was requested.
   2388      1.1  joerg           llvm::BasicBlock *ThenBB = createBasicBlock(".omp.final.then");
   2389      1.1  joerg           DoneBB = createBasicBlock(".omp.final.done");
   2390      1.1  joerg           Builder.CreateCondBr(Cond, ThenBB, DoneBB);
   2391      1.1  joerg           EmitBlock(ThenBB);
   2392      1.1  joerg         }
   2393      1.1  joerg       }
   2394      1.1  joerg       Address OrigAddr = Address::invalid();
   2395      1.1  joerg       if (CED) {
   2396  1.1.1.2  joerg         OrigAddr =
   2397  1.1.1.2  joerg             EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress(*this);
   2398      1.1  joerg       } else {
   2399      1.1  joerg         DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(PrivateVD),
   2400      1.1  joerg                         /*RefersToEnclosingVariableOrCapture=*/false,
   2401      1.1  joerg                         (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc());
   2402  1.1.1.2  joerg         OrigAddr = EmitLValue(&DRE).getAddress(*this);
   2403      1.1  joerg       }
   2404      1.1  joerg       OMPPrivateScope VarScope(*this);
   2405      1.1  joerg       VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; });
   2406      1.1  joerg       (void)VarScope.Privatize();
   2407      1.1  joerg       EmitIgnoredExpr(F);
   2408      1.1  joerg     }
   2409      1.1  joerg     ++IC;
   2410      1.1  joerg     ++IPC;
   2411      1.1  joerg   }
   2412      1.1  joerg   if (DoneBB)
   2413      1.1  joerg     EmitBlock(DoneBB, /*IsFinished=*/true);
   2414      1.1  joerg }
   2415      1.1  joerg 
   2416      1.1  joerg static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF,
   2417      1.1  joerg                                          const OMPLoopDirective &S,
   2418      1.1  joerg                                          CodeGenFunction::JumpDest LoopExit) {
   2419      1.1  joerg   CGF.EmitOMPLoopBody(S, LoopExit);
   2420      1.1  joerg   CGF.EmitStopPoint(&S);
   2421      1.1  joerg }
   2422      1.1  joerg 
   2423      1.1  joerg /// Emit a helper variable and return corresponding lvalue.
   2424      1.1  joerg static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
   2425      1.1  joerg                                const DeclRefExpr *Helper) {
   2426      1.1  joerg   auto VDecl = cast<VarDecl>(Helper->getDecl());
   2427      1.1  joerg   CGF.EmitVarDecl(*VDecl);
   2428      1.1  joerg   return CGF.EmitLValue(Helper);
   2429      1.1  joerg }
   2430      1.1  joerg 
   2431  1.1.1.2  joerg static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S,
   2432  1.1.1.2  joerg                                const RegionCodeGenTy &SimdInitGen,
   2433  1.1.1.2  joerg                                const RegionCodeGenTy &BodyCodeGen) {
   2434  1.1.1.2  joerg   auto &&ThenGen = [&S, &SimdInitGen, &BodyCodeGen](CodeGenFunction &CGF,
   2435  1.1.1.2  joerg                                                     PrePostActionTy &) {
   2436  1.1.1.2  joerg     CGOpenMPRuntime::NontemporalDeclsRAII NontemporalsRegion(CGF.CGM, S);
   2437  1.1.1.2  joerg     CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
   2438  1.1.1.2  joerg     SimdInitGen(CGF);
   2439  1.1.1.2  joerg 
   2440  1.1.1.2  joerg     BodyCodeGen(CGF);
   2441  1.1.1.2  joerg   };
   2442  1.1.1.2  joerg   auto &&ElseGen = [&BodyCodeGen](CodeGenFunction &CGF, PrePostActionTy &) {
   2443  1.1.1.2  joerg     CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
   2444  1.1.1.2  joerg     CGF.LoopStack.setVectorizeEnable(/*Enable=*/false);
   2445  1.1.1.2  joerg 
   2446  1.1.1.2  joerg     BodyCodeGen(CGF);
   2447  1.1.1.2  joerg   };
   2448  1.1.1.2  joerg   const Expr *IfCond = nullptr;
   2449  1.1.1.2  joerg   if (isOpenMPSimdDirective(S.getDirectiveKind())) {
   2450  1.1.1.2  joerg     for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
   2451  1.1.1.2  joerg       if (CGF.getLangOpts().OpenMP >= 50 &&
   2452  1.1.1.2  joerg           (C->getNameModifier() == OMPD_unknown ||
   2453  1.1.1.2  joerg            C->getNameModifier() == OMPD_simd)) {
   2454  1.1.1.2  joerg         IfCond = C->getCondition();
   2455  1.1.1.2  joerg         break;
   2456  1.1.1.2  joerg       }
   2457  1.1.1.2  joerg     }
   2458  1.1.1.2  joerg   }
   2459  1.1.1.2  joerg   if (IfCond) {
   2460  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitIfClause(CGF, IfCond, ThenGen, ElseGen);
   2461  1.1.1.2  joerg   } else {
   2462  1.1.1.2  joerg     RegionCodeGenTy ThenRCG(ThenGen);
   2463  1.1.1.2  joerg     ThenRCG(CGF);
   2464  1.1.1.2  joerg   }
   2465  1.1.1.2  joerg }
   2466  1.1.1.2  joerg 
   2467      1.1  joerg static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
   2468      1.1  joerg                               PrePostActionTy &Action) {
   2469      1.1  joerg   Action.Enter(CGF);
   2470      1.1  joerg   assert(isOpenMPSimdDirective(S.getDirectiveKind()) &&
   2471      1.1  joerg          "Expected simd directive");
   2472      1.1  joerg   OMPLoopScope PreInitScope(CGF, S);
   2473      1.1  joerg   // if (PreCond) {
   2474      1.1  joerg   //   for (IV in 0..LastIteration) BODY;
   2475      1.1  joerg   //   <Final counter/linear vars updates>;
   2476      1.1  joerg   // }
   2477      1.1  joerg   //
   2478      1.1  joerg   if (isOpenMPDistributeDirective(S.getDirectiveKind()) ||
   2479      1.1  joerg       isOpenMPWorksharingDirective(S.getDirectiveKind()) ||
   2480      1.1  joerg       isOpenMPTaskLoopDirective(S.getDirectiveKind())) {
   2481      1.1  joerg     (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()));
   2482      1.1  joerg     (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()));
   2483      1.1  joerg   }
   2484      1.1  joerg 
   2485      1.1  joerg   // Emit: if (PreCond) - begin.
   2486      1.1  joerg   // If the condition constant folds and can be elided, avoid emitting the
   2487      1.1  joerg   // whole loop.
   2488      1.1  joerg   bool CondConstant;
   2489      1.1  joerg   llvm::BasicBlock *ContBlock = nullptr;
   2490      1.1  joerg   if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
   2491      1.1  joerg     if (!CondConstant)
   2492      1.1  joerg       return;
   2493      1.1  joerg   } else {
   2494      1.1  joerg     llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("simd.if.then");
   2495      1.1  joerg     ContBlock = CGF.createBasicBlock("simd.if.end");
   2496      1.1  joerg     emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
   2497      1.1  joerg                 CGF.getProfileCount(&S));
   2498      1.1  joerg     CGF.EmitBlock(ThenBlock);
   2499      1.1  joerg     CGF.incrementProfileCounter(&S);
   2500      1.1  joerg   }
   2501      1.1  joerg 
   2502      1.1  joerg   // Emit the loop iteration variable.
   2503      1.1  joerg   const Expr *IVExpr = S.getIterationVariable();
   2504      1.1  joerg   const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
   2505      1.1  joerg   CGF.EmitVarDecl(*IVDecl);
   2506      1.1  joerg   CGF.EmitIgnoredExpr(S.getInit());
   2507      1.1  joerg 
   2508      1.1  joerg   // Emit the iterations count variable.
   2509      1.1  joerg   // If it is not a variable, Sema decided to calculate iterations count on
   2510      1.1  joerg   // each iteration (e.g., it is foldable into a constant).
   2511      1.1  joerg   if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
   2512      1.1  joerg     CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
   2513      1.1  joerg     // Emit calculation of the iterations count.
   2514      1.1  joerg     CGF.EmitIgnoredExpr(S.getCalcLastIteration());
   2515      1.1  joerg   }
   2516      1.1  joerg 
   2517      1.1  joerg   emitAlignedClause(CGF, S);
   2518      1.1  joerg   (void)CGF.EmitOMPLinearClauseInit(S);
   2519      1.1  joerg   {
   2520      1.1  joerg     CodeGenFunction::OMPPrivateScope LoopScope(CGF);
   2521      1.1  joerg     CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
   2522      1.1  joerg     CGF.EmitOMPLinearClause(S, LoopScope);
   2523      1.1  joerg     CGF.EmitOMPPrivateClause(S, LoopScope);
   2524      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, LoopScope);
   2525  1.1.1.2  joerg     CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion(
   2526  1.1.1.2  joerg         CGF, S, CGF.EmitLValue(S.getIterationVariable()));
   2527      1.1  joerg     bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
   2528      1.1  joerg     (void)LoopScope.Privatize();
   2529      1.1  joerg     if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
   2530      1.1  joerg       CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
   2531  1.1.1.2  joerg 
   2532  1.1.1.2  joerg     emitCommonSimdLoop(
   2533  1.1.1.2  joerg         CGF, S,
   2534  1.1.1.2  joerg         [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   2535  1.1.1.2  joerg           CGF.EmitOMPSimdInit(S);
   2536  1.1.1.2  joerg         },
   2537  1.1.1.2  joerg         [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
   2538  1.1.1.2  joerg           CGF.EmitOMPInnerLoop(
   2539  1.1.1.2  joerg               S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
   2540  1.1.1.2  joerg               [&S](CodeGenFunction &CGF) {
   2541  1.1.1.2  joerg                 emitOMPLoopBodyWithStopPoint(CGF, S,
   2542  1.1.1.2  joerg                                              CodeGenFunction::JumpDest());
   2543  1.1.1.2  joerg               },
   2544  1.1.1.2  joerg               [](CodeGenFunction &) {});
   2545  1.1.1.2  joerg         });
   2546      1.1  joerg     CGF.EmitOMPSimdFinal(S, [](CodeGenFunction &) { return nullptr; });
   2547      1.1  joerg     // Emit final copy of the lastprivate variables at the end of loops.
   2548      1.1  joerg     if (HasLastprivateClause)
   2549      1.1  joerg       CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
   2550      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd);
   2551      1.1  joerg     emitPostUpdateForReductionClause(CGF, S,
   2552      1.1  joerg                                      [](CodeGenFunction &) { return nullptr; });
   2553      1.1  joerg   }
   2554      1.1  joerg   CGF.EmitOMPLinearClauseFinal(S, [](CodeGenFunction &) { return nullptr; });
   2555      1.1  joerg   // Emit: if (PreCond) - end.
   2556      1.1  joerg   if (ContBlock) {
   2557      1.1  joerg     CGF.EmitBranch(ContBlock);
   2558      1.1  joerg     CGF.EmitBlock(ContBlock, true);
   2559      1.1  joerg   }
   2560      1.1  joerg }
   2561      1.1  joerg 
   2562      1.1  joerg void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
   2563  1.1.1.2  joerg   ParentLoopDirectiveForScanRegion ScanRegion(*this, S);
   2564  1.1.1.2  joerg   OMPFirstScanLoop = true;
   2565      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   2566      1.1  joerg     emitOMPSimdRegion(CGF, S, Action);
   2567      1.1  joerg   };
   2568  1.1.1.2  joerg   {
   2569  1.1.1.2  joerg     auto LPCRegion =
   2570  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   2571  1.1.1.2  joerg     OMPLexicalScope Scope(*this, S, OMPD_unknown);
   2572  1.1.1.2  joerg     CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
   2573  1.1.1.2  joerg   }
   2574  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   2575  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   2576  1.1.1.2  joerg }
   2577  1.1.1.2  joerg 
   2578  1.1.1.2  joerg void CodeGenFunction::EmitOMPTileDirective(const OMPTileDirective &S) {
   2579  1.1.1.2  joerg   // Emit the de-sugared statement.
   2580  1.1.1.2  joerg   OMPTransformDirectiveScopeRAII TileScope(*this, &S);
   2581  1.1.1.2  joerg   EmitStmt(S.getTransformedStmt());
   2582      1.1  joerg }
   2583      1.1  joerg 
   2584      1.1  joerg void CodeGenFunction::EmitOMPOuterLoop(
   2585      1.1  joerg     bool DynamicOrOrdered, bool IsMonotonic, const OMPLoopDirective &S,
   2586      1.1  joerg     CodeGenFunction::OMPPrivateScope &LoopScope,
   2587      1.1  joerg     const CodeGenFunction::OMPLoopArguments &LoopArgs,
   2588      1.1  joerg     const CodeGenFunction::CodeGenLoopTy &CodeGenLoop,
   2589      1.1  joerg     const CodeGenFunction::CodeGenOrderedTy &CodeGenOrdered) {
   2590      1.1  joerg   CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
   2591      1.1  joerg 
   2592      1.1  joerg   const Expr *IVExpr = S.getIterationVariable();
   2593      1.1  joerg   const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
   2594      1.1  joerg   const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
   2595      1.1  joerg 
   2596      1.1  joerg   JumpDest LoopExit = getJumpDestInCurrentScope("omp.dispatch.end");
   2597      1.1  joerg 
   2598      1.1  joerg   // Start the loop with a block that tests the condition.
   2599      1.1  joerg   llvm::BasicBlock *CondBlock = createBasicBlock("omp.dispatch.cond");
   2600      1.1  joerg   EmitBlock(CondBlock);
   2601      1.1  joerg   const SourceRange R = S.getSourceRange();
   2602  1.1.1.2  joerg   OMPLoopNestStack.clear();
   2603      1.1  joerg   LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
   2604      1.1  joerg                  SourceLocToDebugLoc(R.getEnd()));
   2605      1.1  joerg 
   2606      1.1  joerg   llvm::Value *BoolCondVal = nullptr;
   2607      1.1  joerg   if (!DynamicOrOrdered) {
   2608      1.1  joerg     // UB = min(UB, GlobalUB) or
   2609      1.1  joerg     // UB = min(UB, PrevUB) for combined loop sharing constructs (e.g.
   2610      1.1  joerg     // 'distribute parallel for')
   2611      1.1  joerg     EmitIgnoredExpr(LoopArgs.EUB);
   2612      1.1  joerg     // IV = LB
   2613      1.1  joerg     EmitIgnoredExpr(LoopArgs.Init);
   2614      1.1  joerg     // IV < UB
   2615      1.1  joerg     BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond);
   2616      1.1  joerg   } else {
   2617      1.1  joerg     BoolCondVal =
   2618      1.1  joerg         RT.emitForNext(*this, S.getBeginLoc(), IVSize, IVSigned, LoopArgs.IL,
   2619      1.1  joerg                        LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);
   2620      1.1  joerg   }
   2621      1.1  joerg 
   2622      1.1  joerg   // If there are any cleanups between here and the loop-exit scope,
   2623      1.1  joerg   // create a block to stage a loop exit along.
   2624      1.1  joerg   llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
   2625      1.1  joerg   if (LoopScope.requiresCleanups())
   2626      1.1  joerg     ExitBlock = createBasicBlock("omp.dispatch.cleanup");
   2627      1.1  joerg 
   2628      1.1  joerg   llvm::BasicBlock *LoopBody = createBasicBlock("omp.dispatch.body");
   2629      1.1  joerg   Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
   2630      1.1  joerg   if (ExitBlock != LoopExit.getBlock()) {
   2631      1.1  joerg     EmitBlock(ExitBlock);
   2632      1.1  joerg     EmitBranchThroughCleanup(LoopExit);
   2633      1.1  joerg   }
   2634      1.1  joerg   EmitBlock(LoopBody);
   2635      1.1  joerg 
   2636      1.1  joerg   // Emit "IV = LB" (in case of static schedule, we have already calculated new
   2637      1.1  joerg   // LB for loop condition and emitted it above).
   2638      1.1  joerg   if (DynamicOrOrdered)
   2639      1.1  joerg     EmitIgnoredExpr(LoopArgs.Init);
   2640      1.1  joerg 
   2641      1.1  joerg   // Create a block for the increment.
   2642      1.1  joerg   JumpDest Continue = getJumpDestInCurrentScope("omp.dispatch.inc");
   2643      1.1  joerg   BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
   2644      1.1  joerg 
   2645  1.1.1.2  joerg   emitCommonSimdLoop(
   2646  1.1.1.2  joerg       *this, S,
   2647  1.1.1.2  joerg       [&S, IsMonotonic](CodeGenFunction &CGF, PrePostActionTy &) {
   2648  1.1.1.2  joerg         // Generate !llvm.loop.parallel metadata for loads and stores for loops
   2649  1.1.1.2  joerg         // with dynamic/guided scheduling and without ordered clause.
   2650  1.1.1.2  joerg         if (!isOpenMPSimdDirective(S.getDirectiveKind())) {
   2651  1.1.1.2  joerg           CGF.LoopStack.setParallel(!IsMonotonic);
   2652  1.1.1.2  joerg           if (const auto *C = S.getSingleClause<OMPOrderClause>())
   2653  1.1.1.2  joerg             if (C->getKind() == OMPC_ORDER_concurrent)
   2654  1.1.1.2  joerg               CGF.LoopStack.setParallel(/*Enable=*/true);
   2655  1.1.1.2  joerg         } else {
   2656  1.1.1.2  joerg           CGF.EmitOMPSimdInit(S, IsMonotonic);
   2657  1.1.1.2  joerg         }
   2658      1.1  joerg       },
   2659  1.1.1.2  joerg       [&S, &LoopArgs, LoopExit, &CodeGenLoop, IVSize, IVSigned, &CodeGenOrdered,
   2660  1.1.1.2  joerg        &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
   2661  1.1.1.2  joerg         SourceLocation Loc = S.getBeginLoc();
   2662  1.1.1.2  joerg         // when 'distribute' is not combined with a 'for':
   2663  1.1.1.2  joerg         // while (idx <= UB) { BODY; ++idx; }
   2664  1.1.1.2  joerg         // when 'distribute' is combined with a 'for'
   2665  1.1.1.2  joerg         // (e.g. 'distribute parallel for')
   2666  1.1.1.2  joerg         // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; }
   2667  1.1.1.2  joerg         CGF.EmitOMPInnerLoop(
   2668  1.1.1.2  joerg             S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr,
   2669  1.1.1.2  joerg             [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
   2670  1.1.1.2  joerg               CodeGenLoop(CGF, S, LoopExit);
   2671  1.1.1.2  joerg             },
   2672  1.1.1.2  joerg             [IVSize, IVSigned, Loc, &CodeGenOrdered](CodeGenFunction &CGF) {
   2673  1.1.1.2  joerg               CodeGenOrdered(CGF, Loc, IVSize, IVSigned);
   2674  1.1.1.2  joerg             });
   2675      1.1  joerg       });
   2676      1.1  joerg 
   2677      1.1  joerg   EmitBlock(Continue.getBlock());
   2678      1.1  joerg   BreakContinueStack.pop_back();
   2679      1.1  joerg   if (!DynamicOrOrdered) {
   2680      1.1  joerg     // Emit "LB = LB + Stride", "UB = UB + Stride".
   2681      1.1  joerg     EmitIgnoredExpr(LoopArgs.NextLB);
   2682      1.1  joerg     EmitIgnoredExpr(LoopArgs.NextUB);
   2683      1.1  joerg   }
   2684      1.1  joerg 
   2685      1.1  joerg   EmitBranch(CondBlock);
   2686  1.1.1.2  joerg   OMPLoopNestStack.clear();
   2687      1.1  joerg   LoopStack.pop();
   2688      1.1  joerg   // Emit the fall-through block.
   2689      1.1  joerg   EmitBlock(LoopExit.getBlock());
   2690      1.1  joerg 
   2691      1.1  joerg   // Tell the runtime we are done.
   2692      1.1  joerg   auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) {
   2693      1.1  joerg     if (!DynamicOrOrdered)
   2694      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
   2695      1.1  joerg                                                      S.getDirectiveKind());
   2696      1.1  joerg   };
   2697      1.1  joerg   OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
   2698      1.1  joerg }
   2699      1.1  joerg 
   2700      1.1  joerg void CodeGenFunction::EmitOMPForOuterLoop(
   2701      1.1  joerg     const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic,
   2702      1.1  joerg     const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered,
   2703      1.1  joerg     const OMPLoopArguments &LoopArgs,
   2704      1.1  joerg     const CodeGenDispatchBoundsTy &CGDispatchBounds) {
   2705      1.1  joerg   CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
   2706      1.1  joerg 
   2707      1.1  joerg   // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime).
   2708      1.1  joerg   const bool DynamicOrOrdered =
   2709      1.1  joerg       Ordered || RT.isDynamic(ScheduleKind.Schedule);
   2710      1.1  joerg 
   2711      1.1  joerg   assert((Ordered ||
   2712      1.1  joerg           !RT.isStaticNonchunked(ScheduleKind.Schedule,
   2713      1.1  joerg                                  LoopArgs.Chunk != nullptr)) &&
   2714      1.1  joerg          "static non-chunked schedule does not need outer loop");
   2715      1.1  joerg 
   2716      1.1  joerg   // Emit outer loop.
   2717      1.1  joerg   //
   2718      1.1  joerg   // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
   2719      1.1  joerg   // When schedule(dynamic,chunk_size) is specified, the iterations are
   2720      1.1  joerg   // distributed to threads in the team in chunks as the threads request them.
   2721      1.1  joerg   // Each thread executes a chunk of iterations, then requests another chunk,
   2722      1.1  joerg   // until no chunks remain to be distributed. Each chunk contains chunk_size
   2723      1.1  joerg   // iterations, except for the last chunk to be distributed, which may have
   2724      1.1  joerg   // fewer iterations. When no chunk_size is specified, it defaults to 1.
   2725      1.1  joerg   //
   2726      1.1  joerg   // When schedule(guided,chunk_size) is specified, the iterations are assigned
   2727      1.1  joerg   // to threads in the team in chunks as the executing threads request them.
   2728      1.1  joerg   // Each thread executes a chunk of iterations, then requests another chunk,
   2729      1.1  joerg   // until no chunks remain to be assigned. For a chunk_size of 1, the size of
   2730      1.1  joerg   // each chunk is proportional to the number of unassigned iterations divided
   2731      1.1  joerg   // by the number of threads in the team, decreasing to 1. For a chunk_size
   2732      1.1  joerg   // with value k (greater than 1), the size of each chunk is determined in the
   2733      1.1  joerg   // same way, with the restriction that the chunks do not contain fewer than k
   2734      1.1  joerg   // iterations (except for the last chunk to be assigned, which may have fewer
   2735      1.1  joerg   // than k iterations).
   2736      1.1  joerg   //
   2737      1.1  joerg   // When schedule(auto) is specified, the decision regarding scheduling is
   2738      1.1  joerg   // delegated to the compiler and/or runtime system. The programmer gives the
   2739      1.1  joerg   // implementation the freedom to choose any possible mapping of iterations to
   2740      1.1  joerg   // threads in the team.
   2741      1.1  joerg   //
   2742      1.1  joerg   // When schedule(runtime) is specified, the decision regarding scheduling is
   2743      1.1  joerg   // deferred until run time, and the schedule and chunk size are taken from the
   2744      1.1  joerg   // run-sched-var ICV. If the ICV is set to auto, the schedule is
   2745      1.1  joerg   // implementation defined
   2746      1.1  joerg   //
   2747      1.1  joerg   // while(__kmpc_dispatch_next(&LB, &UB)) {
   2748      1.1  joerg   //   idx = LB;
   2749      1.1  joerg   //   while (idx <= UB) { BODY; ++idx;
   2750      1.1  joerg   //   __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only.
   2751      1.1  joerg   //   } // inner loop
   2752      1.1  joerg   // }
   2753      1.1  joerg   //
   2754      1.1  joerg   // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
   2755      1.1  joerg   // When schedule(static, chunk_size) is specified, iterations are divided into
   2756      1.1  joerg   // chunks of size chunk_size, and the chunks are assigned to the threads in
   2757      1.1  joerg   // the team in a round-robin fashion in the order of the thread number.
   2758      1.1  joerg   //
   2759      1.1  joerg   // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) {
   2760      1.1  joerg   //   while (idx <= UB) { BODY; ++idx; } // inner loop
   2761      1.1  joerg   //   LB = LB + ST;
   2762      1.1  joerg   //   UB = UB + ST;
   2763      1.1  joerg   // }
   2764      1.1  joerg   //
   2765      1.1  joerg 
   2766      1.1  joerg   const Expr *IVExpr = S.getIterationVariable();
   2767      1.1  joerg   const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
   2768      1.1  joerg   const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
   2769      1.1  joerg 
   2770      1.1  joerg   if (DynamicOrOrdered) {
   2771      1.1  joerg     const std::pair<llvm::Value *, llvm::Value *> DispatchBounds =
   2772      1.1  joerg         CGDispatchBounds(*this, S, LoopArgs.LB, LoopArgs.UB);
   2773      1.1  joerg     llvm::Value *LBVal = DispatchBounds.first;
   2774      1.1  joerg     llvm::Value *UBVal = DispatchBounds.second;
   2775      1.1  joerg     CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal,
   2776      1.1  joerg                                                              LoopArgs.Chunk};
   2777      1.1  joerg     RT.emitForDispatchInit(*this, S.getBeginLoc(), ScheduleKind, IVSize,
   2778      1.1  joerg                            IVSigned, Ordered, DipatchRTInputValues);
   2779      1.1  joerg   } else {
   2780      1.1  joerg     CGOpenMPRuntime::StaticRTInput StaticInit(
   2781      1.1  joerg         IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,
   2782      1.1  joerg         LoopArgs.ST, LoopArgs.Chunk);
   2783      1.1  joerg     RT.emitForStaticInit(*this, S.getBeginLoc(), S.getDirectiveKind(),
   2784      1.1  joerg                          ScheduleKind, StaticInit);
   2785      1.1  joerg   }
   2786      1.1  joerg 
   2787      1.1  joerg   auto &&CodeGenOrdered = [Ordered](CodeGenFunction &CGF, SourceLocation Loc,
   2788      1.1  joerg                                     const unsigned IVSize,
   2789      1.1  joerg                                     const bool IVSigned) {
   2790      1.1  joerg     if (Ordered) {
   2791      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(CGF, Loc, IVSize,
   2792      1.1  joerg                                                             IVSigned);
   2793      1.1  joerg     }
   2794      1.1  joerg   };
   2795      1.1  joerg 
   2796      1.1  joerg   OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
   2797      1.1  joerg                                  LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);
   2798      1.1  joerg   OuterLoopArgs.IncExpr = S.getInc();
   2799      1.1  joerg   OuterLoopArgs.Init = S.getInit();
   2800      1.1  joerg   OuterLoopArgs.Cond = S.getCond();
   2801      1.1  joerg   OuterLoopArgs.NextLB = S.getNextLowerBound();
   2802      1.1  joerg   OuterLoopArgs.NextUB = S.getNextUpperBound();
   2803      1.1  joerg   EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,
   2804      1.1  joerg                    emitOMPLoopBodyWithStopPoint, CodeGenOrdered);
   2805      1.1  joerg }
   2806      1.1  joerg 
   2807      1.1  joerg static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc,
   2808      1.1  joerg                              const unsigned IVSize, const bool IVSigned) {}
   2809      1.1  joerg 
   2810      1.1  joerg void CodeGenFunction::EmitOMPDistributeOuterLoop(
   2811      1.1  joerg     OpenMPDistScheduleClauseKind ScheduleKind, const OMPLoopDirective &S,
   2812      1.1  joerg     OMPPrivateScope &LoopScope, const OMPLoopArguments &LoopArgs,
   2813      1.1  joerg     const CodeGenLoopTy &CodeGenLoopContent) {
   2814      1.1  joerg 
   2815      1.1  joerg   CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
   2816      1.1  joerg 
   2817      1.1  joerg   // Emit outer loop.
   2818      1.1  joerg   // Same behavior as a OMPForOuterLoop, except that schedule cannot be
   2819      1.1  joerg   // dynamic
   2820      1.1  joerg   //
   2821      1.1  joerg 
   2822      1.1  joerg   const Expr *IVExpr = S.getIterationVariable();
   2823      1.1  joerg   const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
   2824      1.1  joerg   const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
   2825      1.1  joerg 
   2826      1.1  joerg   CGOpenMPRuntime::StaticRTInput StaticInit(
   2827      1.1  joerg       IVSize, IVSigned, /* Ordered = */ false, LoopArgs.IL, LoopArgs.LB,
   2828      1.1  joerg       LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk);
   2829      1.1  joerg   RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind, StaticInit);
   2830      1.1  joerg 
   2831      1.1  joerg   // for combined 'distribute' and 'for' the increment expression of distribute
   2832      1.1  joerg   // is stored in DistInc. For 'distribute' alone, it is in Inc.
   2833      1.1  joerg   Expr *IncExpr;
   2834      1.1  joerg   if (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()))
   2835      1.1  joerg     IncExpr = S.getDistInc();
   2836      1.1  joerg   else
   2837      1.1  joerg     IncExpr = S.getInc();
   2838      1.1  joerg 
   2839      1.1  joerg   // this routine is shared by 'omp distribute parallel for' and
   2840      1.1  joerg   // 'omp distribute': select the right EUB expression depending on the
   2841      1.1  joerg   // directive
   2842      1.1  joerg   OMPLoopArguments OuterLoopArgs;
   2843      1.1  joerg   OuterLoopArgs.LB = LoopArgs.LB;
   2844      1.1  joerg   OuterLoopArgs.UB = LoopArgs.UB;
   2845      1.1  joerg   OuterLoopArgs.ST = LoopArgs.ST;
   2846      1.1  joerg   OuterLoopArgs.IL = LoopArgs.IL;
   2847      1.1  joerg   OuterLoopArgs.Chunk = LoopArgs.Chunk;
   2848      1.1  joerg   OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   2849      1.1  joerg                           ? S.getCombinedEnsureUpperBound()
   2850      1.1  joerg                           : S.getEnsureUpperBound();
   2851      1.1  joerg   OuterLoopArgs.IncExpr = IncExpr;
   2852      1.1  joerg   OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   2853      1.1  joerg                            ? S.getCombinedInit()
   2854      1.1  joerg                            : S.getInit();
   2855      1.1  joerg   OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   2856      1.1  joerg                            ? S.getCombinedCond()
   2857      1.1  joerg                            : S.getCond();
   2858      1.1  joerg   OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   2859      1.1  joerg                              ? S.getCombinedNextLowerBound()
   2860      1.1  joerg                              : S.getNextLowerBound();
   2861      1.1  joerg   OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   2862      1.1  joerg                              ? S.getCombinedNextUpperBound()
   2863      1.1  joerg                              : S.getNextUpperBound();
   2864      1.1  joerg 
   2865      1.1  joerg   EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, S,
   2866      1.1  joerg                    LoopScope, OuterLoopArgs, CodeGenLoopContent,
   2867      1.1  joerg                    emitEmptyOrdered);
   2868      1.1  joerg }
   2869      1.1  joerg 
   2870      1.1  joerg static std::pair<LValue, LValue>
   2871      1.1  joerg emitDistributeParallelForInnerBounds(CodeGenFunction &CGF,
   2872      1.1  joerg                                      const OMPExecutableDirective &S) {
   2873      1.1  joerg   const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
   2874      1.1  joerg   LValue LB =
   2875      1.1  joerg       EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
   2876      1.1  joerg   LValue UB =
   2877      1.1  joerg       EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
   2878      1.1  joerg 
   2879      1.1  joerg   // When composing 'distribute' with 'for' (e.g. as in 'distribute
   2880      1.1  joerg   // parallel for') we need to use the 'distribute'
   2881      1.1  joerg   // chunk lower and upper bounds rather than the whole loop iteration
   2882      1.1  joerg   // space. These are parameters to the outlined function for 'parallel'
   2883      1.1  joerg   // and we copy the bounds of the previous schedule into the
   2884      1.1  joerg   // the current ones.
   2885      1.1  joerg   LValue PrevLB = CGF.EmitLValue(LS.getPrevLowerBoundVariable());
   2886      1.1  joerg   LValue PrevUB = CGF.EmitLValue(LS.getPrevUpperBoundVariable());
   2887      1.1  joerg   llvm::Value *PrevLBVal = CGF.EmitLoadOfScalar(
   2888      1.1  joerg       PrevLB, LS.getPrevLowerBoundVariable()->getExprLoc());
   2889      1.1  joerg   PrevLBVal = CGF.EmitScalarConversion(
   2890      1.1  joerg       PrevLBVal, LS.getPrevLowerBoundVariable()->getType(),
   2891      1.1  joerg       LS.getIterationVariable()->getType(),
   2892      1.1  joerg       LS.getPrevLowerBoundVariable()->getExprLoc());
   2893      1.1  joerg   llvm::Value *PrevUBVal = CGF.EmitLoadOfScalar(
   2894      1.1  joerg       PrevUB, LS.getPrevUpperBoundVariable()->getExprLoc());
   2895      1.1  joerg   PrevUBVal = CGF.EmitScalarConversion(
   2896      1.1  joerg       PrevUBVal, LS.getPrevUpperBoundVariable()->getType(),
   2897      1.1  joerg       LS.getIterationVariable()->getType(),
   2898      1.1  joerg       LS.getPrevUpperBoundVariable()->getExprLoc());
   2899      1.1  joerg 
   2900      1.1  joerg   CGF.EmitStoreOfScalar(PrevLBVal, LB);
   2901      1.1  joerg   CGF.EmitStoreOfScalar(PrevUBVal, UB);
   2902      1.1  joerg 
   2903      1.1  joerg   return {LB, UB};
   2904      1.1  joerg }
   2905      1.1  joerg 
   2906      1.1  joerg /// if the 'for' loop has a dispatch schedule (e.g. dynamic, guided) then
   2907      1.1  joerg /// we need to use the LB and UB expressions generated by the worksharing
   2908      1.1  joerg /// code generation support, whereas in non combined situations we would
   2909      1.1  joerg /// just emit 0 and the LastIteration expression
   2910      1.1  joerg /// This function is necessary due to the difference of the LB and UB
   2911      1.1  joerg /// types for the RT emission routines for 'for_static_init' and
   2912      1.1  joerg /// 'for_dispatch_init'
   2913      1.1  joerg static std::pair<llvm::Value *, llvm::Value *>
   2914      1.1  joerg emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF,
   2915      1.1  joerg                                         const OMPExecutableDirective &S,
   2916      1.1  joerg                                         Address LB, Address UB) {
   2917      1.1  joerg   const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
   2918      1.1  joerg   const Expr *IVExpr = LS.getIterationVariable();
   2919      1.1  joerg   // when implementing a dynamic schedule for a 'for' combined with a
   2920      1.1  joerg   // 'distribute' (e.g. 'distribute parallel for'), the 'for' loop
   2921      1.1  joerg   // is not normalized as each team only executes its own assigned
   2922      1.1  joerg   // distribute chunk
   2923      1.1  joerg   QualType IteratorTy = IVExpr->getType();
   2924      1.1  joerg   llvm::Value *LBVal =
   2925      1.1  joerg       CGF.EmitLoadOfScalar(LB, /*Volatile=*/false, IteratorTy, S.getBeginLoc());
   2926      1.1  joerg   llvm::Value *UBVal =
   2927      1.1  joerg       CGF.EmitLoadOfScalar(UB, /*Volatile=*/false, IteratorTy, S.getBeginLoc());
   2928      1.1  joerg   return {LBVal, UBVal};
   2929      1.1  joerg }
   2930      1.1  joerg 
   2931      1.1  joerg static void emitDistributeParallelForDistributeInnerBoundParams(
   2932      1.1  joerg     CodeGenFunction &CGF, const OMPExecutableDirective &S,
   2933      1.1  joerg     llvm::SmallVectorImpl<llvm::Value *> &CapturedVars) {
   2934      1.1  joerg   const auto &Dir = cast<OMPLoopDirective>(S);
   2935      1.1  joerg   LValue LB =
   2936      1.1  joerg       CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));
   2937  1.1.1.2  joerg   llvm::Value *LBCast =
   2938  1.1.1.2  joerg       CGF.Builder.CreateIntCast(CGF.Builder.CreateLoad(LB.getAddress(CGF)),
   2939  1.1.1.2  joerg                                 CGF.SizeTy, /*isSigned=*/false);
   2940      1.1  joerg   CapturedVars.push_back(LBCast);
   2941      1.1  joerg   LValue UB =
   2942      1.1  joerg       CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));
   2943      1.1  joerg 
   2944  1.1.1.2  joerg   llvm::Value *UBCast =
   2945  1.1.1.2  joerg       CGF.Builder.CreateIntCast(CGF.Builder.CreateLoad(UB.getAddress(CGF)),
   2946  1.1.1.2  joerg                                 CGF.SizeTy, /*isSigned=*/false);
   2947      1.1  joerg   CapturedVars.push_back(UBCast);
   2948      1.1  joerg }
   2949      1.1  joerg 
   2950      1.1  joerg static void
   2951      1.1  joerg emitInnerParallelForWhenCombined(CodeGenFunction &CGF,
   2952      1.1  joerg                                  const OMPLoopDirective &S,
   2953      1.1  joerg                                  CodeGenFunction::JumpDest LoopExit) {
   2954      1.1  joerg   auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF,
   2955      1.1  joerg                                          PrePostActionTy &Action) {
   2956      1.1  joerg     Action.Enter(CGF);
   2957      1.1  joerg     bool HasCancel = false;
   2958      1.1  joerg     if (!isOpenMPSimdDirective(S.getDirectiveKind())) {
   2959      1.1  joerg       if (const auto *D = dyn_cast<OMPTeamsDistributeParallelForDirective>(&S))
   2960      1.1  joerg         HasCancel = D->hasCancel();
   2961      1.1  joerg       else if (const auto *D = dyn_cast<OMPDistributeParallelForDirective>(&S))
   2962      1.1  joerg         HasCancel = D->hasCancel();
   2963      1.1  joerg       else if (const auto *D =
   2964      1.1  joerg                    dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&S))
   2965      1.1  joerg         HasCancel = D->hasCancel();
   2966      1.1  joerg     }
   2967      1.1  joerg     CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(),
   2968      1.1  joerg                                                      HasCancel);
   2969      1.1  joerg     CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(),
   2970      1.1  joerg                                emitDistributeParallelForInnerBounds,
   2971      1.1  joerg                                emitDistributeParallelForDispatchBounds);
   2972      1.1  joerg   };
   2973      1.1  joerg 
   2974      1.1  joerg   emitCommonOMPParallelDirective(
   2975      1.1  joerg       CGF, S,
   2976      1.1  joerg       isOpenMPSimdDirective(S.getDirectiveKind()) ? OMPD_for_simd : OMPD_for,
   2977      1.1  joerg       CGInlinedWorksharingLoop,
   2978      1.1  joerg       emitDistributeParallelForDistributeInnerBoundParams);
   2979      1.1  joerg }
   2980      1.1  joerg 
   2981      1.1  joerg void CodeGenFunction::EmitOMPDistributeParallelForDirective(
   2982      1.1  joerg     const OMPDistributeParallelForDirective &S) {
   2983      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   2984      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
   2985      1.1  joerg                               S.getDistInc());
   2986      1.1  joerg   };
   2987      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_parallel);
   2988      1.1  joerg   CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
   2989      1.1  joerg }
   2990      1.1  joerg 
   2991      1.1  joerg void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective(
   2992      1.1  joerg     const OMPDistributeParallelForSimdDirective &S) {
   2993      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   2994      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
   2995      1.1  joerg                               S.getDistInc());
   2996      1.1  joerg   };
   2997      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_parallel);
   2998      1.1  joerg   CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
   2999      1.1  joerg }
   3000      1.1  joerg 
   3001      1.1  joerg void CodeGenFunction::EmitOMPDistributeSimdDirective(
   3002      1.1  joerg     const OMPDistributeSimdDirective &S) {
   3003      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   3004      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
   3005      1.1  joerg   };
   3006      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_unknown);
   3007      1.1  joerg   CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
   3008      1.1  joerg }
   3009      1.1  joerg 
   3010      1.1  joerg void CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
   3011      1.1  joerg     CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S) {
   3012      1.1  joerg   // Emit SPMD target parallel for region as a standalone region.
   3013      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   3014      1.1  joerg     emitOMPSimdRegion(CGF, S, Action);
   3015      1.1  joerg   };
   3016      1.1  joerg   llvm::Function *Fn;
   3017      1.1  joerg   llvm::Constant *Addr;
   3018      1.1  joerg   // Emit target region as a standalone region.
   3019      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   3020      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   3021      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   3022      1.1  joerg }
   3023      1.1  joerg 
   3024      1.1  joerg void CodeGenFunction::EmitOMPTargetSimdDirective(
   3025      1.1  joerg     const OMPTargetSimdDirective &S) {
   3026      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   3027      1.1  joerg     emitOMPSimdRegion(CGF, S, Action);
   3028      1.1  joerg   };
   3029      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   3030      1.1  joerg }
   3031      1.1  joerg 
   3032      1.1  joerg namespace {
   3033      1.1  joerg   struct ScheduleKindModifiersTy {
   3034      1.1  joerg     OpenMPScheduleClauseKind Kind;
   3035      1.1  joerg     OpenMPScheduleClauseModifier M1;
   3036      1.1  joerg     OpenMPScheduleClauseModifier M2;
   3037      1.1  joerg     ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind,
   3038      1.1  joerg                             OpenMPScheduleClauseModifier M1,
   3039      1.1  joerg                             OpenMPScheduleClauseModifier M2)
   3040      1.1  joerg         : Kind(Kind), M1(M1), M2(M2) {}
   3041      1.1  joerg   };
   3042      1.1  joerg } // namespace
   3043      1.1  joerg 
   3044      1.1  joerg bool CodeGenFunction::EmitOMPWorksharingLoop(
   3045      1.1  joerg     const OMPLoopDirective &S, Expr *EUB,
   3046      1.1  joerg     const CodeGenLoopBoundsTy &CodeGenLoopBounds,
   3047      1.1  joerg     const CodeGenDispatchBoundsTy &CGDispatchBounds) {
   3048      1.1  joerg   // Emit the loop iteration variable.
   3049      1.1  joerg   const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
   3050      1.1  joerg   const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
   3051      1.1  joerg   EmitVarDecl(*IVDecl);
   3052      1.1  joerg 
   3053      1.1  joerg   // Emit the iterations count variable.
   3054      1.1  joerg   // If it is not a variable, Sema decided to calculate iterations count on each
   3055      1.1  joerg   // iteration (e.g., it is foldable into a constant).
   3056      1.1  joerg   if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
   3057      1.1  joerg     EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
   3058      1.1  joerg     // Emit calculation of the iterations count.
   3059      1.1  joerg     EmitIgnoredExpr(S.getCalcLastIteration());
   3060      1.1  joerg   }
   3061      1.1  joerg 
   3062      1.1  joerg   CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
   3063      1.1  joerg 
   3064      1.1  joerg   bool HasLastprivateClause;
   3065      1.1  joerg   // Check pre-condition.
   3066      1.1  joerg   {
   3067      1.1  joerg     OMPLoopScope PreInitScope(*this, S);
   3068      1.1  joerg     // Skip the entire loop if we don't meet the precondition.
   3069      1.1  joerg     // If the condition constant folds and can be elided, avoid emitting the
   3070      1.1  joerg     // whole loop.
   3071      1.1  joerg     bool CondConstant;
   3072      1.1  joerg     llvm::BasicBlock *ContBlock = nullptr;
   3073      1.1  joerg     if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
   3074      1.1  joerg       if (!CondConstant)
   3075      1.1  joerg         return false;
   3076      1.1  joerg     } else {
   3077      1.1  joerg       llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then");
   3078      1.1  joerg       ContBlock = createBasicBlock("omp.precond.end");
   3079      1.1  joerg       emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
   3080      1.1  joerg                   getProfileCount(&S));
   3081      1.1  joerg       EmitBlock(ThenBlock);
   3082      1.1  joerg       incrementProfileCounter(&S);
   3083      1.1  joerg     }
   3084      1.1  joerg 
   3085      1.1  joerg     RunCleanupsScope DoacrossCleanupScope(*this);
   3086      1.1  joerg     bool Ordered = false;
   3087      1.1  joerg     if (const auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) {
   3088      1.1  joerg       if (OrderedClause->getNumForLoops())
   3089      1.1  joerg         RT.emitDoacrossInit(*this, S, OrderedClause->getLoopNumIterations());
   3090      1.1  joerg       else
   3091      1.1  joerg         Ordered = true;
   3092      1.1  joerg     }
   3093      1.1  joerg 
   3094      1.1  joerg     llvm::DenseSet<const Expr *> EmittedFinals;
   3095      1.1  joerg     emitAlignedClause(*this, S);
   3096      1.1  joerg     bool HasLinears = EmitOMPLinearClauseInit(S);
   3097      1.1  joerg     // Emit helper vars inits.
   3098      1.1  joerg 
   3099      1.1  joerg     std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S);
   3100      1.1  joerg     LValue LB = Bounds.first;
   3101      1.1  joerg     LValue UB = Bounds.second;
   3102      1.1  joerg     LValue ST =
   3103      1.1  joerg         EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
   3104      1.1  joerg     LValue IL =
   3105      1.1  joerg         EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
   3106      1.1  joerg 
   3107      1.1  joerg     // Emit 'then' code.
   3108      1.1  joerg     {
   3109      1.1  joerg       OMPPrivateScope LoopScope(*this);
   3110      1.1  joerg       if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) {
   3111      1.1  joerg         // Emit implicit barrier to synchronize threads and avoid data races on
   3112      1.1  joerg         // initialization of firstprivate variables and post-update of
   3113      1.1  joerg         // lastprivate variables.
   3114      1.1  joerg         CGM.getOpenMPRuntime().emitBarrierCall(
   3115      1.1  joerg             *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
   3116      1.1  joerg             /*ForceSimpleCall=*/true);
   3117      1.1  joerg       }
   3118      1.1  joerg       EmitOMPPrivateClause(S, LoopScope);
   3119  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion(
   3120  1.1.1.2  joerg           *this, S, EmitLValue(S.getIterationVariable()));
   3121      1.1  joerg       HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
   3122      1.1  joerg       EmitOMPReductionClauseInit(S, LoopScope);
   3123      1.1  joerg       EmitOMPPrivateLoopCounters(S, LoopScope);
   3124      1.1  joerg       EmitOMPLinearClause(S, LoopScope);
   3125      1.1  joerg       (void)LoopScope.Privatize();
   3126      1.1  joerg       if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
   3127      1.1  joerg         CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S);
   3128      1.1  joerg 
   3129      1.1  joerg       // Detect the loop schedule kind and chunk.
   3130      1.1  joerg       const Expr *ChunkExpr = nullptr;
   3131      1.1  joerg       OpenMPScheduleTy ScheduleKind;
   3132      1.1  joerg       if (const auto *C = S.getSingleClause<OMPScheduleClause>()) {
   3133      1.1  joerg         ScheduleKind.Schedule = C->getScheduleKind();
   3134      1.1  joerg         ScheduleKind.M1 = C->getFirstScheduleModifier();
   3135      1.1  joerg         ScheduleKind.M2 = C->getSecondScheduleModifier();
   3136      1.1  joerg         ChunkExpr = C->getChunkSize();
   3137      1.1  joerg       } else {
   3138      1.1  joerg         // Default behaviour for schedule clause.
   3139      1.1  joerg         CGM.getOpenMPRuntime().getDefaultScheduleAndChunk(
   3140      1.1  joerg             *this, S, ScheduleKind.Schedule, ChunkExpr);
   3141      1.1  joerg       }
   3142      1.1  joerg       bool HasChunkSizeOne = false;
   3143      1.1  joerg       llvm::Value *Chunk = nullptr;
   3144      1.1  joerg       if (ChunkExpr) {
   3145      1.1  joerg         Chunk = EmitScalarExpr(ChunkExpr);
   3146      1.1  joerg         Chunk = EmitScalarConversion(Chunk, ChunkExpr->getType(),
   3147      1.1  joerg                                      S.getIterationVariable()->getType(),
   3148      1.1  joerg                                      S.getBeginLoc());
   3149      1.1  joerg         Expr::EvalResult Result;
   3150      1.1  joerg         if (ChunkExpr->EvaluateAsInt(Result, getContext())) {
   3151      1.1  joerg           llvm::APSInt EvaluatedChunk = Result.Val.getInt();
   3152      1.1  joerg           HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1);
   3153      1.1  joerg         }
   3154      1.1  joerg       }
   3155      1.1  joerg       const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
   3156      1.1  joerg       const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
   3157      1.1  joerg       // OpenMP 4.5, 2.7.1 Loop Construct, Description.
   3158      1.1  joerg       // If the static schedule kind is specified or if the ordered clause is
   3159      1.1  joerg       // specified, and if no monotonic modifier is specified, the effect will
   3160      1.1  joerg       // be as if the monotonic modifier was specified.
   3161      1.1  joerg       bool StaticChunkedOne = RT.isStaticChunked(ScheduleKind.Schedule,
   3162      1.1  joerg           /* Chunked */ Chunk != nullptr) && HasChunkSizeOne &&
   3163      1.1  joerg           isOpenMPLoopBoundSharingDirective(S.getDirectiveKind());
   3164  1.1.1.2  joerg       bool IsMonotonic =
   3165  1.1.1.2  joerg           Ordered ||
   3166  1.1.1.2  joerg           ((ScheduleKind.Schedule == OMPC_SCHEDULE_static ||
   3167  1.1.1.2  joerg             ScheduleKind.Schedule == OMPC_SCHEDULE_unknown) &&
   3168  1.1.1.2  joerg            !(ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
   3169  1.1.1.2  joerg              ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)) ||
   3170  1.1.1.2  joerg           ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
   3171  1.1.1.2  joerg           ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
   3172      1.1  joerg       if ((RT.isStaticNonchunked(ScheduleKind.Schedule,
   3173      1.1  joerg                                  /* Chunked */ Chunk != nullptr) ||
   3174      1.1  joerg            StaticChunkedOne) &&
   3175      1.1  joerg           !Ordered) {
   3176      1.1  joerg         JumpDest LoopExit =
   3177      1.1  joerg             getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
   3178  1.1.1.2  joerg         emitCommonSimdLoop(
   3179  1.1.1.2  joerg             *this, S,
   3180  1.1.1.2  joerg             [&S, IsMonotonic](CodeGenFunction &CGF, PrePostActionTy &) {
   3181  1.1.1.2  joerg               if (isOpenMPSimdDirective(S.getDirectiveKind())) {
   3182  1.1.1.2  joerg                 CGF.EmitOMPSimdInit(S, IsMonotonic);
   3183  1.1.1.2  joerg               } else if (const auto *C = S.getSingleClause<OMPOrderClause>()) {
   3184  1.1.1.2  joerg                 if (C->getKind() == OMPC_ORDER_concurrent)
   3185  1.1.1.2  joerg                   CGF.LoopStack.setParallel(/*Enable=*/true);
   3186  1.1.1.2  joerg               }
   3187      1.1  joerg             },
   3188  1.1.1.2  joerg             [IVSize, IVSigned, Ordered, IL, LB, UB, ST, StaticChunkedOne, Chunk,
   3189  1.1.1.2  joerg              &S, ScheduleKind, LoopExit,
   3190  1.1.1.2  joerg              &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
   3191  1.1.1.2  joerg               // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
   3192  1.1.1.2  joerg               // When no chunk_size is specified, the iteration space is divided
   3193  1.1.1.2  joerg               // into chunks that are approximately equal in size, and at most
   3194  1.1.1.2  joerg               // one chunk is distributed to each thread. Note that the size of
   3195  1.1.1.2  joerg               // the chunks is unspecified in this case.
   3196  1.1.1.2  joerg               CGOpenMPRuntime::StaticRTInput StaticInit(
   3197  1.1.1.2  joerg                   IVSize, IVSigned, Ordered, IL.getAddress(CGF),
   3198  1.1.1.2  joerg                   LB.getAddress(CGF), UB.getAddress(CGF), ST.getAddress(CGF),
   3199  1.1.1.2  joerg                   StaticChunkedOne ? Chunk : nullptr);
   3200  1.1.1.2  joerg               CGF.CGM.getOpenMPRuntime().emitForStaticInit(
   3201  1.1.1.2  joerg                   CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind,
   3202  1.1.1.2  joerg                   StaticInit);
   3203  1.1.1.2  joerg               // UB = min(UB, GlobalUB);
   3204  1.1.1.2  joerg               if (!StaticChunkedOne)
   3205  1.1.1.2  joerg                 CGF.EmitIgnoredExpr(S.getEnsureUpperBound());
   3206  1.1.1.2  joerg               // IV = LB;
   3207  1.1.1.2  joerg               CGF.EmitIgnoredExpr(S.getInit());
   3208  1.1.1.2  joerg               // For unchunked static schedule generate:
   3209  1.1.1.2  joerg               //
   3210  1.1.1.2  joerg               // while (idx <= UB) {
   3211  1.1.1.2  joerg               //   BODY;
   3212  1.1.1.2  joerg               //   ++idx;
   3213  1.1.1.2  joerg               // }
   3214  1.1.1.2  joerg               //
   3215  1.1.1.2  joerg               // For static schedule with chunk one:
   3216  1.1.1.2  joerg               //
   3217  1.1.1.2  joerg               // while (IV <= PrevUB) {
   3218  1.1.1.2  joerg               //   BODY;
   3219  1.1.1.2  joerg               //   IV += ST;
   3220  1.1.1.2  joerg               // }
   3221  1.1.1.2  joerg               CGF.EmitOMPInnerLoop(
   3222  1.1.1.2  joerg                   S, LoopScope.requiresCleanups(),
   3223  1.1.1.2  joerg                   StaticChunkedOne ? S.getCombinedParForInDistCond()
   3224  1.1.1.2  joerg                                    : S.getCond(),
   3225  1.1.1.2  joerg                   StaticChunkedOne ? S.getDistInc() : S.getInc(),
   3226  1.1.1.2  joerg                   [&S, LoopExit](CodeGenFunction &CGF) {
   3227  1.1.1.2  joerg                     emitOMPLoopBodyWithStopPoint(CGF, S, LoopExit);
   3228  1.1.1.2  joerg                   },
   3229  1.1.1.2  joerg                   [](CodeGenFunction &) {});
   3230  1.1.1.2  joerg             });
   3231      1.1  joerg         EmitBlock(LoopExit.getBlock());
   3232      1.1  joerg         // Tell the runtime we are done.
   3233      1.1  joerg         auto &&CodeGen = [&S](CodeGenFunction &CGF) {
   3234      1.1  joerg           CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
   3235      1.1  joerg                                                          S.getDirectiveKind());
   3236      1.1  joerg         };
   3237      1.1  joerg         OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
   3238      1.1  joerg       } else {
   3239      1.1  joerg         // Emit the outer loop, which requests its work chunk [LB..UB] from
   3240      1.1  joerg         // runtime and runs the inner loop to process it.
   3241  1.1.1.2  joerg         const OMPLoopArguments LoopArguments(
   3242  1.1.1.2  joerg             LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this),
   3243  1.1.1.2  joerg             IL.getAddress(*this), Chunk, EUB);
   3244      1.1  joerg         EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
   3245      1.1  joerg                             LoopArguments, CGDispatchBounds);
   3246      1.1  joerg       }
   3247      1.1  joerg       if (isOpenMPSimdDirective(S.getDirectiveKind())) {
   3248      1.1  joerg         EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) {
   3249      1.1  joerg           return CGF.Builder.CreateIsNotNull(
   3250      1.1  joerg               CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
   3251      1.1  joerg         });
   3252      1.1  joerg       }
   3253      1.1  joerg       EmitOMPReductionClauseFinal(
   3254      1.1  joerg           S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind())
   3255      1.1  joerg                  ? /*Parallel and Simd*/ OMPD_parallel_for_simd
   3256      1.1  joerg                  : /*Parallel only*/ OMPD_parallel);
   3257      1.1  joerg       // Emit post-update of the reduction variables if IsLastIter != 0.
   3258      1.1  joerg       emitPostUpdateForReductionClause(
   3259      1.1  joerg           *this, S, [IL, &S](CodeGenFunction &CGF) {
   3260      1.1  joerg             return CGF.Builder.CreateIsNotNull(
   3261      1.1  joerg                 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
   3262      1.1  joerg           });
   3263      1.1  joerg       // Emit final copy of the lastprivate variables if IsLastIter != 0.
   3264      1.1  joerg       if (HasLastprivateClause)
   3265      1.1  joerg         EmitOMPLastprivateClauseFinal(
   3266      1.1  joerg             S, isOpenMPSimdDirective(S.getDirectiveKind()),
   3267      1.1  joerg             Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc())));
   3268      1.1  joerg     }
   3269      1.1  joerg     EmitOMPLinearClauseFinal(S, [IL, &S](CodeGenFunction &CGF) {
   3270      1.1  joerg       return CGF.Builder.CreateIsNotNull(
   3271      1.1  joerg           CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
   3272      1.1  joerg     });
   3273      1.1  joerg     DoacrossCleanupScope.ForceCleanup();
   3274      1.1  joerg     // We're now done with the loop, so jump to the continuation block.
   3275      1.1  joerg     if (ContBlock) {
   3276      1.1  joerg       EmitBranch(ContBlock);
   3277      1.1  joerg       EmitBlock(ContBlock, /*IsFinished=*/true);
   3278      1.1  joerg     }
   3279      1.1  joerg   }
   3280      1.1  joerg   return HasLastprivateClause;
   3281      1.1  joerg }
   3282      1.1  joerg 
   3283      1.1  joerg /// The following two functions generate expressions for the loop lower
   3284      1.1  joerg /// and upper bounds in case of static and dynamic (dispatch) schedule
   3285      1.1  joerg /// of the associated 'for' or 'distribute' loop.
   3286      1.1  joerg static std::pair<LValue, LValue>
   3287      1.1  joerg emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
   3288      1.1  joerg   const auto &LS = cast<OMPLoopDirective>(S);
   3289      1.1  joerg   LValue LB =
   3290      1.1  joerg       EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
   3291      1.1  joerg   LValue UB =
   3292      1.1  joerg       EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
   3293      1.1  joerg   return {LB, UB};
   3294      1.1  joerg }
   3295      1.1  joerg 
   3296      1.1  joerg /// When dealing with dispatch schedules (e.g. dynamic, guided) we do not
   3297      1.1  joerg /// consider the lower and upper bound expressions generated by the
   3298      1.1  joerg /// worksharing loop support, but we use 0 and the iteration space size as
   3299      1.1  joerg /// constants
   3300      1.1  joerg static std::pair<llvm::Value *, llvm::Value *>
   3301      1.1  joerg emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S,
   3302      1.1  joerg                           Address LB, Address UB) {
   3303      1.1  joerg   const auto &LS = cast<OMPLoopDirective>(S);
   3304      1.1  joerg   const Expr *IVExpr = LS.getIterationVariable();
   3305      1.1  joerg   const unsigned IVSize = CGF.getContext().getTypeSize(IVExpr->getType());
   3306      1.1  joerg   llvm::Value *LBVal = CGF.Builder.getIntN(IVSize, 0);
   3307      1.1  joerg   llvm::Value *UBVal = CGF.EmitScalarExpr(LS.getLastIteration());
   3308      1.1  joerg   return {LBVal, UBVal};
   3309      1.1  joerg }
   3310      1.1  joerg 
   3311  1.1.1.2  joerg /// Emits internal temp array declarations for the directive with inscan
   3312  1.1.1.2  joerg /// reductions.
   3313  1.1.1.2  joerg /// The code is the following:
   3314  1.1.1.2  joerg /// \code
   3315  1.1.1.2  joerg /// size num_iters = <num_iters>;
   3316  1.1.1.2  joerg /// <type> buffer[num_iters];
   3317  1.1.1.2  joerg /// \endcode
   3318  1.1.1.2  joerg static void emitScanBasedDirectiveDecls(
   3319  1.1.1.2  joerg     CodeGenFunction &CGF, const OMPLoopDirective &S,
   3320  1.1.1.2  joerg     llvm::function_ref<llvm::Value *(CodeGenFunction &)> NumIteratorsGen) {
   3321  1.1.1.2  joerg   llvm::Value *OMPScanNumIterations = CGF.Builder.CreateIntCast(
   3322  1.1.1.2  joerg       NumIteratorsGen(CGF), CGF.SizeTy, /*isSigned=*/false);
   3323  1.1.1.2  joerg   SmallVector<const Expr *, 4> Shareds;
   3324  1.1.1.2  joerg   SmallVector<const Expr *, 4> Privates;
   3325  1.1.1.2  joerg   SmallVector<const Expr *, 4> ReductionOps;
   3326  1.1.1.2  joerg   SmallVector<const Expr *, 4> CopyArrayTemps;
   3327  1.1.1.2  joerg   for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
   3328  1.1.1.2  joerg     assert(C->getModifier() == OMPC_REDUCTION_inscan &&
   3329  1.1.1.2  joerg            "Only inscan reductions are expected.");
   3330  1.1.1.2  joerg     Shareds.append(C->varlist_begin(), C->varlist_end());
   3331  1.1.1.2  joerg     Privates.append(C->privates().begin(), C->privates().end());
   3332  1.1.1.2  joerg     ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
   3333  1.1.1.2  joerg     CopyArrayTemps.append(C->copy_array_temps().begin(),
   3334  1.1.1.2  joerg                           C->copy_array_temps().end());
   3335  1.1.1.2  joerg   }
   3336  1.1.1.2  joerg   {
   3337  1.1.1.2  joerg     // Emit buffers for each reduction variables.
   3338  1.1.1.2  joerg     // ReductionCodeGen is required to emit correctly the code for array
   3339  1.1.1.2  joerg     // reductions.
   3340  1.1.1.2  joerg     ReductionCodeGen RedCG(Shareds, Shareds, Privates, ReductionOps);
   3341  1.1.1.2  joerg     unsigned Count = 0;
   3342  1.1.1.2  joerg     auto *ITA = CopyArrayTemps.begin();
   3343  1.1.1.2  joerg     for (const Expr *IRef : Privates) {
   3344  1.1.1.2  joerg       const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
   3345  1.1.1.2  joerg       // Emit variably modified arrays, used for arrays/array sections
   3346  1.1.1.2  joerg       // reductions.
   3347  1.1.1.2  joerg       if (PrivateVD->getType()->isVariablyModifiedType()) {
   3348  1.1.1.2  joerg         RedCG.emitSharedOrigLValue(CGF, Count);
   3349  1.1.1.2  joerg         RedCG.emitAggregateType(CGF, Count);
   3350  1.1.1.2  joerg       }
   3351  1.1.1.2  joerg       CodeGenFunction::OpaqueValueMapping DimMapping(
   3352  1.1.1.2  joerg           CGF,
   3353  1.1.1.2  joerg           cast<OpaqueValueExpr>(
   3354  1.1.1.2  joerg               cast<VariableArrayType>((*ITA)->getType()->getAsArrayTypeUnsafe())
   3355  1.1.1.2  joerg                   ->getSizeExpr()),
   3356  1.1.1.2  joerg           RValue::get(OMPScanNumIterations));
   3357  1.1.1.2  joerg       // Emit temp buffer.
   3358  1.1.1.2  joerg       CGF.EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(*ITA)->getDecl()));
   3359  1.1.1.2  joerg       ++ITA;
   3360  1.1.1.2  joerg       ++Count;
   3361  1.1.1.2  joerg     }
   3362  1.1.1.2  joerg   }
   3363  1.1.1.2  joerg }
   3364  1.1.1.2  joerg 
   3365  1.1.1.2  joerg /// Emits the code for the directive with inscan reductions.
   3366  1.1.1.2  joerg /// The code is the following:
   3367  1.1.1.2  joerg /// \code
   3368  1.1.1.2  joerg /// #pragma omp ...
   3369  1.1.1.2  joerg /// for (i: 0..<num_iters>) {
   3370  1.1.1.2  joerg ///   <input phase>;
   3371  1.1.1.2  joerg ///   buffer[i] = red;
   3372  1.1.1.2  joerg /// }
   3373  1.1.1.2  joerg /// #pragma omp master // in parallel region
   3374  1.1.1.2  joerg /// for (int k = 0; k != ceil(log2(num_iters)); ++k)
   3375  1.1.1.2  joerg /// for (size cnt = last_iter; cnt >= pow(2, k); --k)
   3376  1.1.1.2  joerg ///   buffer[i] op= buffer[i-pow(2,k)];
   3377  1.1.1.2  joerg /// #pragma omp barrier // in parallel region
   3378  1.1.1.2  joerg /// #pragma omp ...
   3379  1.1.1.2  joerg /// for (0..<num_iters>) {
   3380  1.1.1.2  joerg ///   red = InclusiveScan ? buffer[i] : buffer[i-1];
   3381  1.1.1.2  joerg ///   <scan phase>;
   3382  1.1.1.2  joerg /// }
   3383  1.1.1.2  joerg /// \endcode
   3384  1.1.1.2  joerg static void emitScanBasedDirective(
   3385  1.1.1.2  joerg     CodeGenFunction &CGF, const OMPLoopDirective &S,
   3386  1.1.1.2  joerg     llvm::function_ref<llvm::Value *(CodeGenFunction &)> NumIteratorsGen,
   3387  1.1.1.2  joerg     llvm::function_ref<void(CodeGenFunction &)> FirstGen,
   3388  1.1.1.2  joerg     llvm::function_ref<void(CodeGenFunction &)> SecondGen) {
   3389  1.1.1.2  joerg   llvm::Value *OMPScanNumIterations = CGF.Builder.CreateIntCast(
   3390  1.1.1.2  joerg       NumIteratorsGen(CGF), CGF.SizeTy, /*isSigned=*/false);
   3391  1.1.1.2  joerg   SmallVector<const Expr *, 4> Privates;
   3392  1.1.1.2  joerg   SmallVector<const Expr *, 4> ReductionOps;
   3393  1.1.1.2  joerg   SmallVector<const Expr *, 4> LHSs;
   3394  1.1.1.2  joerg   SmallVector<const Expr *, 4> RHSs;
   3395  1.1.1.2  joerg   SmallVector<const Expr *, 4> CopyArrayElems;
   3396  1.1.1.2  joerg   for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
   3397  1.1.1.2  joerg     assert(C->getModifier() == OMPC_REDUCTION_inscan &&
   3398  1.1.1.2  joerg            "Only inscan reductions are expected.");
   3399  1.1.1.2  joerg     Privates.append(C->privates().begin(), C->privates().end());
   3400  1.1.1.2  joerg     ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
   3401  1.1.1.2  joerg     LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
   3402  1.1.1.2  joerg     RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
   3403  1.1.1.2  joerg     CopyArrayElems.append(C->copy_array_elems().begin(),
   3404  1.1.1.2  joerg                           C->copy_array_elems().end());
   3405  1.1.1.2  joerg   }
   3406  1.1.1.2  joerg   CodeGenFunction::ParentLoopDirectiveForScanRegion ScanRegion(CGF, S);
   3407  1.1.1.2  joerg   {
   3408  1.1.1.2  joerg     // Emit loop with input phase:
   3409  1.1.1.2  joerg     // #pragma omp ...
   3410  1.1.1.2  joerg     // for (i: 0..<num_iters>) {
   3411  1.1.1.2  joerg     //   <input phase>;
   3412  1.1.1.2  joerg     //   buffer[i] = red;
   3413  1.1.1.2  joerg     // }
   3414  1.1.1.2  joerg     CGF.OMPFirstScanLoop = true;
   3415  1.1.1.2  joerg     CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
   3416  1.1.1.2  joerg     FirstGen(CGF);
   3417  1.1.1.2  joerg   }
   3418  1.1.1.2  joerg   // #pragma omp barrier // in parallel region
   3419  1.1.1.2  joerg   auto &&CodeGen = [&S, OMPScanNumIterations, &LHSs, &RHSs, &CopyArrayElems,
   3420  1.1.1.2  joerg                     &ReductionOps,
   3421  1.1.1.2  joerg                     &Privates](CodeGenFunction &CGF, PrePostActionTy &Action) {
   3422  1.1.1.2  joerg     Action.Enter(CGF);
   3423  1.1.1.2  joerg     // Emit prefix reduction:
   3424  1.1.1.2  joerg     // #pragma omp master // in parallel region
   3425  1.1.1.2  joerg     // for (int k = 0; k <= ceil(log2(n)); ++k)
   3426  1.1.1.2  joerg     llvm::BasicBlock *InputBB = CGF.Builder.GetInsertBlock();
   3427  1.1.1.2  joerg     llvm::BasicBlock *LoopBB = CGF.createBasicBlock("omp.outer.log.scan.body");
   3428  1.1.1.2  joerg     llvm::BasicBlock *ExitBB = CGF.createBasicBlock("omp.outer.log.scan.exit");
   3429  1.1.1.2  joerg     llvm::Function *F =
   3430  1.1.1.2  joerg         CGF.CGM.getIntrinsic(llvm::Intrinsic::log2, CGF.DoubleTy);
   3431  1.1.1.2  joerg     llvm::Value *Arg =
   3432  1.1.1.2  joerg         CGF.Builder.CreateUIToFP(OMPScanNumIterations, CGF.DoubleTy);
   3433  1.1.1.2  joerg     llvm::Value *LogVal = CGF.EmitNounwindRuntimeCall(F, Arg);
   3434  1.1.1.2  joerg     F = CGF.CGM.getIntrinsic(llvm::Intrinsic::ceil, CGF.DoubleTy);
   3435  1.1.1.2  joerg     LogVal = CGF.EmitNounwindRuntimeCall(F, LogVal);
   3436  1.1.1.2  joerg     LogVal = CGF.Builder.CreateFPToUI(LogVal, CGF.IntTy);
   3437  1.1.1.2  joerg     llvm::Value *NMin1 = CGF.Builder.CreateNUWSub(
   3438  1.1.1.2  joerg         OMPScanNumIterations, llvm::ConstantInt::get(CGF.SizeTy, 1));
   3439  1.1.1.2  joerg     auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, S.getBeginLoc());
   3440  1.1.1.2  joerg     CGF.EmitBlock(LoopBB);
   3441  1.1.1.2  joerg     auto *Counter = CGF.Builder.CreatePHI(CGF.IntTy, 2);
   3442  1.1.1.2  joerg     // size pow2k = 1;
   3443  1.1.1.2  joerg     auto *Pow2K = CGF.Builder.CreatePHI(CGF.SizeTy, 2);
   3444  1.1.1.2  joerg     Counter->addIncoming(llvm::ConstantInt::get(CGF.IntTy, 0), InputBB);
   3445  1.1.1.2  joerg     Pow2K->addIncoming(llvm::ConstantInt::get(CGF.SizeTy, 1), InputBB);
   3446  1.1.1.2  joerg     // for (size i = n - 1; i >= 2 ^ k; --i)
   3447  1.1.1.2  joerg     //   tmp[i] op= tmp[i-pow2k];
   3448  1.1.1.2  joerg     llvm::BasicBlock *InnerLoopBB =
   3449  1.1.1.2  joerg         CGF.createBasicBlock("omp.inner.log.scan.body");
   3450  1.1.1.2  joerg     llvm::BasicBlock *InnerExitBB =
   3451  1.1.1.2  joerg         CGF.createBasicBlock("omp.inner.log.scan.exit");
   3452  1.1.1.2  joerg     llvm::Value *CmpI = CGF.Builder.CreateICmpUGE(NMin1, Pow2K);
   3453  1.1.1.2  joerg     CGF.Builder.CreateCondBr(CmpI, InnerLoopBB, InnerExitBB);
   3454  1.1.1.2  joerg     CGF.EmitBlock(InnerLoopBB);
   3455  1.1.1.2  joerg     auto *IVal = CGF.Builder.CreatePHI(CGF.SizeTy, 2);
   3456  1.1.1.2  joerg     IVal->addIncoming(NMin1, LoopBB);
   3457  1.1.1.2  joerg     {
   3458  1.1.1.2  joerg       CodeGenFunction::OMPPrivateScope PrivScope(CGF);
   3459  1.1.1.2  joerg       auto *ILHS = LHSs.begin();
   3460  1.1.1.2  joerg       auto *IRHS = RHSs.begin();
   3461  1.1.1.2  joerg       for (const Expr *CopyArrayElem : CopyArrayElems) {
   3462  1.1.1.2  joerg         const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
   3463  1.1.1.2  joerg         const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
   3464  1.1.1.2  joerg         Address LHSAddr = Address::invalid();
   3465  1.1.1.2  joerg         {
   3466  1.1.1.2  joerg           CodeGenFunction::OpaqueValueMapping IdxMapping(
   3467  1.1.1.2  joerg               CGF,
   3468  1.1.1.2  joerg               cast<OpaqueValueExpr>(
   3469  1.1.1.2  joerg                   cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
   3470  1.1.1.2  joerg               RValue::get(IVal));
   3471  1.1.1.2  joerg           LHSAddr = CGF.EmitLValue(CopyArrayElem).getAddress(CGF);
   3472  1.1.1.2  joerg         }
   3473  1.1.1.2  joerg         PrivScope.addPrivate(LHSVD, [LHSAddr]() { return LHSAddr; });
   3474  1.1.1.2  joerg         Address RHSAddr = Address::invalid();
   3475  1.1.1.2  joerg         {
   3476  1.1.1.2  joerg           llvm::Value *OffsetIVal = CGF.Builder.CreateNUWSub(IVal, Pow2K);
   3477  1.1.1.2  joerg           CodeGenFunction::OpaqueValueMapping IdxMapping(
   3478  1.1.1.2  joerg               CGF,
   3479  1.1.1.2  joerg               cast<OpaqueValueExpr>(
   3480  1.1.1.2  joerg                   cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
   3481  1.1.1.2  joerg               RValue::get(OffsetIVal));
   3482  1.1.1.2  joerg           RHSAddr = CGF.EmitLValue(CopyArrayElem).getAddress(CGF);
   3483  1.1.1.2  joerg         }
   3484  1.1.1.2  joerg         PrivScope.addPrivate(RHSVD, [RHSAddr]() { return RHSAddr; });
   3485  1.1.1.2  joerg         ++ILHS;
   3486  1.1.1.2  joerg         ++IRHS;
   3487  1.1.1.2  joerg       }
   3488  1.1.1.2  joerg       PrivScope.Privatize();
   3489  1.1.1.2  joerg       CGF.CGM.getOpenMPRuntime().emitReduction(
   3490  1.1.1.2  joerg           CGF, S.getEndLoc(), Privates, LHSs, RHSs, ReductionOps,
   3491  1.1.1.2  joerg           {/*WithNowait=*/true, /*SimpleReduction=*/true, OMPD_unknown});
   3492  1.1.1.2  joerg     }
   3493  1.1.1.2  joerg     llvm::Value *NextIVal =
   3494  1.1.1.2  joerg         CGF.Builder.CreateNUWSub(IVal, llvm::ConstantInt::get(CGF.SizeTy, 1));
   3495  1.1.1.2  joerg     IVal->addIncoming(NextIVal, CGF.Builder.GetInsertBlock());
   3496  1.1.1.2  joerg     CmpI = CGF.Builder.CreateICmpUGE(NextIVal, Pow2K);
   3497  1.1.1.2  joerg     CGF.Builder.CreateCondBr(CmpI, InnerLoopBB, InnerExitBB);
   3498  1.1.1.2  joerg     CGF.EmitBlock(InnerExitBB);
   3499  1.1.1.2  joerg     llvm::Value *Next =
   3500  1.1.1.2  joerg         CGF.Builder.CreateNUWAdd(Counter, llvm::ConstantInt::get(CGF.IntTy, 1));
   3501  1.1.1.2  joerg     Counter->addIncoming(Next, CGF.Builder.GetInsertBlock());
   3502  1.1.1.2  joerg     // pow2k <<= 1;
   3503  1.1.1.2  joerg     llvm::Value *NextPow2K =
   3504  1.1.1.2  joerg         CGF.Builder.CreateShl(Pow2K, 1, "", /*HasNUW=*/true);
   3505  1.1.1.2  joerg     Pow2K->addIncoming(NextPow2K, CGF.Builder.GetInsertBlock());
   3506  1.1.1.2  joerg     llvm::Value *Cmp = CGF.Builder.CreateICmpNE(Next, LogVal);
   3507  1.1.1.2  joerg     CGF.Builder.CreateCondBr(Cmp, LoopBB, ExitBB);
   3508  1.1.1.2  joerg     auto DL1 = ApplyDebugLocation::CreateDefaultArtificial(CGF, S.getEndLoc());
   3509  1.1.1.2  joerg     CGF.EmitBlock(ExitBB);
   3510  1.1.1.2  joerg   };
   3511  1.1.1.2  joerg   if (isOpenMPParallelDirective(S.getDirectiveKind())) {
   3512  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc());
   3513  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitBarrierCall(
   3514  1.1.1.2  joerg         CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
   3515  1.1.1.2  joerg         /*ForceSimpleCall=*/true);
   3516  1.1.1.2  joerg   } else {
   3517  1.1.1.2  joerg     RegionCodeGenTy RCG(CodeGen);
   3518  1.1.1.2  joerg     RCG(CGF);
   3519  1.1.1.2  joerg   }
   3520  1.1.1.2  joerg 
   3521  1.1.1.2  joerg   CGF.OMPFirstScanLoop = false;
   3522  1.1.1.2  joerg   SecondGen(CGF);
   3523  1.1.1.2  joerg }
   3524  1.1.1.2  joerg 
   3525  1.1.1.2  joerg static bool emitWorksharingDirective(CodeGenFunction &CGF,
   3526  1.1.1.2  joerg                                      const OMPLoopDirective &S,
   3527  1.1.1.2  joerg                                      bool HasCancel) {
   3528  1.1.1.2  joerg   bool HasLastprivates;
   3529  1.1.1.2  joerg   if (llvm::any_of(S.getClausesOfKind<OMPReductionClause>(),
   3530  1.1.1.2  joerg                    [](const OMPReductionClause *C) {
   3531  1.1.1.2  joerg                      return C->getModifier() == OMPC_REDUCTION_inscan;
   3532  1.1.1.2  joerg                    })) {
   3533  1.1.1.2  joerg     const auto &&NumIteratorsGen = [&S](CodeGenFunction &CGF) {
   3534  1.1.1.2  joerg       CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
   3535  1.1.1.2  joerg       OMPLoopScope LoopScope(CGF, S);
   3536  1.1.1.2  joerg       return CGF.EmitScalarExpr(S.getNumIterations());
   3537  1.1.1.2  joerg     };
   3538  1.1.1.2  joerg     const auto &&FirstGen = [&S, HasCancel](CodeGenFunction &CGF) {
   3539  1.1.1.2  joerg       CodeGenFunction::OMPCancelStackRAII CancelRegion(
   3540  1.1.1.2  joerg           CGF, S.getDirectiveKind(), HasCancel);
   3541  1.1.1.2  joerg       (void)CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
   3542  1.1.1.2  joerg                                        emitForLoopBounds,
   3543  1.1.1.2  joerg                                        emitDispatchForLoopBounds);
   3544  1.1.1.2  joerg       // Emit an implicit barrier at the end.
   3545  1.1.1.2  joerg       CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getBeginLoc(),
   3546  1.1.1.2  joerg                                                  OMPD_for);
   3547  1.1.1.2  joerg     };
   3548  1.1.1.2  joerg     const auto &&SecondGen = [&S, HasCancel,
   3549  1.1.1.2  joerg                               &HasLastprivates](CodeGenFunction &CGF) {
   3550  1.1.1.2  joerg       CodeGenFunction::OMPCancelStackRAII CancelRegion(
   3551  1.1.1.2  joerg           CGF, S.getDirectiveKind(), HasCancel);
   3552  1.1.1.2  joerg       HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
   3553  1.1.1.2  joerg                                                    emitForLoopBounds,
   3554  1.1.1.2  joerg                                                    emitDispatchForLoopBounds);
   3555  1.1.1.2  joerg     };
   3556  1.1.1.2  joerg     if (!isOpenMPParallelDirective(S.getDirectiveKind()))
   3557  1.1.1.2  joerg       emitScanBasedDirectiveDecls(CGF, S, NumIteratorsGen);
   3558  1.1.1.2  joerg     emitScanBasedDirective(CGF, S, NumIteratorsGen, FirstGen, SecondGen);
   3559  1.1.1.2  joerg   } else {
   3560  1.1.1.2  joerg     CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(),
   3561  1.1.1.2  joerg                                                      HasCancel);
   3562      1.1  joerg     HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
   3563      1.1  joerg                                                  emitForLoopBounds,
   3564      1.1  joerg                                                  emitDispatchForLoopBounds);
   3565  1.1.1.2  joerg   }
   3566  1.1.1.2  joerg   return HasLastprivates;
   3567  1.1.1.2  joerg }
   3568  1.1.1.2  joerg 
   3569  1.1.1.2  joerg static bool isSupportedByOpenMPIRBuilder(const OMPForDirective &S) {
   3570  1.1.1.2  joerg   if (S.hasCancel())
   3571  1.1.1.2  joerg     return false;
   3572  1.1.1.2  joerg   for (OMPClause *C : S.clauses())
   3573  1.1.1.2  joerg     if (!isa<OMPNowaitClause>(C))
   3574  1.1.1.2  joerg       return false;
   3575  1.1.1.2  joerg 
   3576  1.1.1.2  joerg   return true;
   3577  1.1.1.2  joerg }
   3578  1.1.1.2  joerg 
   3579  1.1.1.2  joerg void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
   3580  1.1.1.2  joerg   bool HasLastprivates = false;
   3581  1.1.1.2  joerg   bool UseOMPIRBuilder =
   3582  1.1.1.2  joerg       CGM.getLangOpts().OpenMPIRBuilder && isSupportedByOpenMPIRBuilder(S);
   3583  1.1.1.2  joerg   auto &&CodeGen = [this, &S, &HasLastprivates,
   3584  1.1.1.2  joerg                     UseOMPIRBuilder](CodeGenFunction &CGF, PrePostActionTy &) {
   3585  1.1.1.2  joerg     // Use the OpenMPIRBuilder if enabled.
   3586  1.1.1.2  joerg     if (UseOMPIRBuilder) {
   3587  1.1.1.2  joerg       // Emit the associated statement and get its loop representation.
   3588  1.1.1.2  joerg       const Stmt *Inner = S.getRawStmt();
   3589  1.1.1.2  joerg       llvm::CanonicalLoopInfo *CLI =
   3590  1.1.1.2  joerg           EmitOMPCollapsedCanonicalLoopNest(Inner, 1);
   3591  1.1.1.2  joerg 
   3592  1.1.1.2  joerg       bool NeedsBarrier = !S.getSingleClause<OMPNowaitClause>();
   3593  1.1.1.2  joerg       llvm::OpenMPIRBuilder &OMPBuilder =
   3594  1.1.1.2  joerg           CGM.getOpenMPRuntime().getOMPBuilder();
   3595  1.1.1.2  joerg       llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
   3596  1.1.1.2  joerg           AllocaInsertPt->getParent(), AllocaInsertPt->getIterator());
   3597  1.1.1.2  joerg       OMPBuilder.createWorkshareLoop(Builder, CLI, AllocaIP, NeedsBarrier);
   3598  1.1.1.2  joerg       return;
   3599  1.1.1.2  joerg     }
   3600  1.1.1.2  joerg 
   3601  1.1.1.2  joerg     HasLastprivates = emitWorksharingDirective(CGF, S, S.hasCancel());
   3602      1.1  joerg   };
   3603      1.1  joerg   {
   3604  1.1.1.2  joerg     auto LPCRegion =
   3605  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   3606      1.1  joerg     OMPLexicalScope Scope(*this, S, OMPD_unknown);
   3607      1.1  joerg     CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
   3608      1.1  joerg                                                 S.hasCancel());
   3609      1.1  joerg   }
   3610      1.1  joerg 
   3611  1.1.1.2  joerg   if (!UseOMPIRBuilder) {
   3612  1.1.1.2  joerg     // Emit an implicit barrier at the end.
   3613  1.1.1.2  joerg     if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates)
   3614  1.1.1.2  joerg       CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for);
   3615  1.1.1.2  joerg   }
   3616  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   3617  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   3618      1.1  joerg }
   3619      1.1  joerg 
   3620      1.1  joerg void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {
   3621      1.1  joerg   bool HasLastprivates = false;
   3622      1.1  joerg   auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
   3623      1.1  joerg                                           PrePostActionTy &) {
   3624  1.1.1.2  joerg     HasLastprivates = emitWorksharingDirective(CGF, S, /*HasCancel=*/false);
   3625      1.1  joerg   };
   3626      1.1  joerg   {
   3627  1.1.1.2  joerg     auto LPCRegion =
   3628  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   3629      1.1  joerg     OMPLexicalScope Scope(*this, S, OMPD_unknown);
   3630      1.1  joerg     CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
   3631      1.1  joerg   }
   3632      1.1  joerg 
   3633      1.1  joerg   // Emit an implicit barrier at the end.
   3634      1.1  joerg   if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates)
   3635      1.1  joerg     CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for);
   3636  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   3637  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   3638      1.1  joerg }
   3639      1.1  joerg 
   3640      1.1  joerg static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
   3641      1.1  joerg                                 const Twine &Name,
   3642      1.1  joerg                                 llvm::Value *Init = nullptr) {
   3643      1.1  joerg   LValue LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty);
   3644      1.1  joerg   if (Init)
   3645      1.1  joerg     CGF.EmitStoreThroughLValue(RValue::get(Init), LVal, /*isInit*/ true);
   3646      1.1  joerg   return LVal;
   3647      1.1  joerg }
   3648      1.1  joerg 
   3649      1.1  joerg void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
   3650      1.1  joerg   const Stmt *CapturedStmt = S.getInnermostCapturedStmt()->getCapturedStmt();
   3651      1.1  joerg   const auto *CS = dyn_cast<CompoundStmt>(CapturedStmt);
   3652      1.1  joerg   bool HasLastprivates = false;
   3653      1.1  joerg   auto &&CodeGen = [&S, CapturedStmt, CS,
   3654      1.1  joerg                     &HasLastprivates](CodeGenFunction &CGF, PrePostActionTy &) {
   3655  1.1.1.2  joerg     const ASTContext &C = CGF.getContext();
   3656      1.1  joerg     QualType KmpInt32Ty =
   3657      1.1  joerg         C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
   3658      1.1  joerg     // Emit helper vars inits.
   3659      1.1  joerg     LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
   3660      1.1  joerg                                   CGF.Builder.getInt32(0));
   3661      1.1  joerg     llvm::ConstantInt *GlobalUBVal = CS != nullptr
   3662      1.1  joerg                                          ? CGF.Builder.getInt32(CS->size() - 1)
   3663      1.1  joerg                                          : CGF.Builder.getInt32(0);
   3664      1.1  joerg     LValue UB =
   3665      1.1  joerg         createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
   3666      1.1  joerg     LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
   3667      1.1  joerg                                   CGF.Builder.getInt32(1));
   3668      1.1  joerg     LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
   3669      1.1  joerg                                   CGF.Builder.getInt32(0));
   3670      1.1  joerg     // Loop counter.
   3671      1.1  joerg     LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
   3672      1.1  joerg     OpaqueValueExpr IVRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue);
   3673      1.1  joerg     CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
   3674      1.1  joerg     OpaqueValueExpr UBRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue);
   3675      1.1  joerg     CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
   3676      1.1  joerg     // Generate condition for loop.
   3677  1.1.1.2  joerg     BinaryOperator *Cond = BinaryOperator::Create(
   3678  1.1.1.2  joerg         C, &IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue, OK_Ordinary,
   3679  1.1.1.2  joerg         S.getBeginLoc(), FPOptionsOverride());
   3680      1.1  joerg     // Increment for loop counter.
   3681  1.1.1.2  joerg     UnaryOperator *Inc = UnaryOperator::Create(
   3682  1.1.1.2  joerg         C, &IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
   3683  1.1.1.2  joerg         S.getBeginLoc(), true, FPOptionsOverride());
   3684      1.1  joerg     auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) {
   3685      1.1  joerg       // Iterate through all sections and emit a switch construct:
   3686      1.1  joerg       // switch (IV) {
   3687      1.1  joerg       //   case 0:
   3688      1.1  joerg       //     <SectionStmt[0]>;
   3689      1.1  joerg       //     break;
   3690      1.1  joerg       // ...
   3691      1.1  joerg       //   case <NumSection> - 1:
   3692      1.1  joerg       //     <SectionStmt[<NumSection> - 1]>;
   3693      1.1  joerg       //     break;
   3694      1.1  joerg       // }
   3695      1.1  joerg       // .omp.sections.exit:
   3696      1.1  joerg       llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
   3697      1.1  joerg       llvm::SwitchInst *SwitchStmt =
   3698      1.1  joerg           CGF.Builder.CreateSwitch(CGF.EmitLoadOfScalar(IV, S.getBeginLoc()),
   3699      1.1  joerg                                    ExitBB, CS == nullptr ? 1 : CS->size());
   3700      1.1  joerg       if (CS) {
   3701      1.1  joerg         unsigned CaseNumber = 0;
   3702      1.1  joerg         for (const Stmt *SubStmt : CS->children()) {
   3703      1.1  joerg           auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
   3704      1.1  joerg           CGF.EmitBlock(CaseBB);
   3705      1.1  joerg           SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
   3706      1.1  joerg           CGF.EmitStmt(SubStmt);
   3707      1.1  joerg           CGF.EmitBranch(ExitBB);
   3708      1.1  joerg           ++CaseNumber;
   3709      1.1  joerg         }
   3710      1.1  joerg       } else {
   3711      1.1  joerg         llvm::BasicBlock *CaseBB = CGF.createBasicBlock(".omp.sections.case");
   3712      1.1  joerg         CGF.EmitBlock(CaseBB);
   3713      1.1  joerg         SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
   3714      1.1  joerg         CGF.EmitStmt(CapturedStmt);
   3715      1.1  joerg         CGF.EmitBranch(ExitBB);
   3716      1.1  joerg       }
   3717      1.1  joerg       CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
   3718      1.1  joerg     };
   3719      1.1  joerg 
   3720      1.1  joerg     CodeGenFunction::OMPPrivateScope LoopScope(CGF);
   3721      1.1  joerg     if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
   3722      1.1  joerg       // Emit implicit barrier to synchronize threads and avoid data races on
   3723      1.1  joerg       // initialization of firstprivate variables and post-update of lastprivate
   3724      1.1  joerg       // variables.
   3725      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitBarrierCall(
   3726      1.1  joerg           CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
   3727      1.1  joerg           /*ForceSimpleCall=*/true);
   3728      1.1  joerg     }
   3729      1.1  joerg     CGF.EmitOMPPrivateClause(S, LoopScope);
   3730  1.1.1.2  joerg     CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion(CGF, S, IV);
   3731      1.1  joerg     HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
   3732      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, LoopScope);
   3733      1.1  joerg     (void)LoopScope.Privatize();
   3734      1.1  joerg     if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
   3735      1.1  joerg       CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
   3736      1.1  joerg 
   3737      1.1  joerg     // Emit static non-chunked loop.
   3738      1.1  joerg     OpenMPScheduleTy ScheduleKind;
   3739      1.1  joerg     ScheduleKind.Schedule = OMPC_SCHEDULE_static;
   3740      1.1  joerg     CGOpenMPRuntime::StaticRTInput StaticInit(
   3741  1.1.1.2  joerg         /*IVSize=*/32, /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(CGF),
   3742  1.1.1.2  joerg         LB.getAddress(CGF), UB.getAddress(CGF), ST.getAddress(CGF));
   3743      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitForStaticInit(
   3744      1.1  joerg         CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind, StaticInit);
   3745      1.1  joerg     // UB = min(UB, GlobalUB);
   3746      1.1  joerg     llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, S.getBeginLoc());
   3747      1.1  joerg     llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect(
   3748      1.1  joerg         CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
   3749      1.1  joerg     CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
   3750      1.1  joerg     // IV = LB;
   3751      1.1  joerg     CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getBeginLoc()), IV);
   3752      1.1  joerg     // while (idx <= UB) { BODY; ++idx; }
   3753  1.1.1.2  joerg     CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, Cond, Inc, BodyGen,
   3754      1.1  joerg                          [](CodeGenFunction &) {});
   3755      1.1  joerg     // Tell the runtime we are done.
   3756      1.1  joerg     auto &&CodeGen = [&S](CodeGenFunction &CGF) {
   3757      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
   3758      1.1  joerg                                                      S.getDirectiveKind());
   3759      1.1  joerg     };
   3760      1.1  joerg     CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
   3761      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
   3762      1.1  joerg     // Emit post-update of the reduction variables if IsLastIter != 0.
   3763      1.1  joerg     emitPostUpdateForReductionClause(CGF, S, [IL, &S](CodeGenFunction &CGF) {
   3764      1.1  joerg       return CGF.Builder.CreateIsNotNull(
   3765      1.1  joerg           CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
   3766      1.1  joerg     });
   3767      1.1  joerg 
   3768      1.1  joerg     // Emit final copy of the lastprivate variables if IsLastIter != 0.
   3769      1.1  joerg     if (HasLastprivates)
   3770      1.1  joerg       CGF.EmitOMPLastprivateClauseFinal(
   3771      1.1  joerg           S, /*NoFinals=*/false,
   3772      1.1  joerg           CGF.Builder.CreateIsNotNull(
   3773      1.1  joerg               CGF.EmitLoadOfScalar(IL, S.getBeginLoc())));
   3774      1.1  joerg   };
   3775      1.1  joerg 
   3776      1.1  joerg   bool HasCancel = false;
   3777      1.1  joerg   if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
   3778      1.1  joerg     HasCancel = OSD->hasCancel();
   3779      1.1  joerg   else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
   3780      1.1  joerg     HasCancel = OPSD->hasCancel();
   3781      1.1  joerg   OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel);
   3782      1.1  joerg   CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
   3783      1.1  joerg                                               HasCancel);
   3784      1.1  joerg   // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
   3785      1.1  joerg   // clause. Otherwise the barrier will be generated by the codegen for the
   3786      1.1  joerg   // directive.
   3787      1.1  joerg   if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
   3788      1.1  joerg     // Emit implicit barrier to synchronize threads and avoid data races on
   3789      1.1  joerg     // initialization of firstprivate variables.
   3790      1.1  joerg     CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(),
   3791      1.1  joerg                                            OMPD_unknown);
   3792      1.1  joerg   }
   3793      1.1  joerg }
   3794      1.1  joerg 
   3795      1.1  joerg void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
   3796  1.1.1.2  joerg   if (CGM.getLangOpts().OpenMPIRBuilder) {
   3797  1.1.1.2  joerg     llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   3798  1.1.1.2  joerg     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
   3799  1.1.1.2  joerg     using BodyGenCallbackTy = llvm::OpenMPIRBuilder::StorableBodyGenCallbackTy;
   3800  1.1.1.2  joerg 
   3801  1.1.1.2  joerg     auto FiniCB = [this](InsertPointTy IP) {
   3802  1.1.1.2  joerg       OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
   3803  1.1.1.2  joerg     };
   3804  1.1.1.2  joerg 
   3805  1.1.1.2  joerg     const CapturedStmt *ICS = S.getInnermostCapturedStmt();
   3806  1.1.1.2  joerg     const Stmt *CapturedStmt = S.getInnermostCapturedStmt()->getCapturedStmt();
   3807  1.1.1.2  joerg     const auto *CS = dyn_cast<CompoundStmt>(CapturedStmt);
   3808  1.1.1.2  joerg     llvm::SmallVector<BodyGenCallbackTy, 4> SectionCBVector;
   3809  1.1.1.2  joerg     if (CS) {
   3810  1.1.1.2  joerg       for (const Stmt *SubStmt : CS->children()) {
   3811  1.1.1.2  joerg         auto SectionCB = [this, SubStmt](InsertPointTy AllocaIP,
   3812  1.1.1.2  joerg                                          InsertPointTy CodeGenIP,
   3813  1.1.1.2  joerg                                          llvm::BasicBlock &FiniBB) {
   3814  1.1.1.2  joerg           OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP,
   3815  1.1.1.2  joerg                                                          FiniBB);
   3816  1.1.1.2  joerg           OMPBuilderCBHelpers::EmitOMPRegionBody(*this, SubStmt, CodeGenIP,
   3817  1.1.1.2  joerg                                                  FiniBB);
   3818  1.1.1.2  joerg         };
   3819  1.1.1.2  joerg         SectionCBVector.push_back(SectionCB);
   3820  1.1.1.2  joerg       }
   3821  1.1.1.2  joerg     } else {
   3822  1.1.1.2  joerg       auto SectionCB = [this, CapturedStmt](InsertPointTy AllocaIP,
   3823  1.1.1.2  joerg                                             InsertPointTy CodeGenIP,
   3824  1.1.1.2  joerg                                             llvm::BasicBlock &FiniBB) {
   3825  1.1.1.2  joerg         OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
   3826  1.1.1.2  joerg         OMPBuilderCBHelpers::EmitOMPRegionBody(*this, CapturedStmt, CodeGenIP,
   3827  1.1.1.2  joerg                                                FiniBB);
   3828  1.1.1.2  joerg       };
   3829  1.1.1.2  joerg       SectionCBVector.push_back(SectionCB);
   3830  1.1.1.2  joerg     }
   3831  1.1.1.2  joerg 
   3832  1.1.1.2  joerg     // Privatization callback that performs appropriate action for
   3833  1.1.1.2  joerg     // shared/private/firstprivate/lastprivate/copyin/... variables.
   3834  1.1.1.2  joerg     //
   3835  1.1.1.2  joerg     // TODO: This defaults to shared right now.
   3836  1.1.1.2  joerg     auto PrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
   3837  1.1.1.2  joerg                      llvm::Value &, llvm::Value &Val, llvm::Value *&ReplVal) {
   3838  1.1.1.2  joerg       // The next line is appropriate only for variables (Val) with the
   3839  1.1.1.2  joerg       // data-sharing attribute "shared".
   3840  1.1.1.2  joerg       ReplVal = &Val;
   3841  1.1.1.2  joerg 
   3842  1.1.1.2  joerg       return CodeGenIP;
   3843  1.1.1.2  joerg     };
   3844  1.1.1.2  joerg 
   3845  1.1.1.2  joerg     CGCapturedStmtInfo CGSI(*ICS, CR_OpenMP);
   3846  1.1.1.2  joerg     CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI);
   3847  1.1.1.2  joerg     llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
   3848  1.1.1.2  joerg         AllocaInsertPt->getParent(), AllocaInsertPt->getIterator());
   3849  1.1.1.2  joerg     Builder.restoreIP(OMPBuilder.createSections(
   3850  1.1.1.2  joerg         Builder, AllocaIP, SectionCBVector, PrivCB, FiniCB, S.hasCancel(),
   3851  1.1.1.2  joerg         S.getSingleClause<OMPNowaitClause>()));
   3852  1.1.1.2  joerg     return;
   3853  1.1.1.2  joerg   }
   3854      1.1  joerg   {
   3855  1.1.1.2  joerg     auto LPCRegion =
   3856  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   3857      1.1  joerg     OMPLexicalScope Scope(*this, S, OMPD_unknown);
   3858      1.1  joerg     EmitSections(S);
   3859      1.1  joerg   }
   3860      1.1  joerg   // Emit an implicit barrier at the end.
   3861      1.1  joerg   if (!S.getSingleClause<OMPNowaitClause>()) {
   3862      1.1  joerg     CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(),
   3863      1.1  joerg                                            OMPD_sections);
   3864      1.1  joerg   }
   3865  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   3866  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   3867      1.1  joerg }
   3868      1.1  joerg 
   3869      1.1  joerg void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
   3870  1.1.1.2  joerg   if (CGM.getLangOpts().OpenMPIRBuilder) {
   3871  1.1.1.2  joerg     llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   3872  1.1.1.2  joerg     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
   3873  1.1.1.2  joerg 
   3874  1.1.1.2  joerg     const Stmt *SectionRegionBodyStmt = S.getAssociatedStmt();
   3875  1.1.1.2  joerg     auto FiniCB = [this](InsertPointTy IP) {
   3876  1.1.1.2  joerg       OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
   3877  1.1.1.2  joerg     };
   3878  1.1.1.2  joerg 
   3879  1.1.1.2  joerg     auto BodyGenCB = [SectionRegionBodyStmt, this](InsertPointTy AllocaIP,
   3880  1.1.1.2  joerg                                                    InsertPointTy CodeGenIP,
   3881  1.1.1.2  joerg                                                    llvm::BasicBlock &FiniBB) {
   3882  1.1.1.2  joerg       OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
   3883  1.1.1.2  joerg       OMPBuilderCBHelpers::EmitOMPRegionBody(*this, SectionRegionBodyStmt,
   3884  1.1.1.2  joerg                                              CodeGenIP, FiniBB);
   3885  1.1.1.2  joerg     };
   3886  1.1.1.2  joerg 
   3887  1.1.1.2  joerg     LexicalScope Scope(*this, S.getSourceRange());
   3888  1.1.1.2  joerg     EmitStopPoint(&S);
   3889  1.1.1.2  joerg     Builder.restoreIP(OMPBuilder.createSection(Builder, BodyGenCB, FiniCB));
   3890  1.1.1.2  joerg 
   3891  1.1.1.2  joerg     return;
   3892  1.1.1.2  joerg   }
   3893  1.1.1.2  joerg   LexicalScope Scope(*this, S.getSourceRange());
   3894  1.1.1.2  joerg   EmitStopPoint(&S);
   3895  1.1.1.2  joerg   EmitStmt(S.getAssociatedStmt());
   3896      1.1  joerg }
   3897      1.1  joerg 
   3898      1.1  joerg void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
   3899      1.1  joerg   llvm::SmallVector<const Expr *, 8> CopyprivateVars;
   3900      1.1  joerg   llvm::SmallVector<const Expr *, 8> DestExprs;
   3901      1.1  joerg   llvm::SmallVector<const Expr *, 8> SrcExprs;
   3902      1.1  joerg   llvm::SmallVector<const Expr *, 8> AssignmentOps;
   3903      1.1  joerg   // Check if there are any 'copyprivate' clauses associated with this
   3904      1.1  joerg   // 'single' construct.
   3905      1.1  joerg   // Build a list of copyprivate variables along with helper expressions
   3906      1.1  joerg   // (<source>, <destination>, <destination>=<source> expressions)
   3907      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) {
   3908      1.1  joerg     CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
   3909      1.1  joerg     DestExprs.append(C->destination_exprs().begin(),
   3910      1.1  joerg                      C->destination_exprs().end());
   3911      1.1  joerg     SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
   3912      1.1  joerg     AssignmentOps.append(C->assignment_ops().begin(),
   3913      1.1  joerg                          C->assignment_ops().end());
   3914      1.1  joerg   }
   3915      1.1  joerg   // Emit code for 'single' region along with 'copyprivate' clauses
   3916      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   3917      1.1  joerg     Action.Enter(CGF);
   3918      1.1  joerg     OMPPrivateScope SingleScope(CGF);
   3919      1.1  joerg     (void)CGF.EmitOMPFirstprivateClause(S, SingleScope);
   3920      1.1  joerg     CGF.EmitOMPPrivateClause(S, SingleScope);
   3921      1.1  joerg     (void)SingleScope.Privatize();
   3922      1.1  joerg     CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
   3923      1.1  joerg   };
   3924      1.1  joerg   {
   3925  1.1.1.2  joerg     auto LPCRegion =
   3926  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   3927      1.1  joerg     OMPLexicalScope Scope(*this, S, OMPD_unknown);
   3928      1.1  joerg     CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getBeginLoc(),
   3929      1.1  joerg                                             CopyprivateVars, DestExprs,
   3930      1.1  joerg                                             SrcExprs, AssignmentOps);
   3931      1.1  joerg   }
   3932      1.1  joerg   // Emit an implicit barrier at the end (to avoid data race on firstprivate
   3933      1.1  joerg   // init or if no 'nowait' clause was specified and no 'copyprivate' clause).
   3934      1.1  joerg   if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) {
   3935      1.1  joerg     CGM.getOpenMPRuntime().emitBarrierCall(
   3936      1.1  joerg         *this, S.getBeginLoc(),
   3937      1.1  joerg         S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single);
   3938      1.1  joerg   }
   3939  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   3940  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   3941  1.1.1.2  joerg }
   3942  1.1.1.2  joerg 
   3943  1.1.1.2  joerg static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
   3944  1.1.1.2  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   3945  1.1.1.2  joerg     Action.Enter(CGF);
   3946  1.1.1.2  joerg     CGF.EmitStmt(S.getRawStmt());
   3947  1.1.1.2  joerg   };
   3948  1.1.1.2  joerg   CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc());
   3949      1.1  joerg }
   3950      1.1  joerg 
   3951      1.1  joerg void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
   3952  1.1.1.2  joerg   if (CGM.getLangOpts().OpenMPIRBuilder) {
   3953  1.1.1.2  joerg     llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   3954  1.1.1.2  joerg     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
   3955  1.1.1.2  joerg 
   3956  1.1.1.2  joerg     const Stmt *MasterRegionBodyStmt = S.getAssociatedStmt();
   3957  1.1.1.2  joerg 
   3958  1.1.1.2  joerg     auto FiniCB = [this](InsertPointTy IP) {
   3959  1.1.1.2  joerg       OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
   3960  1.1.1.2  joerg     };
   3961  1.1.1.2  joerg 
   3962  1.1.1.2  joerg     auto BodyGenCB = [MasterRegionBodyStmt, this](InsertPointTy AllocaIP,
   3963  1.1.1.2  joerg                                                   InsertPointTy CodeGenIP,
   3964  1.1.1.2  joerg                                                   llvm::BasicBlock &FiniBB) {
   3965  1.1.1.2  joerg       OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
   3966  1.1.1.2  joerg       OMPBuilderCBHelpers::EmitOMPRegionBody(*this, MasterRegionBodyStmt,
   3967  1.1.1.2  joerg                                              CodeGenIP, FiniBB);
   3968  1.1.1.2  joerg     };
   3969  1.1.1.2  joerg 
   3970  1.1.1.2  joerg     LexicalScope Scope(*this, S.getSourceRange());
   3971  1.1.1.2  joerg     EmitStopPoint(&S);
   3972  1.1.1.2  joerg     Builder.restoreIP(OMPBuilder.createMaster(Builder, BodyGenCB, FiniCB));
   3973  1.1.1.2  joerg 
   3974  1.1.1.2  joerg     return;
   3975  1.1.1.2  joerg   }
   3976  1.1.1.2  joerg   LexicalScope Scope(*this, S.getSourceRange());
   3977  1.1.1.2  joerg   EmitStopPoint(&S);
   3978  1.1.1.2  joerg   emitMaster(*this, S);
   3979  1.1.1.2  joerg }
   3980  1.1.1.2  joerg 
   3981  1.1.1.2  joerg static void emitMasked(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
   3982      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   3983      1.1  joerg     Action.Enter(CGF);
   3984  1.1.1.2  joerg     CGF.EmitStmt(S.getRawStmt());
   3985      1.1  joerg   };
   3986  1.1.1.2  joerg   Expr *Filter = nullptr;
   3987  1.1.1.2  joerg   if (const auto *FilterClause = S.getSingleClause<OMPFilterClause>())
   3988  1.1.1.2  joerg     Filter = FilterClause->getThreadID();
   3989  1.1.1.2  joerg   CGF.CGM.getOpenMPRuntime().emitMaskedRegion(CGF, CodeGen, S.getBeginLoc(),
   3990  1.1.1.2  joerg                                               Filter);
   3991  1.1.1.2  joerg }
   3992  1.1.1.2  joerg 
   3993  1.1.1.2  joerg void CodeGenFunction::EmitOMPMaskedDirective(const OMPMaskedDirective &S) {
   3994  1.1.1.2  joerg   if (CGM.getLangOpts().OpenMPIRBuilder) {
   3995  1.1.1.2  joerg     llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   3996  1.1.1.2  joerg     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
   3997  1.1.1.2  joerg 
   3998  1.1.1.2  joerg     const Stmt *MaskedRegionBodyStmt = S.getAssociatedStmt();
   3999  1.1.1.2  joerg     const Expr *Filter = nullptr;
   4000  1.1.1.2  joerg     if (const auto *FilterClause = S.getSingleClause<OMPFilterClause>())
   4001  1.1.1.2  joerg       Filter = FilterClause->getThreadID();
   4002  1.1.1.2  joerg     llvm::Value *FilterVal = Filter
   4003  1.1.1.2  joerg                                  ? EmitScalarExpr(Filter, CGM.Int32Ty)
   4004  1.1.1.2  joerg                                  : llvm::ConstantInt::get(CGM.Int32Ty, /*V=*/0);
   4005  1.1.1.2  joerg 
   4006  1.1.1.2  joerg     auto FiniCB = [this](InsertPointTy IP) {
   4007  1.1.1.2  joerg       OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
   4008  1.1.1.2  joerg     };
   4009  1.1.1.2  joerg 
   4010  1.1.1.2  joerg     auto BodyGenCB = [MaskedRegionBodyStmt, this](InsertPointTy AllocaIP,
   4011  1.1.1.2  joerg                                                   InsertPointTy CodeGenIP,
   4012  1.1.1.2  joerg                                                   llvm::BasicBlock &FiniBB) {
   4013  1.1.1.2  joerg       OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
   4014  1.1.1.2  joerg       OMPBuilderCBHelpers::EmitOMPRegionBody(*this, MaskedRegionBodyStmt,
   4015  1.1.1.2  joerg                                              CodeGenIP, FiniBB);
   4016  1.1.1.2  joerg     };
   4017  1.1.1.2  joerg 
   4018  1.1.1.2  joerg     LexicalScope Scope(*this, S.getSourceRange());
   4019  1.1.1.2  joerg     EmitStopPoint(&S);
   4020  1.1.1.2  joerg     Builder.restoreIP(
   4021  1.1.1.2  joerg         OMPBuilder.createMasked(Builder, BodyGenCB, FiniCB, FilterVal));
   4022  1.1.1.2  joerg 
   4023  1.1.1.2  joerg     return;
   4024  1.1.1.2  joerg   }
   4025  1.1.1.2  joerg   LexicalScope Scope(*this, S.getSourceRange());
   4026  1.1.1.2  joerg   EmitStopPoint(&S);
   4027  1.1.1.2  joerg   emitMasked(*this, S);
   4028      1.1  joerg }
   4029      1.1  joerg 
   4030      1.1  joerg void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
   4031  1.1.1.2  joerg   if (CGM.getLangOpts().OpenMPIRBuilder) {
   4032  1.1.1.2  joerg     llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   4033  1.1.1.2  joerg     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
   4034  1.1.1.2  joerg 
   4035  1.1.1.2  joerg     const Stmt *CriticalRegionBodyStmt = S.getAssociatedStmt();
   4036  1.1.1.2  joerg     const Expr *Hint = nullptr;
   4037  1.1.1.2  joerg     if (const auto *HintClause = S.getSingleClause<OMPHintClause>())
   4038  1.1.1.2  joerg       Hint = HintClause->getHint();
   4039  1.1.1.2  joerg 
   4040  1.1.1.2  joerg     // TODO: This is slightly different from what's currently being done in
   4041  1.1.1.2  joerg     // clang. Fix the Int32Ty to IntPtrTy (pointer width size) when everything
   4042  1.1.1.2  joerg     // about typing is final.
   4043  1.1.1.2  joerg     llvm::Value *HintInst = nullptr;
   4044  1.1.1.2  joerg     if (Hint)
   4045  1.1.1.2  joerg       HintInst =
   4046  1.1.1.2  joerg           Builder.CreateIntCast(EmitScalarExpr(Hint), CGM.Int32Ty, false);
   4047  1.1.1.2  joerg 
   4048  1.1.1.2  joerg     auto FiniCB = [this](InsertPointTy IP) {
   4049  1.1.1.2  joerg       OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
   4050  1.1.1.2  joerg     };
   4051  1.1.1.2  joerg 
   4052  1.1.1.2  joerg     auto BodyGenCB = [CriticalRegionBodyStmt, this](InsertPointTy AllocaIP,
   4053  1.1.1.2  joerg                                                     InsertPointTy CodeGenIP,
   4054  1.1.1.2  joerg                                                     llvm::BasicBlock &FiniBB) {
   4055  1.1.1.2  joerg       OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
   4056  1.1.1.2  joerg       OMPBuilderCBHelpers::EmitOMPRegionBody(*this, CriticalRegionBodyStmt,
   4057  1.1.1.2  joerg                                              CodeGenIP, FiniBB);
   4058  1.1.1.2  joerg     };
   4059  1.1.1.2  joerg 
   4060  1.1.1.2  joerg     LexicalScope Scope(*this, S.getSourceRange());
   4061  1.1.1.2  joerg     EmitStopPoint(&S);
   4062  1.1.1.2  joerg     Builder.restoreIP(OMPBuilder.createCritical(
   4063  1.1.1.2  joerg         Builder, BodyGenCB, FiniCB, S.getDirectiveName().getAsString(),
   4064  1.1.1.2  joerg         HintInst));
   4065  1.1.1.2  joerg 
   4066  1.1.1.2  joerg     return;
   4067  1.1.1.2  joerg   }
   4068  1.1.1.2  joerg 
   4069      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   4070      1.1  joerg     Action.Enter(CGF);
   4071  1.1.1.2  joerg     CGF.EmitStmt(S.getAssociatedStmt());
   4072      1.1  joerg   };
   4073      1.1  joerg   const Expr *Hint = nullptr;
   4074      1.1  joerg   if (const auto *HintClause = S.getSingleClause<OMPHintClause>())
   4075      1.1  joerg     Hint = HintClause->getHint();
   4076  1.1.1.2  joerg   LexicalScope Scope(*this, S.getSourceRange());
   4077  1.1.1.2  joerg   EmitStopPoint(&S);
   4078      1.1  joerg   CGM.getOpenMPRuntime().emitCriticalRegion(*this,
   4079      1.1  joerg                                             S.getDirectiveName().getAsString(),
   4080      1.1  joerg                                             CodeGen, S.getBeginLoc(), Hint);
   4081      1.1  joerg }
   4082      1.1  joerg 
   4083      1.1  joerg void CodeGenFunction::EmitOMPParallelForDirective(
   4084      1.1  joerg     const OMPParallelForDirective &S) {
   4085      1.1  joerg   // Emit directive as a combined directive that consists of two implicit
   4086      1.1  joerg   // directives: 'parallel' with 'for' directive.
   4087      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   4088      1.1  joerg     Action.Enter(CGF);
   4089  1.1.1.2  joerg     (void)emitWorksharingDirective(CGF, S, S.hasCancel());
   4090      1.1  joerg   };
   4091  1.1.1.2  joerg   {
   4092  1.1.1.2  joerg     if (llvm::any_of(S.getClausesOfKind<OMPReductionClause>(),
   4093  1.1.1.2  joerg                      [](const OMPReductionClause *C) {
   4094  1.1.1.2  joerg                        return C->getModifier() == OMPC_REDUCTION_inscan;
   4095  1.1.1.2  joerg                      })) {
   4096  1.1.1.2  joerg       const auto &&NumIteratorsGen = [&S](CodeGenFunction &CGF) {
   4097  1.1.1.2  joerg         CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
   4098  1.1.1.2  joerg         CGCapturedStmtInfo CGSI(CR_OpenMP);
   4099  1.1.1.2  joerg         CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGSI);
   4100  1.1.1.2  joerg         OMPLoopScope LoopScope(CGF, S);
   4101  1.1.1.2  joerg         return CGF.EmitScalarExpr(S.getNumIterations());
   4102  1.1.1.2  joerg       };
   4103  1.1.1.2  joerg       emitScanBasedDirectiveDecls(*this, S, NumIteratorsGen);
   4104  1.1.1.2  joerg     }
   4105  1.1.1.2  joerg     auto LPCRegion =
   4106  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   4107  1.1.1.2  joerg     emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen,
   4108  1.1.1.2  joerg                                    emitEmptyBoundParameters);
   4109  1.1.1.2  joerg   }
   4110  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   4111  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   4112      1.1  joerg }
   4113      1.1  joerg 
   4114      1.1  joerg void CodeGenFunction::EmitOMPParallelForSimdDirective(
   4115      1.1  joerg     const OMPParallelForSimdDirective &S) {
   4116      1.1  joerg   // Emit directive as a combined directive that consists of two implicit
   4117      1.1  joerg   // directives: 'parallel' with 'for' directive.
   4118      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   4119      1.1  joerg     Action.Enter(CGF);
   4120  1.1.1.2  joerg     (void)emitWorksharingDirective(CGF, S, /*HasCancel=*/false);
   4121      1.1  joerg   };
   4122  1.1.1.2  joerg   {
   4123  1.1.1.2  joerg     if (llvm::any_of(S.getClausesOfKind<OMPReductionClause>(),
   4124  1.1.1.2  joerg                      [](const OMPReductionClause *C) {
   4125  1.1.1.2  joerg                        return C->getModifier() == OMPC_REDUCTION_inscan;
   4126  1.1.1.2  joerg                      })) {
   4127  1.1.1.2  joerg       const auto &&NumIteratorsGen = [&S](CodeGenFunction &CGF) {
   4128  1.1.1.2  joerg         CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
   4129  1.1.1.2  joerg         CGCapturedStmtInfo CGSI(CR_OpenMP);
   4130  1.1.1.2  joerg         CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGSI);
   4131  1.1.1.2  joerg         OMPLoopScope LoopScope(CGF, S);
   4132  1.1.1.2  joerg         return CGF.EmitScalarExpr(S.getNumIterations());
   4133  1.1.1.2  joerg       };
   4134  1.1.1.2  joerg       emitScanBasedDirectiveDecls(*this, S, NumIteratorsGen);
   4135  1.1.1.2  joerg     }
   4136  1.1.1.2  joerg     auto LPCRegion =
   4137  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   4138  1.1.1.2  joerg     emitCommonOMPParallelDirective(*this, S, OMPD_for_simd, CodeGen,
   4139  1.1.1.2  joerg                                    emitEmptyBoundParameters);
   4140  1.1.1.2  joerg   }
   4141  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   4142  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   4143  1.1.1.2  joerg }
   4144  1.1.1.2  joerg 
   4145  1.1.1.2  joerg void CodeGenFunction::EmitOMPParallelMasterDirective(
   4146  1.1.1.2  joerg     const OMPParallelMasterDirective &S) {
   4147  1.1.1.2  joerg   // Emit directive as a combined directive that consists of two implicit
   4148  1.1.1.2  joerg   // directives: 'parallel' with 'master' directive.
   4149  1.1.1.2  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   4150  1.1.1.2  joerg     Action.Enter(CGF);
   4151  1.1.1.2  joerg     OMPPrivateScope PrivateScope(CGF);
   4152  1.1.1.2  joerg     bool Copyins = CGF.EmitOMPCopyinClause(S);
   4153  1.1.1.2  joerg     (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
   4154  1.1.1.2  joerg     if (Copyins) {
   4155  1.1.1.2  joerg       // Emit implicit barrier to synchronize threads and avoid data races on
   4156  1.1.1.2  joerg       // propagation master's thread values of threadprivate variables to local
   4157  1.1.1.2  joerg       // instances of that variables of all other implicit threads.
   4158  1.1.1.2  joerg       CGF.CGM.getOpenMPRuntime().emitBarrierCall(
   4159  1.1.1.2  joerg           CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
   4160  1.1.1.2  joerg           /*ForceSimpleCall=*/true);
   4161  1.1.1.2  joerg     }
   4162  1.1.1.2  joerg     CGF.EmitOMPPrivateClause(S, PrivateScope);
   4163  1.1.1.2  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   4164  1.1.1.2  joerg     (void)PrivateScope.Privatize();
   4165  1.1.1.2  joerg     emitMaster(CGF, S);
   4166  1.1.1.2  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
   4167  1.1.1.2  joerg   };
   4168  1.1.1.2  joerg   {
   4169  1.1.1.2  joerg     auto LPCRegion =
   4170  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   4171  1.1.1.2  joerg     emitCommonOMPParallelDirective(*this, S, OMPD_master, CodeGen,
   4172  1.1.1.2  joerg                                    emitEmptyBoundParameters);
   4173  1.1.1.2  joerg     emitPostUpdateForReductionClause(*this, S,
   4174  1.1.1.2  joerg                                      [](CodeGenFunction &) { return nullptr; });
   4175  1.1.1.2  joerg   }
   4176  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   4177  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   4178      1.1  joerg }
   4179      1.1  joerg 
   4180      1.1  joerg void CodeGenFunction::EmitOMPParallelSectionsDirective(
   4181      1.1  joerg     const OMPParallelSectionsDirective &S) {
   4182      1.1  joerg   // Emit directive as a combined directive that consists of two implicit
   4183      1.1  joerg   // directives: 'parallel' with 'sections' directive.
   4184      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   4185      1.1  joerg     Action.Enter(CGF);
   4186      1.1  joerg     CGF.EmitSections(S);
   4187      1.1  joerg   };
   4188  1.1.1.2  joerg   {
   4189  1.1.1.2  joerg     auto LPCRegion =
   4190  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   4191  1.1.1.2  joerg     emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen,
   4192  1.1.1.2  joerg                                    emitEmptyBoundParameters);
   4193  1.1.1.2  joerg   }
   4194  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   4195  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, S);
   4196      1.1  joerg }
   4197      1.1  joerg 
   4198  1.1.1.2  joerg namespace {
   4199  1.1.1.2  joerg /// Get the list of variables declared in the context of the untied tasks.
   4200  1.1.1.2  joerg class CheckVarsEscapingUntiedTaskDeclContext final
   4201  1.1.1.2  joerg     : public ConstStmtVisitor<CheckVarsEscapingUntiedTaskDeclContext> {
   4202  1.1.1.2  joerg   llvm::SmallVector<const VarDecl *, 4> PrivateDecls;
   4203  1.1.1.2  joerg 
   4204  1.1.1.2  joerg public:
   4205  1.1.1.2  joerg   explicit CheckVarsEscapingUntiedTaskDeclContext() = default;
   4206  1.1.1.2  joerg   virtual ~CheckVarsEscapingUntiedTaskDeclContext() = default;
   4207  1.1.1.2  joerg   void VisitDeclStmt(const DeclStmt *S) {
   4208  1.1.1.2  joerg     if (!S)
   4209  1.1.1.2  joerg       return;
   4210  1.1.1.2  joerg     // Need to privatize only local vars, static locals can be processed as is.
   4211  1.1.1.2  joerg     for (const Decl *D : S->decls()) {
   4212  1.1.1.2  joerg       if (const auto *VD = dyn_cast_or_null<VarDecl>(D))
   4213  1.1.1.2  joerg         if (VD->hasLocalStorage())
   4214  1.1.1.2  joerg           PrivateDecls.push_back(VD);
   4215  1.1.1.2  joerg     }
   4216  1.1.1.2  joerg   }
   4217  1.1.1.2  joerg   void VisitOMPExecutableDirective(const OMPExecutableDirective *) { return; }
   4218  1.1.1.2  joerg   void VisitCapturedStmt(const CapturedStmt *) { return; }
   4219  1.1.1.2  joerg   void VisitLambdaExpr(const LambdaExpr *) { return; }
   4220  1.1.1.2  joerg   void VisitBlockExpr(const BlockExpr *) { return; }
   4221  1.1.1.2  joerg   void VisitStmt(const Stmt *S) {
   4222  1.1.1.2  joerg     if (!S)
   4223  1.1.1.2  joerg       return;
   4224  1.1.1.2  joerg     for (const Stmt *Child : S->children())
   4225  1.1.1.2  joerg       if (Child)
   4226  1.1.1.2  joerg         Visit(Child);
   4227  1.1.1.2  joerg   }
   4228  1.1.1.2  joerg 
   4229  1.1.1.2  joerg   /// Swaps list of vars with the provided one.
   4230  1.1.1.2  joerg   ArrayRef<const VarDecl *> getPrivateDecls() const { return PrivateDecls; }
   4231  1.1.1.2  joerg };
   4232  1.1.1.2  joerg } // anonymous namespace
   4233  1.1.1.2  joerg 
   4234      1.1  joerg void CodeGenFunction::EmitOMPTaskBasedDirective(
   4235      1.1  joerg     const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion,
   4236      1.1  joerg     const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen,
   4237      1.1  joerg     OMPTaskDataTy &Data) {
   4238      1.1  joerg   // Emit outlined function for task construct.
   4239      1.1  joerg   const CapturedStmt *CS = S.getCapturedStmt(CapturedRegion);
   4240      1.1  joerg   auto I = CS->getCapturedDecl()->param_begin();
   4241      1.1  joerg   auto PartId = std::next(I);
   4242      1.1  joerg   auto TaskT = std::next(I, 4);
   4243      1.1  joerg   // Check if the task is final
   4244      1.1  joerg   if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
   4245      1.1  joerg     // If the condition constant folds and can be elided, try to avoid emitting
   4246      1.1  joerg     // the condition and the dead arm of the if/else.
   4247      1.1  joerg     const Expr *Cond = Clause->getCondition();
   4248      1.1  joerg     bool CondConstant;
   4249      1.1  joerg     if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
   4250      1.1  joerg       Data.Final.setInt(CondConstant);
   4251      1.1  joerg     else
   4252      1.1  joerg       Data.Final.setPointer(EvaluateExprAsBool(Cond));
   4253      1.1  joerg   } else {
   4254      1.1  joerg     // By default the task is not final.
   4255      1.1  joerg     Data.Final.setInt(/*IntVal=*/false);
   4256      1.1  joerg   }
   4257      1.1  joerg   // Check if the task has 'priority' clause.
   4258      1.1  joerg   if (const auto *Clause = S.getSingleClause<OMPPriorityClause>()) {
   4259      1.1  joerg     const Expr *Prio = Clause->getPriority();
   4260      1.1  joerg     Data.Priority.setInt(/*IntVal=*/true);
   4261      1.1  joerg     Data.Priority.setPointer(EmitScalarConversion(
   4262      1.1  joerg         EmitScalarExpr(Prio), Prio->getType(),
   4263      1.1  joerg         getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1),
   4264      1.1  joerg         Prio->getExprLoc()));
   4265      1.1  joerg   }
   4266      1.1  joerg   // The first function argument for tasks is a thread id, the second one is a
   4267      1.1  joerg   // part id (0 for tied tasks, >=0 for untied task).
   4268      1.1  joerg   llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
   4269      1.1  joerg   // Get list of private variables.
   4270      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
   4271      1.1  joerg     auto IRef = C->varlist_begin();
   4272      1.1  joerg     for (const Expr *IInit : C->private_copies()) {
   4273      1.1  joerg       const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
   4274      1.1  joerg       if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
   4275      1.1  joerg         Data.PrivateVars.push_back(*IRef);
   4276      1.1  joerg         Data.PrivateCopies.push_back(IInit);
   4277      1.1  joerg       }
   4278      1.1  joerg       ++IRef;
   4279      1.1  joerg     }
   4280      1.1  joerg   }
   4281      1.1  joerg   EmittedAsPrivate.clear();
   4282      1.1  joerg   // Get list of firstprivate variables.
   4283      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
   4284      1.1  joerg     auto IRef = C->varlist_begin();
   4285      1.1  joerg     auto IElemInitRef = C->inits().begin();
   4286      1.1  joerg     for (const Expr *IInit : C->private_copies()) {
   4287      1.1  joerg       const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
   4288      1.1  joerg       if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
   4289      1.1  joerg         Data.FirstprivateVars.push_back(*IRef);
   4290      1.1  joerg         Data.FirstprivateCopies.push_back(IInit);
   4291      1.1  joerg         Data.FirstprivateInits.push_back(*IElemInitRef);
   4292      1.1  joerg       }
   4293      1.1  joerg       ++IRef;
   4294      1.1  joerg       ++IElemInitRef;
   4295      1.1  joerg     }
   4296      1.1  joerg   }
   4297      1.1  joerg   // Get list of lastprivate variables (for taskloops).
   4298  1.1.1.2  joerg   llvm::MapVector<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
   4299      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
   4300      1.1  joerg     auto IRef = C->varlist_begin();
   4301      1.1  joerg     auto ID = C->destination_exprs().begin();
   4302      1.1  joerg     for (const Expr *IInit : C->private_copies()) {
   4303      1.1  joerg       const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
   4304      1.1  joerg       if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
   4305      1.1  joerg         Data.LastprivateVars.push_back(*IRef);
   4306      1.1  joerg         Data.LastprivateCopies.push_back(IInit);
   4307      1.1  joerg       }
   4308      1.1  joerg       LastprivateDstsOrigs.insert(
   4309  1.1.1.2  joerg           std::make_pair(cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
   4310  1.1.1.2  joerg                          cast<DeclRefExpr>(*IRef)));
   4311      1.1  joerg       ++IRef;
   4312      1.1  joerg       ++ID;
   4313      1.1  joerg     }
   4314      1.1  joerg   }
   4315      1.1  joerg   SmallVector<const Expr *, 4> LHSs;
   4316      1.1  joerg   SmallVector<const Expr *, 4> RHSs;
   4317      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
   4318  1.1.1.2  joerg     Data.ReductionVars.append(C->varlist_begin(), C->varlist_end());
   4319  1.1.1.2  joerg     Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end());
   4320  1.1.1.2  joerg     Data.ReductionCopies.append(C->privates().begin(), C->privates().end());
   4321  1.1.1.2  joerg     Data.ReductionOps.append(C->reduction_ops().begin(),
   4322  1.1.1.2  joerg                              C->reduction_ops().end());
   4323  1.1.1.2  joerg     LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
   4324  1.1.1.2  joerg     RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
   4325      1.1  joerg   }
   4326      1.1  joerg   Data.Reductions = CGM.getOpenMPRuntime().emitTaskReductionInit(
   4327      1.1  joerg       *this, S.getBeginLoc(), LHSs, RHSs, Data);
   4328      1.1  joerg   // Build list of dependences.
   4329  1.1.1.2  joerg   for (const auto *C : S.getClausesOfKind<OMPDependClause>()) {
   4330  1.1.1.2  joerg     OMPTaskDataTy::DependData &DD =
   4331  1.1.1.2  joerg         Data.Dependences.emplace_back(C->getDependencyKind(), C->getModifier());
   4332  1.1.1.2  joerg     DD.DepExprs.append(C->varlist_begin(), C->varlist_end());
   4333  1.1.1.2  joerg   }
   4334  1.1.1.2  joerg   // Get list of local vars for untied tasks.
   4335  1.1.1.2  joerg   if (!Data.Tied) {
   4336  1.1.1.2  joerg     CheckVarsEscapingUntiedTaskDeclContext Checker;
   4337  1.1.1.2  joerg     Checker.Visit(S.getInnermostCapturedStmt()->getCapturedStmt());
   4338  1.1.1.2  joerg     Data.PrivateLocals.append(Checker.getPrivateDecls().begin(),
   4339  1.1.1.2  joerg                               Checker.getPrivateDecls().end());
   4340  1.1.1.2  joerg   }
   4341      1.1  joerg   auto &&CodeGen = [&Data, &S, CS, &BodyGen, &LastprivateDstsOrigs,
   4342      1.1  joerg                     CapturedRegion](CodeGenFunction &CGF,
   4343      1.1  joerg                                     PrePostActionTy &Action) {
   4344  1.1.1.2  joerg     llvm::MapVector<CanonicalDeclPtr<const VarDecl>,
   4345  1.1.1.2  joerg                     std::pair<Address, Address>>
   4346  1.1.1.2  joerg         UntiedLocalVars;
   4347      1.1  joerg     // Set proper addresses for generated private copies.
   4348      1.1  joerg     OMPPrivateScope Scope(CGF);
   4349  1.1.1.2  joerg     llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> FirstprivatePtrs;
   4350      1.1  joerg     if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() ||
   4351  1.1.1.2  joerg         !Data.LastprivateVars.empty() || !Data.PrivateLocals.empty()) {
   4352      1.1  joerg       enum { PrivatesParam = 2, CopyFnParam = 3 };
   4353      1.1  joerg       llvm::Value *CopyFn = CGF.Builder.CreateLoad(
   4354      1.1  joerg           CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
   4355      1.1  joerg       llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
   4356      1.1  joerg           CS->getCapturedDecl()->getParam(PrivatesParam)));
   4357      1.1  joerg       // Map privates.
   4358      1.1  joerg       llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
   4359      1.1  joerg       llvm::SmallVector<llvm::Value *, 16> CallArgs;
   4360  1.1.1.2  joerg       llvm::SmallVector<llvm::Type *, 4> ParamTypes;
   4361      1.1  joerg       CallArgs.push_back(PrivatesPtr);
   4362  1.1.1.2  joerg       ParamTypes.push_back(PrivatesPtr->getType());
   4363      1.1  joerg       for (const Expr *E : Data.PrivateVars) {
   4364      1.1  joerg         const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   4365      1.1  joerg         Address PrivatePtr = CGF.CreateMemTemp(
   4366      1.1  joerg             CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr");
   4367      1.1  joerg         PrivatePtrs.emplace_back(VD, PrivatePtr);
   4368      1.1  joerg         CallArgs.push_back(PrivatePtr.getPointer());
   4369  1.1.1.2  joerg         ParamTypes.push_back(PrivatePtr.getType());
   4370      1.1  joerg       }
   4371      1.1  joerg       for (const Expr *E : Data.FirstprivateVars) {
   4372      1.1  joerg         const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   4373      1.1  joerg         Address PrivatePtr =
   4374      1.1  joerg             CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
   4375      1.1  joerg                               ".firstpriv.ptr.addr");
   4376      1.1  joerg         PrivatePtrs.emplace_back(VD, PrivatePtr);
   4377  1.1.1.2  joerg         FirstprivatePtrs.emplace_back(VD, PrivatePtr);
   4378      1.1  joerg         CallArgs.push_back(PrivatePtr.getPointer());
   4379  1.1.1.2  joerg         ParamTypes.push_back(PrivatePtr.getType());
   4380      1.1  joerg       }
   4381      1.1  joerg       for (const Expr *E : Data.LastprivateVars) {
   4382      1.1  joerg         const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   4383      1.1  joerg         Address PrivatePtr =
   4384      1.1  joerg             CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
   4385      1.1  joerg                               ".lastpriv.ptr.addr");
   4386      1.1  joerg         PrivatePtrs.emplace_back(VD, PrivatePtr);
   4387      1.1  joerg         CallArgs.push_back(PrivatePtr.getPointer());
   4388  1.1.1.2  joerg         ParamTypes.push_back(PrivatePtr.getType());
   4389  1.1.1.2  joerg       }
   4390  1.1.1.2  joerg       for (const VarDecl *VD : Data.PrivateLocals) {
   4391  1.1.1.2  joerg         QualType Ty = VD->getType().getNonReferenceType();
   4392  1.1.1.2  joerg         if (VD->getType()->isLValueReferenceType())
   4393  1.1.1.2  joerg           Ty = CGF.getContext().getPointerType(Ty);
   4394  1.1.1.2  joerg         if (isAllocatableDecl(VD))
   4395  1.1.1.2  joerg           Ty = CGF.getContext().getPointerType(Ty);
   4396  1.1.1.2  joerg         Address PrivatePtr = CGF.CreateMemTemp(
   4397  1.1.1.2  joerg             CGF.getContext().getPointerType(Ty), ".local.ptr.addr");
   4398  1.1.1.2  joerg         auto Result = UntiedLocalVars.insert(
   4399  1.1.1.2  joerg             std::make_pair(VD, std::make_pair(PrivatePtr, Address::invalid())));
   4400  1.1.1.2  joerg         // If key exists update in place.
   4401  1.1.1.2  joerg         if (Result.second == false)
   4402  1.1.1.2  joerg           *Result.first = std::make_pair(
   4403  1.1.1.2  joerg               VD, std::make_pair(PrivatePtr, Address::invalid()));
   4404  1.1.1.2  joerg         CallArgs.push_back(PrivatePtr.getPointer());
   4405  1.1.1.2  joerg         ParamTypes.push_back(PrivatePtr.getType());
   4406      1.1  joerg       }
   4407  1.1.1.2  joerg       auto *CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(),
   4408  1.1.1.2  joerg                                                ParamTypes, /*isVarArg=*/false);
   4409  1.1.1.2  joerg       CopyFn = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
   4410  1.1.1.2  joerg           CopyFn, CopyFnTy->getPointerTo());
   4411      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
   4412      1.1  joerg           CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
   4413      1.1  joerg       for (const auto &Pair : LastprivateDstsOrigs) {
   4414      1.1  joerg         const auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
   4415      1.1  joerg         DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(OrigVD),
   4416      1.1  joerg                         /*RefersToEnclosingVariableOrCapture=*/
   4417      1.1  joerg                             CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr,
   4418      1.1  joerg                         Pair.second->getType(), VK_LValue,
   4419      1.1  joerg                         Pair.second->getExprLoc());
   4420      1.1  joerg         Scope.addPrivate(Pair.first, [&CGF, &DRE]() {
   4421  1.1.1.2  joerg           return CGF.EmitLValue(&DRE).getAddress(CGF);
   4422      1.1  joerg         });
   4423      1.1  joerg       }
   4424      1.1  joerg       for (const auto &Pair : PrivatePtrs) {
   4425      1.1  joerg         Address Replacement(CGF.Builder.CreateLoad(Pair.second),
   4426      1.1  joerg                             CGF.getContext().getDeclAlign(Pair.first));
   4427      1.1  joerg         Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
   4428      1.1  joerg       }
   4429  1.1.1.2  joerg       // Adjust mapping for internal locals by mapping actual memory instead of
   4430  1.1.1.2  joerg       // a pointer to this memory.
   4431  1.1.1.2  joerg       for (auto &Pair : UntiedLocalVars) {
   4432  1.1.1.2  joerg         if (isAllocatableDecl(Pair.first)) {
   4433  1.1.1.2  joerg           llvm::Value *Ptr = CGF.Builder.CreateLoad(Pair.second.first);
   4434  1.1.1.2  joerg           Address Replacement(Ptr, CGF.getPointerAlign());
   4435  1.1.1.2  joerg           Pair.second.first = Replacement;
   4436  1.1.1.2  joerg           Ptr = CGF.Builder.CreateLoad(Replacement);
   4437  1.1.1.2  joerg           Replacement = Address(Ptr, CGF.getContext().getDeclAlign(Pair.first));
   4438  1.1.1.2  joerg           Pair.second.second = Replacement;
   4439  1.1.1.2  joerg         } else {
   4440  1.1.1.2  joerg           llvm::Value *Ptr = CGF.Builder.CreateLoad(Pair.second.first);
   4441  1.1.1.2  joerg           Address Replacement(Ptr, CGF.getContext().getDeclAlign(Pair.first));
   4442  1.1.1.2  joerg           Pair.second.first = Replacement;
   4443  1.1.1.2  joerg         }
   4444  1.1.1.2  joerg       }
   4445      1.1  joerg     }
   4446      1.1  joerg     if (Data.Reductions) {
   4447  1.1.1.2  joerg       OMPPrivateScope FirstprivateScope(CGF);
   4448  1.1.1.2  joerg       for (const auto &Pair : FirstprivatePtrs) {
   4449  1.1.1.2  joerg         Address Replacement(CGF.Builder.CreateLoad(Pair.second),
   4450  1.1.1.2  joerg                             CGF.getContext().getDeclAlign(Pair.first));
   4451  1.1.1.2  joerg         FirstprivateScope.addPrivate(Pair.first,
   4452  1.1.1.2  joerg                                      [Replacement]() { return Replacement; });
   4453  1.1.1.2  joerg       }
   4454  1.1.1.2  joerg       (void)FirstprivateScope.Privatize();
   4455      1.1  joerg       OMPLexicalScope LexScope(CGF, S, CapturedRegion);
   4456  1.1.1.2  joerg       ReductionCodeGen RedCG(Data.ReductionVars, Data.ReductionVars,
   4457  1.1.1.2  joerg                              Data.ReductionCopies, Data.ReductionOps);
   4458      1.1  joerg       llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad(
   4459      1.1  joerg           CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9)));
   4460      1.1  joerg       for (unsigned Cnt = 0, E = Data.ReductionVars.size(); Cnt < E; ++Cnt) {
   4461  1.1.1.2  joerg         RedCG.emitSharedOrigLValue(CGF, Cnt);
   4462      1.1  joerg         RedCG.emitAggregateType(CGF, Cnt);
   4463      1.1  joerg         // FIXME: This must removed once the runtime library is fixed.
   4464      1.1  joerg         // Emit required threadprivate variables for
   4465      1.1  joerg         // initializer/combiner/finalizer.
   4466      1.1  joerg         CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
   4467      1.1  joerg                                                            RedCG, Cnt);
   4468      1.1  joerg         Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
   4469      1.1  joerg             CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
   4470      1.1  joerg         Replacement =
   4471      1.1  joerg             Address(CGF.EmitScalarConversion(
   4472      1.1  joerg                         Replacement.getPointer(), CGF.getContext().VoidPtrTy,
   4473      1.1  joerg                         CGF.getContext().getPointerType(
   4474      1.1  joerg                             Data.ReductionCopies[Cnt]->getType()),
   4475      1.1  joerg                         Data.ReductionCopies[Cnt]->getExprLoc()),
   4476      1.1  joerg                     Replacement.getAlignment());
   4477      1.1  joerg         Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
   4478      1.1  joerg         Scope.addPrivate(RedCG.getBaseDecl(Cnt),
   4479      1.1  joerg                          [Replacement]() { return Replacement; });
   4480      1.1  joerg       }
   4481      1.1  joerg     }
   4482      1.1  joerg     // Privatize all private variables except for in_reduction items.
   4483      1.1  joerg     (void)Scope.Privatize();
   4484      1.1  joerg     SmallVector<const Expr *, 4> InRedVars;
   4485      1.1  joerg     SmallVector<const Expr *, 4> InRedPrivs;
   4486      1.1  joerg     SmallVector<const Expr *, 4> InRedOps;
   4487      1.1  joerg     SmallVector<const Expr *, 4> TaskgroupDescriptors;
   4488      1.1  joerg     for (const auto *C : S.getClausesOfKind<OMPInReductionClause>()) {
   4489      1.1  joerg       auto IPriv = C->privates().begin();
   4490      1.1  joerg       auto IRed = C->reduction_ops().begin();
   4491      1.1  joerg       auto ITD = C->taskgroup_descriptors().begin();
   4492      1.1  joerg       for (const Expr *Ref : C->varlists()) {
   4493      1.1  joerg         InRedVars.emplace_back(Ref);
   4494      1.1  joerg         InRedPrivs.emplace_back(*IPriv);
   4495      1.1  joerg         InRedOps.emplace_back(*IRed);
   4496      1.1  joerg         TaskgroupDescriptors.emplace_back(*ITD);
   4497      1.1  joerg         std::advance(IPriv, 1);
   4498      1.1  joerg         std::advance(IRed, 1);
   4499      1.1  joerg         std::advance(ITD, 1);
   4500      1.1  joerg       }
   4501      1.1  joerg     }
   4502      1.1  joerg     // Privatize in_reduction items here, because taskgroup descriptors must be
   4503      1.1  joerg     // privatized earlier.
   4504      1.1  joerg     OMPPrivateScope InRedScope(CGF);
   4505      1.1  joerg     if (!InRedVars.empty()) {
   4506  1.1.1.2  joerg       ReductionCodeGen RedCG(InRedVars, InRedVars, InRedPrivs, InRedOps);
   4507      1.1  joerg       for (unsigned Cnt = 0, E = InRedVars.size(); Cnt < E; ++Cnt) {
   4508  1.1.1.2  joerg         RedCG.emitSharedOrigLValue(CGF, Cnt);
   4509      1.1  joerg         RedCG.emitAggregateType(CGF, Cnt);
   4510      1.1  joerg         // The taskgroup descriptor variable is always implicit firstprivate and
   4511      1.1  joerg         // privatized already during processing of the firstprivates.
   4512      1.1  joerg         // FIXME: This must removed once the runtime library is fixed.
   4513      1.1  joerg         // Emit required threadprivate variables for
   4514      1.1  joerg         // initializer/combiner/finalizer.
   4515      1.1  joerg         CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
   4516      1.1  joerg                                                            RedCG, Cnt);
   4517  1.1.1.2  joerg         llvm::Value *ReductionsPtr;
   4518  1.1.1.2  joerg         if (const Expr *TRExpr = TaskgroupDescriptors[Cnt]) {
   4519  1.1.1.2  joerg           ReductionsPtr = CGF.EmitLoadOfScalar(CGF.EmitLValue(TRExpr),
   4520  1.1.1.2  joerg                                                TRExpr->getExprLoc());
   4521  1.1.1.2  joerg         } else {
   4522  1.1.1.2  joerg           ReductionsPtr = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
   4523  1.1.1.2  joerg         }
   4524      1.1  joerg         Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
   4525      1.1  joerg             CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
   4526      1.1  joerg         Replacement = Address(
   4527      1.1  joerg             CGF.EmitScalarConversion(
   4528      1.1  joerg                 Replacement.getPointer(), CGF.getContext().VoidPtrTy,
   4529      1.1  joerg                 CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()),
   4530      1.1  joerg                 InRedPrivs[Cnt]->getExprLoc()),
   4531      1.1  joerg             Replacement.getAlignment());
   4532      1.1  joerg         Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
   4533      1.1  joerg         InRedScope.addPrivate(RedCG.getBaseDecl(Cnt),
   4534      1.1  joerg                               [Replacement]() { return Replacement; });
   4535      1.1  joerg       }
   4536      1.1  joerg     }
   4537      1.1  joerg     (void)InRedScope.Privatize();
   4538      1.1  joerg 
   4539  1.1.1.2  joerg     CGOpenMPRuntime::UntiedTaskLocalDeclsRAII LocalVarsScope(CGF,
   4540  1.1.1.2  joerg                                                              UntiedLocalVars);
   4541      1.1  joerg     Action.Enter(CGF);
   4542      1.1  joerg     BodyGen(CGF);
   4543      1.1  joerg   };
   4544      1.1  joerg   llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
   4545      1.1  joerg       S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied,
   4546      1.1  joerg       Data.NumberOfParts);
   4547      1.1  joerg   OMPLexicalScope Scope(*this, S, llvm::None,
   4548  1.1.1.2  joerg                         !isOpenMPParallelDirective(S.getDirectiveKind()) &&
   4549  1.1.1.2  joerg                             !isOpenMPSimdDirective(S.getDirectiveKind()));
   4550      1.1  joerg   TaskGen(*this, OutlinedFn, Data);
   4551      1.1  joerg }
   4552      1.1  joerg 
   4553      1.1  joerg static ImplicitParamDecl *
   4554      1.1  joerg createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data,
   4555      1.1  joerg                                   QualType Ty, CapturedDecl *CD,
   4556      1.1  joerg                                   SourceLocation Loc) {
   4557      1.1  joerg   auto *OrigVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty,
   4558      1.1  joerg                                            ImplicitParamDecl::Other);
   4559      1.1  joerg   auto *OrigRef = DeclRefExpr::Create(
   4560      1.1  joerg       C, NestedNameSpecifierLoc(), SourceLocation(), OrigVD,
   4561      1.1  joerg       /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue);
   4562      1.1  joerg   auto *PrivateVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty,
   4563      1.1  joerg                                               ImplicitParamDecl::Other);
   4564      1.1  joerg   auto *PrivateRef = DeclRefExpr::Create(
   4565      1.1  joerg       C, NestedNameSpecifierLoc(), SourceLocation(), PrivateVD,
   4566      1.1  joerg       /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue);
   4567      1.1  joerg   QualType ElemType = C.getBaseElementType(Ty);
   4568      1.1  joerg   auto *InitVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, ElemType,
   4569      1.1  joerg                                            ImplicitParamDecl::Other);
   4570      1.1  joerg   auto *InitRef = DeclRefExpr::Create(
   4571      1.1  joerg       C, NestedNameSpecifierLoc(), SourceLocation(), InitVD,
   4572      1.1  joerg       /*RefersToEnclosingVariableOrCapture=*/false, Loc, ElemType, VK_LValue);
   4573      1.1  joerg   PrivateVD->setInitStyle(VarDecl::CInit);
   4574      1.1  joerg   PrivateVD->setInit(ImplicitCastExpr::Create(C, ElemType, CK_LValueToRValue,
   4575      1.1  joerg                                               InitRef, /*BasePath=*/nullptr,
   4576  1.1.1.2  joerg                                               VK_RValue, FPOptionsOverride()));
   4577      1.1  joerg   Data.FirstprivateVars.emplace_back(OrigRef);
   4578      1.1  joerg   Data.FirstprivateCopies.emplace_back(PrivateRef);
   4579      1.1  joerg   Data.FirstprivateInits.emplace_back(InitRef);
   4580      1.1  joerg   return OrigVD;
   4581      1.1  joerg }
   4582      1.1  joerg 
   4583      1.1  joerg void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
   4584      1.1  joerg     const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen,
   4585      1.1  joerg     OMPTargetDataInfo &InputInfo) {
   4586      1.1  joerg   // Emit outlined function for task construct.
   4587      1.1  joerg   const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
   4588      1.1  joerg   Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
   4589      1.1  joerg   QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
   4590      1.1  joerg   auto I = CS->getCapturedDecl()->param_begin();
   4591      1.1  joerg   auto PartId = std::next(I);
   4592      1.1  joerg   auto TaskT = std::next(I, 4);
   4593      1.1  joerg   OMPTaskDataTy Data;
   4594      1.1  joerg   // The task is not final.
   4595      1.1  joerg   Data.Final.setInt(/*IntVal=*/false);
   4596      1.1  joerg   // Get list of firstprivate variables.
   4597      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
   4598      1.1  joerg     auto IRef = C->varlist_begin();
   4599      1.1  joerg     auto IElemInitRef = C->inits().begin();
   4600      1.1  joerg     for (auto *IInit : C->private_copies()) {
   4601      1.1  joerg       Data.FirstprivateVars.push_back(*IRef);
   4602      1.1  joerg       Data.FirstprivateCopies.push_back(IInit);
   4603      1.1  joerg       Data.FirstprivateInits.push_back(*IElemInitRef);
   4604      1.1  joerg       ++IRef;
   4605      1.1  joerg       ++IElemInitRef;
   4606      1.1  joerg     }
   4607      1.1  joerg   }
   4608      1.1  joerg   OMPPrivateScope TargetScope(*this);
   4609      1.1  joerg   VarDecl *BPVD = nullptr;
   4610      1.1  joerg   VarDecl *PVD = nullptr;
   4611      1.1  joerg   VarDecl *SVD = nullptr;
   4612  1.1.1.2  joerg   VarDecl *MVD = nullptr;
   4613      1.1  joerg   if (InputInfo.NumberOfTargetItems > 0) {
   4614      1.1  joerg     auto *CD = CapturedDecl::Create(
   4615      1.1  joerg         getContext(), getContext().getTranslationUnitDecl(), /*NumParams=*/0);
   4616      1.1  joerg     llvm::APInt ArrSize(/*numBits=*/32, InputInfo.NumberOfTargetItems);
   4617  1.1.1.2  joerg     QualType BaseAndPointerAndMapperType = getContext().getConstantArrayType(
   4618      1.1  joerg         getContext().VoidPtrTy, ArrSize, nullptr, ArrayType::Normal,
   4619      1.1  joerg         /*IndexTypeQuals=*/0);
   4620      1.1  joerg     BPVD = createImplicitFirstprivateForType(
   4621  1.1.1.2  joerg         getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
   4622      1.1  joerg     PVD = createImplicitFirstprivateForType(
   4623  1.1.1.2  joerg         getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
   4624      1.1  joerg     QualType SizesType = getContext().getConstantArrayType(
   4625      1.1  joerg         getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1),
   4626      1.1  joerg         ArrSize, nullptr, ArrayType::Normal,
   4627      1.1  joerg         /*IndexTypeQuals=*/0);
   4628      1.1  joerg     SVD = createImplicitFirstprivateForType(getContext(), Data, SizesType, CD,
   4629      1.1  joerg                                             S.getBeginLoc());
   4630      1.1  joerg     TargetScope.addPrivate(
   4631      1.1  joerg         BPVD, [&InputInfo]() { return InputInfo.BasePointersArray; });
   4632      1.1  joerg     TargetScope.addPrivate(PVD,
   4633      1.1  joerg                            [&InputInfo]() { return InputInfo.PointersArray; });
   4634      1.1  joerg     TargetScope.addPrivate(SVD,
   4635      1.1  joerg                            [&InputInfo]() { return InputInfo.SizesArray; });
   4636  1.1.1.2  joerg     // If there is no user-defined mapper, the mapper array will be nullptr. In
   4637  1.1.1.2  joerg     // this case, we don't need to privatize it.
   4638  1.1.1.2  joerg     if (!dyn_cast_or_null<llvm::ConstantPointerNull>(
   4639  1.1.1.2  joerg             InputInfo.MappersArray.getPointer())) {
   4640  1.1.1.2  joerg       MVD = createImplicitFirstprivateForType(
   4641  1.1.1.2  joerg           getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
   4642  1.1.1.2  joerg       TargetScope.addPrivate(MVD,
   4643  1.1.1.2  joerg                              [&InputInfo]() { return InputInfo.MappersArray; });
   4644  1.1.1.2  joerg     }
   4645      1.1  joerg   }
   4646      1.1  joerg   (void)TargetScope.Privatize();
   4647      1.1  joerg   // Build list of dependences.
   4648  1.1.1.2  joerg   for (const auto *C : S.getClausesOfKind<OMPDependClause>()) {
   4649  1.1.1.2  joerg     OMPTaskDataTy::DependData &DD =
   4650  1.1.1.2  joerg         Data.Dependences.emplace_back(C->getDependencyKind(), C->getModifier());
   4651  1.1.1.2  joerg     DD.DepExprs.append(C->varlist_begin(), C->varlist_end());
   4652  1.1.1.2  joerg   }
   4653  1.1.1.2  joerg   auto &&CodeGen = [&Data, &S, CS, &BodyGen, BPVD, PVD, SVD, MVD,
   4654      1.1  joerg                     &InputInfo](CodeGenFunction &CGF, PrePostActionTy &Action) {
   4655      1.1  joerg     // Set proper addresses for generated private copies.
   4656      1.1  joerg     OMPPrivateScope Scope(CGF);
   4657      1.1  joerg     if (!Data.FirstprivateVars.empty()) {
   4658      1.1  joerg       enum { PrivatesParam = 2, CopyFnParam = 3 };
   4659      1.1  joerg       llvm::Value *CopyFn = CGF.Builder.CreateLoad(
   4660      1.1  joerg           CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
   4661      1.1  joerg       llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
   4662      1.1  joerg           CS->getCapturedDecl()->getParam(PrivatesParam)));
   4663      1.1  joerg       // Map privates.
   4664      1.1  joerg       llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
   4665      1.1  joerg       llvm::SmallVector<llvm::Value *, 16> CallArgs;
   4666  1.1.1.2  joerg       llvm::SmallVector<llvm::Type *, 4> ParamTypes;
   4667      1.1  joerg       CallArgs.push_back(PrivatesPtr);
   4668  1.1.1.2  joerg       ParamTypes.push_back(PrivatesPtr->getType());
   4669      1.1  joerg       for (const Expr *E : Data.FirstprivateVars) {
   4670      1.1  joerg         const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   4671      1.1  joerg         Address PrivatePtr =
   4672      1.1  joerg             CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
   4673      1.1  joerg                               ".firstpriv.ptr.addr");
   4674      1.1  joerg         PrivatePtrs.emplace_back(VD, PrivatePtr);
   4675      1.1  joerg         CallArgs.push_back(PrivatePtr.getPointer());
   4676  1.1.1.2  joerg         ParamTypes.push_back(PrivatePtr.getType());
   4677      1.1  joerg       }
   4678  1.1.1.2  joerg       auto *CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(),
   4679  1.1.1.2  joerg                                                ParamTypes, /*isVarArg=*/false);
   4680  1.1.1.2  joerg       CopyFn = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
   4681  1.1.1.2  joerg           CopyFn, CopyFnTy->getPointerTo());
   4682      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
   4683      1.1  joerg           CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
   4684      1.1  joerg       for (const auto &Pair : PrivatePtrs) {
   4685      1.1  joerg         Address Replacement(CGF.Builder.CreateLoad(Pair.second),
   4686      1.1  joerg                             CGF.getContext().getDeclAlign(Pair.first));
   4687      1.1  joerg         Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
   4688      1.1  joerg       }
   4689      1.1  joerg     }
   4690      1.1  joerg     // Privatize all private variables except for in_reduction items.
   4691      1.1  joerg     (void)Scope.Privatize();
   4692      1.1  joerg     if (InputInfo.NumberOfTargetItems > 0) {
   4693      1.1  joerg       InputInfo.BasePointersArray = CGF.Builder.CreateConstArrayGEP(
   4694      1.1  joerg           CGF.GetAddrOfLocalVar(BPVD), /*Index=*/0);
   4695      1.1  joerg       InputInfo.PointersArray = CGF.Builder.CreateConstArrayGEP(
   4696      1.1  joerg           CGF.GetAddrOfLocalVar(PVD), /*Index=*/0);
   4697      1.1  joerg       InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(
   4698      1.1  joerg           CGF.GetAddrOfLocalVar(SVD), /*Index=*/0);
   4699  1.1.1.2  joerg       // If MVD is nullptr, the mapper array is not privatized
   4700  1.1.1.2  joerg       if (MVD)
   4701  1.1.1.2  joerg         InputInfo.MappersArray = CGF.Builder.CreateConstArrayGEP(
   4702  1.1.1.2  joerg             CGF.GetAddrOfLocalVar(MVD), /*Index=*/0);
   4703      1.1  joerg     }
   4704      1.1  joerg 
   4705      1.1  joerg     Action.Enter(CGF);
   4706      1.1  joerg     OMPLexicalScope LexScope(CGF, S, OMPD_task, /*EmitPreInitStmt=*/false);
   4707      1.1  joerg     BodyGen(CGF);
   4708      1.1  joerg   };
   4709      1.1  joerg   llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
   4710      1.1  joerg       S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, /*Tied=*/true,
   4711      1.1  joerg       Data.NumberOfParts);
   4712      1.1  joerg   llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<OMPNowaitClause>() ? 1 : 0);
   4713      1.1  joerg   IntegerLiteral IfCond(getContext(), TrueOrFalse,
   4714      1.1  joerg                         getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
   4715      1.1  joerg                         SourceLocation());
   4716      1.1  joerg 
   4717      1.1  joerg   CGM.getOpenMPRuntime().emitTaskCall(*this, S.getBeginLoc(), S, OutlinedFn,
   4718      1.1  joerg                                       SharedsTy, CapturedStruct, &IfCond, Data);
   4719      1.1  joerg }
   4720      1.1  joerg 
   4721      1.1  joerg void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
   4722      1.1  joerg   // Emit outlined function for task construct.
   4723      1.1  joerg   const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
   4724      1.1  joerg   Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
   4725      1.1  joerg   QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
   4726      1.1  joerg   const Expr *IfCond = nullptr;
   4727      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
   4728      1.1  joerg     if (C->getNameModifier() == OMPD_unknown ||
   4729      1.1  joerg         C->getNameModifier() == OMPD_task) {
   4730      1.1  joerg       IfCond = C->getCondition();
   4731      1.1  joerg       break;
   4732      1.1  joerg     }
   4733      1.1  joerg   }
   4734      1.1  joerg 
   4735      1.1  joerg   OMPTaskDataTy Data;
   4736      1.1  joerg   // Check if we should emit tied or untied task.
   4737      1.1  joerg   Data.Tied = !S.getSingleClause<OMPUntiedClause>();
   4738      1.1  joerg   auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
   4739      1.1  joerg     CGF.EmitStmt(CS->getCapturedStmt());
   4740      1.1  joerg   };
   4741      1.1  joerg   auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
   4742      1.1  joerg                     IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
   4743      1.1  joerg                             const OMPTaskDataTy &Data) {
   4744      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getBeginLoc(), S, OutlinedFn,
   4745      1.1  joerg                                             SharedsTy, CapturedStruct, IfCond,
   4746      1.1  joerg                                             Data);
   4747      1.1  joerg   };
   4748  1.1.1.2  joerg   auto LPCRegion =
   4749  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   4750      1.1  joerg   EmitOMPTaskBasedDirective(S, OMPD_task, BodyGen, TaskGen, Data);
   4751      1.1  joerg }
   4752      1.1  joerg 
   4753      1.1  joerg void CodeGenFunction::EmitOMPTaskyieldDirective(
   4754      1.1  joerg     const OMPTaskyieldDirective &S) {
   4755      1.1  joerg   CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getBeginLoc());
   4756      1.1  joerg }
   4757      1.1  joerg 
   4758      1.1  joerg void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
   4759      1.1  joerg   CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_barrier);
   4760      1.1  joerg }
   4761      1.1  joerg 
   4762      1.1  joerg void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
   4763      1.1  joerg   CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getBeginLoc());
   4764      1.1  joerg }
   4765      1.1  joerg 
   4766      1.1  joerg void CodeGenFunction::EmitOMPTaskgroupDirective(
   4767      1.1  joerg     const OMPTaskgroupDirective &S) {
   4768      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   4769      1.1  joerg     Action.Enter(CGF);
   4770      1.1  joerg     if (const Expr *E = S.getReductionRef()) {
   4771      1.1  joerg       SmallVector<const Expr *, 4> LHSs;
   4772      1.1  joerg       SmallVector<const Expr *, 4> RHSs;
   4773      1.1  joerg       OMPTaskDataTy Data;
   4774      1.1  joerg       for (const auto *C : S.getClausesOfKind<OMPTaskReductionClause>()) {
   4775  1.1.1.2  joerg         Data.ReductionVars.append(C->varlist_begin(), C->varlist_end());
   4776  1.1.1.2  joerg         Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end());
   4777  1.1.1.2  joerg         Data.ReductionCopies.append(C->privates().begin(), C->privates().end());
   4778  1.1.1.2  joerg         Data.ReductionOps.append(C->reduction_ops().begin(),
   4779  1.1.1.2  joerg                                  C->reduction_ops().end());
   4780  1.1.1.2  joerg         LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
   4781  1.1.1.2  joerg         RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
   4782      1.1  joerg       }
   4783      1.1  joerg       llvm::Value *ReductionDesc =
   4784      1.1  joerg           CGF.CGM.getOpenMPRuntime().emitTaskReductionInit(CGF, S.getBeginLoc(),
   4785      1.1  joerg                                                            LHSs, RHSs, Data);
   4786      1.1  joerg       const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   4787      1.1  joerg       CGF.EmitVarDecl(*VD);
   4788      1.1  joerg       CGF.EmitStoreOfScalar(ReductionDesc, CGF.GetAddrOfLocalVar(VD),
   4789      1.1  joerg                             /*Volatile=*/false, E->getType());
   4790      1.1  joerg     }
   4791      1.1  joerg     CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
   4792      1.1  joerg   };
   4793      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_unknown);
   4794      1.1  joerg   CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getBeginLoc());
   4795      1.1  joerg }
   4796      1.1  joerg 
   4797      1.1  joerg void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
   4798  1.1.1.2  joerg   llvm::AtomicOrdering AO = S.getSingleClause<OMPFlushClause>()
   4799  1.1.1.2  joerg                                 ? llvm::AtomicOrdering::NotAtomic
   4800  1.1.1.2  joerg                                 : llvm::AtomicOrdering::AcquireRelease;
   4801      1.1  joerg   CGM.getOpenMPRuntime().emitFlush(
   4802      1.1  joerg       *this,
   4803      1.1  joerg       [&S]() -> ArrayRef<const Expr *> {
   4804      1.1  joerg         if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>())
   4805      1.1  joerg           return llvm::makeArrayRef(FlushClause->varlist_begin(),
   4806      1.1  joerg                                     FlushClause->varlist_end());
   4807      1.1  joerg         return llvm::None;
   4808      1.1  joerg       }(),
   4809  1.1.1.2  joerg       S.getBeginLoc(), AO);
   4810  1.1.1.2  joerg }
   4811  1.1.1.2  joerg 
   4812  1.1.1.2  joerg void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) {
   4813  1.1.1.2  joerg   const auto *DO = S.getSingleClause<OMPDepobjClause>();
   4814  1.1.1.2  joerg   LValue DOLVal = EmitLValue(DO->getDepobj());
   4815  1.1.1.2  joerg   if (const auto *DC = S.getSingleClause<OMPDependClause>()) {
   4816  1.1.1.2  joerg     OMPTaskDataTy::DependData Dependencies(DC->getDependencyKind(),
   4817  1.1.1.2  joerg                                            DC->getModifier());
   4818  1.1.1.2  joerg     Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end());
   4819  1.1.1.2  joerg     Address DepAddr = CGM.getOpenMPRuntime().emitDepobjDependClause(
   4820  1.1.1.2  joerg         *this, Dependencies, DC->getBeginLoc());
   4821  1.1.1.2  joerg     EmitStoreOfScalar(DepAddr.getPointer(), DOLVal);
   4822  1.1.1.2  joerg     return;
   4823  1.1.1.2  joerg   }
   4824  1.1.1.2  joerg   if (const auto *DC = S.getSingleClause<OMPDestroyClause>()) {
   4825  1.1.1.2  joerg     CGM.getOpenMPRuntime().emitDestroyClause(*this, DOLVal, DC->getBeginLoc());
   4826  1.1.1.2  joerg     return;
   4827  1.1.1.2  joerg   }
   4828  1.1.1.2  joerg   if (const auto *UC = S.getSingleClause<OMPUpdateClause>()) {
   4829  1.1.1.2  joerg     CGM.getOpenMPRuntime().emitUpdateClause(
   4830  1.1.1.2  joerg         *this, DOLVal, UC->getDependencyKind(), UC->getBeginLoc());
   4831  1.1.1.2  joerg     return;
   4832  1.1.1.2  joerg   }
   4833  1.1.1.2  joerg }
   4834  1.1.1.2  joerg 
   4835  1.1.1.2  joerg void CodeGenFunction::EmitOMPScanDirective(const OMPScanDirective &S) {
   4836  1.1.1.2  joerg   if (!OMPParentLoopDirectiveForScan)
   4837  1.1.1.2  joerg     return;
   4838  1.1.1.2  joerg   const OMPExecutableDirective &ParentDir = *OMPParentLoopDirectiveForScan;
   4839  1.1.1.2  joerg   bool IsInclusive = S.hasClausesOfKind<OMPInclusiveClause>();
   4840  1.1.1.2  joerg   SmallVector<const Expr *, 4> Shareds;
   4841  1.1.1.2  joerg   SmallVector<const Expr *, 4> Privates;
   4842  1.1.1.2  joerg   SmallVector<const Expr *, 4> LHSs;
   4843  1.1.1.2  joerg   SmallVector<const Expr *, 4> RHSs;
   4844  1.1.1.2  joerg   SmallVector<const Expr *, 4> ReductionOps;
   4845  1.1.1.2  joerg   SmallVector<const Expr *, 4> CopyOps;
   4846  1.1.1.2  joerg   SmallVector<const Expr *, 4> CopyArrayTemps;
   4847  1.1.1.2  joerg   SmallVector<const Expr *, 4> CopyArrayElems;
   4848  1.1.1.2  joerg   for (const auto *C : ParentDir.getClausesOfKind<OMPReductionClause>()) {
   4849  1.1.1.2  joerg     if (C->getModifier() != OMPC_REDUCTION_inscan)
   4850  1.1.1.2  joerg       continue;
   4851  1.1.1.2  joerg     Shareds.append(C->varlist_begin(), C->varlist_end());
   4852  1.1.1.2  joerg     Privates.append(C->privates().begin(), C->privates().end());
   4853  1.1.1.2  joerg     LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
   4854  1.1.1.2  joerg     RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
   4855  1.1.1.2  joerg     ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
   4856  1.1.1.2  joerg     CopyOps.append(C->copy_ops().begin(), C->copy_ops().end());
   4857  1.1.1.2  joerg     CopyArrayTemps.append(C->copy_array_temps().begin(),
   4858  1.1.1.2  joerg                           C->copy_array_temps().end());
   4859  1.1.1.2  joerg     CopyArrayElems.append(C->copy_array_elems().begin(),
   4860  1.1.1.2  joerg                           C->copy_array_elems().end());
   4861  1.1.1.2  joerg   }
   4862  1.1.1.2  joerg   if (ParentDir.getDirectiveKind() == OMPD_simd ||
   4863  1.1.1.2  joerg       (getLangOpts().OpenMPSimd &&
   4864  1.1.1.2  joerg        isOpenMPSimdDirective(ParentDir.getDirectiveKind()))) {
   4865  1.1.1.2  joerg     // For simd directive and simd-based directives in simd only mode, use the
   4866  1.1.1.2  joerg     // following codegen:
   4867  1.1.1.2  joerg     // int x = 0;
   4868  1.1.1.2  joerg     // #pragma omp simd reduction(inscan, +: x)
   4869  1.1.1.2  joerg     // for (..) {
   4870  1.1.1.2  joerg     //   <first part>
   4871  1.1.1.2  joerg     //   #pragma omp scan inclusive(x)
   4872  1.1.1.2  joerg     //   <second part>
   4873  1.1.1.2  joerg     //  }
   4874  1.1.1.2  joerg     // is transformed to:
   4875  1.1.1.2  joerg     // int x = 0;
   4876  1.1.1.2  joerg     // for (..) {
   4877  1.1.1.2  joerg     //   int x_priv = 0;
   4878  1.1.1.2  joerg     //   <first part>
   4879  1.1.1.2  joerg     //   x = x_priv + x;
   4880  1.1.1.2  joerg     //   x_priv = x;
   4881  1.1.1.2  joerg     //   <second part>
   4882  1.1.1.2  joerg     // }
   4883  1.1.1.2  joerg     // and
   4884  1.1.1.2  joerg     // int x = 0;
   4885  1.1.1.2  joerg     // #pragma omp simd reduction(inscan, +: x)
   4886  1.1.1.2  joerg     // for (..) {
   4887  1.1.1.2  joerg     //   <first part>
   4888  1.1.1.2  joerg     //   #pragma omp scan exclusive(x)
   4889  1.1.1.2  joerg     //   <second part>
   4890  1.1.1.2  joerg     // }
   4891  1.1.1.2  joerg     // to
   4892  1.1.1.2  joerg     // int x = 0;
   4893  1.1.1.2  joerg     // for (..) {
   4894  1.1.1.2  joerg     //   int x_priv = 0;
   4895  1.1.1.2  joerg     //   <second part>
   4896  1.1.1.2  joerg     //   int temp = x;
   4897  1.1.1.2  joerg     //   x = x_priv + x;
   4898  1.1.1.2  joerg     //   x_priv = temp;
   4899  1.1.1.2  joerg     //   <first part>
   4900  1.1.1.2  joerg     // }
   4901  1.1.1.2  joerg     llvm::BasicBlock *OMPScanReduce = createBasicBlock("omp.inscan.reduce");
   4902  1.1.1.2  joerg     EmitBranch(IsInclusive
   4903  1.1.1.2  joerg                    ? OMPScanReduce
   4904  1.1.1.2  joerg                    : BreakContinueStack.back().ContinueBlock.getBlock());
   4905  1.1.1.2  joerg     EmitBlock(OMPScanDispatch);
   4906  1.1.1.2  joerg     {
   4907  1.1.1.2  joerg       // New scope for correct construction/destruction of temp variables for
   4908  1.1.1.2  joerg       // exclusive scan.
   4909  1.1.1.2  joerg       LexicalScope Scope(*this, S.getSourceRange());
   4910  1.1.1.2  joerg       EmitBranch(IsInclusive ? OMPBeforeScanBlock : OMPAfterScanBlock);
   4911  1.1.1.2  joerg       EmitBlock(OMPScanReduce);
   4912  1.1.1.2  joerg       if (!IsInclusive) {
   4913  1.1.1.2  joerg         // Create temp var and copy LHS value to this temp value.
   4914  1.1.1.2  joerg         // TMP = LHS;
   4915  1.1.1.2  joerg         for (unsigned I = 0, E = CopyArrayElems.size(); I < E; ++I) {
   4916  1.1.1.2  joerg           const Expr *PrivateExpr = Privates[I];
   4917  1.1.1.2  joerg           const Expr *TempExpr = CopyArrayTemps[I];
   4918  1.1.1.2  joerg           EmitAutoVarDecl(
   4919  1.1.1.2  joerg               *cast<VarDecl>(cast<DeclRefExpr>(TempExpr)->getDecl()));
   4920  1.1.1.2  joerg           LValue DestLVal = EmitLValue(TempExpr);
   4921  1.1.1.2  joerg           LValue SrcLVal = EmitLValue(LHSs[I]);
   4922  1.1.1.2  joerg           EmitOMPCopy(PrivateExpr->getType(), DestLVal.getAddress(*this),
   4923  1.1.1.2  joerg                       SrcLVal.getAddress(*this),
   4924  1.1.1.2  joerg                       cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
   4925  1.1.1.2  joerg                       cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
   4926  1.1.1.2  joerg                       CopyOps[I]);
   4927  1.1.1.2  joerg         }
   4928  1.1.1.2  joerg       }
   4929  1.1.1.2  joerg       CGM.getOpenMPRuntime().emitReduction(
   4930  1.1.1.2  joerg           *this, ParentDir.getEndLoc(), Privates, LHSs, RHSs, ReductionOps,
   4931  1.1.1.2  joerg           {/*WithNowait=*/true, /*SimpleReduction=*/true, OMPD_simd});
   4932  1.1.1.2  joerg       for (unsigned I = 0, E = CopyArrayElems.size(); I < E; ++I) {
   4933  1.1.1.2  joerg         const Expr *PrivateExpr = Privates[I];
   4934  1.1.1.2  joerg         LValue DestLVal;
   4935  1.1.1.2  joerg         LValue SrcLVal;
   4936  1.1.1.2  joerg         if (IsInclusive) {
   4937  1.1.1.2  joerg           DestLVal = EmitLValue(RHSs[I]);
   4938  1.1.1.2  joerg           SrcLVal = EmitLValue(LHSs[I]);
   4939  1.1.1.2  joerg         } else {
   4940  1.1.1.2  joerg           const Expr *TempExpr = CopyArrayTemps[I];
   4941  1.1.1.2  joerg           DestLVal = EmitLValue(RHSs[I]);
   4942  1.1.1.2  joerg           SrcLVal = EmitLValue(TempExpr);
   4943  1.1.1.2  joerg         }
   4944  1.1.1.2  joerg         EmitOMPCopy(PrivateExpr->getType(), DestLVal.getAddress(*this),
   4945  1.1.1.2  joerg                     SrcLVal.getAddress(*this),
   4946  1.1.1.2  joerg                     cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
   4947  1.1.1.2  joerg                     cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
   4948  1.1.1.2  joerg                     CopyOps[I]);
   4949  1.1.1.2  joerg       }
   4950  1.1.1.2  joerg     }
   4951  1.1.1.2  joerg     EmitBranch(IsInclusive ? OMPAfterScanBlock : OMPBeforeScanBlock);
   4952  1.1.1.2  joerg     OMPScanExitBlock = IsInclusive
   4953  1.1.1.2  joerg                            ? BreakContinueStack.back().ContinueBlock.getBlock()
   4954  1.1.1.2  joerg                            : OMPScanReduce;
   4955  1.1.1.2  joerg     EmitBlock(OMPAfterScanBlock);
   4956  1.1.1.2  joerg     return;
   4957  1.1.1.2  joerg   }
   4958  1.1.1.2  joerg   if (!IsInclusive) {
   4959  1.1.1.2  joerg     EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
   4960  1.1.1.2  joerg     EmitBlock(OMPScanExitBlock);
   4961  1.1.1.2  joerg   }
   4962  1.1.1.2  joerg   if (OMPFirstScanLoop) {
   4963  1.1.1.2  joerg     // Emit buffer[i] = red; at the end of the input phase.
   4964  1.1.1.2  joerg     const auto *IVExpr = cast<OMPLoopDirective>(ParentDir)
   4965  1.1.1.2  joerg                              .getIterationVariable()
   4966  1.1.1.2  joerg                              ->IgnoreParenImpCasts();
   4967  1.1.1.2  joerg     LValue IdxLVal = EmitLValue(IVExpr);
   4968  1.1.1.2  joerg     llvm::Value *IdxVal = EmitLoadOfScalar(IdxLVal, IVExpr->getExprLoc());
   4969  1.1.1.2  joerg     IdxVal = Builder.CreateIntCast(IdxVal, SizeTy, /*isSigned=*/false);
   4970  1.1.1.2  joerg     for (unsigned I = 0, E = CopyArrayElems.size(); I < E; ++I) {
   4971  1.1.1.2  joerg       const Expr *PrivateExpr = Privates[I];
   4972  1.1.1.2  joerg       const Expr *OrigExpr = Shareds[I];
   4973  1.1.1.2  joerg       const Expr *CopyArrayElem = CopyArrayElems[I];
   4974  1.1.1.2  joerg       OpaqueValueMapping IdxMapping(
   4975  1.1.1.2  joerg           *this,
   4976  1.1.1.2  joerg           cast<OpaqueValueExpr>(
   4977  1.1.1.2  joerg               cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
   4978  1.1.1.2  joerg           RValue::get(IdxVal));
   4979  1.1.1.2  joerg       LValue DestLVal = EmitLValue(CopyArrayElem);
   4980  1.1.1.2  joerg       LValue SrcLVal = EmitLValue(OrigExpr);
   4981  1.1.1.2  joerg       EmitOMPCopy(PrivateExpr->getType(), DestLVal.getAddress(*this),
   4982  1.1.1.2  joerg                   SrcLVal.getAddress(*this),
   4983  1.1.1.2  joerg                   cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
   4984  1.1.1.2  joerg                   cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
   4985  1.1.1.2  joerg                   CopyOps[I]);
   4986  1.1.1.2  joerg     }
   4987  1.1.1.2  joerg   }
   4988  1.1.1.2  joerg   EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
   4989  1.1.1.2  joerg   if (IsInclusive) {
   4990  1.1.1.2  joerg     EmitBlock(OMPScanExitBlock);
   4991  1.1.1.2  joerg     EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
   4992  1.1.1.2  joerg   }
   4993  1.1.1.2  joerg   EmitBlock(OMPScanDispatch);
   4994  1.1.1.2  joerg   if (!OMPFirstScanLoop) {
   4995  1.1.1.2  joerg     // Emit red = buffer[i]; at the entrance to the scan phase.
   4996  1.1.1.2  joerg     const auto *IVExpr = cast<OMPLoopDirective>(ParentDir)
   4997  1.1.1.2  joerg                              .getIterationVariable()
   4998  1.1.1.2  joerg                              ->IgnoreParenImpCasts();
   4999  1.1.1.2  joerg     LValue IdxLVal = EmitLValue(IVExpr);
   5000  1.1.1.2  joerg     llvm::Value *IdxVal = EmitLoadOfScalar(IdxLVal, IVExpr->getExprLoc());
   5001  1.1.1.2  joerg     IdxVal = Builder.CreateIntCast(IdxVal, SizeTy, /*isSigned=*/false);
   5002  1.1.1.2  joerg     llvm::BasicBlock *ExclusiveExitBB = nullptr;
   5003  1.1.1.2  joerg     if (!IsInclusive) {
   5004  1.1.1.2  joerg       llvm::BasicBlock *ContBB = createBasicBlock("omp.exclusive.dec");
   5005  1.1.1.2  joerg       ExclusiveExitBB = createBasicBlock("omp.exclusive.copy.exit");
   5006  1.1.1.2  joerg       llvm::Value *Cmp = Builder.CreateIsNull(IdxVal);
   5007  1.1.1.2  joerg       Builder.CreateCondBr(Cmp, ExclusiveExitBB, ContBB);
   5008  1.1.1.2  joerg       EmitBlock(ContBB);
   5009  1.1.1.2  joerg       // Use idx - 1 iteration for exclusive scan.
   5010  1.1.1.2  joerg       IdxVal = Builder.CreateNUWSub(IdxVal, llvm::ConstantInt::get(SizeTy, 1));
   5011  1.1.1.2  joerg     }
   5012  1.1.1.2  joerg     for (unsigned I = 0, E = CopyArrayElems.size(); I < E; ++I) {
   5013  1.1.1.2  joerg       const Expr *PrivateExpr = Privates[I];
   5014  1.1.1.2  joerg       const Expr *OrigExpr = Shareds[I];
   5015  1.1.1.2  joerg       const Expr *CopyArrayElem = CopyArrayElems[I];
   5016  1.1.1.2  joerg       OpaqueValueMapping IdxMapping(
   5017  1.1.1.2  joerg           *this,
   5018  1.1.1.2  joerg           cast<OpaqueValueExpr>(
   5019  1.1.1.2  joerg               cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
   5020  1.1.1.2  joerg           RValue::get(IdxVal));
   5021  1.1.1.2  joerg       LValue SrcLVal = EmitLValue(CopyArrayElem);
   5022  1.1.1.2  joerg       LValue DestLVal = EmitLValue(OrigExpr);
   5023  1.1.1.2  joerg       EmitOMPCopy(PrivateExpr->getType(), DestLVal.getAddress(*this),
   5024  1.1.1.2  joerg                   SrcLVal.getAddress(*this),
   5025  1.1.1.2  joerg                   cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
   5026  1.1.1.2  joerg                   cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
   5027  1.1.1.2  joerg                   CopyOps[I]);
   5028  1.1.1.2  joerg     }
   5029  1.1.1.2  joerg     if (!IsInclusive) {
   5030  1.1.1.2  joerg       EmitBlock(ExclusiveExitBB);
   5031  1.1.1.2  joerg     }
   5032  1.1.1.2  joerg   }
   5033  1.1.1.2  joerg   EmitBranch((OMPFirstScanLoop == IsInclusive) ? OMPBeforeScanBlock
   5034  1.1.1.2  joerg                                                : OMPAfterScanBlock);
   5035  1.1.1.2  joerg   EmitBlock(OMPAfterScanBlock);
   5036      1.1  joerg }
   5037      1.1  joerg 
   5038      1.1  joerg void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
   5039      1.1  joerg                                             const CodeGenLoopTy &CodeGenLoop,
   5040      1.1  joerg                                             Expr *IncExpr) {
   5041      1.1  joerg   // Emit the loop iteration variable.
   5042      1.1  joerg   const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
   5043      1.1  joerg   const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
   5044      1.1  joerg   EmitVarDecl(*IVDecl);
   5045      1.1  joerg 
   5046      1.1  joerg   // Emit the iterations count variable.
   5047      1.1  joerg   // If it is not a variable, Sema decided to calculate iterations count on each
   5048      1.1  joerg   // iteration (e.g., it is foldable into a constant).
   5049      1.1  joerg   if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
   5050      1.1  joerg     EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
   5051      1.1  joerg     // Emit calculation of the iterations count.
   5052      1.1  joerg     EmitIgnoredExpr(S.getCalcLastIteration());
   5053      1.1  joerg   }
   5054      1.1  joerg 
   5055      1.1  joerg   CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
   5056      1.1  joerg 
   5057      1.1  joerg   bool HasLastprivateClause = false;
   5058      1.1  joerg   // Check pre-condition.
   5059      1.1  joerg   {
   5060      1.1  joerg     OMPLoopScope PreInitScope(*this, S);
   5061      1.1  joerg     // Skip the entire loop if we don't meet the precondition.
   5062      1.1  joerg     // If the condition constant folds and can be elided, avoid emitting the
   5063      1.1  joerg     // whole loop.
   5064      1.1  joerg     bool CondConstant;
   5065      1.1  joerg     llvm::BasicBlock *ContBlock = nullptr;
   5066      1.1  joerg     if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
   5067      1.1  joerg       if (!CondConstant)
   5068      1.1  joerg         return;
   5069      1.1  joerg     } else {
   5070      1.1  joerg       llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then");
   5071      1.1  joerg       ContBlock = createBasicBlock("omp.precond.end");
   5072      1.1  joerg       emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
   5073      1.1  joerg                   getProfileCount(&S));
   5074      1.1  joerg       EmitBlock(ThenBlock);
   5075      1.1  joerg       incrementProfileCounter(&S);
   5076      1.1  joerg     }
   5077      1.1  joerg 
   5078      1.1  joerg     emitAlignedClause(*this, S);
   5079      1.1  joerg     // Emit 'then' code.
   5080      1.1  joerg     {
   5081      1.1  joerg       // Emit helper vars inits.
   5082      1.1  joerg 
   5083      1.1  joerg       LValue LB = EmitOMPHelperVar(
   5084      1.1  joerg           *this, cast<DeclRefExpr>(
   5085      1.1  joerg                      (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   5086      1.1  joerg                           ? S.getCombinedLowerBoundVariable()
   5087      1.1  joerg                           : S.getLowerBoundVariable())));
   5088      1.1  joerg       LValue UB = EmitOMPHelperVar(
   5089      1.1  joerg           *this, cast<DeclRefExpr>(
   5090      1.1  joerg                      (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   5091      1.1  joerg                           ? S.getCombinedUpperBoundVariable()
   5092      1.1  joerg                           : S.getUpperBoundVariable())));
   5093      1.1  joerg       LValue ST =
   5094      1.1  joerg           EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
   5095      1.1  joerg       LValue IL =
   5096      1.1  joerg           EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
   5097      1.1  joerg 
   5098      1.1  joerg       OMPPrivateScope LoopScope(*this);
   5099      1.1  joerg       if (EmitOMPFirstprivateClause(S, LoopScope)) {
   5100      1.1  joerg         // Emit implicit barrier to synchronize threads and avoid data races
   5101      1.1  joerg         // on initialization of firstprivate variables and post-update of
   5102      1.1  joerg         // lastprivate variables.
   5103      1.1  joerg         CGM.getOpenMPRuntime().emitBarrierCall(
   5104      1.1  joerg             *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
   5105      1.1  joerg             /*ForceSimpleCall=*/true);
   5106      1.1  joerg       }
   5107      1.1  joerg       EmitOMPPrivateClause(S, LoopScope);
   5108      1.1  joerg       if (isOpenMPSimdDirective(S.getDirectiveKind()) &&
   5109      1.1  joerg           !isOpenMPParallelDirective(S.getDirectiveKind()) &&
   5110      1.1  joerg           !isOpenMPTeamsDirective(S.getDirectiveKind()))
   5111      1.1  joerg         EmitOMPReductionClauseInit(S, LoopScope);
   5112      1.1  joerg       HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
   5113      1.1  joerg       EmitOMPPrivateLoopCounters(S, LoopScope);
   5114      1.1  joerg       (void)LoopScope.Privatize();
   5115      1.1  joerg       if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
   5116      1.1  joerg         CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S);
   5117      1.1  joerg 
   5118      1.1  joerg       // Detect the distribute schedule kind and chunk.
   5119      1.1  joerg       llvm::Value *Chunk = nullptr;
   5120      1.1  joerg       OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown;
   5121      1.1  joerg       if (const auto *C = S.getSingleClause<OMPDistScheduleClause>()) {
   5122      1.1  joerg         ScheduleKind = C->getDistScheduleKind();
   5123      1.1  joerg         if (const Expr *Ch = C->getChunkSize()) {
   5124      1.1  joerg           Chunk = EmitScalarExpr(Ch);
   5125      1.1  joerg           Chunk = EmitScalarConversion(Chunk, Ch->getType(),
   5126      1.1  joerg                                        S.getIterationVariable()->getType(),
   5127      1.1  joerg                                        S.getBeginLoc());
   5128      1.1  joerg         }
   5129      1.1  joerg       } else {
   5130      1.1  joerg         // Default behaviour for dist_schedule clause.
   5131      1.1  joerg         CGM.getOpenMPRuntime().getDefaultDistScheduleAndChunk(
   5132      1.1  joerg             *this, S, ScheduleKind, Chunk);
   5133      1.1  joerg       }
   5134      1.1  joerg       const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
   5135      1.1  joerg       const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
   5136      1.1  joerg 
   5137      1.1  joerg       // OpenMP [2.10.8, distribute Construct, Description]
   5138      1.1  joerg       // If dist_schedule is specified, kind must be static. If specified,
   5139      1.1  joerg       // iterations are divided into chunks of size chunk_size, chunks are
   5140      1.1  joerg       // assigned to the teams of the league in a round-robin fashion in the
   5141      1.1  joerg       // order of the team number. When no chunk_size is specified, the
   5142      1.1  joerg       // iteration space is divided into chunks that are approximately equal
   5143      1.1  joerg       // in size, and at most one chunk is distributed to each team of the
   5144      1.1  joerg       // league. The size of the chunks is unspecified in this case.
   5145      1.1  joerg       bool StaticChunked = RT.isStaticChunked(
   5146      1.1  joerg           ScheduleKind, /* Chunked */ Chunk != nullptr) &&
   5147      1.1  joerg           isOpenMPLoopBoundSharingDirective(S.getDirectiveKind());
   5148      1.1  joerg       if (RT.isStaticNonchunked(ScheduleKind,
   5149      1.1  joerg                                 /* Chunked */ Chunk != nullptr) ||
   5150      1.1  joerg           StaticChunked) {
   5151      1.1  joerg         CGOpenMPRuntime::StaticRTInput StaticInit(
   5152  1.1.1.2  joerg             IVSize, IVSigned, /* Ordered = */ false, IL.getAddress(*this),
   5153  1.1.1.2  joerg             LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this),
   5154      1.1  joerg             StaticChunked ? Chunk : nullptr);
   5155      1.1  joerg         RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind,
   5156      1.1  joerg                                     StaticInit);
   5157      1.1  joerg         JumpDest LoopExit =
   5158      1.1  joerg             getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
   5159      1.1  joerg         // UB = min(UB, GlobalUB);
   5160      1.1  joerg         EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   5161      1.1  joerg                             ? S.getCombinedEnsureUpperBound()
   5162      1.1  joerg                             : S.getEnsureUpperBound());
   5163      1.1  joerg         // IV = LB;
   5164      1.1  joerg         EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   5165      1.1  joerg                             ? S.getCombinedInit()
   5166      1.1  joerg                             : S.getInit());
   5167      1.1  joerg 
   5168      1.1  joerg         const Expr *Cond =
   5169      1.1  joerg             isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
   5170      1.1  joerg                 ? S.getCombinedCond()
   5171      1.1  joerg                 : S.getCond();
   5172      1.1  joerg 
   5173      1.1  joerg         if (StaticChunked)
   5174      1.1  joerg           Cond = S.getCombinedDistCond();
   5175      1.1  joerg 
   5176      1.1  joerg         // For static unchunked schedules generate:
   5177      1.1  joerg         //
   5178      1.1  joerg         //  1. For distribute alone, codegen
   5179      1.1  joerg         //    while (idx <= UB) {
   5180      1.1  joerg         //      BODY;
   5181      1.1  joerg         //      ++idx;
   5182      1.1  joerg         //    }
   5183      1.1  joerg         //
   5184      1.1  joerg         //  2. When combined with 'for' (e.g. as in 'distribute parallel for')
   5185      1.1  joerg         //    while (idx <= UB) {
   5186      1.1  joerg         //      <CodeGen rest of pragma>(LB, UB);
   5187      1.1  joerg         //      idx += ST;
   5188      1.1  joerg         //    }
   5189      1.1  joerg         //
   5190      1.1  joerg         // For static chunk one schedule generate:
   5191      1.1  joerg         //
   5192      1.1  joerg         // while (IV <= GlobalUB) {
   5193      1.1  joerg         //   <CodeGen rest of pragma>(LB, UB);
   5194      1.1  joerg         //   LB += ST;
   5195      1.1  joerg         //   UB += ST;
   5196      1.1  joerg         //   UB = min(UB, GlobalUB);
   5197      1.1  joerg         //   IV = LB;
   5198      1.1  joerg         // }
   5199      1.1  joerg         //
   5200  1.1.1.2  joerg         emitCommonSimdLoop(
   5201  1.1.1.2  joerg             *this, S,
   5202  1.1.1.2  joerg             [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   5203  1.1.1.2  joerg               if (isOpenMPSimdDirective(S.getDirectiveKind()))
   5204  1.1.1.2  joerg                 CGF.EmitOMPSimdInit(S, /*IsMonotonic=*/true);
   5205  1.1.1.2  joerg             },
   5206  1.1.1.2  joerg             [&S, &LoopScope, Cond, IncExpr, LoopExit, &CodeGenLoop,
   5207  1.1.1.2  joerg              StaticChunked](CodeGenFunction &CGF, PrePostActionTy &) {
   5208  1.1.1.2  joerg               CGF.EmitOMPInnerLoop(
   5209  1.1.1.2  joerg                   S, LoopScope.requiresCleanups(), Cond, IncExpr,
   5210  1.1.1.2  joerg                   [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
   5211  1.1.1.2  joerg                     CodeGenLoop(CGF, S, LoopExit);
   5212  1.1.1.2  joerg                   },
   5213  1.1.1.2  joerg                   [&S, StaticChunked](CodeGenFunction &CGF) {
   5214  1.1.1.2  joerg                     if (StaticChunked) {
   5215  1.1.1.2  joerg                       CGF.EmitIgnoredExpr(S.getCombinedNextLowerBound());
   5216  1.1.1.2  joerg                       CGF.EmitIgnoredExpr(S.getCombinedNextUpperBound());
   5217  1.1.1.2  joerg                       CGF.EmitIgnoredExpr(S.getCombinedEnsureUpperBound());
   5218  1.1.1.2  joerg                       CGF.EmitIgnoredExpr(S.getCombinedInit());
   5219  1.1.1.2  joerg                     }
   5220  1.1.1.2  joerg                   });
   5221  1.1.1.2  joerg             });
   5222      1.1  joerg         EmitBlock(LoopExit.getBlock());
   5223      1.1  joerg         // Tell the runtime we are done.
   5224  1.1.1.2  joerg         RT.emitForStaticFinish(*this, S.getEndLoc(), S.getDirectiveKind());
   5225      1.1  joerg       } else {
   5226      1.1  joerg         // Emit the outer loop, which requests its work chunk [LB..UB] from
   5227      1.1  joerg         // runtime and runs the inner loop to process it.
   5228      1.1  joerg         const OMPLoopArguments LoopArguments = {
   5229  1.1.1.2  joerg             LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this),
   5230  1.1.1.2  joerg             IL.getAddress(*this), Chunk};
   5231      1.1  joerg         EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,
   5232      1.1  joerg                                    CodeGenLoop);
   5233      1.1  joerg       }
   5234      1.1  joerg       if (isOpenMPSimdDirective(S.getDirectiveKind())) {
   5235      1.1  joerg         EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) {
   5236      1.1  joerg           return CGF.Builder.CreateIsNotNull(
   5237      1.1  joerg               CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
   5238      1.1  joerg         });
   5239      1.1  joerg       }
   5240      1.1  joerg       if (isOpenMPSimdDirective(S.getDirectiveKind()) &&
   5241      1.1  joerg           !isOpenMPParallelDirective(S.getDirectiveKind()) &&
   5242      1.1  joerg           !isOpenMPTeamsDirective(S.getDirectiveKind())) {
   5243      1.1  joerg         EmitOMPReductionClauseFinal(S, OMPD_simd);
   5244      1.1  joerg         // Emit post-update of the reduction variables if IsLastIter != 0.
   5245      1.1  joerg         emitPostUpdateForReductionClause(
   5246      1.1  joerg             *this, S, [IL, &S](CodeGenFunction &CGF) {
   5247      1.1  joerg               return CGF.Builder.CreateIsNotNull(
   5248      1.1  joerg                   CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
   5249      1.1  joerg             });
   5250      1.1  joerg       }
   5251      1.1  joerg       // Emit final copy of the lastprivate variables if IsLastIter != 0.
   5252      1.1  joerg       if (HasLastprivateClause) {
   5253      1.1  joerg         EmitOMPLastprivateClauseFinal(
   5254      1.1  joerg             S, /*NoFinals=*/false,
   5255      1.1  joerg             Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc())));
   5256      1.1  joerg       }
   5257      1.1  joerg     }
   5258      1.1  joerg 
   5259      1.1  joerg     // We're now done with the loop, so jump to the continuation block.
   5260      1.1  joerg     if (ContBlock) {
   5261      1.1  joerg       EmitBranch(ContBlock);
   5262      1.1  joerg       EmitBlock(ContBlock, true);
   5263      1.1  joerg     }
   5264      1.1  joerg   }
   5265      1.1  joerg }
   5266      1.1  joerg 
   5267      1.1  joerg void CodeGenFunction::EmitOMPDistributeDirective(
   5268      1.1  joerg     const OMPDistributeDirective &S) {
   5269      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   5270      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
   5271      1.1  joerg   };
   5272      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_unknown);
   5273      1.1  joerg   CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
   5274      1.1  joerg }
   5275      1.1  joerg 
   5276      1.1  joerg static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
   5277  1.1.1.2  joerg                                                    const CapturedStmt *S,
   5278  1.1.1.2  joerg                                                    SourceLocation Loc) {
   5279      1.1  joerg   CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
   5280      1.1  joerg   CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
   5281      1.1  joerg   CGF.CapturedStmtInfo = &CapStmtInfo;
   5282  1.1.1.2  joerg   llvm::Function *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S, Loc);
   5283      1.1  joerg   Fn->setDoesNotRecurse();
   5284      1.1  joerg   return Fn;
   5285      1.1  joerg }
   5286      1.1  joerg 
   5287      1.1  joerg void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
   5288      1.1  joerg   if (S.hasClausesOfKind<OMPDependClause>()) {
   5289  1.1.1.2  joerg     assert(!S.hasAssociatedStmt() &&
   5290      1.1  joerg            "No associated statement must be in ordered depend construct.");
   5291      1.1  joerg     for (const auto *DC : S.getClausesOfKind<OMPDependClause>())
   5292      1.1  joerg       CGM.getOpenMPRuntime().emitDoacrossOrdered(*this, DC);
   5293      1.1  joerg     return;
   5294      1.1  joerg   }
   5295      1.1  joerg   const auto *C = S.getSingleClause<OMPSIMDClause>();
   5296      1.1  joerg   auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF,
   5297      1.1  joerg                                  PrePostActionTy &Action) {
   5298      1.1  joerg     const CapturedStmt *CS = S.getInnermostCapturedStmt();
   5299      1.1  joerg     if (C) {
   5300      1.1  joerg       llvm::SmallVector<llvm::Value *, 16> CapturedVars;
   5301      1.1  joerg       CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
   5302  1.1.1.2  joerg       llvm::Function *OutlinedFn =
   5303  1.1.1.2  joerg           emitOutlinedOrderedFunction(CGM, CS, S.getBeginLoc());
   5304      1.1  joerg       CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(),
   5305      1.1  joerg                                                       OutlinedFn, CapturedVars);
   5306      1.1  joerg     } else {
   5307      1.1  joerg       Action.Enter(CGF);
   5308      1.1  joerg       CGF.EmitStmt(CS->getCapturedStmt());
   5309      1.1  joerg     }
   5310      1.1  joerg   };
   5311      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_unknown);
   5312      1.1  joerg   CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getBeginLoc(), !C);
   5313      1.1  joerg }
   5314      1.1  joerg 
   5315      1.1  joerg static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
   5316      1.1  joerg                                          QualType SrcType, QualType DestType,
   5317      1.1  joerg                                          SourceLocation Loc) {
   5318      1.1  joerg   assert(CGF.hasScalarEvaluationKind(DestType) &&
   5319      1.1  joerg          "DestType must have scalar evaluation kind.");
   5320      1.1  joerg   assert(!Val.isAggregate() && "Must be a scalar or complex.");
   5321      1.1  joerg   return Val.isScalar() ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType,
   5322      1.1  joerg                                                    DestType, Loc)
   5323      1.1  joerg                         : CGF.EmitComplexToScalarConversion(
   5324      1.1  joerg                               Val.getComplexVal(), SrcType, DestType, Loc);
   5325      1.1  joerg }
   5326      1.1  joerg 
   5327      1.1  joerg static CodeGenFunction::ComplexPairTy
   5328      1.1  joerg convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
   5329      1.1  joerg                       QualType DestType, SourceLocation Loc) {
   5330      1.1  joerg   assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
   5331      1.1  joerg          "DestType must have complex evaluation kind.");
   5332      1.1  joerg   CodeGenFunction::ComplexPairTy ComplexVal;
   5333      1.1  joerg   if (Val.isScalar()) {
   5334      1.1  joerg     // Convert the input element to the element type of the complex.
   5335      1.1  joerg     QualType DestElementType =
   5336      1.1  joerg         DestType->castAs<ComplexType>()->getElementType();
   5337      1.1  joerg     llvm::Value *ScalarVal = CGF.EmitScalarConversion(
   5338      1.1  joerg         Val.getScalarVal(), SrcType, DestElementType, Loc);
   5339      1.1  joerg     ComplexVal = CodeGenFunction::ComplexPairTy(
   5340      1.1  joerg         ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
   5341      1.1  joerg   } else {
   5342      1.1  joerg     assert(Val.isComplex() && "Must be a scalar or complex.");
   5343      1.1  joerg     QualType SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
   5344      1.1  joerg     QualType DestElementType =
   5345      1.1  joerg         DestType->castAs<ComplexType>()->getElementType();
   5346      1.1  joerg     ComplexVal.first = CGF.EmitScalarConversion(
   5347      1.1  joerg         Val.getComplexVal().first, SrcElementType, DestElementType, Loc);
   5348      1.1  joerg     ComplexVal.second = CGF.EmitScalarConversion(
   5349      1.1  joerg         Val.getComplexVal().second, SrcElementType, DestElementType, Loc);
   5350      1.1  joerg   }
   5351      1.1  joerg   return ComplexVal;
   5352      1.1  joerg }
   5353      1.1  joerg 
   5354  1.1.1.2  joerg static void emitSimpleAtomicStore(CodeGenFunction &CGF, llvm::AtomicOrdering AO,
   5355      1.1  joerg                                   LValue LVal, RValue RVal) {
   5356  1.1.1.2  joerg   if (LVal.isGlobalReg())
   5357      1.1  joerg     CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal);
   5358  1.1.1.2  joerg   else
   5359  1.1.1.2  joerg     CGF.EmitAtomicStore(RVal, LVal, AO, LVal.isVolatile(), /*isInit=*/false);
   5360  1.1.1.2  joerg }
   5361  1.1.1.2  joerg 
   5362  1.1.1.2  joerg static RValue emitSimpleAtomicLoad(CodeGenFunction &CGF,
   5363  1.1.1.2  joerg                                    llvm::AtomicOrdering AO, LValue LVal,
   5364  1.1.1.2  joerg                                    SourceLocation Loc) {
   5365  1.1.1.2  joerg   if (LVal.isGlobalReg())
   5366  1.1.1.2  joerg     return CGF.EmitLoadOfLValue(LVal, Loc);
   5367  1.1.1.2  joerg   return CGF.EmitAtomicLoad(
   5368  1.1.1.2  joerg       LVal, Loc, llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO),
   5369  1.1.1.2  joerg       LVal.isVolatile());
   5370      1.1  joerg }
   5371      1.1  joerg 
   5372      1.1  joerg void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal,
   5373      1.1  joerg                                          QualType RValTy, SourceLocation Loc) {
   5374      1.1  joerg   switch (getEvaluationKind(LVal.getType())) {
   5375      1.1  joerg   case TEK_Scalar:
   5376      1.1  joerg     EmitStoreThroughLValue(RValue::get(convertToScalarValue(
   5377      1.1  joerg                                *this, RVal, RValTy, LVal.getType(), Loc)),
   5378      1.1  joerg                            LVal);
   5379      1.1  joerg     break;
   5380      1.1  joerg   case TEK_Complex:
   5381      1.1  joerg     EmitStoreOfComplex(
   5382      1.1  joerg         convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal,
   5383      1.1  joerg         /*isInit=*/false);
   5384      1.1  joerg     break;
   5385      1.1  joerg   case TEK_Aggregate:
   5386      1.1  joerg     llvm_unreachable("Must be a scalar or complex.");
   5387      1.1  joerg   }
   5388      1.1  joerg }
   5389      1.1  joerg 
   5390  1.1.1.2  joerg static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO,
   5391      1.1  joerg                                   const Expr *X, const Expr *V,
   5392      1.1  joerg                                   SourceLocation Loc) {
   5393      1.1  joerg   // v = x;
   5394      1.1  joerg   assert(V->isLValue() && "V of 'omp atomic read' is not lvalue");
   5395      1.1  joerg   assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");
   5396      1.1  joerg   LValue XLValue = CGF.EmitLValue(X);
   5397      1.1  joerg   LValue VLValue = CGF.EmitLValue(V);
   5398  1.1.1.2  joerg   RValue Res = emitSimpleAtomicLoad(CGF, AO, XLValue, Loc);
   5399  1.1.1.2  joerg   // OpenMP, 2.17.7, atomic Construct
   5400  1.1.1.2  joerg   // If the read or capture clause is specified and the acquire, acq_rel, or
   5401  1.1.1.2  joerg   // seq_cst clause is specified then the strong flush on exit from the atomic
   5402  1.1.1.2  joerg   // operation is also an acquire flush.
   5403  1.1.1.2  joerg   switch (AO) {
   5404  1.1.1.2  joerg   case llvm::AtomicOrdering::Acquire:
   5405  1.1.1.2  joerg   case llvm::AtomicOrdering::AcquireRelease:
   5406  1.1.1.2  joerg   case llvm::AtomicOrdering::SequentiallyConsistent:
   5407  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
   5408  1.1.1.2  joerg                                          llvm::AtomicOrdering::Acquire);
   5409  1.1.1.2  joerg     break;
   5410  1.1.1.2  joerg   case llvm::AtomicOrdering::Monotonic:
   5411  1.1.1.2  joerg   case llvm::AtomicOrdering::Release:
   5412  1.1.1.2  joerg     break;
   5413  1.1.1.2  joerg   case llvm::AtomicOrdering::NotAtomic:
   5414  1.1.1.2  joerg   case llvm::AtomicOrdering::Unordered:
   5415  1.1.1.2  joerg     llvm_unreachable("Unexpected ordering.");
   5416  1.1.1.2  joerg   }
   5417      1.1  joerg   CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc);
   5418  1.1.1.2  joerg   CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V);
   5419      1.1  joerg }
   5420      1.1  joerg 
   5421  1.1.1.2  joerg static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF,
   5422  1.1.1.2  joerg                                    llvm::AtomicOrdering AO, const Expr *X,
   5423  1.1.1.2  joerg                                    const Expr *E, SourceLocation Loc) {
   5424      1.1  joerg   // x = expr;
   5425      1.1  joerg   assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
   5426  1.1.1.2  joerg   emitSimpleAtomicStore(CGF, AO, CGF.EmitLValue(X), CGF.EmitAnyExpr(E));
   5427  1.1.1.2  joerg   CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
   5428  1.1.1.2  joerg   // OpenMP, 2.17.7, atomic Construct
   5429  1.1.1.2  joerg   // If the write, update, or capture clause is specified and the release,
   5430  1.1.1.2  joerg   // acq_rel, or seq_cst clause is specified then the strong flush on entry to
   5431  1.1.1.2  joerg   // the atomic operation is also a release flush.
   5432  1.1.1.2  joerg   switch (AO) {
   5433  1.1.1.2  joerg   case llvm::AtomicOrdering::Release:
   5434  1.1.1.2  joerg   case llvm::AtomicOrdering::AcquireRelease:
   5435  1.1.1.2  joerg   case llvm::AtomicOrdering::SequentiallyConsistent:
   5436  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
   5437  1.1.1.2  joerg                                          llvm::AtomicOrdering::Release);
   5438  1.1.1.2  joerg     break;
   5439  1.1.1.2  joerg   case llvm::AtomicOrdering::Acquire:
   5440  1.1.1.2  joerg   case llvm::AtomicOrdering::Monotonic:
   5441  1.1.1.2  joerg     break;
   5442  1.1.1.2  joerg   case llvm::AtomicOrdering::NotAtomic:
   5443  1.1.1.2  joerg   case llvm::AtomicOrdering::Unordered:
   5444  1.1.1.2  joerg     llvm_unreachable("Unexpected ordering.");
   5445  1.1.1.2  joerg   }
   5446      1.1  joerg }
   5447      1.1  joerg 
   5448      1.1  joerg static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
   5449      1.1  joerg                                                 RValue Update,
   5450      1.1  joerg                                                 BinaryOperatorKind BO,
   5451      1.1  joerg                                                 llvm::AtomicOrdering AO,
   5452      1.1  joerg                                                 bool IsXLHSInRHSPart) {
   5453      1.1  joerg   ASTContext &Context = CGF.getContext();
   5454      1.1  joerg   // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x'
   5455      1.1  joerg   // expression is simple and atomic is allowed for the given type for the
   5456      1.1  joerg   // target platform.
   5457      1.1  joerg   if (BO == BO_Comma || !Update.isScalar() ||
   5458  1.1.1.2  joerg       !Update.getScalarVal()->getType()->isIntegerTy() || !X.isSimple() ||
   5459  1.1.1.2  joerg       (!isa<llvm::ConstantInt>(Update.getScalarVal()) &&
   5460  1.1.1.2  joerg        (Update.getScalarVal()->getType() !=
   5461  1.1.1.2  joerg         X.getAddress(CGF).getElementType())) ||
   5462  1.1.1.2  joerg       !X.getAddress(CGF).getElementType()->isIntegerTy() ||
   5463      1.1  joerg       !Context.getTargetInfo().hasBuiltinAtomic(
   5464      1.1  joerg           Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment())))
   5465      1.1  joerg     return std::make_pair(false, RValue::get(nullptr));
   5466      1.1  joerg 
   5467      1.1  joerg   llvm::AtomicRMWInst::BinOp RMWOp;
   5468      1.1  joerg   switch (BO) {
   5469      1.1  joerg   case BO_Add:
   5470      1.1  joerg     RMWOp = llvm::AtomicRMWInst::Add;
   5471      1.1  joerg     break;
   5472      1.1  joerg   case BO_Sub:
   5473      1.1  joerg     if (!IsXLHSInRHSPart)
   5474      1.1  joerg       return std::make_pair(false, RValue::get(nullptr));
   5475      1.1  joerg     RMWOp = llvm::AtomicRMWInst::Sub;
   5476      1.1  joerg     break;
   5477      1.1  joerg   case BO_And:
   5478      1.1  joerg     RMWOp = llvm::AtomicRMWInst::And;
   5479      1.1  joerg     break;
   5480      1.1  joerg   case BO_Or:
   5481      1.1  joerg     RMWOp = llvm::AtomicRMWInst::Or;
   5482      1.1  joerg     break;
   5483      1.1  joerg   case BO_Xor:
   5484      1.1  joerg     RMWOp = llvm::AtomicRMWInst::Xor;
   5485      1.1  joerg     break;
   5486      1.1  joerg   case BO_LT:
   5487      1.1  joerg     RMWOp = X.getType()->hasSignedIntegerRepresentation()
   5488      1.1  joerg                 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
   5489      1.1  joerg                                    : llvm::AtomicRMWInst::Max)
   5490      1.1  joerg                 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
   5491      1.1  joerg                                    : llvm::AtomicRMWInst::UMax);
   5492      1.1  joerg     break;
   5493      1.1  joerg   case BO_GT:
   5494      1.1  joerg     RMWOp = X.getType()->hasSignedIntegerRepresentation()
   5495      1.1  joerg                 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
   5496      1.1  joerg                                    : llvm::AtomicRMWInst::Min)
   5497      1.1  joerg                 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
   5498      1.1  joerg                                    : llvm::AtomicRMWInst::UMin);
   5499      1.1  joerg     break;
   5500      1.1  joerg   case BO_Assign:
   5501      1.1  joerg     RMWOp = llvm::AtomicRMWInst::Xchg;
   5502      1.1  joerg     break;
   5503      1.1  joerg   case BO_Mul:
   5504      1.1  joerg   case BO_Div:
   5505      1.1  joerg   case BO_Rem:
   5506      1.1  joerg   case BO_Shl:
   5507      1.1  joerg   case BO_Shr:
   5508      1.1  joerg   case BO_LAnd:
   5509      1.1  joerg   case BO_LOr:
   5510      1.1  joerg     return std::make_pair(false, RValue::get(nullptr));
   5511      1.1  joerg   case BO_PtrMemD:
   5512      1.1  joerg   case BO_PtrMemI:
   5513      1.1  joerg   case BO_LE:
   5514      1.1  joerg   case BO_GE:
   5515      1.1  joerg   case BO_EQ:
   5516      1.1  joerg   case BO_NE:
   5517      1.1  joerg   case BO_Cmp:
   5518      1.1  joerg   case BO_AddAssign:
   5519      1.1  joerg   case BO_SubAssign:
   5520      1.1  joerg   case BO_AndAssign:
   5521      1.1  joerg   case BO_OrAssign:
   5522      1.1  joerg   case BO_XorAssign:
   5523      1.1  joerg   case BO_MulAssign:
   5524      1.1  joerg   case BO_DivAssign:
   5525      1.1  joerg   case BO_RemAssign:
   5526      1.1  joerg   case BO_ShlAssign:
   5527      1.1  joerg   case BO_ShrAssign:
   5528      1.1  joerg   case BO_Comma:
   5529      1.1  joerg     llvm_unreachable("Unsupported atomic update operation");
   5530      1.1  joerg   }
   5531      1.1  joerg   llvm::Value *UpdateVal = Update.getScalarVal();
   5532      1.1  joerg   if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
   5533      1.1  joerg     UpdateVal = CGF.Builder.CreateIntCast(
   5534  1.1.1.2  joerg         IC, X.getAddress(CGF).getElementType(),
   5535      1.1  joerg         X.getType()->hasSignedIntegerRepresentation());
   5536      1.1  joerg   }
   5537      1.1  joerg   llvm::Value *Res =
   5538  1.1.1.2  joerg       CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(CGF), UpdateVal, AO);
   5539      1.1  joerg   return std::make_pair(true, RValue::get(Res));
   5540      1.1  joerg }
   5541      1.1  joerg 
   5542      1.1  joerg std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr(
   5543      1.1  joerg     LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
   5544      1.1  joerg     llvm::AtomicOrdering AO, SourceLocation Loc,
   5545      1.1  joerg     const llvm::function_ref<RValue(RValue)> CommonGen) {
   5546      1.1  joerg   // Update expressions are allowed to have the following forms:
   5547      1.1  joerg   // x binop= expr; -> xrval + expr;
   5548      1.1  joerg   // x++, ++x -> xrval + 1;
   5549      1.1  joerg   // x--, --x -> xrval - 1;
   5550      1.1  joerg   // x = x binop expr; -> xrval binop expr
   5551      1.1  joerg   // x = expr Op x; - > expr binop xrval;
   5552      1.1  joerg   auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart);
   5553      1.1  joerg   if (!Res.first) {
   5554      1.1  joerg     if (X.isGlobalReg()) {
   5555      1.1  joerg       // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop
   5556      1.1  joerg       // 'xrval'.
   5557      1.1  joerg       EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X);
   5558      1.1  joerg     } else {
   5559      1.1  joerg       // Perform compare-and-swap procedure.
   5560      1.1  joerg       EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified());
   5561      1.1  joerg     }
   5562      1.1  joerg   }
   5563      1.1  joerg   return Res;
   5564      1.1  joerg }
   5565      1.1  joerg 
   5566  1.1.1.2  joerg static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF,
   5567  1.1.1.2  joerg                                     llvm::AtomicOrdering AO, const Expr *X,
   5568  1.1.1.2  joerg                                     const Expr *E, const Expr *UE,
   5569  1.1.1.2  joerg                                     bool IsXLHSInRHSPart, SourceLocation Loc) {
   5570      1.1  joerg   assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
   5571      1.1  joerg          "Update expr in 'atomic update' must be a binary operator.");
   5572      1.1  joerg   const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
   5573      1.1  joerg   // Update expressions are allowed to have the following forms:
   5574      1.1  joerg   // x binop= expr; -> xrval + expr;
   5575      1.1  joerg   // x++, ++x -> xrval + 1;
   5576      1.1  joerg   // x--, --x -> xrval - 1;
   5577      1.1  joerg   // x = x binop expr; -> xrval binop expr
   5578      1.1  joerg   // x = expr Op x; - > expr binop xrval;
   5579      1.1  joerg   assert(X->isLValue() && "X of 'omp atomic update' is not lvalue");
   5580      1.1  joerg   LValue XLValue = CGF.EmitLValue(X);
   5581      1.1  joerg   RValue ExprRValue = CGF.EmitAnyExpr(E);
   5582      1.1  joerg   const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
   5583      1.1  joerg   const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
   5584      1.1  joerg   const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
   5585      1.1  joerg   const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
   5586      1.1  joerg   auto &&Gen = [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) {
   5587      1.1  joerg     CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
   5588      1.1  joerg     CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
   5589      1.1  joerg     return CGF.EmitAnyExpr(UE);
   5590      1.1  joerg   };
   5591      1.1  joerg   (void)CGF.EmitOMPAtomicSimpleUpdateExpr(
   5592      1.1  joerg       XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
   5593  1.1.1.2  joerg   CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
   5594  1.1.1.2  joerg   // OpenMP, 2.17.7, atomic Construct
   5595  1.1.1.2  joerg   // If the write, update, or capture clause is specified and the release,
   5596  1.1.1.2  joerg   // acq_rel, or seq_cst clause is specified then the strong flush on entry to
   5597  1.1.1.2  joerg   // the atomic operation is also a release flush.
   5598  1.1.1.2  joerg   switch (AO) {
   5599  1.1.1.2  joerg   case llvm::AtomicOrdering::Release:
   5600  1.1.1.2  joerg   case llvm::AtomicOrdering::AcquireRelease:
   5601  1.1.1.2  joerg   case llvm::AtomicOrdering::SequentiallyConsistent:
   5602  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
   5603  1.1.1.2  joerg                                          llvm::AtomicOrdering::Release);
   5604  1.1.1.2  joerg     break;
   5605  1.1.1.2  joerg   case llvm::AtomicOrdering::Acquire:
   5606  1.1.1.2  joerg   case llvm::AtomicOrdering::Monotonic:
   5607  1.1.1.2  joerg     break;
   5608  1.1.1.2  joerg   case llvm::AtomicOrdering::NotAtomic:
   5609  1.1.1.2  joerg   case llvm::AtomicOrdering::Unordered:
   5610  1.1.1.2  joerg     llvm_unreachable("Unexpected ordering.");
   5611  1.1.1.2  joerg   }
   5612      1.1  joerg }
   5613      1.1  joerg 
   5614      1.1  joerg static RValue convertToType(CodeGenFunction &CGF, RValue Value,
   5615      1.1  joerg                             QualType SourceType, QualType ResType,
   5616      1.1  joerg                             SourceLocation Loc) {
   5617      1.1  joerg   switch (CGF.getEvaluationKind(ResType)) {
   5618      1.1  joerg   case TEK_Scalar:
   5619      1.1  joerg     return RValue::get(
   5620      1.1  joerg         convertToScalarValue(CGF, Value, SourceType, ResType, Loc));
   5621      1.1  joerg   case TEK_Complex: {
   5622      1.1  joerg     auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc);
   5623      1.1  joerg     return RValue::getComplex(Res.first, Res.second);
   5624      1.1  joerg   }
   5625      1.1  joerg   case TEK_Aggregate:
   5626      1.1  joerg     break;
   5627      1.1  joerg   }
   5628      1.1  joerg   llvm_unreachable("Must be a scalar or complex.");
   5629      1.1  joerg }
   5630      1.1  joerg 
   5631  1.1.1.2  joerg static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF,
   5632  1.1.1.2  joerg                                      llvm::AtomicOrdering AO,
   5633      1.1  joerg                                      bool IsPostfixUpdate, const Expr *V,
   5634      1.1  joerg                                      const Expr *X, const Expr *E,
   5635      1.1  joerg                                      const Expr *UE, bool IsXLHSInRHSPart,
   5636      1.1  joerg                                      SourceLocation Loc) {
   5637      1.1  joerg   assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue");
   5638      1.1  joerg   assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue");
   5639      1.1  joerg   RValue NewVVal;
   5640      1.1  joerg   LValue VLValue = CGF.EmitLValue(V);
   5641      1.1  joerg   LValue XLValue = CGF.EmitLValue(X);
   5642      1.1  joerg   RValue ExprRValue = CGF.EmitAnyExpr(E);
   5643      1.1  joerg   QualType NewVValType;
   5644      1.1  joerg   if (UE) {
   5645      1.1  joerg     // 'x' is updated with some additional value.
   5646      1.1  joerg     assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
   5647      1.1  joerg            "Update expr in 'atomic capture' must be a binary operator.");
   5648      1.1  joerg     const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
   5649      1.1  joerg     // Update expressions are allowed to have the following forms:
   5650      1.1  joerg     // x binop= expr; -> xrval + expr;
   5651      1.1  joerg     // x++, ++x -> xrval + 1;
   5652      1.1  joerg     // x--, --x -> xrval - 1;
   5653      1.1  joerg     // x = x binop expr; -> xrval binop expr
   5654      1.1  joerg     // x = expr Op x; - > expr binop xrval;
   5655      1.1  joerg     const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
   5656      1.1  joerg     const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
   5657      1.1  joerg     const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
   5658      1.1  joerg     NewVValType = XRValExpr->getType();
   5659      1.1  joerg     const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
   5660      1.1  joerg     auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
   5661      1.1  joerg                   IsPostfixUpdate](RValue XRValue) {
   5662      1.1  joerg       CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
   5663      1.1  joerg       CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
   5664      1.1  joerg       RValue Res = CGF.EmitAnyExpr(UE);
   5665      1.1  joerg       NewVVal = IsPostfixUpdate ? XRValue : Res;
   5666      1.1  joerg       return Res;
   5667      1.1  joerg     };
   5668      1.1  joerg     auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
   5669      1.1  joerg         XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
   5670  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
   5671      1.1  joerg     if (Res.first) {
   5672      1.1  joerg       // 'atomicrmw' instruction was generated.
   5673      1.1  joerg       if (IsPostfixUpdate) {
   5674      1.1  joerg         // Use old value from 'atomicrmw'.
   5675      1.1  joerg         NewVVal = Res.second;
   5676      1.1  joerg       } else {
   5677      1.1  joerg         // 'atomicrmw' does not provide new value, so evaluate it using old
   5678      1.1  joerg         // value of 'x'.
   5679      1.1  joerg         CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
   5680      1.1  joerg         CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second);
   5681      1.1  joerg         NewVVal = CGF.EmitAnyExpr(UE);
   5682      1.1  joerg       }
   5683      1.1  joerg     }
   5684      1.1  joerg   } else {
   5685      1.1  joerg     // 'x' is simply rewritten with some 'expr'.
   5686      1.1  joerg     NewVValType = X->getType().getNonReferenceType();
   5687      1.1  joerg     ExprRValue = convertToType(CGF, ExprRValue, E->getType(),
   5688      1.1  joerg                                X->getType().getNonReferenceType(), Loc);
   5689      1.1  joerg     auto &&Gen = [&NewVVal, ExprRValue](RValue XRValue) {
   5690      1.1  joerg       NewVVal = XRValue;
   5691      1.1  joerg       return ExprRValue;
   5692      1.1  joerg     };
   5693      1.1  joerg     // Try to perform atomicrmw xchg, otherwise simple exchange.
   5694      1.1  joerg     auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
   5695      1.1  joerg         XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO,
   5696      1.1  joerg         Loc, Gen);
   5697  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
   5698      1.1  joerg     if (Res.first) {
   5699      1.1  joerg       // 'atomicrmw' instruction was generated.
   5700      1.1  joerg       NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
   5701      1.1  joerg     }
   5702      1.1  joerg   }
   5703      1.1  joerg   // Emit post-update store to 'v' of old/new 'x' value.
   5704      1.1  joerg   CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc);
   5705  1.1.1.2  joerg   CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V);
   5706  1.1.1.2  joerg   // OpenMP, 2.17.7, atomic Construct
   5707  1.1.1.2  joerg   // If the write, update, or capture clause is specified and the release,
   5708  1.1.1.2  joerg   // acq_rel, or seq_cst clause is specified then the strong flush on entry to
   5709  1.1.1.2  joerg   // the atomic operation is also a release flush.
   5710  1.1.1.2  joerg   // If the read or capture clause is specified and the acquire, acq_rel, or
   5711  1.1.1.2  joerg   // seq_cst clause is specified then the strong flush on exit from the atomic
   5712  1.1.1.2  joerg   // operation is also an acquire flush.
   5713  1.1.1.2  joerg   switch (AO) {
   5714  1.1.1.2  joerg   case llvm::AtomicOrdering::Release:
   5715  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
   5716  1.1.1.2  joerg                                          llvm::AtomicOrdering::Release);
   5717  1.1.1.2  joerg     break;
   5718  1.1.1.2  joerg   case llvm::AtomicOrdering::Acquire:
   5719  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
   5720  1.1.1.2  joerg                                          llvm::AtomicOrdering::Acquire);
   5721  1.1.1.2  joerg     break;
   5722  1.1.1.2  joerg   case llvm::AtomicOrdering::AcquireRelease:
   5723  1.1.1.2  joerg   case llvm::AtomicOrdering::SequentiallyConsistent:
   5724  1.1.1.2  joerg     CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
   5725  1.1.1.2  joerg                                          llvm::AtomicOrdering::AcquireRelease);
   5726  1.1.1.2  joerg     break;
   5727  1.1.1.2  joerg   case llvm::AtomicOrdering::Monotonic:
   5728  1.1.1.2  joerg     break;
   5729  1.1.1.2  joerg   case llvm::AtomicOrdering::NotAtomic:
   5730  1.1.1.2  joerg   case llvm::AtomicOrdering::Unordered:
   5731  1.1.1.2  joerg     llvm_unreachable("Unexpected ordering.");
   5732  1.1.1.2  joerg   }
   5733      1.1  joerg }
   5734      1.1  joerg 
   5735      1.1  joerg static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
   5736  1.1.1.2  joerg                               llvm::AtomicOrdering AO, bool IsPostfixUpdate,
   5737      1.1  joerg                               const Expr *X, const Expr *V, const Expr *E,
   5738      1.1  joerg                               const Expr *UE, bool IsXLHSInRHSPart,
   5739      1.1  joerg                               SourceLocation Loc) {
   5740      1.1  joerg   switch (Kind) {
   5741      1.1  joerg   case OMPC_read:
   5742  1.1.1.2  joerg     emitOMPAtomicReadExpr(CGF, AO, X, V, Loc);
   5743      1.1  joerg     break;
   5744      1.1  joerg   case OMPC_write:
   5745  1.1.1.2  joerg     emitOMPAtomicWriteExpr(CGF, AO, X, E, Loc);
   5746      1.1  joerg     break;
   5747      1.1  joerg   case OMPC_unknown:
   5748      1.1  joerg   case OMPC_update:
   5749  1.1.1.2  joerg     emitOMPAtomicUpdateExpr(CGF, AO, X, E, UE, IsXLHSInRHSPart, Loc);
   5750      1.1  joerg     break;
   5751      1.1  joerg   case OMPC_capture:
   5752  1.1.1.2  joerg     emitOMPAtomicCaptureExpr(CGF, AO, IsPostfixUpdate, V, X, E, UE,
   5753      1.1  joerg                              IsXLHSInRHSPart, Loc);
   5754      1.1  joerg     break;
   5755      1.1  joerg   case OMPC_if:
   5756      1.1  joerg   case OMPC_final:
   5757      1.1  joerg   case OMPC_num_threads:
   5758      1.1  joerg   case OMPC_private:
   5759      1.1  joerg   case OMPC_firstprivate:
   5760      1.1  joerg   case OMPC_lastprivate:
   5761      1.1  joerg   case OMPC_reduction:
   5762      1.1  joerg   case OMPC_task_reduction:
   5763      1.1  joerg   case OMPC_in_reduction:
   5764      1.1  joerg   case OMPC_safelen:
   5765      1.1  joerg   case OMPC_simdlen:
   5766  1.1.1.2  joerg   case OMPC_sizes:
   5767      1.1  joerg   case OMPC_allocator:
   5768      1.1  joerg   case OMPC_allocate:
   5769      1.1  joerg   case OMPC_collapse:
   5770      1.1  joerg   case OMPC_default:
   5771      1.1  joerg   case OMPC_seq_cst:
   5772  1.1.1.2  joerg   case OMPC_acq_rel:
   5773  1.1.1.2  joerg   case OMPC_acquire:
   5774  1.1.1.2  joerg   case OMPC_release:
   5775  1.1.1.2  joerg   case OMPC_relaxed:
   5776      1.1  joerg   case OMPC_shared:
   5777      1.1  joerg   case OMPC_linear:
   5778      1.1  joerg   case OMPC_aligned:
   5779      1.1  joerg   case OMPC_copyin:
   5780      1.1  joerg   case OMPC_copyprivate:
   5781      1.1  joerg   case OMPC_flush:
   5782  1.1.1.2  joerg   case OMPC_depobj:
   5783      1.1  joerg   case OMPC_proc_bind:
   5784      1.1  joerg   case OMPC_schedule:
   5785      1.1  joerg   case OMPC_ordered:
   5786      1.1  joerg   case OMPC_nowait:
   5787      1.1  joerg   case OMPC_untied:
   5788      1.1  joerg   case OMPC_threadprivate:
   5789      1.1  joerg   case OMPC_depend:
   5790      1.1  joerg   case OMPC_mergeable:
   5791      1.1  joerg   case OMPC_device:
   5792      1.1  joerg   case OMPC_threads:
   5793      1.1  joerg   case OMPC_simd:
   5794      1.1  joerg   case OMPC_map:
   5795      1.1  joerg   case OMPC_num_teams:
   5796      1.1  joerg   case OMPC_thread_limit:
   5797      1.1  joerg   case OMPC_priority:
   5798      1.1  joerg   case OMPC_grainsize:
   5799      1.1  joerg   case OMPC_nogroup:
   5800      1.1  joerg   case OMPC_num_tasks:
   5801      1.1  joerg   case OMPC_hint:
   5802      1.1  joerg   case OMPC_dist_schedule:
   5803      1.1  joerg   case OMPC_defaultmap:
   5804      1.1  joerg   case OMPC_uniform:
   5805      1.1  joerg   case OMPC_to:
   5806      1.1  joerg   case OMPC_from:
   5807      1.1  joerg   case OMPC_use_device_ptr:
   5808  1.1.1.2  joerg   case OMPC_use_device_addr:
   5809      1.1  joerg   case OMPC_is_device_ptr:
   5810      1.1  joerg   case OMPC_unified_address:
   5811      1.1  joerg   case OMPC_unified_shared_memory:
   5812      1.1  joerg   case OMPC_reverse_offload:
   5813      1.1  joerg   case OMPC_dynamic_allocators:
   5814      1.1  joerg   case OMPC_atomic_default_mem_order:
   5815      1.1  joerg   case OMPC_device_type:
   5816      1.1  joerg   case OMPC_match:
   5817  1.1.1.2  joerg   case OMPC_nontemporal:
   5818  1.1.1.2  joerg   case OMPC_order:
   5819  1.1.1.2  joerg   case OMPC_destroy:
   5820  1.1.1.2  joerg   case OMPC_detach:
   5821  1.1.1.2  joerg   case OMPC_inclusive:
   5822  1.1.1.2  joerg   case OMPC_exclusive:
   5823  1.1.1.2  joerg   case OMPC_uses_allocators:
   5824  1.1.1.2  joerg   case OMPC_affinity:
   5825  1.1.1.2  joerg   case OMPC_init:
   5826  1.1.1.2  joerg   case OMPC_inbranch:
   5827  1.1.1.2  joerg   case OMPC_notinbranch:
   5828  1.1.1.2  joerg   case OMPC_link:
   5829  1.1.1.2  joerg   case OMPC_use:
   5830  1.1.1.2  joerg   case OMPC_novariants:
   5831  1.1.1.2  joerg   case OMPC_nocontext:
   5832  1.1.1.2  joerg   case OMPC_filter:
   5833      1.1  joerg     llvm_unreachable("Clause is not allowed in 'omp atomic'.");
   5834      1.1  joerg   }
   5835      1.1  joerg }
   5836      1.1  joerg 
   5837      1.1  joerg void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
   5838  1.1.1.2  joerg   llvm::AtomicOrdering AO = llvm::AtomicOrdering::Monotonic;
   5839  1.1.1.2  joerg   bool MemOrderingSpecified = false;
   5840  1.1.1.2  joerg   if (S.getSingleClause<OMPSeqCstClause>()) {
   5841  1.1.1.2  joerg     AO = llvm::AtomicOrdering::SequentiallyConsistent;
   5842  1.1.1.2  joerg     MemOrderingSpecified = true;
   5843  1.1.1.2  joerg   } else if (S.getSingleClause<OMPAcqRelClause>()) {
   5844  1.1.1.2  joerg     AO = llvm::AtomicOrdering::AcquireRelease;
   5845  1.1.1.2  joerg     MemOrderingSpecified = true;
   5846  1.1.1.2  joerg   } else if (S.getSingleClause<OMPAcquireClause>()) {
   5847  1.1.1.2  joerg     AO = llvm::AtomicOrdering::Acquire;
   5848  1.1.1.2  joerg     MemOrderingSpecified = true;
   5849  1.1.1.2  joerg   } else if (S.getSingleClause<OMPReleaseClause>()) {
   5850  1.1.1.2  joerg     AO = llvm::AtomicOrdering::Release;
   5851  1.1.1.2  joerg     MemOrderingSpecified = true;
   5852  1.1.1.2  joerg   } else if (S.getSingleClause<OMPRelaxedClause>()) {
   5853  1.1.1.2  joerg     AO = llvm::AtomicOrdering::Monotonic;
   5854  1.1.1.2  joerg     MemOrderingSpecified = true;
   5855  1.1.1.2  joerg   }
   5856      1.1  joerg   OpenMPClauseKind Kind = OMPC_unknown;
   5857      1.1  joerg   for (const OMPClause *C : S.clauses()) {
   5858  1.1.1.2  joerg     // Find first clause (skip seq_cst|acq_rel|aqcuire|release|relaxed clause,
   5859  1.1.1.2  joerg     // if it is first).
   5860  1.1.1.2  joerg     if (C->getClauseKind() != OMPC_seq_cst &&
   5861  1.1.1.2  joerg         C->getClauseKind() != OMPC_acq_rel &&
   5862  1.1.1.2  joerg         C->getClauseKind() != OMPC_acquire &&
   5863  1.1.1.2  joerg         C->getClauseKind() != OMPC_release &&
   5864  1.1.1.2  joerg         C->getClauseKind() != OMPC_relaxed && C->getClauseKind() != OMPC_hint) {
   5865      1.1  joerg       Kind = C->getClauseKind();
   5866      1.1  joerg       break;
   5867      1.1  joerg     }
   5868      1.1  joerg   }
   5869  1.1.1.2  joerg   if (!MemOrderingSpecified) {
   5870  1.1.1.2  joerg     llvm::AtomicOrdering DefaultOrder =
   5871  1.1.1.2  joerg         CGM.getOpenMPRuntime().getDefaultMemoryOrdering();
   5872  1.1.1.2  joerg     if (DefaultOrder == llvm::AtomicOrdering::Monotonic ||
   5873  1.1.1.2  joerg         DefaultOrder == llvm::AtomicOrdering::SequentiallyConsistent ||
   5874  1.1.1.2  joerg         (DefaultOrder == llvm::AtomicOrdering::AcquireRelease &&
   5875  1.1.1.2  joerg          Kind == OMPC_capture)) {
   5876  1.1.1.2  joerg       AO = DefaultOrder;
   5877  1.1.1.2  joerg     } else if (DefaultOrder == llvm::AtomicOrdering::AcquireRelease) {
   5878  1.1.1.2  joerg       if (Kind == OMPC_unknown || Kind == OMPC_update || Kind == OMPC_write) {
   5879  1.1.1.2  joerg         AO = llvm::AtomicOrdering::Release;
   5880  1.1.1.2  joerg       } else if (Kind == OMPC_read) {
   5881  1.1.1.2  joerg         assert(Kind == OMPC_read && "Unexpected atomic kind.");
   5882  1.1.1.2  joerg         AO = llvm::AtomicOrdering::Acquire;
   5883  1.1.1.2  joerg       }
   5884      1.1  joerg     }
   5885      1.1  joerg   }
   5886      1.1  joerg 
   5887  1.1.1.2  joerg   LexicalScope Scope(*this, S.getSourceRange());
   5888  1.1.1.2  joerg   EmitStopPoint(S.getAssociatedStmt());
   5889  1.1.1.2  joerg   emitOMPAtomicExpr(*this, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(),
   5890  1.1.1.2  joerg                     S.getExpr(), S.getUpdateExpr(), S.isXLHSInRHSPart(),
   5891  1.1.1.2  joerg                     S.getBeginLoc());
   5892      1.1  joerg }
   5893      1.1  joerg 
   5894      1.1  joerg static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
   5895      1.1  joerg                                          const OMPExecutableDirective &S,
   5896      1.1  joerg                                          const RegionCodeGenTy &CodeGen) {
   5897      1.1  joerg   assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind()));
   5898      1.1  joerg   CodeGenModule &CGM = CGF.CGM;
   5899      1.1  joerg 
   5900      1.1  joerg   // On device emit this construct as inlined code.
   5901      1.1  joerg   if (CGM.getLangOpts().OpenMPIsDevice) {
   5902      1.1  joerg     OMPLexicalScope Scope(CGF, S, OMPD_target);
   5903      1.1  joerg     CGM.getOpenMPRuntime().emitInlinedDirective(
   5904      1.1  joerg         CGF, OMPD_target, [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   5905      1.1  joerg           CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
   5906      1.1  joerg         });
   5907      1.1  joerg     return;
   5908      1.1  joerg   }
   5909      1.1  joerg 
   5910  1.1.1.2  joerg   auto LPCRegion =
   5911  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII::disable(CGF, S);
   5912      1.1  joerg   llvm::Function *Fn = nullptr;
   5913      1.1  joerg   llvm::Constant *FnID = nullptr;
   5914      1.1  joerg 
   5915      1.1  joerg   const Expr *IfCond = nullptr;
   5916      1.1  joerg   // Check for the at most one if clause associated with the target region.
   5917      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
   5918      1.1  joerg     if (C->getNameModifier() == OMPD_unknown ||
   5919      1.1  joerg         C->getNameModifier() == OMPD_target) {
   5920      1.1  joerg       IfCond = C->getCondition();
   5921      1.1  joerg       break;
   5922      1.1  joerg     }
   5923      1.1  joerg   }
   5924      1.1  joerg 
   5925      1.1  joerg   // Check if we have any device clause associated with the directive.
   5926  1.1.1.2  joerg   llvm::PointerIntPair<const Expr *, 2, OpenMPDeviceClauseModifier> Device(
   5927  1.1.1.2  joerg       nullptr, OMPC_DEVICE_unknown);
   5928      1.1  joerg   if (auto *C = S.getSingleClause<OMPDeviceClause>())
   5929  1.1.1.2  joerg     Device.setPointerAndInt(C->getDevice(), C->getModifier());
   5930      1.1  joerg 
   5931      1.1  joerg   // Check if we have an if clause whose conditional always evaluates to false
   5932      1.1  joerg   // or if we do not have any targets specified. If so the target region is not
   5933      1.1  joerg   // an offload entry point.
   5934      1.1  joerg   bool IsOffloadEntry = true;
   5935      1.1  joerg   if (IfCond) {
   5936      1.1  joerg     bool Val;
   5937      1.1  joerg     if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
   5938      1.1  joerg       IsOffloadEntry = false;
   5939      1.1  joerg   }
   5940      1.1  joerg   if (CGM.getLangOpts().OMPTargetTriples.empty())
   5941      1.1  joerg     IsOffloadEntry = false;
   5942      1.1  joerg 
   5943      1.1  joerg   assert(CGF.CurFuncDecl && "No parent declaration for target region!");
   5944      1.1  joerg   StringRef ParentName;
   5945      1.1  joerg   // In case we have Ctors/Dtors we use the complete type variant to produce
   5946      1.1  joerg   // the mangling of the device outlined kernel.
   5947      1.1  joerg   if (const auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl))
   5948      1.1  joerg     ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete));
   5949      1.1  joerg   else if (const auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl))
   5950      1.1  joerg     ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete));
   5951      1.1  joerg   else
   5952      1.1  joerg     ParentName =
   5953      1.1  joerg         CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl)));
   5954      1.1  joerg 
   5955      1.1  joerg   // Emit target region as a standalone region.
   5956      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
   5957      1.1  joerg                                                     IsOffloadEntry, CodeGen);
   5958      1.1  joerg   OMPLexicalScope Scope(CGF, S, OMPD_task);
   5959      1.1  joerg   auto &&SizeEmitter =
   5960      1.1  joerg       [IsOffloadEntry](CodeGenFunction &CGF,
   5961      1.1  joerg                        const OMPLoopDirective &D) -> llvm::Value * {
   5962      1.1  joerg     if (IsOffloadEntry) {
   5963      1.1  joerg       OMPLoopScope(CGF, D);
   5964      1.1  joerg       // Emit calculation of the iterations count.
   5965      1.1  joerg       llvm::Value *NumIterations = CGF.EmitScalarExpr(D.getNumIterations());
   5966      1.1  joerg       NumIterations = CGF.Builder.CreateIntCast(NumIterations, CGF.Int64Ty,
   5967      1.1  joerg                                                 /*isSigned=*/false);
   5968      1.1  joerg       return NumIterations;
   5969      1.1  joerg     }
   5970      1.1  joerg     return nullptr;
   5971      1.1  joerg   };
   5972      1.1  joerg   CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device,
   5973      1.1  joerg                                         SizeEmitter);
   5974      1.1  joerg }
   5975      1.1  joerg 
   5976      1.1  joerg static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S,
   5977      1.1  joerg                              PrePostActionTy &Action) {
   5978      1.1  joerg   Action.Enter(CGF);
   5979      1.1  joerg   CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
   5980      1.1  joerg   (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
   5981      1.1  joerg   CGF.EmitOMPPrivateClause(S, PrivateScope);
   5982      1.1  joerg   (void)PrivateScope.Privatize();
   5983      1.1  joerg   if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
   5984      1.1  joerg     CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
   5985      1.1  joerg 
   5986      1.1  joerg   CGF.EmitStmt(S.getCapturedStmt(OMPD_target)->getCapturedStmt());
   5987  1.1.1.2  joerg   CGF.EnsureInsertPoint();
   5988      1.1  joerg }
   5989      1.1  joerg 
   5990      1.1  joerg void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
   5991      1.1  joerg                                                   StringRef ParentName,
   5992      1.1  joerg                                                   const OMPTargetDirective &S) {
   5993      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   5994      1.1  joerg     emitTargetRegion(CGF, S, Action);
   5995      1.1  joerg   };
   5996      1.1  joerg   llvm::Function *Fn;
   5997      1.1  joerg   llvm::Constant *Addr;
   5998      1.1  joerg   // Emit target region as a standalone region.
   5999      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6000      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6001      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6002      1.1  joerg }
   6003      1.1  joerg 
   6004      1.1  joerg void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
   6005      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6006      1.1  joerg     emitTargetRegion(CGF, S, Action);
   6007      1.1  joerg   };
   6008      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6009      1.1  joerg }
   6010      1.1  joerg 
   6011      1.1  joerg static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
   6012      1.1  joerg                                         const OMPExecutableDirective &S,
   6013      1.1  joerg                                         OpenMPDirectiveKind InnermostKind,
   6014      1.1  joerg                                         const RegionCodeGenTy &CodeGen) {
   6015      1.1  joerg   const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams);
   6016      1.1  joerg   llvm::Function *OutlinedFn =
   6017      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction(
   6018      1.1  joerg           S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
   6019      1.1  joerg 
   6020      1.1  joerg   const auto *NT = S.getSingleClause<OMPNumTeamsClause>();
   6021      1.1  joerg   const auto *TL = S.getSingleClause<OMPThreadLimitClause>();
   6022      1.1  joerg   if (NT || TL) {
   6023      1.1  joerg     const Expr *NumTeams = NT ? NT->getNumTeams() : nullptr;
   6024      1.1  joerg     const Expr *ThreadLimit = TL ? TL->getThreadLimit() : nullptr;
   6025      1.1  joerg 
   6026      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit,
   6027      1.1  joerg                                                   S.getBeginLoc());
   6028      1.1  joerg   }
   6029      1.1  joerg 
   6030      1.1  joerg   OMPTeamsScope Scope(CGF, S);
   6031      1.1  joerg   llvm::SmallVector<llvm::Value *, 16> CapturedVars;
   6032      1.1  joerg   CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
   6033      1.1  joerg   CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getBeginLoc(), OutlinedFn,
   6034      1.1  joerg                                            CapturedVars);
   6035      1.1  joerg }
   6036      1.1  joerg 
   6037      1.1  joerg void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {
   6038      1.1  joerg   // Emit teams region as a standalone region.
   6039      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6040      1.1  joerg     Action.Enter(CGF);
   6041      1.1  joerg     OMPPrivateScope PrivateScope(CGF);
   6042      1.1  joerg     (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
   6043      1.1  joerg     CGF.EmitOMPPrivateClause(S, PrivateScope);
   6044      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6045      1.1  joerg     (void)PrivateScope.Privatize();
   6046      1.1  joerg     CGF.EmitStmt(S.getCapturedStmt(OMPD_teams)->getCapturedStmt());
   6047      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6048      1.1  joerg   };
   6049      1.1  joerg   emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen);
   6050      1.1  joerg   emitPostUpdateForReductionClause(*this, S,
   6051      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6052      1.1  joerg }
   6053      1.1  joerg 
   6054      1.1  joerg static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
   6055      1.1  joerg                                   const OMPTargetTeamsDirective &S) {
   6056      1.1  joerg   auto *CS = S.getCapturedStmt(OMPD_teams);
   6057      1.1  joerg   Action.Enter(CGF);
   6058      1.1  joerg   // Emit teams region as a standalone region.
   6059      1.1  joerg   auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6060      1.1  joerg     Action.Enter(CGF);
   6061      1.1  joerg     CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
   6062      1.1  joerg     (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
   6063      1.1  joerg     CGF.EmitOMPPrivateClause(S, PrivateScope);
   6064      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6065      1.1  joerg     (void)PrivateScope.Privatize();
   6066      1.1  joerg     if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
   6067      1.1  joerg       CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
   6068      1.1  joerg     CGF.EmitStmt(CS->getCapturedStmt());
   6069      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6070      1.1  joerg   };
   6071      1.1  joerg   emitCommonOMPTeamsDirective(CGF, S, OMPD_teams, CodeGen);
   6072      1.1  joerg   emitPostUpdateForReductionClause(CGF, S,
   6073      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6074      1.1  joerg }
   6075      1.1  joerg 
   6076      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
   6077      1.1  joerg     CodeGenModule &CGM, StringRef ParentName,
   6078      1.1  joerg     const OMPTargetTeamsDirective &S) {
   6079      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6080      1.1  joerg     emitTargetTeamsRegion(CGF, Action, S);
   6081      1.1  joerg   };
   6082      1.1  joerg   llvm::Function *Fn;
   6083      1.1  joerg   llvm::Constant *Addr;
   6084      1.1  joerg   // Emit target region as a standalone region.
   6085      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6086      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6087      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6088      1.1  joerg }
   6089      1.1  joerg 
   6090      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDirective(
   6091      1.1  joerg     const OMPTargetTeamsDirective &S) {
   6092      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6093      1.1  joerg     emitTargetTeamsRegion(CGF, Action, S);
   6094      1.1  joerg   };
   6095      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6096      1.1  joerg }
   6097      1.1  joerg 
   6098      1.1  joerg static void
   6099      1.1  joerg emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
   6100      1.1  joerg                                 const OMPTargetTeamsDistributeDirective &S) {
   6101      1.1  joerg   Action.Enter(CGF);
   6102      1.1  joerg   auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6103      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
   6104      1.1  joerg   };
   6105      1.1  joerg 
   6106      1.1  joerg   // Emit teams region as a standalone region.
   6107      1.1  joerg   auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
   6108      1.1  joerg                                             PrePostActionTy &Action) {
   6109      1.1  joerg     Action.Enter(CGF);
   6110      1.1  joerg     CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
   6111      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6112      1.1  joerg     (void)PrivateScope.Privatize();
   6113      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
   6114      1.1  joerg                                                     CodeGenDistribute);
   6115      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6116      1.1  joerg   };
   6117      1.1  joerg   emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute, CodeGen);
   6118      1.1  joerg   emitPostUpdateForReductionClause(CGF, S,
   6119      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6120      1.1  joerg }
   6121      1.1  joerg 
   6122      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
   6123      1.1  joerg     CodeGenModule &CGM, StringRef ParentName,
   6124      1.1  joerg     const OMPTargetTeamsDistributeDirective &S) {
   6125      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6126      1.1  joerg     emitTargetTeamsDistributeRegion(CGF, Action, S);
   6127      1.1  joerg   };
   6128      1.1  joerg   llvm::Function *Fn;
   6129      1.1  joerg   llvm::Constant *Addr;
   6130      1.1  joerg   // Emit target region as a standalone region.
   6131      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6132      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6133      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6134      1.1  joerg }
   6135      1.1  joerg 
   6136      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective(
   6137      1.1  joerg     const OMPTargetTeamsDistributeDirective &S) {
   6138      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6139      1.1  joerg     emitTargetTeamsDistributeRegion(CGF, Action, S);
   6140      1.1  joerg   };
   6141      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6142      1.1  joerg }
   6143      1.1  joerg 
   6144      1.1  joerg static void emitTargetTeamsDistributeSimdRegion(
   6145      1.1  joerg     CodeGenFunction &CGF, PrePostActionTy &Action,
   6146      1.1  joerg     const OMPTargetTeamsDistributeSimdDirective &S) {
   6147      1.1  joerg   Action.Enter(CGF);
   6148      1.1  joerg   auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6149      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
   6150      1.1  joerg   };
   6151      1.1  joerg 
   6152      1.1  joerg   // Emit teams region as a standalone region.
   6153      1.1  joerg   auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
   6154      1.1  joerg                                             PrePostActionTy &Action) {
   6155      1.1  joerg     Action.Enter(CGF);
   6156      1.1  joerg     CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
   6157      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6158      1.1  joerg     (void)PrivateScope.Privatize();
   6159      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
   6160      1.1  joerg                                                     CodeGenDistribute);
   6161      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6162      1.1  joerg   };
   6163      1.1  joerg   emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_simd, CodeGen);
   6164      1.1  joerg   emitPostUpdateForReductionClause(CGF, S,
   6165      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6166      1.1  joerg }
   6167      1.1  joerg 
   6168      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
   6169      1.1  joerg     CodeGenModule &CGM, StringRef ParentName,
   6170      1.1  joerg     const OMPTargetTeamsDistributeSimdDirective &S) {
   6171      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6172      1.1  joerg     emitTargetTeamsDistributeSimdRegion(CGF, Action, S);
   6173      1.1  joerg   };
   6174      1.1  joerg   llvm::Function *Fn;
   6175      1.1  joerg   llvm::Constant *Addr;
   6176      1.1  joerg   // Emit target region as a standalone region.
   6177      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6178      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6179      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6180      1.1  joerg }
   6181      1.1  joerg 
   6182      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
   6183      1.1  joerg     const OMPTargetTeamsDistributeSimdDirective &S) {
   6184      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6185      1.1  joerg     emitTargetTeamsDistributeSimdRegion(CGF, Action, S);
   6186      1.1  joerg   };
   6187      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6188      1.1  joerg }
   6189      1.1  joerg 
   6190      1.1  joerg void CodeGenFunction::EmitOMPTeamsDistributeDirective(
   6191      1.1  joerg     const OMPTeamsDistributeDirective &S) {
   6192      1.1  joerg 
   6193      1.1  joerg   auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6194      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
   6195      1.1  joerg   };
   6196      1.1  joerg 
   6197      1.1  joerg   // Emit teams region as a standalone region.
   6198      1.1  joerg   auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
   6199      1.1  joerg                                             PrePostActionTy &Action) {
   6200      1.1  joerg     Action.Enter(CGF);
   6201      1.1  joerg     OMPPrivateScope PrivateScope(CGF);
   6202      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6203      1.1  joerg     (void)PrivateScope.Privatize();
   6204      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
   6205      1.1  joerg                                                     CodeGenDistribute);
   6206      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6207      1.1  joerg   };
   6208      1.1  joerg   emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen);
   6209      1.1  joerg   emitPostUpdateForReductionClause(*this, S,
   6210      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6211      1.1  joerg }
   6212      1.1  joerg 
   6213      1.1  joerg void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective(
   6214      1.1  joerg     const OMPTeamsDistributeSimdDirective &S) {
   6215      1.1  joerg   auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6216      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
   6217      1.1  joerg   };
   6218      1.1  joerg 
   6219      1.1  joerg   // Emit teams region as a standalone region.
   6220      1.1  joerg   auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
   6221      1.1  joerg                                             PrePostActionTy &Action) {
   6222      1.1  joerg     Action.Enter(CGF);
   6223      1.1  joerg     OMPPrivateScope PrivateScope(CGF);
   6224      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6225      1.1  joerg     (void)PrivateScope.Privatize();
   6226      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd,
   6227      1.1  joerg                                                     CodeGenDistribute);
   6228      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6229      1.1  joerg   };
   6230      1.1  joerg   emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_simd, CodeGen);
   6231      1.1  joerg   emitPostUpdateForReductionClause(*this, S,
   6232      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6233      1.1  joerg }
   6234      1.1  joerg 
   6235      1.1  joerg void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective(
   6236      1.1  joerg     const OMPTeamsDistributeParallelForDirective &S) {
   6237      1.1  joerg   auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6238      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
   6239      1.1  joerg                               S.getDistInc());
   6240      1.1  joerg   };
   6241      1.1  joerg 
   6242      1.1  joerg   // Emit teams region as a standalone region.
   6243      1.1  joerg   auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
   6244      1.1  joerg                                             PrePostActionTy &Action) {
   6245      1.1  joerg     Action.Enter(CGF);
   6246      1.1  joerg     OMPPrivateScope PrivateScope(CGF);
   6247      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6248      1.1  joerg     (void)PrivateScope.Privatize();
   6249      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
   6250      1.1  joerg                                                     CodeGenDistribute);
   6251      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6252      1.1  joerg   };
   6253      1.1  joerg   emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for, CodeGen);
   6254      1.1  joerg   emitPostUpdateForReductionClause(*this, S,
   6255      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6256      1.1  joerg }
   6257      1.1  joerg 
   6258      1.1  joerg void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective(
   6259      1.1  joerg     const OMPTeamsDistributeParallelForSimdDirective &S) {
   6260      1.1  joerg   auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6261      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
   6262      1.1  joerg                               S.getDistInc());
   6263      1.1  joerg   };
   6264      1.1  joerg 
   6265      1.1  joerg   // Emit teams region as a standalone region.
   6266      1.1  joerg   auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
   6267      1.1  joerg                                             PrePostActionTy &Action) {
   6268      1.1  joerg     Action.Enter(CGF);
   6269      1.1  joerg     OMPPrivateScope PrivateScope(CGF);
   6270      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6271      1.1  joerg     (void)PrivateScope.Privatize();
   6272      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
   6273      1.1  joerg         CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
   6274      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6275      1.1  joerg   };
   6276  1.1.1.2  joerg   emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for_simd,
   6277  1.1.1.2  joerg                               CodeGen);
   6278      1.1  joerg   emitPostUpdateForReductionClause(*this, S,
   6279      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6280      1.1  joerg }
   6281      1.1  joerg 
   6282      1.1  joerg static void emitTargetTeamsDistributeParallelForRegion(
   6283      1.1  joerg     CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S,
   6284      1.1  joerg     PrePostActionTy &Action) {
   6285      1.1  joerg   Action.Enter(CGF);
   6286      1.1  joerg   auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6287      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
   6288      1.1  joerg                               S.getDistInc());
   6289      1.1  joerg   };
   6290      1.1  joerg 
   6291      1.1  joerg   // Emit teams region as a standalone region.
   6292      1.1  joerg   auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
   6293      1.1  joerg                                                  PrePostActionTy &Action) {
   6294      1.1  joerg     Action.Enter(CGF);
   6295      1.1  joerg     CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
   6296      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6297      1.1  joerg     (void)PrivateScope.Privatize();
   6298      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
   6299      1.1  joerg         CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
   6300      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6301      1.1  joerg   };
   6302      1.1  joerg 
   6303      1.1  joerg   emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for,
   6304      1.1  joerg                               CodeGenTeams);
   6305      1.1  joerg   emitPostUpdateForReductionClause(CGF, S,
   6306      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6307      1.1  joerg }
   6308      1.1  joerg 
   6309      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
   6310      1.1  joerg     CodeGenModule &CGM, StringRef ParentName,
   6311      1.1  joerg     const OMPTargetTeamsDistributeParallelForDirective &S) {
   6312      1.1  joerg   // Emit SPMD target teams distribute parallel for region as a standalone
   6313      1.1  joerg   // region.
   6314      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6315      1.1  joerg     emitTargetTeamsDistributeParallelForRegion(CGF, S, Action);
   6316      1.1  joerg   };
   6317      1.1  joerg   llvm::Function *Fn;
   6318      1.1  joerg   llvm::Constant *Addr;
   6319      1.1  joerg   // Emit target region as a standalone region.
   6320      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6321      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6322      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6323      1.1  joerg }
   6324      1.1  joerg 
   6325      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective(
   6326      1.1  joerg     const OMPTargetTeamsDistributeParallelForDirective &S) {
   6327      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6328      1.1  joerg     emitTargetTeamsDistributeParallelForRegion(CGF, S, Action);
   6329      1.1  joerg   };
   6330      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6331      1.1  joerg }
   6332      1.1  joerg 
   6333      1.1  joerg static void emitTargetTeamsDistributeParallelForSimdRegion(
   6334      1.1  joerg     CodeGenFunction &CGF,
   6335      1.1  joerg     const OMPTargetTeamsDistributeParallelForSimdDirective &S,
   6336      1.1  joerg     PrePostActionTy &Action) {
   6337      1.1  joerg   Action.Enter(CGF);
   6338      1.1  joerg   auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6339      1.1  joerg     CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
   6340      1.1  joerg                               S.getDistInc());
   6341      1.1  joerg   };
   6342      1.1  joerg 
   6343      1.1  joerg   // Emit teams region as a standalone region.
   6344      1.1  joerg   auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
   6345      1.1  joerg                                                  PrePostActionTy &Action) {
   6346      1.1  joerg     Action.Enter(CGF);
   6347      1.1  joerg     CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
   6348      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6349      1.1  joerg     (void)PrivateScope.Privatize();
   6350      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
   6351      1.1  joerg         CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
   6352      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   6353      1.1  joerg   };
   6354      1.1  joerg 
   6355      1.1  joerg   emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for_simd,
   6356      1.1  joerg                               CodeGenTeams);
   6357      1.1  joerg   emitPostUpdateForReductionClause(CGF, S,
   6358      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6359      1.1  joerg }
   6360      1.1  joerg 
   6361      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
   6362      1.1  joerg     CodeGenModule &CGM, StringRef ParentName,
   6363      1.1  joerg     const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
   6364      1.1  joerg   // Emit SPMD target teams distribute parallel for simd region as a standalone
   6365      1.1  joerg   // region.
   6366      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6367      1.1  joerg     emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action);
   6368      1.1  joerg   };
   6369      1.1  joerg   llvm::Function *Fn;
   6370      1.1  joerg   llvm::Constant *Addr;
   6371      1.1  joerg   // Emit target region as a standalone region.
   6372      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6373      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6374      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6375      1.1  joerg }
   6376      1.1  joerg 
   6377      1.1  joerg void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
   6378      1.1  joerg     const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
   6379      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6380      1.1  joerg     emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action);
   6381      1.1  joerg   };
   6382      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6383      1.1  joerg }
   6384      1.1  joerg 
   6385      1.1  joerg void CodeGenFunction::EmitOMPCancellationPointDirective(
   6386      1.1  joerg     const OMPCancellationPointDirective &S) {
   6387      1.1  joerg   CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getBeginLoc(),
   6388      1.1  joerg                                                    S.getCancelRegion());
   6389      1.1  joerg }
   6390      1.1  joerg 
   6391      1.1  joerg void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
   6392      1.1  joerg   const Expr *IfCond = nullptr;
   6393      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
   6394      1.1  joerg     if (C->getNameModifier() == OMPD_unknown ||
   6395      1.1  joerg         C->getNameModifier() == OMPD_cancel) {
   6396      1.1  joerg       IfCond = C->getCondition();
   6397      1.1  joerg       break;
   6398      1.1  joerg     }
   6399      1.1  joerg   }
   6400  1.1.1.2  joerg   if (CGM.getLangOpts().OpenMPIRBuilder) {
   6401  1.1.1.2  joerg     llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
   6402  1.1.1.2  joerg     // TODO: This check is necessary as we only generate `omp parallel` through
   6403  1.1.1.2  joerg     // the OpenMPIRBuilder for now.
   6404  1.1.1.2  joerg     if (S.getCancelRegion() == OMPD_parallel ||
   6405  1.1.1.2  joerg         S.getCancelRegion() == OMPD_sections ||
   6406  1.1.1.2  joerg         S.getCancelRegion() == OMPD_section) {
   6407  1.1.1.2  joerg       llvm::Value *IfCondition = nullptr;
   6408  1.1.1.2  joerg       if (IfCond)
   6409  1.1.1.2  joerg         IfCondition = EmitScalarExpr(IfCond,
   6410  1.1.1.2  joerg                                      /*IgnoreResultAssign=*/true);
   6411  1.1.1.2  joerg       return Builder.restoreIP(
   6412  1.1.1.2  joerg           OMPBuilder.createCancel(Builder, IfCondition, S.getCancelRegion()));
   6413  1.1.1.2  joerg     }
   6414  1.1.1.2  joerg   }
   6415  1.1.1.2  joerg 
   6416      1.1  joerg   CGM.getOpenMPRuntime().emitCancelCall(*this, S.getBeginLoc(), IfCond,
   6417      1.1  joerg                                         S.getCancelRegion());
   6418      1.1  joerg }
   6419      1.1  joerg 
   6420      1.1  joerg CodeGenFunction::JumpDest
   6421      1.1  joerg CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
   6422      1.1  joerg   if (Kind == OMPD_parallel || Kind == OMPD_task ||
   6423  1.1.1.2  joerg       Kind == OMPD_target_parallel || Kind == OMPD_taskloop ||
   6424  1.1.1.2  joerg       Kind == OMPD_master_taskloop || Kind == OMPD_parallel_master_taskloop)
   6425      1.1  joerg     return ReturnBlock;
   6426      1.1  joerg   assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
   6427      1.1  joerg          Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
   6428      1.1  joerg          Kind == OMPD_distribute_parallel_for ||
   6429      1.1  joerg          Kind == OMPD_target_parallel_for ||
   6430      1.1  joerg          Kind == OMPD_teams_distribute_parallel_for ||
   6431      1.1  joerg          Kind == OMPD_target_teams_distribute_parallel_for);
   6432      1.1  joerg   return OMPCancelStack.getExitBlock();
   6433      1.1  joerg }
   6434      1.1  joerg 
   6435      1.1  joerg void CodeGenFunction::EmitOMPUseDevicePtrClause(
   6436  1.1.1.2  joerg     const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope,
   6437      1.1  joerg     const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
   6438      1.1  joerg   auto OrigVarIt = C.varlist_begin();
   6439      1.1  joerg   auto InitIt = C.inits().begin();
   6440      1.1  joerg   for (const Expr *PvtVarIt : C.private_copies()) {
   6441      1.1  joerg     const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl());
   6442      1.1  joerg     const auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl());
   6443      1.1  joerg     const auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl());
   6444      1.1  joerg 
   6445      1.1  joerg     // In order to identify the right initializer we need to match the
   6446      1.1  joerg     // declaration used by the mapping logic. In some cases we may get
   6447      1.1  joerg     // OMPCapturedExprDecl that refers to the original declaration.
   6448      1.1  joerg     const ValueDecl *MatchingVD = OrigVD;
   6449      1.1  joerg     if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
   6450      1.1  joerg       // OMPCapturedExprDecl are used to privative fields of the current
   6451      1.1  joerg       // structure.
   6452      1.1  joerg       const auto *ME = cast<MemberExpr>(OED->getInit());
   6453      1.1  joerg       assert(isa<CXXThisExpr>(ME->getBase()) &&
   6454      1.1  joerg              "Base should be the current struct!");
   6455      1.1  joerg       MatchingVD = ME->getMemberDecl();
   6456      1.1  joerg     }
   6457      1.1  joerg 
   6458      1.1  joerg     // If we don't have information about the current list item, move on to
   6459      1.1  joerg     // the next one.
   6460      1.1  joerg     auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
   6461      1.1  joerg     if (InitAddrIt == CaptureDeviceAddrMap.end())
   6462      1.1  joerg       continue;
   6463      1.1  joerg 
   6464      1.1  joerg     bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, OrigVD,
   6465      1.1  joerg                                                          InitAddrIt, InitVD,
   6466      1.1  joerg                                                          PvtVD]() {
   6467      1.1  joerg       // Initialize the temporary initialization variable with the address we
   6468      1.1  joerg       // get from the runtime library. We have to cast the source address
   6469      1.1  joerg       // because it is always a void *. References are materialized in the
   6470      1.1  joerg       // privatization scope, so the initialization here disregards the fact
   6471      1.1  joerg       // the original variable is a reference.
   6472      1.1  joerg       QualType AddrQTy =
   6473      1.1  joerg           getContext().getPointerType(OrigVD->getType().getNonReferenceType());
   6474      1.1  joerg       llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy);
   6475      1.1  joerg       Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy);
   6476      1.1  joerg       setAddrOfLocalVar(InitVD, InitAddr);
   6477      1.1  joerg 
   6478      1.1  joerg       // Emit private declaration, it will be initialized by the value we
   6479      1.1  joerg       // declaration we just added to the local declarations map.
   6480      1.1  joerg       EmitDecl(*PvtVD);
   6481      1.1  joerg 
   6482      1.1  joerg       // The initialization variables reached its purpose in the emission
   6483      1.1  joerg       // of the previous declaration, so we don't need it anymore.
   6484      1.1  joerg       LocalDeclMap.erase(InitVD);
   6485      1.1  joerg 
   6486      1.1  joerg       // Return the address of the private variable.
   6487      1.1  joerg       return GetAddrOfLocalVar(PvtVD);
   6488      1.1  joerg     });
   6489      1.1  joerg     assert(IsRegistered && "firstprivate var already registered as private");
   6490      1.1  joerg     // Silence the warning about unused variable.
   6491      1.1  joerg     (void)IsRegistered;
   6492      1.1  joerg 
   6493      1.1  joerg     ++OrigVarIt;
   6494      1.1  joerg     ++InitIt;
   6495      1.1  joerg   }
   6496      1.1  joerg }
   6497      1.1  joerg 
   6498  1.1.1.2  joerg static const VarDecl *getBaseDecl(const Expr *Ref) {
   6499  1.1.1.2  joerg   const Expr *Base = Ref->IgnoreParenImpCasts();
   6500  1.1.1.2  joerg   while (const auto *OASE = dyn_cast<OMPArraySectionExpr>(Base))
   6501  1.1.1.2  joerg     Base = OASE->getBase()->IgnoreParenImpCasts();
   6502  1.1.1.2  joerg   while (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Base))
   6503  1.1.1.2  joerg     Base = ASE->getBase()->IgnoreParenImpCasts();
   6504  1.1.1.2  joerg   return cast<VarDecl>(cast<DeclRefExpr>(Base)->getDecl());
   6505  1.1.1.2  joerg }
   6506  1.1.1.2  joerg 
   6507  1.1.1.2  joerg void CodeGenFunction::EmitOMPUseDeviceAddrClause(
   6508  1.1.1.2  joerg     const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope,
   6509  1.1.1.2  joerg     const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
   6510  1.1.1.2  joerg   llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>, 4> Processed;
   6511  1.1.1.2  joerg   for (const Expr *Ref : C.varlists()) {
   6512  1.1.1.2  joerg     const VarDecl *OrigVD = getBaseDecl(Ref);
   6513  1.1.1.2  joerg     if (!Processed.insert(OrigVD).second)
   6514  1.1.1.2  joerg       continue;
   6515  1.1.1.2  joerg     // In order to identify the right initializer we need to match the
   6516  1.1.1.2  joerg     // declaration used by the mapping logic. In some cases we may get
   6517  1.1.1.2  joerg     // OMPCapturedExprDecl that refers to the original declaration.
   6518  1.1.1.2  joerg     const ValueDecl *MatchingVD = OrigVD;
   6519  1.1.1.2  joerg     if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
   6520  1.1.1.2  joerg       // OMPCapturedExprDecl are used to privative fields of the current
   6521  1.1.1.2  joerg       // structure.
   6522  1.1.1.2  joerg       const auto *ME = cast<MemberExpr>(OED->getInit());
   6523  1.1.1.2  joerg       assert(isa<CXXThisExpr>(ME->getBase()) &&
   6524  1.1.1.2  joerg              "Base should be the current struct!");
   6525  1.1.1.2  joerg       MatchingVD = ME->getMemberDecl();
   6526  1.1.1.2  joerg     }
   6527  1.1.1.2  joerg 
   6528  1.1.1.2  joerg     // If we don't have information about the current list item, move on to
   6529  1.1.1.2  joerg     // the next one.
   6530  1.1.1.2  joerg     auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
   6531  1.1.1.2  joerg     if (InitAddrIt == CaptureDeviceAddrMap.end())
   6532  1.1.1.2  joerg       continue;
   6533  1.1.1.2  joerg 
   6534  1.1.1.2  joerg     Address PrivAddr = InitAddrIt->getSecond();
   6535  1.1.1.2  joerg     // For declrefs and variable length array need to load the pointer for
   6536  1.1.1.2  joerg     // correct mapping, since the pointer to the data was passed to the runtime.
   6537  1.1.1.2  joerg     if (isa<DeclRefExpr>(Ref->IgnoreParenImpCasts()) ||
   6538  1.1.1.2  joerg         MatchingVD->getType()->isArrayType())
   6539  1.1.1.2  joerg       PrivAddr =
   6540  1.1.1.2  joerg           EmitLoadOfPointer(PrivAddr, getContext()
   6541  1.1.1.2  joerg                                           .getPointerType(OrigVD->getType())
   6542  1.1.1.2  joerg                                           ->castAs<PointerType>());
   6543  1.1.1.2  joerg     llvm::Type *RealTy =
   6544  1.1.1.2  joerg         ConvertTypeForMem(OrigVD->getType().getNonReferenceType())
   6545  1.1.1.2  joerg             ->getPointerTo();
   6546  1.1.1.2  joerg     PrivAddr = Builder.CreatePointerBitCastOrAddrSpaceCast(PrivAddr, RealTy);
   6547  1.1.1.2  joerg 
   6548  1.1.1.2  joerg     (void)PrivateScope.addPrivate(OrigVD, [PrivAddr]() { return PrivAddr; });
   6549  1.1.1.2  joerg   }
   6550  1.1.1.2  joerg }
   6551  1.1.1.2  joerg 
   6552      1.1  joerg // Generate the instructions for '#pragma omp target data' directive.
   6553      1.1  joerg void CodeGenFunction::EmitOMPTargetDataDirective(
   6554      1.1  joerg     const OMPTargetDataDirective &S) {
   6555  1.1.1.2  joerg   CGOpenMPRuntime::TargetDataInfo Info(/*RequiresDevicePointerInfo=*/true,
   6556  1.1.1.2  joerg                                        /*SeparateBeginEndCalls=*/true);
   6557      1.1  joerg 
   6558      1.1  joerg   // Create a pre/post action to signal the privatization of the device pointer.
   6559      1.1  joerg   // This action can be replaced by the OpenMP runtime code generation to
   6560      1.1  joerg   // deactivate privatization.
   6561      1.1  joerg   bool PrivatizeDevicePointers = false;
   6562      1.1  joerg   class DevicePointerPrivActionTy : public PrePostActionTy {
   6563      1.1  joerg     bool &PrivatizeDevicePointers;
   6564      1.1  joerg 
   6565      1.1  joerg   public:
   6566      1.1  joerg     explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers)
   6567      1.1  joerg         : PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {}
   6568      1.1  joerg     void Enter(CodeGenFunction &CGF) override {
   6569      1.1  joerg       PrivatizeDevicePointers = true;
   6570      1.1  joerg     }
   6571      1.1  joerg   };
   6572      1.1  joerg   DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);
   6573      1.1  joerg 
   6574      1.1  joerg   auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers](
   6575      1.1  joerg                        CodeGenFunction &CGF, PrePostActionTy &Action) {
   6576      1.1  joerg     auto &&InnermostCodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6577      1.1  joerg       CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
   6578      1.1  joerg     };
   6579      1.1  joerg 
   6580      1.1  joerg     // Codegen that selects whether to generate the privatization code or not.
   6581      1.1  joerg     auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers,
   6582      1.1  joerg                           &InnermostCodeGen](CodeGenFunction &CGF,
   6583      1.1  joerg                                              PrePostActionTy &Action) {
   6584      1.1  joerg       RegionCodeGenTy RCG(InnermostCodeGen);
   6585      1.1  joerg       PrivatizeDevicePointers = false;
   6586      1.1  joerg 
   6587      1.1  joerg       // Call the pre-action to change the status of PrivatizeDevicePointers if
   6588      1.1  joerg       // needed.
   6589      1.1  joerg       Action.Enter(CGF);
   6590      1.1  joerg 
   6591      1.1  joerg       if (PrivatizeDevicePointers) {
   6592      1.1  joerg         OMPPrivateScope PrivateScope(CGF);
   6593      1.1  joerg         // Emit all instances of the use_device_ptr clause.
   6594      1.1  joerg         for (const auto *C : S.getClausesOfKind<OMPUseDevicePtrClause>())
   6595      1.1  joerg           CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope,
   6596      1.1  joerg                                         Info.CaptureDeviceAddrMap);
   6597  1.1.1.2  joerg         for (const auto *C : S.getClausesOfKind<OMPUseDeviceAddrClause>())
   6598  1.1.1.2  joerg           CGF.EmitOMPUseDeviceAddrClause(*C, PrivateScope,
   6599  1.1.1.2  joerg                                          Info.CaptureDeviceAddrMap);
   6600      1.1  joerg         (void)PrivateScope.Privatize();
   6601      1.1  joerg         RCG(CGF);
   6602      1.1  joerg       } else {
   6603  1.1.1.2  joerg         OMPLexicalScope Scope(CGF, S, OMPD_unknown);
   6604      1.1  joerg         RCG(CGF);
   6605      1.1  joerg       }
   6606      1.1  joerg     };
   6607      1.1  joerg 
   6608      1.1  joerg     // Forward the provided action to the privatization codegen.
   6609      1.1  joerg     RegionCodeGenTy PrivRCG(PrivCodeGen);
   6610      1.1  joerg     PrivRCG.setAction(Action);
   6611      1.1  joerg 
   6612      1.1  joerg     // Notwithstanding the body of the region is emitted as inlined directive,
   6613      1.1  joerg     // we don't use an inline scope as changes in the references inside the
   6614      1.1  joerg     // region are expected to be visible outside, so we do not privative them.
   6615      1.1  joerg     OMPLexicalScope Scope(CGF, S);
   6616      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,
   6617      1.1  joerg                                                     PrivRCG);
   6618      1.1  joerg   };
   6619      1.1  joerg 
   6620      1.1  joerg   RegionCodeGenTy RCG(CodeGen);
   6621      1.1  joerg 
   6622      1.1  joerg   // If we don't have target devices, don't bother emitting the data mapping
   6623      1.1  joerg   // code.
   6624      1.1  joerg   if (CGM.getLangOpts().OMPTargetTriples.empty()) {
   6625      1.1  joerg     RCG(*this);
   6626      1.1  joerg     return;
   6627      1.1  joerg   }
   6628      1.1  joerg 
   6629      1.1  joerg   // Check if we have any if clause associated with the directive.
   6630      1.1  joerg   const Expr *IfCond = nullptr;
   6631      1.1  joerg   if (const auto *C = S.getSingleClause<OMPIfClause>())
   6632      1.1  joerg     IfCond = C->getCondition();
   6633      1.1  joerg 
   6634      1.1  joerg   // Check if we have any device clause associated with the directive.
   6635      1.1  joerg   const Expr *Device = nullptr;
   6636      1.1  joerg   if (const auto *C = S.getSingleClause<OMPDeviceClause>())
   6637      1.1  joerg     Device = C->getDevice();
   6638      1.1  joerg 
   6639      1.1  joerg   // Set the action to signal privatization of device pointers.
   6640      1.1  joerg   RCG.setAction(PrivAction);
   6641      1.1  joerg 
   6642      1.1  joerg   // Emit region code.
   6643      1.1  joerg   CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, RCG,
   6644      1.1  joerg                                              Info);
   6645      1.1  joerg }
   6646      1.1  joerg 
   6647      1.1  joerg void CodeGenFunction::EmitOMPTargetEnterDataDirective(
   6648      1.1  joerg     const OMPTargetEnterDataDirective &S) {
   6649      1.1  joerg   // If we don't have target devices, don't bother emitting the data mapping
   6650      1.1  joerg   // code.
   6651      1.1  joerg   if (CGM.getLangOpts().OMPTargetTriples.empty())
   6652      1.1  joerg     return;
   6653      1.1  joerg 
   6654      1.1  joerg   // Check if we have any if clause associated with the directive.
   6655      1.1  joerg   const Expr *IfCond = nullptr;
   6656      1.1  joerg   if (const auto *C = S.getSingleClause<OMPIfClause>())
   6657      1.1  joerg     IfCond = C->getCondition();
   6658      1.1  joerg 
   6659      1.1  joerg   // Check if we have any device clause associated with the directive.
   6660      1.1  joerg   const Expr *Device = nullptr;
   6661      1.1  joerg   if (const auto *C = S.getSingleClause<OMPDeviceClause>())
   6662      1.1  joerg     Device = C->getDevice();
   6663      1.1  joerg 
   6664      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_task);
   6665      1.1  joerg   CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
   6666      1.1  joerg }
   6667      1.1  joerg 
   6668      1.1  joerg void CodeGenFunction::EmitOMPTargetExitDataDirective(
   6669      1.1  joerg     const OMPTargetExitDataDirective &S) {
   6670      1.1  joerg   // If we don't have target devices, don't bother emitting the data mapping
   6671      1.1  joerg   // code.
   6672      1.1  joerg   if (CGM.getLangOpts().OMPTargetTriples.empty())
   6673      1.1  joerg     return;
   6674      1.1  joerg 
   6675      1.1  joerg   // Check if we have any if clause associated with the directive.
   6676      1.1  joerg   const Expr *IfCond = nullptr;
   6677      1.1  joerg   if (const auto *C = S.getSingleClause<OMPIfClause>())
   6678      1.1  joerg     IfCond = C->getCondition();
   6679      1.1  joerg 
   6680      1.1  joerg   // Check if we have any device clause associated with the directive.
   6681      1.1  joerg   const Expr *Device = nullptr;
   6682      1.1  joerg   if (const auto *C = S.getSingleClause<OMPDeviceClause>())
   6683      1.1  joerg     Device = C->getDevice();
   6684      1.1  joerg 
   6685      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_task);
   6686      1.1  joerg   CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
   6687      1.1  joerg }
   6688      1.1  joerg 
   6689      1.1  joerg static void emitTargetParallelRegion(CodeGenFunction &CGF,
   6690      1.1  joerg                                      const OMPTargetParallelDirective &S,
   6691      1.1  joerg                                      PrePostActionTy &Action) {
   6692      1.1  joerg   // Get the captured statement associated with the 'parallel' region.
   6693      1.1  joerg   const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
   6694      1.1  joerg   Action.Enter(CGF);
   6695      1.1  joerg   auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6696      1.1  joerg     Action.Enter(CGF);
   6697      1.1  joerg     CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
   6698      1.1  joerg     (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
   6699      1.1  joerg     CGF.EmitOMPPrivateClause(S, PrivateScope);
   6700      1.1  joerg     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
   6701      1.1  joerg     (void)PrivateScope.Privatize();
   6702      1.1  joerg     if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
   6703      1.1  joerg       CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
   6704      1.1  joerg     // TODO: Add support for clauses.
   6705      1.1  joerg     CGF.EmitStmt(CS->getCapturedStmt());
   6706      1.1  joerg     CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
   6707      1.1  joerg   };
   6708      1.1  joerg   emitCommonOMPParallelDirective(CGF, S, OMPD_parallel, CodeGen,
   6709      1.1  joerg                                  emitEmptyBoundParameters);
   6710      1.1  joerg   emitPostUpdateForReductionClause(CGF, S,
   6711      1.1  joerg                                    [](CodeGenFunction &) { return nullptr; });
   6712      1.1  joerg }
   6713      1.1  joerg 
   6714      1.1  joerg void CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
   6715      1.1  joerg     CodeGenModule &CGM, StringRef ParentName,
   6716      1.1  joerg     const OMPTargetParallelDirective &S) {
   6717      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6718      1.1  joerg     emitTargetParallelRegion(CGF, S, Action);
   6719      1.1  joerg   };
   6720      1.1  joerg   llvm::Function *Fn;
   6721      1.1  joerg   llvm::Constant *Addr;
   6722      1.1  joerg   // Emit target region as a standalone region.
   6723      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6724      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6725      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6726      1.1  joerg }
   6727      1.1  joerg 
   6728      1.1  joerg void CodeGenFunction::EmitOMPTargetParallelDirective(
   6729      1.1  joerg     const OMPTargetParallelDirective &S) {
   6730      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6731      1.1  joerg     emitTargetParallelRegion(CGF, S, Action);
   6732      1.1  joerg   };
   6733      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6734      1.1  joerg }
   6735      1.1  joerg 
   6736      1.1  joerg static void emitTargetParallelForRegion(CodeGenFunction &CGF,
   6737      1.1  joerg                                         const OMPTargetParallelForDirective &S,
   6738      1.1  joerg                                         PrePostActionTy &Action) {
   6739      1.1  joerg   Action.Enter(CGF);
   6740      1.1  joerg   // Emit directive as a combined directive that consists of two implicit
   6741      1.1  joerg   // directives: 'parallel' with 'for' directive.
   6742      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6743      1.1  joerg     Action.Enter(CGF);
   6744      1.1  joerg     CodeGenFunction::OMPCancelStackRAII CancelRegion(
   6745      1.1  joerg         CGF, OMPD_target_parallel_for, S.hasCancel());
   6746      1.1  joerg     CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
   6747      1.1  joerg                                emitDispatchForLoopBounds);
   6748      1.1  joerg   };
   6749      1.1  joerg   emitCommonOMPParallelDirective(CGF, S, OMPD_for, CodeGen,
   6750      1.1  joerg                                  emitEmptyBoundParameters);
   6751      1.1  joerg }
   6752      1.1  joerg 
   6753      1.1  joerg void CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
   6754      1.1  joerg     CodeGenModule &CGM, StringRef ParentName,
   6755      1.1  joerg     const OMPTargetParallelForDirective &S) {
   6756      1.1  joerg   // Emit SPMD target parallel for region as a standalone region.
   6757      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6758      1.1  joerg     emitTargetParallelForRegion(CGF, S, Action);
   6759      1.1  joerg   };
   6760      1.1  joerg   llvm::Function *Fn;
   6761      1.1  joerg   llvm::Constant *Addr;
   6762      1.1  joerg   // Emit target region as a standalone region.
   6763      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6764      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6765      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6766      1.1  joerg }
   6767      1.1  joerg 
   6768      1.1  joerg void CodeGenFunction::EmitOMPTargetParallelForDirective(
   6769      1.1  joerg     const OMPTargetParallelForDirective &S) {
   6770      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6771      1.1  joerg     emitTargetParallelForRegion(CGF, S, Action);
   6772      1.1  joerg   };
   6773      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6774      1.1  joerg }
   6775      1.1  joerg 
   6776      1.1  joerg static void
   6777      1.1  joerg emitTargetParallelForSimdRegion(CodeGenFunction &CGF,
   6778      1.1  joerg                                 const OMPTargetParallelForSimdDirective &S,
   6779      1.1  joerg                                 PrePostActionTy &Action) {
   6780      1.1  joerg   Action.Enter(CGF);
   6781      1.1  joerg   // Emit directive as a combined directive that consists of two implicit
   6782      1.1  joerg   // directives: 'parallel' with 'for' directive.
   6783      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6784      1.1  joerg     Action.Enter(CGF);
   6785      1.1  joerg     CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
   6786      1.1  joerg                                emitDispatchForLoopBounds);
   6787      1.1  joerg   };
   6788      1.1  joerg   emitCommonOMPParallelDirective(CGF, S, OMPD_simd, CodeGen,
   6789      1.1  joerg                                  emitEmptyBoundParameters);
   6790      1.1  joerg }
   6791      1.1  joerg 
   6792      1.1  joerg void CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
   6793      1.1  joerg     CodeGenModule &CGM, StringRef ParentName,
   6794      1.1  joerg     const OMPTargetParallelForSimdDirective &S) {
   6795      1.1  joerg   // Emit SPMD target parallel for region as a standalone region.
   6796      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6797      1.1  joerg     emitTargetParallelForSimdRegion(CGF, S, Action);
   6798      1.1  joerg   };
   6799      1.1  joerg   llvm::Function *Fn;
   6800      1.1  joerg   llvm::Constant *Addr;
   6801      1.1  joerg   // Emit target region as a standalone region.
   6802      1.1  joerg   CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
   6803      1.1  joerg       S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
   6804      1.1  joerg   assert(Fn && Addr && "Target device function emission failed.");
   6805      1.1  joerg }
   6806      1.1  joerg 
   6807      1.1  joerg void CodeGenFunction::EmitOMPTargetParallelForSimdDirective(
   6808      1.1  joerg     const OMPTargetParallelForSimdDirective &S) {
   6809      1.1  joerg   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   6810      1.1  joerg     emitTargetParallelForSimdRegion(CGF, S, Action);
   6811      1.1  joerg   };
   6812      1.1  joerg   emitCommonOMPTargetDirective(*this, S, CodeGen);
   6813      1.1  joerg }
   6814      1.1  joerg 
   6815      1.1  joerg /// Emit a helper variable and return corresponding lvalue.
   6816      1.1  joerg static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper,
   6817      1.1  joerg                      const ImplicitParamDecl *PVD,
   6818      1.1  joerg                      CodeGenFunction::OMPPrivateScope &Privates) {
   6819      1.1  joerg   const auto *VDecl = cast<VarDecl>(Helper->getDecl());
   6820      1.1  joerg   Privates.addPrivate(VDecl,
   6821      1.1  joerg                       [&CGF, PVD]() { return CGF.GetAddrOfLocalVar(PVD); });
   6822      1.1  joerg }
   6823      1.1  joerg 
   6824      1.1  joerg void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
   6825      1.1  joerg   assert(isOpenMPTaskLoopDirective(S.getDirectiveKind()));
   6826      1.1  joerg   // Emit outlined function for task construct.
   6827      1.1  joerg   const CapturedStmt *CS = S.getCapturedStmt(OMPD_taskloop);
   6828  1.1.1.2  joerg   Address CapturedStruct = Address::invalid();
   6829  1.1.1.2  joerg   {
   6830  1.1.1.2  joerg     OMPLexicalScope Scope(*this, S, OMPD_taskloop, /*EmitPreInitStmt=*/false);
   6831  1.1.1.2  joerg     CapturedStruct = GenerateCapturedStmtArgument(*CS);
   6832  1.1.1.2  joerg   }
   6833      1.1  joerg   QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
   6834      1.1  joerg   const Expr *IfCond = nullptr;
   6835      1.1  joerg   for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
   6836      1.1  joerg     if (C->getNameModifier() == OMPD_unknown ||
   6837      1.1  joerg         C->getNameModifier() == OMPD_taskloop) {
   6838      1.1  joerg       IfCond = C->getCondition();
   6839      1.1  joerg       break;
   6840      1.1  joerg     }
   6841      1.1  joerg   }
   6842      1.1  joerg 
   6843      1.1  joerg   OMPTaskDataTy Data;
   6844      1.1  joerg   // Check if taskloop must be emitted without taskgroup.
   6845      1.1  joerg   Data.Nogroup = S.getSingleClause<OMPNogroupClause>();
   6846      1.1  joerg   // TODO: Check if we should emit tied or untied task.
   6847      1.1  joerg   Data.Tied = true;
   6848      1.1  joerg   // Set scheduling for taskloop
   6849      1.1  joerg   if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) {
   6850      1.1  joerg     // grainsize clause
   6851      1.1  joerg     Data.Schedule.setInt(/*IntVal=*/false);
   6852      1.1  joerg     Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
   6853      1.1  joerg   } else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) {
   6854      1.1  joerg     // num_tasks clause
   6855      1.1  joerg     Data.Schedule.setInt(/*IntVal=*/true);
   6856      1.1  joerg     Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
   6857      1.1  joerg   }
   6858      1.1  joerg 
   6859      1.1  joerg   auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
   6860      1.1  joerg     // if (PreCond) {
   6861      1.1  joerg     //   for (IV in 0..LastIteration) BODY;
   6862      1.1  joerg     //   <Final counter/linear vars updates>;
   6863      1.1  joerg     // }
   6864      1.1  joerg     //
   6865      1.1  joerg 
   6866      1.1  joerg     // Emit: if (PreCond) - begin.
   6867      1.1  joerg     // If the condition constant folds and can be elided, avoid emitting the
   6868      1.1  joerg     // whole loop.
   6869      1.1  joerg     bool CondConstant;
   6870      1.1  joerg     llvm::BasicBlock *ContBlock = nullptr;
   6871      1.1  joerg     OMPLoopScope PreInitScope(CGF, S);
   6872      1.1  joerg     if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
   6873      1.1  joerg       if (!CondConstant)
   6874      1.1  joerg         return;
   6875      1.1  joerg     } else {
   6876      1.1  joerg       llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("taskloop.if.then");
   6877      1.1  joerg       ContBlock = CGF.createBasicBlock("taskloop.if.end");
   6878      1.1  joerg       emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
   6879      1.1  joerg                   CGF.getProfileCount(&S));
   6880      1.1  joerg       CGF.EmitBlock(ThenBlock);
   6881      1.1  joerg       CGF.incrementProfileCounter(&S);
   6882      1.1  joerg     }
   6883      1.1  joerg 
   6884  1.1.1.2  joerg     (void)CGF.EmitOMPLinearClauseInit(S);
   6885      1.1  joerg 
   6886      1.1  joerg     OMPPrivateScope LoopScope(CGF);
   6887      1.1  joerg     // Emit helper vars inits.
   6888      1.1  joerg     enum { LowerBound = 5, UpperBound, Stride, LastIter };
   6889      1.1  joerg     auto *I = CS->getCapturedDecl()->param_begin();
   6890      1.1  joerg     auto *LBP = std::next(I, LowerBound);
   6891      1.1  joerg     auto *UBP = std::next(I, UpperBound);
   6892      1.1  joerg     auto *STP = std::next(I, Stride);
   6893      1.1  joerg     auto *LIP = std::next(I, LastIter);
   6894      1.1  joerg     mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP,
   6895      1.1  joerg              LoopScope);
   6896      1.1  joerg     mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP,
   6897      1.1  joerg              LoopScope);
   6898      1.1  joerg     mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope);
   6899      1.1  joerg     mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP,
   6900      1.1  joerg              LoopScope);
   6901      1.1  joerg     CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
   6902  1.1.1.2  joerg     CGF.EmitOMPLinearClause(S, LoopScope);
   6903      1.1  joerg     bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
   6904      1.1  joerg     (void)LoopScope.Privatize();
   6905      1.1  joerg     // Emit the loop iteration variable.
   6906      1.1  joerg     const Expr *IVExpr = S.getIterationVariable();
   6907      1.1  joerg     const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
   6908      1.1  joerg     CGF.EmitVarDecl(*IVDecl);
   6909      1.1  joerg     CGF.EmitIgnoredExpr(S.getInit());
   6910      1.1  joerg 
   6911      1.1  joerg     // Emit the iterations count variable.
   6912      1.1  joerg     // If it is not a variable, Sema decided to calculate iterations count on
   6913      1.1  joerg     // each iteration (e.g., it is foldable into a constant).
   6914      1.1  joerg     if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
   6915      1.1  joerg       CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
   6916      1.1  joerg       // Emit calculation of the iterations count.
   6917      1.1  joerg       CGF.EmitIgnoredExpr(S.getCalcLastIteration());
   6918      1.1  joerg     }
   6919      1.1  joerg 
   6920  1.1.1.2  joerg     {
   6921  1.1.1.2  joerg       OMPLexicalScope Scope(CGF, S, OMPD_taskloop, /*EmitPreInitStmt=*/false);
   6922  1.1.1.2  joerg       emitCommonSimdLoop(
   6923  1.1.1.2  joerg           CGF, S,
   6924  1.1.1.2  joerg           [&S](CodeGenFunction &CGF, PrePostActionTy &) {
   6925  1.1.1.2  joerg             if (isOpenMPSimdDirective(S.getDirectiveKind()))
   6926  1.1.1.2  joerg               CGF.EmitOMPSimdInit(S);
   6927  1.1.1.2  joerg           },
   6928  1.1.1.2  joerg           [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
   6929  1.1.1.2  joerg             CGF.EmitOMPInnerLoop(
   6930  1.1.1.2  joerg                 S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
   6931  1.1.1.2  joerg                 [&S](CodeGenFunction &CGF) {
   6932  1.1.1.2  joerg                   emitOMPLoopBodyWithStopPoint(CGF, S,
   6933  1.1.1.2  joerg                                                CodeGenFunction::JumpDest());
   6934  1.1.1.2  joerg                 },
   6935  1.1.1.2  joerg                 [](CodeGenFunction &) {});
   6936  1.1.1.2  joerg           });
   6937  1.1.1.2  joerg     }
   6938      1.1  joerg     // Emit: if (PreCond) - end.
   6939      1.1  joerg     if (ContBlock) {
   6940      1.1  joerg       CGF.EmitBranch(ContBlock);
   6941      1.1  joerg       CGF.EmitBlock(ContBlock, true);
   6942      1.1  joerg     }
   6943      1.1  joerg     // Emit final copy of the lastprivate variables if IsLastIter != 0.
   6944      1.1  joerg     if (HasLastprivateClause) {
   6945      1.1  joerg       CGF.EmitOMPLastprivateClauseFinal(
   6946      1.1  joerg           S, isOpenMPSimdDirective(S.getDirectiveKind()),
   6947      1.1  joerg           CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
   6948      1.1  joerg               CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false,
   6949      1.1  joerg               (*LIP)->getType(), S.getBeginLoc())));
   6950      1.1  joerg     }
   6951  1.1.1.2  joerg     CGF.EmitOMPLinearClauseFinal(S, [LIP, &S](CodeGenFunction &CGF) {
   6952  1.1.1.2  joerg       return CGF.Builder.CreateIsNotNull(
   6953  1.1.1.2  joerg           CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false,
   6954  1.1.1.2  joerg                                (*LIP)->getType(), S.getBeginLoc()));
   6955  1.1.1.2  joerg     });
   6956      1.1  joerg   };
   6957      1.1  joerg   auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
   6958      1.1  joerg                     IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
   6959      1.1  joerg                             const OMPTaskDataTy &Data) {
   6960      1.1  joerg     auto &&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond,
   6961      1.1  joerg                       &Data](CodeGenFunction &CGF, PrePostActionTy &) {
   6962      1.1  joerg       OMPLoopScope PreInitScope(CGF, S);
   6963      1.1  joerg       CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getBeginLoc(), S,
   6964      1.1  joerg                                                   OutlinedFn, SharedsTy,
   6965      1.1  joerg                                                   CapturedStruct, IfCond, Data);
   6966      1.1  joerg     };
   6967      1.1  joerg     CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
   6968      1.1  joerg                                                     CodeGen);
   6969      1.1  joerg   };
   6970      1.1  joerg   if (Data.Nogroup) {
   6971      1.1  joerg     EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen, Data);
   6972      1.1  joerg   } else {
   6973      1.1  joerg     CGM.getOpenMPRuntime().emitTaskgroupRegion(
   6974      1.1  joerg         *this,
   6975      1.1  joerg         [&S, &BodyGen, &TaskGen, &Data](CodeGenFunction &CGF,
   6976      1.1  joerg                                         PrePostActionTy &Action) {
   6977      1.1  joerg           Action.Enter(CGF);
   6978      1.1  joerg           CGF.EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen,
   6979      1.1  joerg                                         Data);
   6980      1.1  joerg         },
   6981      1.1  joerg         S.getBeginLoc());
   6982      1.1  joerg   }
   6983      1.1  joerg }
   6984      1.1  joerg 
   6985      1.1  joerg void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
   6986  1.1.1.2  joerg   auto LPCRegion =
   6987  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   6988      1.1  joerg   EmitOMPTaskLoopBasedDirective(S);
   6989      1.1  joerg }
   6990      1.1  joerg 
   6991      1.1  joerg void CodeGenFunction::EmitOMPTaskLoopSimdDirective(
   6992      1.1  joerg     const OMPTaskLoopSimdDirective &S) {
   6993  1.1.1.2  joerg   auto LPCRegion =
   6994  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   6995  1.1.1.2  joerg   OMPLexicalScope Scope(*this, S);
   6996      1.1  joerg   EmitOMPTaskLoopBasedDirective(S);
   6997      1.1  joerg }
   6998      1.1  joerg 
   6999      1.1  joerg void CodeGenFunction::EmitOMPMasterTaskLoopDirective(
   7000      1.1  joerg     const OMPMasterTaskLoopDirective &S) {
   7001      1.1  joerg   auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   7002      1.1  joerg     Action.Enter(CGF);
   7003      1.1  joerg     EmitOMPTaskLoopBasedDirective(S);
   7004      1.1  joerg   };
   7005  1.1.1.2  joerg   auto LPCRegion =
   7006  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   7007      1.1  joerg   OMPLexicalScope Scope(*this, S, llvm::None, /*EmitPreInitStmt=*/false);
   7008      1.1  joerg   CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getBeginLoc());
   7009      1.1  joerg }
   7010      1.1  joerg 
   7011      1.1  joerg void CodeGenFunction::EmitOMPMasterTaskLoopSimdDirective(
   7012      1.1  joerg     const OMPMasterTaskLoopSimdDirective &S) {
   7013      1.1  joerg   auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   7014      1.1  joerg     Action.Enter(CGF);
   7015      1.1  joerg     EmitOMPTaskLoopBasedDirective(S);
   7016      1.1  joerg   };
   7017  1.1.1.2  joerg   auto LPCRegion =
   7018  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   7019  1.1.1.2  joerg   OMPLexicalScope Scope(*this, S);
   7020      1.1  joerg   CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getBeginLoc());
   7021      1.1  joerg }
   7022      1.1  joerg 
   7023      1.1  joerg void CodeGenFunction::EmitOMPParallelMasterTaskLoopDirective(
   7024      1.1  joerg     const OMPParallelMasterTaskLoopDirective &S) {
   7025      1.1  joerg   auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   7026      1.1  joerg     auto &&TaskLoopCodeGen = [&S](CodeGenFunction &CGF,
   7027      1.1  joerg                                   PrePostActionTy &Action) {
   7028      1.1  joerg       Action.Enter(CGF);
   7029      1.1  joerg       CGF.EmitOMPTaskLoopBasedDirective(S);
   7030      1.1  joerg     };
   7031  1.1.1.2  joerg     OMPLexicalScope Scope(CGF, S, OMPD_parallel, /*EmitPreInitStmt=*/false);
   7032      1.1  joerg     CGM.getOpenMPRuntime().emitMasterRegion(CGF, TaskLoopCodeGen,
   7033      1.1  joerg                                             S.getBeginLoc());
   7034      1.1  joerg   };
   7035  1.1.1.2  joerg   auto LPCRegion =
   7036  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   7037      1.1  joerg   emitCommonOMPParallelDirective(*this, S, OMPD_master_taskloop, CodeGen,
   7038      1.1  joerg                                  emitEmptyBoundParameters);
   7039      1.1  joerg }
   7040      1.1  joerg 
   7041  1.1.1.2  joerg void CodeGenFunction::EmitOMPParallelMasterTaskLoopSimdDirective(
   7042  1.1.1.2  joerg     const OMPParallelMasterTaskLoopSimdDirective &S) {
   7043  1.1.1.2  joerg   auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) {
   7044  1.1.1.2  joerg     auto &&TaskLoopCodeGen = [&S](CodeGenFunction &CGF,
   7045  1.1.1.2  joerg                                   PrePostActionTy &Action) {
   7046  1.1.1.2  joerg       Action.Enter(CGF);
   7047  1.1.1.2  joerg       CGF.EmitOMPTaskLoopBasedDirective(S);
   7048  1.1.1.2  joerg     };
   7049  1.1.1.2  joerg     OMPLexicalScope Scope(CGF, S, OMPD_parallel, /*EmitPreInitStmt=*/false);
   7050  1.1.1.2  joerg     CGM.getOpenMPRuntime().emitMasterRegion(CGF, TaskLoopCodeGen,
   7051  1.1.1.2  joerg                                             S.getBeginLoc());
   7052  1.1.1.2  joerg   };
   7053  1.1.1.2  joerg   auto LPCRegion =
   7054  1.1.1.2  joerg       CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
   7055  1.1.1.2  joerg   emitCommonOMPParallelDirective(*this, S, OMPD_master_taskloop_simd, CodeGen,
   7056  1.1.1.2  joerg                                  emitEmptyBoundParameters);
   7057  1.1.1.2  joerg }
   7058  1.1.1.2  joerg 
   7059      1.1  joerg // Generate the instructions for '#pragma omp target update' directive.
   7060      1.1  joerg void CodeGenFunction::EmitOMPTargetUpdateDirective(
   7061      1.1  joerg     const OMPTargetUpdateDirective &S) {
   7062      1.1  joerg   // If we don't have target devices, don't bother emitting the data mapping
   7063      1.1  joerg   // code.
   7064      1.1  joerg   if (CGM.getLangOpts().OMPTargetTriples.empty())
   7065      1.1  joerg     return;
   7066      1.1  joerg 
   7067      1.1  joerg   // Check if we have any if clause associated with the directive.
   7068      1.1  joerg   const Expr *IfCond = nullptr;
   7069      1.1  joerg   if (const auto *C = S.getSingleClause<OMPIfClause>())
   7070      1.1  joerg     IfCond = C->getCondition();
   7071      1.1  joerg 
   7072      1.1  joerg   // Check if we have any device clause associated with the directive.
   7073      1.1  joerg   const Expr *Device = nullptr;
   7074      1.1  joerg   if (const auto *C = S.getSingleClause<OMPDeviceClause>())
   7075      1.1  joerg     Device = C->getDevice();
   7076      1.1  joerg 
   7077      1.1  joerg   OMPLexicalScope Scope(*this, S, OMPD_task);
   7078      1.1  joerg   CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
   7079      1.1  joerg }
   7080      1.1  joerg 
   7081      1.1  joerg void CodeGenFunction::EmitSimpleOMPExecutableDirective(
   7082      1.1  joerg     const OMPExecutableDirective &D) {
   7083  1.1.1.2  joerg   if (const auto *SD = dyn_cast<OMPScanDirective>(&D)) {
   7084  1.1.1.2  joerg     EmitOMPScanDirective(*SD);
   7085  1.1.1.2  joerg     return;
   7086  1.1.1.2  joerg   }
   7087      1.1  joerg   if (!D.hasAssociatedStmt() || !D.getAssociatedStmt())
   7088      1.1  joerg     return;
   7089      1.1  joerg   auto &&CodeGen = [&D](CodeGenFunction &CGF, PrePostActionTy &Action) {
   7090  1.1.1.2  joerg     OMPPrivateScope GlobalsScope(CGF);
   7091  1.1.1.2  joerg     if (isOpenMPTaskingDirective(D.getDirectiveKind())) {
   7092  1.1.1.2  joerg       // Capture global firstprivates to avoid crash.
   7093  1.1.1.2  joerg       for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
   7094  1.1.1.2  joerg         for (const Expr *Ref : C->varlists()) {
   7095  1.1.1.2  joerg           const auto *DRE = cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
   7096  1.1.1.2  joerg           if (!DRE)
   7097  1.1.1.2  joerg             continue;
   7098  1.1.1.2  joerg           const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
   7099  1.1.1.2  joerg           if (!VD || VD->hasLocalStorage())
   7100  1.1.1.2  joerg             continue;
   7101  1.1.1.2  joerg           if (!CGF.LocalDeclMap.count(VD)) {
   7102  1.1.1.2  joerg             LValue GlobLVal = CGF.EmitLValue(Ref);
   7103  1.1.1.2  joerg             GlobalsScope.addPrivate(
   7104  1.1.1.2  joerg                 VD, [&GlobLVal, &CGF]() { return GlobLVal.getAddress(CGF); });
   7105  1.1.1.2  joerg           }
   7106  1.1.1.2  joerg         }
   7107  1.1.1.2  joerg       }
   7108  1.1.1.2  joerg     }
   7109      1.1  joerg     if (isOpenMPSimdDirective(D.getDirectiveKind())) {
   7110  1.1.1.2  joerg       (void)GlobalsScope.Privatize();
   7111  1.1.1.2  joerg       ParentLoopDirectiveForScanRegion ScanRegion(CGF, D);
   7112      1.1  joerg       emitOMPSimdRegion(CGF, cast<OMPLoopDirective>(D), Action);
   7113      1.1  joerg     } else {
   7114      1.1  joerg       if (const auto *LD = dyn_cast<OMPLoopDirective>(&D)) {
   7115      1.1  joerg         for (const Expr *E : LD->counters()) {
   7116  1.1.1.2  joerg           const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
   7117      1.1  joerg           if (!VD->hasLocalStorage() && !CGF.LocalDeclMap.count(VD)) {
   7118      1.1  joerg             LValue GlobLVal = CGF.EmitLValue(E);
   7119  1.1.1.2  joerg             GlobalsScope.addPrivate(
   7120  1.1.1.2  joerg                 VD, [&GlobLVal, &CGF]() { return GlobLVal.getAddress(CGF); });
   7121      1.1  joerg           }
   7122      1.1  joerg           if (isa<OMPCapturedExprDecl>(VD)) {
   7123      1.1  joerg             // Emit only those that were not explicitly referenced in clauses.
   7124      1.1  joerg             if (!CGF.LocalDeclMap.count(VD))
   7125      1.1  joerg               CGF.EmitVarDecl(*VD);
   7126      1.1  joerg           }
   7127      1.1  joerg         }
   7128      1.1  joerg         for (const auto *C : D.getClausesOfKind<OMPOrderedClause>()) {
   7129      1.1  joerg           if (!C->getNumForLoops())
   7130      1.1  joerg             continue;
   7131  1.1.1.2  joerg           for (unsigned I = LD->getLoopsNumber(),
   7132      1.1  joerg                         E = C->getLoopNumIterations().size();
   7133      1.1  joerg                I < E; ++I) {
   7134      1.1  joerg             if (const auto *VD = dyn_cast<OMPCapturedExprDecl>(
   7135      1.1  joerg                     cast<DeclRefExpr>(C->getLoopCounter(I))->getDecl())) {
   7136      1.1  joerg               // Emit only those that were not explicitly referenced in clauses.
   7137      1.1  joerg               if (!CGF.LocalDeclMap.count(VD))
   7138      1.1  joerg                 CGF.EmitVarDecl(*VD);
   7139      1.1  joerg             }
   7140      1.1  joerg           }
   7141      1.1  joerg         }
   7142      1.1  joerg       }
   7143  1.1.1.2  joerg       (void)GlobalsScope.Privatize();
   7144      1.1  joerg       CGF.EmitStmt(D.getInnermostCapturedStmt()->getCapturedStmt());
   7145      1.1  joerg     }
   7146      1.1  joerg   };
   7147  1.1.1.2  joerg   if (D.getDirectiveKind() == OMPD_atomic ||
   7148  1.1.1.2  joerg       D.getDirectiveKind() == OMPD_critical ||
   7149  1.1.1.2  joerg       D.getDirectiveKind() == OMPD_section ||
   7150  1.1.1.2  joerg       D.getDirectiveKind() == OMPD_master ||
   7151  1.1.1.2  joerg       D.getDirectiveKind() == OMPD_masked) {
   7152  1.1.1.2  joerg     EmitStmt(D.getAssociatedStmt());
   7153  1.1.1.2  joerg   } else {
   7154  1.1.1.2  joerg     auto LPCRegion =
   7155  1.1.1.2  joerg         CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, D);
   7156  1.1.1.2  joerg     OMPSimdLexicalScope Scope(*this, D);
   7157  1.1.1.2  joerg     CGM.getOpenMPRuntime().emitInlinedDirective(
   7158  1.1.1.2  joerg         *this,
   7159  1.1.1.2  joerg         isOpenMPSimdDirective(D.getDirectiveKind()) ? OMPD_simd
   7160  1.1.1.2  joerg                                                     : D.getDirectiveKind(),
   7161  1.1.1.2  joerg         CodeGen);
   7162  1.1.1.2  joerg   }
   7163  1.1.1.2  joerg   // Check for outer lastprivate conditional update.
   7164  1.1.1.2  joerg   checkForLastprivateConditionalUpdate(*this, D);
   7165      1.1  joerg }
   7166