| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 1 | //===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|  | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 | // | 
|  | 9 | // This contains code to emit OpenMP nodes as LLVM code. | 
|  | 10 | // | 
|  | 11 | //===----------------------------------------------------------------------===// | 
|  | 12 |  | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 13 | #include "CGCleanup.h" | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 14 | #include "CGOpenMPRuntime.h" | 
|  | 15 | #include "CodeGenFunction.h" | 
|  | 16 | #include "CodeGenModule.h" | 
| Chandler Carruth | 0d9593d | 2015-01-14 11:29:14 +0000 | [diff] [blame] | 17 | #include "TargetInfo.h" | 
| Alexey Bataev | 6120582 | 2019-12-04 09:50:21 -0500 | [diff] [blame] | 18 | #include "clang/AST/ASTContext.h" | 
| Reid Kleckner | 9803178 | 2019-12-09 16:11:56 -0800 | [diff] [blame] | 19 | #include "clang/AST/Attr.h" | 
|  | 20 | #include "clang/AST/DeclOpenMP.h" | 
| Alexey Bataev | e6d2583 | 2020-01-27 14:10:17 -0500 | [diff] [blame] | 21 | #include "clang/AST/OpenMPClause.h" | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 22 | #include "clang/AST/Stmt.h" | 
|  | 23 | #include "clang/AST/StmtOpenMP.h" | 
| Alexey Bataev | ea9166b | 2020-02-06 16:30:23 -0500 | [diff] [blame] | 24 | #include "clang/Basic/OpenMPKinds.h" | 
| Alexey Bataev | 8bbf2e3 | 2019-11-04 09:59:11 -0500 | [diff] [blame] | 25 | #include "clang/Basic/PrettyStackTrace.h" | 
| Johannes Doerfert | 10fedd9 | 2019-12-26 11:23:38 -0600 | [diff] [blame] | 26 | #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" | 
| Alexey Bataev | 0fca766 | 2020-03-27 11:15:17 -0400 | [diff] [blame] | 27 | #include "llvm/IR/Constants.h" | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 28 | #include "llvm/IR/Instructions.h" | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame] | 29 | #include "llvm/Support/AtomicOrdering.h" | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 30 | using namespace clang; | 
|  | 31 | using namespace CodeGen; | 
| Johannes Doerfert | eb3e81f | 2019-11-04 22:00:49 -0600 | [diff] [blame] | 32 | using namespace llvm::omp; | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 33 |  | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 34 | namespace { | 
|  | 35 | /// Lexical scope for OpenMP executable constructs, that handles correct codegen | 
|  | 36 | /// for captured expressions. | 
| Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 37 | class OMPLexicalScope : public CodeGenFunction::LexicalScope { | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 38 | void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) { | 
|  | 39 | for (const auto *C : S.clauses()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 40 | if (const auto *CPI = OMPClauseWithPreInit::get(C)) { | 
|  | 41 | if (const auto *PreInit = | 
|  | 42 | cast_or_null<DeclStmt>(CPI->getPreInitStmt())) { | 
| Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 43 | for (const auto *I : PreInit->decls()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 44 | if (!I->hasAttr<OMPCaptureNoInitAttr>()) { | 
| Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 45 | CGF.EmitVarDecl(cast<VarDecl>(*I)); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 46 | } else { | 
| Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 47 | CodeGenFunction::AutoVarEmission Emission = | 
|  | 48 | CGF.EmitAutoVarAlloca(cast<VarDecl>(*I)); | 
|  | 49 | CGF.EmitAutoVarCleanups(Emission); | 
|  | 50 | } | 
|  | 51 | } | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 52 | } | 
|  | 53 | } | 
|  | 54 | } | 
|  | 55 | } | 
| Alexey Bataev | 4ba78a4 | 2016-04-27 07:56:03 +0000 | [diff] [blame] | 56 | CodeGenFunction::OMPPrivateScope InlinedShareds; | 
|  | 57 |  | 
|  | 58 | static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) { | 
|  | 59 | return CGF.LambdaCaptureFields.lookup(VD) || | 
|  | 60 | (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) || | 
| Alexey Bataev | 172f146 | 2020-03-12 12:52:02 -0400 | [diff] [blame] | 61 | (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) && | 
|  | 62 | cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD)); | 
| Alexey Bataev | 4ba78a4 | 2016-04-27 07:56:03 +0000 | [diff] [blame] | 63 | } | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 64 |  | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 65 | public: | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 66 | OMPLexicalScope( | 
|  | 67 | CodeGenFunction &CGF, const OMPExecutableDirective &S, | 
|  | 68 | const llvm::Optional<OpenMPDirectiveKind> CapturedRegion = llvm::None, | 
|  | 69 | const bool EmitPreInitStmt = true) | 
| Alexey Bataev | 4ba78a4 | 2016-04-27 07:56:03 +0000 | [diff] [blame] | 70 | : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()), | 
|  | 71 | InlinedShareds(CGF) { | 
| Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 72 | if (EmitPreInitStmt) | 
|  | 73 | emitPreInitStmt(CGF, S); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 74 | if (!CapturedRegion.hasValue()) | 
|  | 75 | return; | 
|  | 76 | assert(S.hasAssociatedStmt() && | 
|  | 77 | "Expected associated statement for inlined directive."); | 
|  | 78 | const CapturedStmt *CS = S.getCapturedStmt(*CapturedRegion); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 79 | for (const auto &C : CS->captures()) { | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 80 | if (C.capturesVariable() || C.capturesVariableByCopy()) { | 
|  | 81 | auto *VD = C.getCapturedVar(); | 
|  | 82 | assert(VD == VD->getCanonicalDecl() && | 
|  | 83 | "Canonical decl must be captured."); | 
|  | 84 | DeclRefExpr DRE( | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 85 | CGF.getContext(), const_cast<VarDecl *>(VD), | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 86 | isCapturedVar(CGF, VD) || (CGF.CapturedStmtInfo && | 
|  | 87 | InlinedShareds.isGlobalVarCaptured(VD)), | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 88 | VD->getType().getNonReferenceType(), VK_LValue, C.getLocation()); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 89 | InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address { | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 90 | return CGF.EmitLValue(&DRE).getAddress(CGF); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 91 | }); | 
| Alexey Bataev | 4ba78a4 | 2016-04-27 07:56:03 +0000 | [diff] [blame] | 92 | } | 
|  | 93 | } | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 94 | (void)InlinedShareds.Privatize(); | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 95 | } | 
|  | 96 | }; | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 97 |  | 
| Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 98 | /// Lexical scope for OpenMP parallel construct, that handles correct codegen | 
|  | 99 | /// for captured expressions. | 
|  | 100 | class OMPParallelScope final : public OMPLexicalScope { | 
|  | 101 | bool EmitPreInitStmt(const OMPExecutableDirective &S) { | 
|  | 102 | OpenMPDirectiveKind Kind = S.getDirectiveKind(); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 103 | return !(isOpenMPTargetExecutionDirective(Kind) || | 
|  | 104 | isOpenMPLoopBoundSharingDirective(Kind)) && | 
| Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 105 | isOpenMPParallelDirective(Kind); | 
|  | 106 | } | 
|  | 107 |  | 
|  | 108 | public: | 
|  | 109 | OMPParallelScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 110 | : OMPLexicalScope(CGF, S, /*CapturedRegion=*/llvm::None, | 
|  | 111 | EmitPreInitStmt(S)) {} | 
| Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 112 | }; | 
|  | 113 |  | 
| Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 114 | /// Lexical scope for OpenMP teams construct, that handles correct codegen | 
|  | 115 | /// for captured expressions. | 
|  | 116 | class OMPTeamsScope final : public OMPLexicalScope { | 
|  | 117 | bool EmitPreInitStmt(const OMPExecutableDirective &S) { | 
|  | 118 | OpenMPDirectiveKind Kind = S.getDirectiveKind(); | 
|  | 119 | return !isOpenMPTargetExecutionDirective(Kind) && | 
|  | 120 | isOpenMPTeamsDirective(Kind); | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | public: | 
|  | 124 | OMPTeamsScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 125 | : OMPLexicalScope(CGF, S, /*CapturedRegion=*/llvm::None, | 
|  | 126 | EmitPreInitStmt(S)) {} | 
| Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 127 | }; | 
|  | 128 |  | 
| Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 129 | /// Private scope for OpenMP loop-based directives, that supports capturing | 
|  | 130 | /// of used expression from loop statement. | 
|  | 131 | class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { | 
|  | 132 | void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopDirective &S) { | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 133 | CodeGenFunction::OMPMapVars PreCondVars; | 
| Alexey Bataev | f71939c | 2019-09-18 19:24:07 +0000 | [diff] [blame] | 134 | llvm::DenseSet<const VarDecl *> EmittedAsPrivate; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 135 | for (const auto *E : S.counters()) { | 
| Alexey Bataev | e83b3e8 | 2017-12-08 20:18:58 +0000 | [diff] [blame] | 136 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
| Alexey Bataev | f71939c | 2019-09-18 19:24:07 +0000 | [diff] [blame] | 137 | EmittedAsPrivate.insert(VD->getCanonicalDecl()); | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 138 | (void)PreCondVars.setVarAddr( | 
|  | 139 | CGF, VD, CGF.CreateMemTemp(VD->getType().getNonReferenceType())); | 
| Alexey Bataev | e83b3e8 | 2017-12-08 20:18:58 +0000 | [diff] [blame] | 140 | } | 
| Alexey Bataev | f71939c | 2019-09-18 19:24:07 +0000 | [diff] [blame] | 141 | // Mark private vars as undefs. | 
|  | 142 | for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) { | 
|  | 143 | for (const Expr *IRef : C->varlists()) { | 
|  | 144 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl()); | 
|  | 145 | if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { | 
|  | 146 | (void)PreCondVars.setVarAddr( | 
|  | 147 | CGF, OrigVD, | 
|  | 148 | Address(llvm::UndefValue::get( | 
|  | 149 | CGF.ConvertTypeForMem(CGF.getContext().getPointerType( | 
|  | 150 | OrigVD->getType().getNonReferenceType()))), | 
|  | 151 | CGF.getContext().getDeclAlign(OrigVD))); | 
|  | 152 | } | 
|  | 153 | } | 
|  | 154 | } | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 155 | (void)PreCondVars.apply(CGF); | 
| Alexey Bataev | bef93a9 | 2019-10-07 18:54:57 +0000 | [diff] [blame] | 156 | // Emit init, __range and __end variables for C++ range loops. | 
|  | 157 | const Stmt *Body = | 
|  | 158 | S.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers(); | 
|  | 159 | for (unsigned Cnt = 0; Cnt < S.getCollapsedNumber(); ++Cnt) { | 
| Alexey Bataev | 8bbf2e3 | 2019-11-04 09:59:11 -0500 | [diff] [blame] | 160 | Body = OMPLoopDirective::tryToFindNextInnerLoop( | 
|  | 161 | Body, /*TryImperfectlyNestedLoops=*/true); | 
| Alexey Bataev | bef93a9 | 2019-10-07 18:54:57 +0000 | [diff] [blame] | 162 | if (auto *For = dyn_cast<ForStmt>(Body)) { | 
|  | 163 | Body = For->getBody(); | 
|  | 164 | } else { | 
|  | 165 | assert(isa<CXXForRangeStmt>(Body) && | 
| Alexey Bataev | d457f7e | 2019-10-07 19:57:40 +0000 | [diff] [blame] | 166 | "Expected canonical for loop or range-based for loop."); | 
| Alexey Bataev | bef93a9 | 2019-10-07 18:54:57 +0000 | [diff] [blame] | 167 | auto *CXXFor = cast<CXXForRangeStmt>(Body); | 
|  | 168 | if (const Stmt *Init = CXXFor->getInit()) | 
|  | 169 | CGF.EmitStmt(Init); | 
|  | 170 | CGF.EmitStmt(CXXFor->getRangeStmt()); | 
|  | 171 | CGF.EmitStmt(CXXFor->getEndStmt()); | 
|  | 172 | Body = CXXFor->getBody(); | 
|  | 173 | } | 
|  | 174 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 175 | if (const auto *PreInits = cast_or_null<DeclStmt>(S.getPreInits())) { | 
| George Burgess IV | 00f70bd | 2018-03-01 05:43:23 +0000 | [diff] [blame] | 176 | for (const auto *I : PreInits->decls()) | 
|  | 177 | CGF.EmitVarDecl(cast<VarDecl>(*I)); | 
| Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 178 | } | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 179 | PreCondVars.restore(CGF); | 
| Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 180 | } | 
|  | 181 |  | 
|  | 182 | public: | 
|  | 183 | OMPLoopScope(CodeGenFunction &CGF, const OMPLoopDirective &S) | 
|  | 184 | : CodeGenFunction::RunCleanupsScope(CGF) { | 
|  | 185 | emitPreInitStmt(CGF, S); | 
|  | 186 | } | 
|  | 187 | }; | 
|  | 188 |  | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 189 | class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope { | 
|  | 190 | CodeGenFunction::OMPPrivateScope InlinedShareds; | 
|  | 191 |  | 
|  | 192 | static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) { | 
|  | 193 | return CGF.LambdaCaptureFields.lookup(VD) || | 
|  | 194 | (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) || | 
|  | 195 | (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) && | 
|  | 196 | cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD)); | 
|  | 197 | } | 
|  | 198 |  | 
|  | 199 | public: | 
|  | 200 | OMPSimdLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) | 
|  | 201 | : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()), | 
|  | 202 | InlinedShareds(CGF) { | 
|  | 203 | for (const auto *C : S.clauses()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 204 | if (const auto *CPI = OMPClauseWithPreInit::get(C)) { | 
|  | 205 | if (const auto *PreInit = | 
|  | 206 | cast_or_null<DeclStmt>(CPI->getPreInitStmt())) { | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 207 | for (const auto *I : PreInit->decls()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 208 | if (!I->hasAttr<OMPCaptureNoInitAttr>()) { | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 209 | CGF.EmitVarDecl(cast<VarDecl>(*I)); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 210 | } else { | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 211 | CodeGenFunction::AutoVarEmission Emission = | 
|  | 212 | CGF.EmitAutoVarAlloca(cast<VarDecl>(*I)); | 
|  | 213 | CGF.EmitAutoVarCleanups(Emission); | 
|  | 214 | } | 
|  | 215 | } | 
|  | 216 | } | 
|  | 217 | } else if (const auto *UDP = dyn_cast<OMPUseDevicePtrClause>(C)) { | 
|  | 218 | for (const Expr *E : UDP->varlists()) { | 
|  | 219 | const Decl *D = cast<DeclRefExpr>(E)->getDecl(); | 
|  | 220 | if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(D)) | 
|  | 221 | CGF.EmitVarDecl(*OED); | 
|  | 222 | } | 
|  | 223 | } | 
|  | 224 | } | 
|  | 225 | if (!isOpenMPSimdDirective(S.getDirectiveKind())) | 
|  | 226 | CGF.EmitOMPPrivateClause(S, InlinedShareds); | 
|  | 227 | if (const auto *TG = dyn_cast<OMPTaskgroupDirective>(&S)) { | 
|  | 228 | if (const Expr *E = TG->getReductionRef()) | 
|  | 229 | CGF.EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl())); | 
|  | 230 | } | 
|  | 231 | const auto *CS = cast_or_null<CapturedStmt>(S.getAssociatedStmt()); | 
|  | 232 | while (CS) { | 
|  | 233 | for (auto &C : CS->captures()) { | 
|  | 234 | if (C.capturesVariable() || C.capturesVariableByCopy()) { | 
|  | 235 | auto *VD = C.getCapturedVar(); | 
|  | 236 | assert(VD == VD->getCanonicalDecl() && | 
|  | 237 | "Canonical decl must be captured."); | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 238 | DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD), | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 239 | isCapturedVar(CGF, VD) || | 
|  | 240 | (CGF.CapturedStmtInfo && | 
|  | 241 | InlinedShareds.isGlobalVarCaptured(VD)), | 
|  | 242 | VD->getType().getNonReferenceType(), VK_LValue, | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 243 | C.getLocation()); | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 244 | InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address { | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 245 | return CGF.EmitLValue(&DRE).getAddress(CGF); | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 246 | }); | 
|  | 247 | } | 
|  | 248 | } | 
|  | 249 | CS = dyn_cast<CapturedStmt>(CS->getCapturedStmt()); | 
|  | 250 | } | 
|  | 251 | (void)InlinedShareds.Privatize(); | 
|  | 252 | } | 
|  | 253 | }; | 
|  | 254 |  | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 255 | } // namespace | 
|  | 256 |  | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 257 | static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, | 
|  | 258 | const OMPExecutableDirective &S, | 
|  | 259 | const RegionCodeGenTy &CodeGen); | 
|  | 260 |  | 
| Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 261 | LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 262 | if (const auto *OrigDRE = dyn_cast<DeclRefExpr>(E)) { | 
|  | 263 | if (const auto *OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) { | 
| Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 264 | OrigVD = OrigVD->getCanonicalDecl(); | 
|  | 265 | bool IsCaptured = | 
|  | 266 | LambdaCaptureFields.lookup(OrigVD) || | 
|  | 267 | (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) || | 
|  | 268 | (CurCodeDecl && isa<BlockDecl>(CurCodeDecl)); | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 269 | DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), IsCaptured, | 
| Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 270 | OrigDRE->getType(), VK_LValue, OrigDRE->getExprLoc()); | 
|  | 271 | return EmitLValue(&DRE); | 
|  | 272 | } | 
|  | 273 | } | 
|  | 274 | return EmitLValue(E); | 
|  | 275 | } | 
|  | 276 |  | 
| Alexey Bataev | 1189bd0 | 2016-01-26 12:20:39 +0000 | [diff] [blame] | 277 | llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 278 | ASTContext &C = getContext(); | 
| Alexey Bataev | 1189bd0 | 2016-01-26 12:20:39 +0000 | [diff] [blame] | 279 | llvm::Value *Size = nullptr; | 
|  | 280 | auto SizeInChars = C.getTypeSizeInChars(Ty); | 
|  | 281 | if (SizeInChars.isZero()) { | 
|  | 282 | // getTypeSizeInChars() returns 0 for a VLA. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 283 | while (const VariableArrayType *VAT = C.getAsVariableArrayType(Ty)) { | 
|  | 284 | VlaSizePair VlaSize = getVLASize(VAT); | 
| Sander de Smalen | 891af03a | 2018-02-03 13:55:59 +0000 | [diff] [blame] | 285 | Ty = VlaSize.Type; | 
|  | 286 | Size = Size ? Builder.CreateNUWMul(Size, VlaSize.NumElts) | 
|  | 287 | : VlaSize.NumElts; | 
| Alexey Bataev | 1189bd0 | 2016-01-26 12:20:39 +0000 | [diff] [blame] | 288 | } | 
|  | 289 | SizeInChars = C.getTypeSizeInChars(Ty); | 
|  | 290 | if (SizeInChars.isZero()) | 
|  | 291 | return llvm::ConstantInt::get(SizeTy, /*V=*/0); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 292 | return Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars)); | 
|  | 293 | } | 
|  | 294 | return CGM.getSize(SizeInChars); | 
| Alexey Bataev | 1189bd0 | 2016-01-26 12:20:39 +0000 | [diff] [blame] | 295 | } | 
|  | 296 |  | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 297 | void CodeGenFunction::GenerateOpenMPCapturedVars( | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 298 | const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) { | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 299 | const RecordDecl *RD = S.getCapturedRecordDecl(); | 
|  | 300 | auto CurField = RD->field_begin(); | 
|  | 301 | auto CurCap = S.captures().begin(); | 
|  | 302 | for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(), | 
|  | 303 | E = S.capture_init_end(); | 
|  | 304 | I != E; ++I, ++CurField, ++CurCap) { | 
|  | 305 | if (CurField->hasCapturedVLAType()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 306 | const VariableArrayType *VAT = CurField->getCapturedVLAType(); | 
|  | 307 | llvm::Value *Val = VLASizeMap[VAT->getSizeExpr()]; | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 308 | CapturedVars.push_back(Val); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 309 | } else if (CurCap->capturesThis()) { | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 310 | CapturedVars.push_back(CXXThisValue); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 311 | } else if (CurCap->capturesVariableByCopy()) { | 
| Alexey Bataev | 1e49137 | 2018-01-23 18:44:14 +0000 | [diff] [blame] | 312 | llvm::Value *CV = EmitLoadOfScalar(EmitLValue(*I), CurCap->getLocation()); | 
| Samuel Antao | 6d00426 | 2016-06-16 18:39:34 +0000 | [diff] [blame] | 313 |  | 
|  | 314 | // If the field is not a pointer, we need to save the actual value | 
|  | 315 | // and load it as a void pointer. | 
|  | 316 | if (!CurField->getType()->isAnyPointerType()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 317 | ASTContext &Ctx = getContext(); | 
|  | 318 | Address DstAddr = CreateMemTemp( | 
| Samuel Antao | 6d00426 | 2016-06-16 18:39:34 +0000 | [diff] [blame] | 319 | Ctx.getUIntPtrType(), | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 320 | Twine(CurCap->getCapturedVar()->getName(), ".casted")); | 
| Samuel Antao | 6d00426 | 2016-06-16 18:39:34 +0000 | [diff] [blame] | 321 | LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType()); | 
|  | 322 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 323 | llvm::Value *SrcAddrVal = EmitScalarConversion( | 
| Samuel Antao | 6d00426 | 2016-06-16 18:39:34 +0000 | [diff] [blame] | 324 | DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()), | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 325 | Ctx.getPointerType(CurField->getType()), CurCap->getLocation()); | 
| Samuel Antao | 6d00426 | 2016-06-16 18:39:34 +0000 | [diff] [blame] | 326 | LValue SrcLV = | 
|  | 327 | MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType()); | 
|  | 328 |  | 
|  | 329 | // Store the value using the source type pointer. | 
|  | 330 | EmitStoreThroughLValue(RValue::get(CV), SrcLV); | 
|  | 331 |  | 
|  | 332 | // Load the value using the destination type pointer. | 
| Alexey Bataev | 1e49137 | 2018-01-23 18:44:14 +0000 | [diff] [blame] | 333 | CV = EmitLoadOfScalar(DstLV, CurCap->getLocation()); | 
| Samuel Antao | 6d00426 | 2016-06-16 18:39:34 +0000 | [diff] [blame] | 334 | } | 
|  | 335 | CapturedVars.push_back(CV); | 
|  | 336 | } else { | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 337 | assert(CurCap->capturesVariable() && "Expected capture by reference."); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 338 | CapturedVars.push_back(EmitLValue(*I).getAddress(*this).getPointer()); | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 339 | } | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 340 | } | 
|  | 341 | } | 
|  | 342 |  | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 343 | static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 344 | QualType DstType, StringRef Name, | 
| Alexey Bataev | 06e80f6 | 2019-05-23 18:19:54 +0000 | [diff] [blame] | 345 | LValue AddrLV) { | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 346 | ASTContext &Ctx = CGF.getContext(); | 
|  | 347 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 348 | llvm::Value *CastedPtr = CGF.EmitScalarConversion( | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 349 | AddrLV.getAddress(CGF).getPointer(), Ctx.getUIntPtrType(), | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 350 | Ctx.getPointerType(DstType), Loc); | 
|  | 351 | Address TmpAddr = | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 352 | CGF.MakeNaturalAlignAddrLValue(CastedPtr, Ctx.getPointerType(DstType)) | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 353 | .getAddress(CGF); | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 354 | return TmpAddr; | 
|  | 355 | } | 
|  | 356 |  | 
| Alexey Bataev | f7ce166 | 2017-04-10 19:16:45 +0000 | [diff] [blame] | 357 | static QualType getCanonicalParamType(ASTContext &C, QualType T) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 358 | if (T->isLValueReferenceType()) | 
| Alexey Bataev | f7ce166 | 2017-04-10 19:16:45 +0000 | [diff] [blame] | 359 | return C.getLValueReferenceType( | 
|  | 360 | getCanonicalParamType(C, T.getNonReferenceType()), | 
|  | 361 | /*SpelledAsLValue=*/false); | 
| Alexey Bataev | f7ce166 | 2017-04-10 19:16:45 +0000 | [diff] [blame] | 362 | if (T->isPointerType()) | 
|  | 363 | return C.getPointerType(getCanonicalParamType(C, T->getPointeeType())); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 364 | if (const ArrayType *A = T->getAsArrayTypeUnsafe()) { | 
|  | 365 | if (const auto *VLA = dyn_cast<VariableArrayType>(A)) | 
| Alexey Bataev | 1b48c5e | 2017-10-24 19:52:31 +0000 | [diff] [blame] | 366 | return getCanonicalParamType(C, VLA->getElementType()); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 367 | if (!A->isVariablyModifiedType()) | 
| Alexey Bataev | 1b48c5e | 2017-10-24 19:52:31 +0000 | [diff] [blame] | 368 | return C.getCanonicalType(T); | 
|  | 369 | } | 
| Alexey Bataev | f7ce166 | 2017-04-10 19:16:45 +0000 | [diff] [blame] | 370 | return C.getCanonicalParamType(T); | 
|  | 371 | } | 
|  | 372 |  | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 373 | namespace { | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 374 | /// Contains required data for proper outlined function codegen. | 
|  | 375 | struct FunctionOptions { | 
|  | 376 | /// Captured statement for which the function is generated. | 
|  | 377 | const CapturedStmt *S = nullptr; | 
|  | 378 | /// true if cast to/from  UIntPtr is required for variables captured by | 
|  | 379 | /// value. | 
|  | 380 | const bool UIntPtrCastRequired = true; | 
|  | 381 | /// true if only casted arguments must be registered as local args or VLA | 
|  | 382 | /// sizes. | 
|  | 383 | const bool RegisterCastedArgsOnly = false; | 
|  | 384 | /// Name of the generated function. | 
|  | 385 | const StringRef FunctionName; | 
|  | 386 | /// Location of the non-debug version of the outlined function. | 
|  | 387 | SourceLocation Loc; | 
|  | 388 | explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired, | 
|  | 389 | bool RegisterCastedArgsOnly, StringRef FunctionName, | 
|  | 390 | SourceLocation Loc) | 
|  | 391 | : S(S), UIntPtrCastRequired(UIntPtrCastRequired), | 
|  | 392 | RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly), | 
|  | 393 | FunctionName(FunctionName), Loc(Loc) {} | 
|  | 394 | }; | 
|  | 395 | } // namespace | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 396 |  | 
| Alexey Bataev | e754b18 | 2017-08-09 19:38:53 +0000 | [diff] [blame] | 397 | static llvm::Function *emitOutlinedFunctionPrologue( | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 398 | CodeGenFunction &CGF, FunctionArgList &Args, | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 399 | llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 400 | &LocalAddrs, | 
|  | 401 | llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> | 
|  | 402 | &VLASizes, | 
|  | 403 | llvm::Value *&CXXThisValue, const FunctionOptions &FO) { | 
|  | 404 | const CapturedDecl *CD = FO.S->getCapturedDecl(); | 
|  | 405 | const RecordDecl *RD = FO.S->getCapturedRecordDecl(); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 406 | assert(CD->hasBody() && "missing CapturedDecl body"); | 
|  | 407 |  | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 408 | CXXThisValue = nullptr; | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 409 | // Build the argument list. | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 410 | CodeGenModule &CGM = CGF.CGM; | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 411 | ASTContext &Ctx = CGM.getContext(); | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 412 | FunctionArgList TargetArgs; | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 413 | Args.append(CD->param_begin(), | 
|  | 414 | std::next(CD->param_begin(), CD->getContextParamPosition())); | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 415 | TargetArgs.append( | 
|  | 416 | CD->param_begin(), | 
|  | 417 | std::next(CD->param_begin(), CD->getContextParamPosition())); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 418 | auto I = FO.S->captures().begin(); | 
| Alexey Bataev | b45d43c | 2017-11-22 16:02:03 +0000 | [diff] [blame] | 419 | FunctionDecl *DebugFunctionDecl = nullptr; | 
|  | 420 | if (!FO.UIntPtrCastRequired) { | 
|  | 421 | FunctionProtoType::ExtProtoInfo EPI; | 
| Jonas Devlieghere | 64a2630 | 2018-11-11 00:56:15 +0000 | [diff] [blame] | 422 | QualType FunctionTy = Ctx.getFunctionType(Ctx.VoidTy, llvm::None, EPI); | 
| Alexey Bataev | b45d43c | 2017-11-22 16:02:03 +0000 | [diff] [blame] | 423 | DebugFunctionDecl = FunctionDecl::Create( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 424 | Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(), | 
| Jonas Devlieghere | 64a2630 | 2018-11-11 00:56:15 +0000 | [diff] [blame] | 425 | SourceLocation(), DeclarationName(), FunctionTy, | 
|  | 426 | Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static, | 
|  | 427 | /*isInlineSpecified=*/false, /*hasWrittenPrototype=*/false); | 
| Alexey Bataev | b45d43c | 2017-11-22 16:02:03 +0000 | [diff] [blame] | 428 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 429 | for (const FieldDecl *FD : RD->fields()) { | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 430 | QualType ArgType = FD->getType(); | 
|  | 431 | IdentifierInfo *II = nullptr; | 
|  | 432 | VarDecl *CapVar = nullptr; | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 433 |  | 
|  | 434 | // If this is a capture by copy and the type is not a pointer, the outlined | 
|  | 435 | // function argument type should be uintptr and the value properly casted to | 
|  | 436 | // uintptr. This is necessary given that the runtime library is only able to | 
|  | 437 | // deal with pointers. We can pass in the same way the VLA type sizes to the | 
|  | 438 | // outlined function. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 439 | if (FO.UIntPtrCastRequired && | 
|  | 440 | ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) || | 
|  | 441 | I->capturesVariableArrayType())) | 
|  | 442 | ArgType = Ctx.getUIntPtrType(); | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 443 |  | 
|  | 444 | if (I->capturesVariable() || I->capturesVariableByCopy()) { | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 445 | CapVar = I->getCapturedVar(); | 
|  | 446 | II = CapVar->getIdentifier(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 447 | } else if (I->capturesThis()) { | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 448 | II = &Ctx.Idents.get("this"); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 449 | } else { | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 450 | assert(I->capturesVariableArrayType()); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 451 | II = &Ctx.Idents.get("vla"); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 452 | } | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 453 | if (ArgType->isVariablyModifiedType()) | 
| Alexey Bataev | 1b48c5e | 2017-10-24 19:52:31 +0000 | [diff] [blame] | 454 | ArgType = getCanonicalParamType(Ctx, ArgType); | 
| Alexey Bataev | b45d43c | 2017-11-22 16:02:03 +0000 | [diff] [blame] | 455 | VarDecl *Arg; | 
|  | 456 | if (DebugFunctionDecl && (CapVar || I->capturesThis())) { | 
|  | 457 | Arg = ParmVarDecl::Create( | 
|  | 458 | Ctx, DebugFunctionDecl, | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 459 | CapVar ? CapVar->getBeginLoc() : FD->getBeginLoc(), | 
| Alexey Bataev | b45d43c | 2017-11-22 16:02:03 +0000 | [diff] [blame] | 460 | CapVar ? CapVar->getLocation() : FD->getLocation(), II, ArgType, | 
|  | 461 | /*TInfo=*/nullptr, SC_None, /*DefArg=*/nullptr); | 
|  | 462 | } else { | 
|  | 463 | Arg = ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(), | 
|  | 464 | II, ArgType, ImplicitParamDecl::Other); | 
|  | 465 | } | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 466 | Args.emplace_back(Arg); | 
|  | 467 | // Do not cast arguments if we emit function with non-original types. | 
|  | 468 | TargetArgs.emplace_back( | 
|  | 469 | FO.UIntPtrCastRequired | 
|  | 470 | ? Arg | 
|  | 471 | : CGM.getOpenMPRuntime().translateParameter(FD, Arg)); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 472 | ++I; | 
|  | 473 | } | 
|  | 474 | Args.append( | 
|  | 475 | std::next(CD->param_begin(), CD->getContextParamPosition() + 1), | 
|  | 476 | CD->param_end()); | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 477 | TargetArgs.append( | 
|  | 478 | std::next(CD->param_begin(), CD->getContextParamPosition() + 1), | 
|  | 479 | CD->param_end()); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 480 |  | 
|  | 481 | // Create the function declaration. | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 482 | const CGFunctionInfo &FuncInfo = | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 483 | CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, TargetArgs); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 484 | llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo); | 
|  | 485 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 486 | auto *F = | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 487 | llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage, | 
|  | 488 | FO.FunctionName, &CGM.getModule()); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 489 | CGM.SetInternalFunctionAttributes(CD, F, FuncInfo); | 
|  | 490 | if (CD->isNothrow()) | 
| Alexey Bataev | 2c7eee5 | 2017-08-04 19:10:54 +0000 | [diff] [blame] | 491 | F->setDoesNotThrow(); | 
| Alexey Bataev | c0f879b | 2018-04-10 20:10:53 +0000 | [diff] [blame] | 492 | F->setDoesNotRecurse(); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 493 |  | 
|  | 494 | // Generate the function. | 
| Alexey Bataev | 6e01dc1 | 2017-08-14 16:03:47 +0000 | [diff] [blame] | 495 | CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs, | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 496 | FO.UIntPtrCastRequired ? FO.Loc : FO.S->getBeginLoc(), | 
|  | 497 | FO.UIntPtrCastRequired ? FO.Loc | 
|  | 498 | : CD->getBody()->getBeginLoc()); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 499 | unsigned Cnt = CD->getContextParamPosition(); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 500 | I = FO.S->captures().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 501 | for (const FieldDecl *FD : RD->fields()) { | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 502 | // Do not map arguments if we emit function with non-original types. | 
|  | 503 | Address LocalAddr(Address::invalid()); | 
|  | 504 | if (!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) { | 
|  | 505 | LocalAddr = CGM.getOpenMPRuntime().getParameterAddress(CGF, Args[Cnt], | 
|  | 506 | TargetArgs[Cnt]); | 
|  | 507 | } else { | 
|  | 508 | LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]); | 
|  | 509 | } | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 510 | // If we are capturing a pointer by copy we don't need to do anything, just | 
|  | 511 | // use the value that we get from the arguments. | 
|  | 512 | if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) { | 
| Samuel Antao | 403ffd4 | 2016-07-27 22:49:49 +0000 | [diff] [blame] | 513 | const VarDecl *CurVD = I->getCapturedVar(); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 514 | if (!FO.RegisterCastedArgsOnly) | 
|  | 515 | LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}}); | 
| Richard Trieu | cc3949d | 2016-02-18 22:34:54 +0000 | [diff] [blame] | 516 | ++Cnt; | 
|  | 517 | ++I; | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 518 | continue; | 
|  | 519 | } | 
|  | 520 |  | 
| Ivan A. Kosarev | 5f8c0ca | 2017-10-10 09:39:32 +0000 | [diff] [blame] | 521 | LValue ArgLVal = CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(), | 
|  | 522 | AlignmentSource::Decl); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 523 | if (FD->hasCapturedVLAType()) { | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 524 | if (FO.UIntPtrCastRequired) { | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 525 | ArgLVal = CGF.MakeAddrLValue( | 
|  | 526 | castValueFromUintptr(CGF, I->getLocation(), FD->getType(), | 
|  | 527 | Args[Cnt]->getName(), ArgLVal), | 
|  | 528 | FD->getType(), AlignmentSource::Decl); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 529 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 530 | llvm::Value *ExprArg = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation()); | 
|  | 531 | const VariableArrayType *VAT = FD->getCapturedVLAType(); | 
|  | 532 | VLASizes.try_emplace(Args[Cnt], VAT->getSizeExpr(), ExprArg); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 533 | } else if (I->capturesVariable()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 534 | const VarDecl *Var = I->getCapturedVar(); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 535 | QualType VarTy = Var->getType(); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 536 | Address ArgAddr = ArgLVal.getAddress(CGF); | 
| Alexey Bataev | 06e80f6 | 2019-05-23 18:19:54 +0000 | [diff] [blame] | 537 | if (ArgLVal.getType()->isLValueReferenceType()) { | 
|  | 538 | ArgAddr = CGF.EmitLoadOfReference(ArgLVal); | 
|  | 539 | } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) { | 
|  | 540 | assert(ArgLVal.getType()->isPointerType()); | 
|  | 541 | ArgAddr = CGF.EmitLoadOfPointer( | 
|  | 542 | ArgAddr, ArgLVal.getType()->castAs<PointerType>()); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 543 | } | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 544 | if (!FO.RegisterCastedArgsOnly) { | 
|  | 545 | LocalAddrs.insert( | 
|  | 546 | {Args[Cnt], | 
|  | 547 | {Var, Address(ArgAddr.getPointer(), Ctx.getDeclAlign(Var))}}); | 
|  | 548 | } | 
| Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 549 | } else if (I->capturesVariableByCopy()) { | 
|  | 550 | assert(!FD->getType()->isAnyPointerType() && | 
|  | 551 | "Not expecting a captured pointer."); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 552 | const VarDecl *Var = I->getCapturedVar(); | 
| Alexey Bataev | 06e80f6 | 2019-05-23 18:19:54 +0000 | [diff] [blame] | 553 | LocalAddrs.insert({Args[Cnt], | 
|  | 554 | {Var, FO.UIntPtrCastRequired | 
|  | 555 | ? castValueFromUintptr( | 
|  | 556 | CGF, I->getLocation(), FD->getType(), | 
|  | 557 | Args[Cnt]->getName(), ArgLVal) | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 558 | : ArgLVal.getAddress(CGF)}}); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 559 | } else { | 
|  | 560 | // If 'this' is captured, load it into CXXThisValue. | 
|  | 561 | assert(I->capturesThis()); | 
| Alexey Bataev | 1e49137 | 2018-01-23 18:44:14 +0000 | [diff] [blame] | 562 | CXXThisValue = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation()); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 563 | LocalAddrs.insert({Args[Cnt], {nullptr, ArgLVal.getAddress(CGF)}}); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 564 | } | 
| Richard Trieu | cc3949d | 2016-02-18 22:34:54 +0000 | [diff] [blame] | 565 | ++Cnt; | 
|  | 566 | ++I; | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 567 | } | 
|  | 568 |  | 
| Alexey Bataev | e754b18 | 2017-08-09 19:38:53 +0000 | [diff] [blame] | 569 | return F; | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 570 | } | 
|  | 571 |  | 
|  | 572 | llvm::Function * | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 573 | CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, | 
|  | 574 | SourceLocation Loc) { | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 575 | assert( | 
|  | 576 | CapturedStmtInfo && | 
|  | 577 | "CapturedStmtInfo should be set when generating the captured function"); | 
|  | 578 | const CapturedDecl *CD = S.getCapturedDecl(); | 
|  | 579 | // Build the argument list. | 
|  | 580 | bool NeedWrapperFunction = | 
| Amy Huang | 53539bb | 2020-01-13 15:54:54 -0800 | [diff] [blame] | 581 | getDebugInfo() && CGM.getCodeGenOpts().hasReducedDebugInfo(); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 582 | FunctionArgList Args; | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 583 | llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs; | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 584 | llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes; | 
| Alexey Bataev | e754b18 | 2017-08-09 19:38:53 +0000 | [diff] [blame] | 585 | SmallString<256> Buffer; | 
|  | 586 | llvm::raw_svector_ostream Out(Buffer); | 
|  | 587 | Out << CapturedStmtInfo->getHelperName(); | 
|  | 588 | if (NeedWrapperFunction) | 
|  | 589 | Out << "_debug__"; | 
| Alexey Bataev | 4aa1905 | 2017-08-08 16:45:36 +0000 | [diff] [blame] | 590 | FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false, | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 591 | Out.str(), Loc); | 
| Alexey Bataev | e754b18 | 2017-08-09 19:38:53 +0000 | [diff] [blame] | 592 | llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs, | 
|  | 593 | VLASizes, CXXThisValue, FO); | 
| Alexey Bataev | 06e80f6 | 2019-05-23 18:19:54 +0000 | [diff] [blame] | 594 | CodeGenFunction::OMPPrivateScope LocalScope(*this); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 595 | for (const auto &LocalAddrPair : LocalAddrs) { | 
|  | 596 | if (LocalAddrPair.second.first) { | 
| Alexey Bataev | 06e80f6 | 2019-05-23 18:19:54 +0000 | [diff] [blame] | 597 | LocalScope.addPrivate(LocalAddrPair.second.first, [&LocalAddrPair]() { | 
|  | 598 | return LocalAddrPair.second.second; | 
|  | 599 | }); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 600 | } | 
|  | 601 | } | 
| Alexey Bataev | 06e80f6 | 2019-05-23 18:19:54 +0000 | [diff] [blame] | 602 | (void)LocalScope.Privatize(); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 603 | for (const auto &VLASizePair : VLASizes) | 
|  | 604 | VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second; | 
| Serge Pavlov | 3a56145 | 2015-12-06 14:32:39 +0000 | [diff] [blame] | 605 | PGO.assignRegionCounters(GlobalDecl(CD), F); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 606 | CapturedStmtInfo->EmitBody(*this, CD->getBody()); | 
| Alexey Bataev | 06e80f6 | 2019-05-23 18:19:54 +0000 | [diff] [blame] | 607 | (void)LocalScope.ForceCleanup(); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 608 | FinishFunction(CD->getBodyRBrace()); | 
| Alexey Bataev | e754b18 | 2017-08-09 19:38:53 +0000 | [diff] [blame] | 609 | if (!NeedWrapperFunction) | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 610 | return F; | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 611 |  | 
| Alexey Bataev | efd884d | 2017-08-04 21:26:25 +0000 | [diff] [blame] | 612 | FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true, | 
| Alexey Bataev | e754b18 | 2017-08-09 19:38:53 +0000 | [diff] [blame] | 613 | /*RegisterCastedArgsOnly=*/true, | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 614 | CapturedStmtInfo->getHelperName(), Loc); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 615 | CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true); | 
| Gheorghe-Teodor Bercea | d3dcf2f | 2018-03-14 14:17:45 +0000 | [diff] [blame] | 616 | WrapperCGF.CapturedStmtInfo = CapturedStmtInfo; | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 617 | Args.clear(); | 
|  | 618 | LocalAddrs.clear(); | 
|  | 619 | VLASizes.clear(); | 
|  | 620 | llvm::Function *WrapperF = | 
|  | 621 | emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes, | 
| Alexey Bataev | e754b18 | 2017-08-09 19:38:53 +0000 | [diff] [blame] | 622 | WrapperCGF.CXXThisValue, WrapperFO); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 623 | llvm::SmallVector<llvm::Value *, 4> CallArgs; | 
|  | 624 | for (const auto *Arg : Args) { | 
|  | 625 | llvm::Value *CallArg; | 
|  | 626 | auto I = LocalAddrs.find(Arg); | 
|  | 627 | if (I != LocalAddrs.end()) { | 
| Alexey Bataev | 7ba57af | 2017-10-17 16:47:34 +0000 | [diff] [blame] | 628 | LValue LV = WrapperCGF.MakeAddrLValue( | 
|  | 629 | I->second.second, | 
|  | 630 | I->second.first ? I->second.first->getType() : Arg->getType(), | 
|  | 631 | AlignmentSource::Decl); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 632 | CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc()); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 633 | } else { | 
|  | 634 | auto EI = VLASizes.find(Arg); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 635 | if (EI != VLASizes.end()) { | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 636 | CallArg = EI->second.second; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 637 | } else { | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 638 | LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg), | 
| Ivan A. Kosarev | 5f8c0ca | 2017-10-10 09:39:32 +0000 | [diff] [blame] | 639 | Arg->getType(), | 
|  | 640 | AlignmentSource::Decl); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 641 | CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc()); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 642 | } | 
|  | 643 | } | 
| Alexey Bataev | 7ba57af | 2017-10-17 16:47:34 +0000 | [diff] [blame] | 644 | CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType())); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 645 | } | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 646 | CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, Loc, F, CallArgs); | 
| Alexey Bataev | 1fdfdf7 | 2017-06-29 16:43:05 +0000 | [diff] [blame] | 647 | WrapperCGF.FinishFunction(); | 
|  | 648 | return WrapperF; | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 649 | } | 
|  | 650 |  | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 651 | //===----------------------------------------------------------------------===// | 
|  | 652 | //                              OpenMP Directive Emission | 
|  | 653 | //===----------------------------------------------------------------------===// | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 654 | void CodeGenFunction::EmitOMPAggregateAssign( | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 655 | Address DestAddr, Address SrcAddr, QualType OriginalType, | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 656 | const llvm::function_ref<void(Address, Address)> CopyGen) { | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 657 | // Perform element-by-element initialization. | 
|  | 658 | QualType ElementTy; | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 659 |  | 
|  | 660 | // Drill down to the base element type on both arrays. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 661 | const ArrayType *ArrayTy = OriginalType->getAsArrayTypeUnsafe(); | 
|  | 662 | llvm::Value *NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr); | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 663 | SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType()); | 
|  | 664 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 665 | llvm::Value *SrcBegin = SrcAddr.getPointer(); | 
|  | 666 | llvm::Value *DestBegin = DestAddr.getPointer(); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 667 | // Cast from pointer to array type to pointer to single element. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 668 | llvm::Value *DestEnd = Builder.CreateGEP(DestBegin, NumElements); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 669 | // The basic structure here is a while-do loop. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 670 | llvm::BasicBlock *BodyBB = createBasicBlock("omp.arraycpy.body"); | 
|  | 671 | llvm::BasicBlock *DoneBB = createBasicBlock("omp.arraycpy.done"); | 
|  | 672 | llvm::Value *IsEmpty = | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 673 | Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty"); | 
|  | 674 | Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 675 |  | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 676 | // Enter the loop body, making that address the current address. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 677 | llvm::BasicBlock *EntryBB = Builder.GetInsertBlock(); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 678 | EmitBlock(BodyBB); | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 679 |  | 
|  | 680 | CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy); | 
|  | 681 |  | 
|  | 682 | llvm::PHINode *SrcElementPHI = | 
|  | 683 | Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast"); | 
|  | 684 | SrcElementPHI->addIncoming(SrcBegin, EntryBB); | 
|  | 685 | Address SrcElementCurrent = | 
|  | 686 | Address(SrcElementPHI, | 
|  | 687 | SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize)); | 
|  | 688 |  | 
|  | 689 | llvm::PHINode *DestElementPHI = | 
|  | 690 | Builder.CreatePHI(DestBegin->getType(), 2, "omp.arraycpy.destElementPast"); | 
|  | 691 | DestElementPHI->addIncoming(DestBegin, EntryBB); | 
|  | 692 | Address DestElementCurrent = | 
|  | 693 | Address(DestElementPHI, | 
|  | 694 | DestAddr.getAlignment().alignmentOfArrayElement(ElementSize)); | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 695 |  | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 696 | // Emit copy. | 
|  | 697 | CopyGen(DestElementCurrent, SrcElementCurrent); | 
|  | 698 |  | 
|  | 699 | // Shift the address forward by one element. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 700 | llvm::Value *DestElementNext = Builder.CreateConstGEP1_32( | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 701 | DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element"); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 702 | llvm::Value *SrcElementNext = Builder.CreateConstGEP1_32( | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 703 | SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element"); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 704 | // Check whether we've reached the end. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 705 | llvm::Value *Done = | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 706 | Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done"); | 
|  | 707 | Builder.CreateCondBr(Done, DoneBB, BodyBB); | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 708 | DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock()); | 
|  | 709 | SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock()); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 710 |  | 
|  | 711 | // Done. | 
|  | 712 | EmitBlock(DoneBB, /*IsFinished=*/true); | 
|  | 713 | } | 
|  | 714 |  | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 715 | void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr, | 
|  | 716 | Address SrcAddr, const VarDecl *DestVD, | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 717 | const VarDecl *SrcVD, const Expr *Copy) { | 
|  | 718 | if (OriginalType->isArrayType()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 719 | const auto *BO = dyn_cast<BinaryOperator>(Copy); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 720 | if (BO && BO->getOpcode() == BO_Assign) { | 
|  | 721 | // Perform simple memcpy for simple copying. | 
| Ivan A. Kosarev | 1860b52 | 2018-01-25 14:21:55 +0000 | [diff] [blame] | 722 | LValue Dest = MakeAddrLValue(DestAddr, OriginalType); | 
|  | 723 | LValue Src = MakeAddrLValue(SrcAddr, OriginalType); | 
|  | 724 | EmitAggregateAssign(Dest, Src, OriginalType); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 725 | } else { | 
|  | 726 | // For arrays with complex element types perform element by element | 
|  | 727 | // copying. | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 728 | EmitOMPAggregateAssign( | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 729 | DestAddr, SrcAddr, OriginalType, | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 730 | [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) { | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 731 | // Working with the single array element, so have to remap | 
|  | 732 | // destination and source variables to corresponding array | 
|  | 733 | // elements. | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 734 | CodeGenFunction::OMPPrivateScope Remap(*this); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 735 | Remap.addPrivate(DestVD, [DestElement]() { return DestElement; }); | 
|  | 736 | Remap.addPrivate(SrcVD, [SrcElement]() { return SrcElement; }); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 737 | (void)Remap.Privatize(); | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 738 | EmitIgnoredExpr(Copy); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 739 | }); | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 740 | } | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 741 | } else { | 
|  | 742 | // Remap pseudo source variable to private copy. | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 743 | CodeGenFunction::OMPPrivateScope Remap(*this); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 744 | Remap.addPrivate(SrcVD, [SrcAddr]() { return SrcAddr; }); | 
|  | 745 | Remap.addPrivate(DestVD, [DestAddr]() { return DestAddr; }); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 746 | (void)Remap.Privatize(); | 
|  | 747 | // Emit copying of the whole variable. | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 748 | EmitIgnoredExpr(Copy); | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 749 | } | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 750 | } | 
|  | 751 |  | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 752 | bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, | 
|  | 753 | OMPPrivateScope &PrivateScope) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 754 | if (!HaveInsertPoint()) | 
|  | 755 | return false; | 
| Alexey Bataev | 1af5bd5 | 2019-03-05 17:47:18 +0000 | [diff] [blame] | 756 | bool DeviceConstTarget = | 
|  | 757 | getLangOpts().OpenMPIsDevice && | 
|  | 758 | isOpenMPTargetExecutionDirective(D.getDirectiveKind()); | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 759 | bool FirstprivateIsLastprivate = false; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 760 | llvm::DenseMap<const VarDecl *, OpenMPLastprivateModifier> Lastprivates; | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 761 | for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { | 
|  | 762 | for (const auto *D : C->varlists()) | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 763 | Lastprivates.try_emplace( | 
|  | 764 | cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl(), | 
|  | 765 | C->getKind()); | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 766 | } | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 767 | llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 768 | llvm::SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | 
|  | 769 | getOpenMPCaptureRegions(CaptureRegions, D.getDirectiveKind()); | 
|  | 770 | // Force emission of the firstprivate copy if the directive does not emit | 
|  | 771 | // outlined function, like omp for, omp simd, omp distribute etc. | 
|  | 772 | bool MustEmitFirstprivateCopy = | 
|  | 773 | CaptureRegions.size() == 1 && CaptureRegions.back() == OMPD_unknown; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 774 | for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 775 | const auto *IRef = C->varlist_begin(); | 
|  | 776 | const auto *InitsRef = C->inits().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 777 | for (const Expr *IInit : C->private_copies()) { | 
|  | 778 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); | 
| Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 779 | bool ThisFirstprivateIsLastprivate = | 
|  | 780 | Lastprivates.count(OrigVD->getCanonicalDecl()) > 0; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 781 | const FieldDecl *FD = CapturedStmtInfo->lookup(OrigVD); | 
| Alexey Bataev | 9c39781 | 2019-04-03 17:57:06 +0000 | [diff] [blame] | 782 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 783 | if (!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD && | 
| Alexey Bataev | 9c39781 | 2019-04-03 17:57:06 +0000 | [diff] [blame] | 784 | !FD->getType()->isReferenceType() && | 
|  | 785 | (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) { | 
| Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 786 | EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()); | 
|  | 787 | ++IRef; | 
|  | 788 | ++InitsRef; | 
|  | 789 | continue; | 
|  | 790 | } | 
| Alexey Bataev | 1af5bd5 | 2019-03-05 17:47:18 +0000 | [diff] [blame] | 791 | // Do not emit copy for firstprivate constant variables in target regions, | 
|  | 792 | // captured by reference. | 
|  | 793 | if (DeviceConstTarget && OrigVD->getType().isConstant(getContext()) && | 
| Alexey Bataev | 9c39781 | 2019-04-03 17:57:06 +0000 | [diff] [blame] | 794 | FD && FD->getType()->isReferenceType() && | 
|  | 795 | (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) { | 
| Alexey Bataev | 1af5bd5 | 2019-03-05 17:47:18 +0000 | [diff] [blame] | 796 | (void)CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(*this, | 
|  | 797 | OrigVD); | 
|  | 798 | ++IRef; | 
|  | 799 | ++InitsRef; | 
|  | 800 | continue; | 
|  | 801 | } | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 802 | FirstprivateIsLastprivate = | 
| Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 803 | FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate; | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 804 | if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 805 | const auto *VDInit = | 
|  | 806 | cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl()); | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 807 | bool IsRegistered; | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 808 | DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), | 
| Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 809 | /*RefersToEnclosingVariableOrCapture=*/FD != nullptr, | 
|  | 810 | (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc()); | 
| Alexey Bataev | e0ef04f | 2019-05-23 22:30:43 +0000 | [diff] [blame] | 811 | LValue OriginalLVal; | 
|  | 812 | if (!FD) { | 
|  | 813 | // Check if the firstprivate variable is just a constant value. | 
|  | 814 | ConstantEmission CE = tryEmitAsConstant(&DRE); | 
|  | 815 | if (CE && !CE.isReference()) { | 
|  | 816 | // Constant value, no need to create a copy. | 
|  | 817 | ++IRef; | 
|  | 818 | ++InitsRef; | 
|  | 819 | continue; | 
|  | 820 | } | 
|  | 821 | if (CE && CE.isReference()) { | 
|  | 822 | OriginalLVal = CE.getReferenceLValue(*this, &DRE); | 
|  | 823 | } else { | 
|  | 824 | assert(!CE && "Expected non-constant firstprivate."); | 
|  | 825 | OriginalLVal = EmitLValue(&DRE); | 
|  | 826 | } | 
|  | 827 | } else { | 
|  | 828 | OriginalLVal = EmitLValue(&DRE); | 
|  | 829 | } | 
| Alexey Bataev | feddd64 | 2016-04-22 09:05:03 +0000 | [diff] [blame] | 830 | QualType Type = VD->getType(); | 
| Alexey Bataev | 1d9c15c | 2015-05-19 12:31:28 +0000 | [diff] [blame] | 831 | if (Type->isArrayType()) { | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 832 | // Emit VarDecl with copy init for arrays. | 
|  | 833 | // Get the address of the original variable captured in current | 
|  | 834 | // captured region. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 835 | IsRegistered = PrivateScope.addPrivate( | 
|  | 836 | OrigVD, [this, VD, Type, OriginalLVal, VDInit]() { | 
|  | 837 | AutoVarEmission Emission = EmitAutoVarAlloca(*VD); | 
|  | 838 | const Expr *Init = VD->getInit(); | 
|  | 839 | if (!isa<CXXConstructExpr>(Init) || | 
|  | 840 | isTrivialInitializer(Init)) { | 
|  | 841 | // Perform simple memcpy. | 
|  | 842 | LValue Dest = | 
|  | 843 | MakeAddrLValue(Emission.getAllocatedAddress(), Type); | 
|  | 844 | EmitAggregateAssign(Dest, OriginalLVal, Type); | 
|  | 845 | } else { | 
|  | 846 | EmitOMPAggregateAssign( | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 847 | Emission.getAllocatedAddress(), | 
|  | 848 | OriginalLVal.getAddress(*this), Type, | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 849 | [this, VDInit, Init](Address DestElement, | 
|  | 850 | Address SrcElement) { | 
|  | 851 | // Clean up any temporaries needed by the | 
|  | 852 | // initialization. | 
|  | 853 | RunCleanupsScope InitScope(*this); | 
|  | 854 | // Emit initialization for single element. | 
|  | 855 | setAddrOfLocalVar(VDInit, SrcElement); | 
|  | 856 | EmitAnyExprToMem(Init, DestElement, | 
|  | 857 | Init->getType().getQualifiers(), | 
|  | 858 | /*IsInitializer*/ false); | 
|  | 859 | LocalDeclMap.erase(VDInit); | 
|  | 860 | }); | 
|  | 861 | } | 
|  | 862 | EmitAutoVarCleanups(Emission); | 
|  | 863 | return Emission.getAllocatedAddress(); | 
|  | 864 | }); | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 865 | } else { | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 866 | Address OriginalAddr = OriginalLVal.getAddress(*this); | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 867 | IsRegistered = | 
|  | 868 | PrivateScope.addPrivate(OrigVD, [this, VDInit, OriginalAddr, VD, | 
|  | 869 | ThisFirstprivateIsLastprivate, | 
|  | 870 | OrigVD, &Lastprivates, IRef]() { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 871 | // Emit private VarDecl with copy init. | 
|  | 872 | // Remap temp VDInit variable to the address of the original | 
|  | 873 | // variable (for proper handling of captured global variables). | 
|  | 874 | setAddrOfLocalVar(VDInit, OriginalAddr); | 
|  | 875 | EmitDecl(*VD); | 
|  | 876 | LocalDeclMap.erase(VDInit); | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 877 | if (ThisFirstprivateIsLastprivate && | 
|  | 878 | Lastprivates[OrigVD->getCanonicalDecl()] == | 
|  | 879 | OMPC_LASTPRIVATE_conditional) { | 
|  | 880 | // Create/init special variable for lastprivate conditionals. | 
|  | 881 | Address VDAddr = | 
|  | 882 | CGM.getOpenMPRuntime().emitLastprivateConditionalInit( | 
|  | 883 | *this, OrigVD); | 
|  | 884 | llvm::Value *V = EmitLoadOfScalar( | 
|  | 885 | MakeAddrLValue(GetAddrOfLocalVar(VD), (*IRef)->getType(), | 
|  | 886 | AlignmentSource::Decl), | 
|  | 887 | (*IRef)->getExprLoc()); | 
|  | 888 | EmitStoreOfScalar(V, | 
|  | 889 | MakeAddrLValue(VDAddr, (*IRef)->getType(), | 
|  | 890 | AlignmentSource::Decl)); | 
|  | 891 | LocalDeclMap.erase(VD); | 
|  | 892 | setAddrOfLocalVar(VD, VDAddr); | 
|  | 893 | return VDAddr; | 
|  | 894 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 895 | return GetAddrOfLocalVar(VD); | 
|  | 896 | }); | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 897 | } | 
|  | 898 | assert(IsRegistered && | 
|  | 899 | "firstprivate var already registered as private"); | 
|  | 900 | // Silence the warning about unused variable. | 
|  | 901 | (void)IsRegistered; | 
|  | 902 | } | 
| Richard Trieu | cc3949d | 2016-02-18 22:34:54 +0000 | [diff] [blame] | 903 | ++IRef; | 
|  | 904 | ++InitsRef; | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 905 | } | 
|  | 906 | } | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 907 | return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty(); | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 908 | } | 
|  | 909 |  | 
| Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 910 | void CodeGenFunction::EmitOMPPrivateClause( | 
|  | 911 | const OMPExecutableDirective &D, | 
|  | 912 | CodeGenFunction::OMPPrivateScope &PrivateScope) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 913 | if (!HaveInsertPoint()) | 
|  | 914 | return; | 
| Alexey Bataev | 50a6458 | 2015-04-22 12:24:45 +0000 | [diff] [blame] | 915 | llvm::DenseSet<const VarDecl *> EmittedAsPrivate; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 916 | for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) { | 
| Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 917 | auto IRef = C->varlist_begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 918 | for (const Expr *IInit : C->private_copies()) { | 
|  | 919 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); | 
| Alexey Bataev | 50a6458 | 2015-04-22 12:24:45 +0000 | [diff] [blame] | 920 | if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 921 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); | 
|  | 922 | bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD]() { | 
|  | 923 | // Emit private VarDecl with copy init. | 
|  | 924 | EmitDecl(*VD); | 
|  | 925 | return GetAddrOfLocalVar(VD); | 
|  | 926 | }); | 
| Alexey Bataev | 50a6458 | 2015-04-22 12:24:45 +0000 | [diff] [blame] | 927 | assert(IsRegistered && "private var already registered as private"); | 
|  | 928 | // Silence the warning about unused variable. | 
|  | 929 | (void)IsRegistered; | 
|  | 930 | } | 
| Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 931 | ++IRef; | 
|  | 932 | } | 
|  | 933 | } | 
|  | 934 | } | 
|  | 935 |  | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 936 | bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 937 | if (!HaveInsertPoint()) | 
|  | 938 | return false; | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 939 | // threadprivate_var1 = master_threadprivate_var1; | 
|  | 940 | // operator=(threadprivate_var2, master_threadprivate_var2); | 
|  | 941 | // ... | 
|  | 942 | // __kmpc_barrier(&loc, global_tid); | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 943 | llvm::DenseSet<const VarDecl *> CopiedVars; | 
|  | 944 | llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 945 | for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) { | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 946 | auto IRef = C->varlist_begin(); | 
|  | 947 | auto ISrcRef = C->source_exprs().begin(); | 
|  | 948 | auto IDestRef = C->destination_exprs().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 949 | for (const Expr *AssignOp : C->assignment_ops()) { | 
|  | 950 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); | 
| Alexey Bataev | 1d9c15c | 2015-05-19 12:31:28 +0000 | [diff] [blame] | 951 | QualType Type = VD->getType(); | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 952 | if (CopiedVars.insert(VD->getCanonicalDecl()).second) { | 
| Samuel Antao | 9c75cfe | 2015-07-27 16:38:06 +0000 | [diff] [blame] | 953 | // Get the address of the master variable. If we are emitting code with | 
|  | 954 | // TLS support, the address is passed from the master as field in the | 
|  | 955 | // captured declaration. | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 956 | Address MasterAddr = Address::invalid(); | 
| Samuel Antao | 9c75cfe | 2015-07-27 16:38:06 +0000 | [diff] [blame] | 957 | if (getLangOpts().OpenMPUseTLS && | 
|  | 958 | getContext().getTargetInfo().isTLSSupported()) { | 
|  | 959 | assert(CapturedStmtInfo->lookup(VD) && | 
|  | 960 | "Copyin threadprivates should have been captured!"); | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 961 | DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD), true, | 
|  | 962 | (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc()); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 963 | MasterAddr = EmitLValue(&DRE).getAddress(*this); | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 964 | LocalDeclMap.erase(VD); | 
| Samuel Antao | 9c75cfe | 2015-07-27 16:38:06 +0000 | [diff] [blame] | 965 | } else { | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 966 | MasterAddr = | 
|  | 967 | Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD) | 
|  | 968 | : CGM.GetAddrOfGlobal(VD), | 
|  | 969 | getContext().getDeclAlign(VD)); | 
| Samuel Antao | 9c75cfe | 2015-07-27 16:38:06 +0000 | [diff] [blame] | 970 | } | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 971 | // Get the address of the threadprivate variable. | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 972 | Address PrivateAddr = EmitLValue(*IRef).getAddress(*this); | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 973 | if (CopiedVars.size() == 1) { | 
|  | 974 | // At first check if current thread is a master thread. If it is, no | 
|  | 975 | // need to copy data. | 
|  | 976 | CopyBegin = createBasicBlock("copyin.not.master"); | 
|  | 977 | CopyEnd = createBasicBlock("copyin.not.master.end"); | 
|  | 978 | Builder.CreateCondBr( | 
|  | 979 | Builder.CreateICmpNE( | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 980 | Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy), | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 981 | Builder.CreatePtrToInt(PrivateAddr.getPointer(), | 
|  | 982 | CGM.IntPtrTy)), | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 983 | CopyBegin, CopyEnd); | 
|  | 984 | EmitBlock(CopyBegin); | 
|  | 985 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 986 | const auto *SrcVD = | 
|  | 987 | cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl()); | 
|  | 988 | const auto *DestVD = | 
|  | 989 | cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 990 | EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp); | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 991 | } | 
|  | 992 | ++IRef; | 
|  | 993 | ++ISrcRef; | 
|  | 994 | ++IDestRef; | 
|  | 995 | } | 
|  | 996 | } | 
|  | 997 | if (CopyEnd) { | 
|  | 998 | // Exit out of copying procedure for non-master thread. | 
|  | 999 | EmitBlock(CopyEnd, /*IsFinished=*/true); | 
|  | 1000 | return true; | 
|  | 1001 | } | 
|  | 1002 | return false; | 
|  | 1003 | } | 
|  | 1004 |  | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1005 | bool CodeGenFunction::EmitOMPLastprivateClauseInit( | 
|  | 1006 | const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1007 | if (!HaveInsertPoint()) | 
|  | 1008 | return false; | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1009 | bool HasAtLeastOneLastprivate = false; | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1010 | llvm::DenseSet<const VarDecl *> SIMDLCVs; | 
|  | 1011 | if (isOpenMPSimdDirective(D.getDirectiveKind())) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1012 | const auto *LoopDirective = cast<OMPLoopDirective>(&D); | 
|  | 1013 | for (const Expr *C : LoopDirective->counters()) { | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1014 | SIMDLCVs.insert( | 
|  | 1015 | cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl()); | 
|  | 1016 | } | 
|  | 1017 | } | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1018 | llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1019 | for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { | 
| Alexey Bataev | d130fd1 | 2015-05-13 10:23:02 +0000 | [diff] [blame] | 1020 | HasAtLeastOneLastprivate = true; | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1021 | if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) && | 
|  | 1022 | !getLangOpts().OpenMPSimd) | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 1023 | break; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 1024 | const auto *IRef = C->varlist_begin(); | 
|  | 1025 | const auto *IDestRef = C->destination_exprs().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1026 | for (const Expr *IInit : C->private_copies()) { | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1027 | // Keep the address of the original variable for future update at the end | 
|  | 1028 | // of the loop. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1029 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 1030 | // Taskloops do not require additional initialization, it is done in | 
|  | 1031 | // runtime support library. | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1032 | if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1033 | const auto *DestVD = | 
|  | 1034 | cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); | 
|  | 1035 | PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() { | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 1036 | DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), | 
|  | 1037 | /*RefersToEnclosingVariableOrCapture=*/ | 
|  | 1038 | CapturedStmtInfo->lookup(OrigVD) != nullptr, | 
|  | 1039 | (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc()); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 1040 | return EmitLValue(&DRE).getAddress(*this); | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1041 | }); | 
|  | 1042 | // Check if the variable is also a firstprivate: in this case IInit is | 
|  | 1043 | // not generated. Initialization of this variable will happen in codegen | 
|  | 1044 | // for 'firstprivate' clause. | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1045 | if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1046 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 1047 | bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD, C, | 
|  | 1048 | OrigVD]() { | 
|  | 1049 | if (C->getKind() == OMPC_LASTPRIVATE_conditional) { | 
|  | 1050 | Address VDAddr = | 
|  | 1051 | CGM.getOpenMPRuntime().emitLastprivateConditionalInit(*this, | 
|  | 1052 | OrigVD); | 
|  | 1053 | setAddrOfLocalVar(VD, VDAddr); | 
|  | 1054 | return VDAddr; | 
|  | 1055 | } | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 1056 | // Emit private VarDecl with copy init. | 
|  | 1057 | EmitDecl(*VD); | 
|  | 1058 | return GetAddrOfLocalVar(VD); | 
|  | 1059 | }); | 
| Alexey Bataev | d130fd1 | 2015-05-13 10:23:02 +0000 | [diff] [blame] | 1060 | assert(IsRegistered && | 
|  | 1061 | "lastprivate var already registered as private"); | 
|  | 1062 | (void)IsRegistered; | 
|  | 1063 | } | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1064 | } | 
| Richard Trieu | cc3949d | 2016-02-18 22:34:54 +0000 | [diff] [blame] | 1065 | ++IRef; | 
|  | 1066 | ++IDestRef; | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1067 | } | 
|  | 1068 | } | 
|  | 1069 | return HasAtLeastOneLastprivate; | 
|  | 1070 | } | 
|  | 1071 |  | 
|  | 1072 | void CodeGenFunction::EmitOMPLastprivateClauseFinal( | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1073 | const OMPExecutableDirective &D, bool NoFinals, | 
|  | 1074 | llvm::Value *IsLastIterCond) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1075 | if (!HaveInsertPoint()) | 
|  | 1076 | return; | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1077 | // Emit following code: | 
|  | 1078 | // if (<IsLastIterCond>) { | 
|  | 1079 | //   orig_var1 = private_orig_var1; | 
|  | 1080 | //   ... | 
|  | 1081 | //   orig_varn = private_orig_varn; | 
|  | 1082 | // } | 
| Alexey Bataev | fc087ec | 2015-06-16 13:14:42 +0000 | [diff] [blame] | 1083 | llvm::BasicBlock *ThenBB = nullptr; | 
|  | 1084 | llvm::BasicBlock *DoneBB = nullptr; | 
|  | 1085 | if (IsLastIterCond) { | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 1086 | // Emit implicit barrier if at least one lastprivate conditional is found | 
|  | 1087 | // and this is not a simd mode. | 
|  | 1088 | if (!getLangOpts().OpenMPSimd && | 
|  | 1089 | llvm::any_of(D.getClausesOfKind<OMPLastprivateClause>(), | 
|  | 1090 | [](const OMPLastprivateClause *C) { | 
|  | 1091 | return C->getKind() == OMPC_LASTPRIVATE_conditional; | 
|  | 1092 | })) { | 
|  | 1093 | CGM.getOpenMPRuntime().emitBarrierCall(*this, D.getBeginLoc(), | 
|  | 1094 | OMPD_unknown, | 
|  | 1095 | /*EmitChecks=*/false, | 
|  | 1096 | /*ForceSimpleCall=*/true); | 
|  | 1097 | } | 
| Alexey Bataev | fc087ec | 2015-06-16 13:14:42 +0000 | [diff] [blame] | 1098 | ThenBB = createBasicBlock(".omp.lastprivate.then"); | 
|  | 1099 | DoneBB = createBasicBlock(".omp.lastprivate.done"); | 
|  | 1100 | Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB); | 
|  | 1101 | EmitBlock(ThenBB); | 
|  | 1102 | } | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1103 | llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; | 
|  | 1104 | llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1105 | if (const auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) { | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1106 | auto IC = LoopDirective->counters().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1107 | for (const Expr *F : LoopDirective->finals()) { | 
|  | 1108 | const auto *D = | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1109 | cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl(); | 
|  | 1110 | if (NoFinals) | 
|  | 1111 | AlreadyEmittedVars.insert(D); | 
|  | 1112 | else | 
|  | 1113 | LoopCountersAndUpdates[D] = F; | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1114 | ++IC; | 
| Alexey Bataev | 7a228ff | 2015-05-21 07:59:51 +0000 | [diff] [blame] | 1115 | } | 
|  | 1116 | } | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1117 | for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { | 
|  | 1118 | auto IRef = C->varlist_begin(); | 
|  | 1119 | auto ISrcRef = C->source_exprs().begin(); | 
|  | 1120 | auto IDestRef = C->destination_exprs().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1121 | for (const Expr *AssignOp : C->assignment_ops()) { | 
|  | 1122 | const auto *PrivateVD = | 
|  | 1123 | cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1124 | QualType Type = PrivateVD->getType(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1125 | const auto *CanonicalVD = PrivateVD->getCanonicalDecl(); | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1126 | if (AlreadyEmittedVars.insert(CanonicalVD).second) { | 
|  | 1127 | // If lastprivate variable is a loop control variable for loop-based | 
|  | 1128 | // directive, update its value before copyin back to original | 
|  | 1129 | // variable. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1130 | if (const Expr *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1131 | EmitIgnoredExpr(FinalExpr); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1132 | const auto *SrcVD = | 
|  | 1133 | cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl()); | 
|  | 1134 | const auto *DestVD = | 
|  | 1135 | cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1136 | // Get the address of the private variable. | 
|  | 1137 | Address PrivateAddr = GetAddrOfLocalVar(PrivateVD); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1138 | if (const auto *RefTy = PrivateVD->getType()->getAs<ReferenceType>()) | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1139 | PrivateAddr = | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 1140 | Address(Builder.CreateLoad(PrivateAddr), | 
|  | 1141 | getNaturalTypeAlignment(RefTy->getPointeeType())); | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 1142 | // Store the last value to the private copy in the last iteration. | 
|  | 1143 | if (C->getKind() == OMPC_LASTPRIVATE_conditional) | 
|  | 1144 | CGM.getOpenMPRuntime().emitLastprivateConditionalFinalUpdate( | 
|  | 1145 | *this, MakeAddrLValue(PrivateAddr, (*IRef)->getType()), PrivateVD, | 
|  | 1146 | (*IRef)->getExprLoc()); | 
|  | 1147 | // Get the address of the original variable. | 
|  | 1148 | Address OriginalAddr = GetAddrOfLocalVar(DestVD); | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1149 | EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp); | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1150 | } | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1151 | ++IRef; | 
|  | 1152 | ++ISrcRef; | 
|  | 1153 | ++IDestRef; | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1154 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1155 | if (const Expr *PostUpdate = C->getPostUpdateExpr()) | 
| Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 1156 | EmitIgnoredExpr(PostUpdate); | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1157 | } | 
| Alexey Bataev | 8ffcc94 | 2016-02-18 13:48:15 +0000 | [diff] [blame] | 1158 | if (IsLastIterCond) | 
| Alexey Bataev | fc087ec | 2015-06-16 13:14:42 +0000 | [diff] [blame] | 1159 | EmitBlock(DoneBB, /*IsFinished=*/true); | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1160 | } | 
|  | 1161 |  | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1162 | void CodeGenFunction::EmitOMPReductionClauseInit( | 
|  | 1163 | const OMPExecutableDirective &D, | 
|  | 1164 | CodeGenFunction::OMPPrivateScope &PrivateScope) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1165 | if (!HaveInsertPoint()) | 
|  | 1166 | return; | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1167 | SmallVector<const Expr *, 4> Shareds; | 
|  | 1168 | SmallVector<const Expr *, 4> Privates; | 
|  | 1169 | SmallVector<const Expr *, 4> ReductionOps; | 
|  | 1170 | SmallVector<const Expr *, 4> LHSs; | 
|  | 1171 | SmallVector<const Expr *, 4> RHSs; | 
| Alexey Bataev | 8c2f4e0 | 2020-04-24 09:56:29 -0400 | [diff] [blame] | 1172 | OMPTaskDataTy Data; | 
|  | 1173 | SmallVector<const Expr *, 4> TaskLHSs; | 
|  | 1174 | SmallVector<const Expr *, 4> TaskRHSs; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1175 | for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { | 
| Alexey Bataev | 8c2f4e0 | 2020-04-24 09:56:29 -0400 | [diff] [blame] | 1176 | Shareds.append(C->varlist_begin(), C->varlist_end()); | 
|  | 1177 | Privates.append(C->privates().begin(), C->privates().end()); | 
|  | 1178 | ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end()); | 
|  | 1179 | LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); | 
|  | 1180 | RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); | 
|  | 1181 | if (C->getModifier() == OMPC_REDUCTION_task) { | 
|  | 1182 | Data.ReductionVars.append(C->privates().begin(), C->privates().end()); | 
|  | 1183 | Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end()); | 
|  | 1184 | Data.ReductionCopies.append(C->privates().begin(), C->privates().end()); | 
|  | 1185 | Data.ReductionOps.append(C->reduction_ops().begin(), | 
|  | 1186 | C->reduction_ops().end()); | 
|  | 1187 | TaskLHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); | 
|  | 1188 | TaskRHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1189 | } | 
|  | 1190 | } | 
| Alexey Bataev | e9bfa1d | 2020-04-23 13:27:03 -0400 | [diff] [blame] | 1191 | ReductionCodeGen RedCG(Shareds, Shareds, Privates, ReductionOps); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1192 | unsigned Count = 0; | 
| Alexey Bataev | e9bfa1d | 2020-04-23 13:27:03 -0400 | [diff] [blame] | 1193 | auto *ILHS = LHSs.begin(); | 
|  | 1194 | auto *IRHS = RHSs.begin(); | 
|  | 1195 | auto *IPriv = Privates.begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1196 | for (const Expr *IRef : Shareds) { | 
|  | 1197 | const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl()); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1198 | // Emit private VarDecl with reduction init. | 
| Alexey Bataev | e9bfa1d | 2020-04-23 13:27:03 -0400 | [diff] [blame] | 1199 | RedCG.emitSharedOrigLValue(*this, Count); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1200 | RedCG.emitAggregateType(*this, Count); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1201 | AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1202 | RedCG.emitInitialization(*this, Count, Emission.getAllocatedAddress(), | 
|  | 1203 | RedCG.getSharedLValue(Count), | 
|  | 1204 | [&Emission](CodeGenFunction &CGF) { | 
|  | 1205 | CGF.EmitAutoVarInit(Emission); | 
|  | 1206 | return true; | 
|  | 1207 | }); | 
|  | 1208 | EmitAutoVarCleanups(Emission); | 
|  | 1209 | Address BaseAddr = RedCG.adjustPrivateAddress( | 
|  | 1210 | *this, Count, Emission.getAllocatedAddress()); | 
|  | 1211 | bool IsRegistered = PrivateScope.addPrivate( | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1212 | RedCG.getBaseDecl(Count), [BaseAddr]() { return BaseAddr; }); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1213 | assert(IsRegistered && "private var already registered as private"); | 
|  | 1214 | // Silence the warning about unused variable. | 
|  | 1215 | (void)IsRegistered; | 
|  | 1216 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1217 | const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl()); | 
|  | 1218 | const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl()); | 
| Jonas Hahnfeld | 4525c82 | 2017-10-23 19:01:35 +0000 | [diff] [blame] | 1219 | QualType Type = PrivateVD->getType(); | 
|  | 1220 | bool isaOMPArraySectionExpr = isa<OMPArraySectionExpr>(IRef); | 
|  | 1221 | if (isaOMPArraySectionExpr && Type->isVariablyModifiedType()) { | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1222 | // Store the address of the original variable associated with the LHS | 
|  | 1223 | // implicit variable. | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 1224 | PrivateScope.addPrivate(LHSVD, [&RedCG, Count, this]() { | 
|  | 1225 | return RedCG.getSharedLValue(Count).getAddress(*this); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1226 | }); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1227 | PrivateScope.addPrivate( | 
|  | 1228 | RHSVD, [this, PrivateVD]() { return GetAddrOfLocalVar(PrivateVD); }); | 
| Jonas Hahnfeld | 4525c82 | 2017-10-23 19:01:35 +0000 | [diff] [blame] | 1229 | } else if ((isaOMPArraySectionExpr && Type->isScalarType()) || | 
|  | 1230 | isa<ArraySubscriptExpr>(IRef)) { | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1231 | // Store the address of the original variable associated with the LHS | 
|  | 1232 | // implicit variable. | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 1233 | PrivateScope.addPrivate(LHSVD, [&RedCG, Count, this]() { | 
|  | 1234 | return RedCG.getSharedLValue(Count).getAddress(*this); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1235 | }); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1236 | PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() { | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1237 | return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD), | 
|  | 1238 | ConvertTypeForMem(RHSVD->getType()), | 
|  | 1239 | "rhs.begin"); | 
|  | 1240 | }); | 
|  | 1241 | } else { | 
|  | 1242 | QualType Type = PrivateVD->getType(); | 
|  | 1243 | bool IsArray = getContext().getAsArrayType(Type) != nullptr; | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 1244 | Address OriginalAddr = RedCG.getSharedLValue(Count).getAddress(*this); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1245 | // Store the address of the original variable associated with the LHS | 
|  | 1246 | // implicit variable. | 
|  | 1247 | if (IsArray) { | 
|  | 1248 | OriginalAddr = Builder.CreateElementBitCast( | 
|  | 1249 | OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin"); | 
|  | 1250 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1251 | PrivateScope.addPrivate(LHSVD, [OriginalAddr]() { return OriginalAddr; }); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1252 | PrivateScope.addPrivate( | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1253 | RHSVD, [this, PrivateVD, RHSVD, IsArray]() { | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 1254 | return IsArray | 
|  | 1255 | ? Builder.CreateElementBitCast( | 
|  | 1256 | GetAddrOfLocalVar(PrivateVD), | 
|  | 1257 | ConvertTypeForMem(RHSVD->getType()), "rhs.begin") | 
|  | 1258 | : GetAddrOfLocalVar(PrivateVD); | 
|  | 1259 | }); | 
|  | 1260 | } | 
|  | 1261 | ++ILHS; | 
|  | 1262 | ++IRHS; | 
|  | 1263 | ++IPriv; | 
|  | 1264 | ++Count; | 
|  | 1265 | } | 
| Alexey Bataev | 8c2f4e0 | 2020-04-24 09:56:29 -0400 | [diff] [blame] | 1266 | if (!Data.ReductionVars.empty()) { | 
|  | 1267 | Data.IsReductionWithTaskMod = true; | 
|  | 1268 | Data.IsWorksharingReduction = | 
|  | 1269 | isOpenMPWorksharingDirective(D.getDirectiveKind()); | 
|  | 1270 | llvm::Value *ReductionDesc = CGM.getOpenMPRuntime().emitTaskReductionInit( | 
|  | 1271 | *this, D.getBeginLoc(), TaskLHSs, TaskRHSs, Data); | 
|  | 1272 | const Expr *TaskRedRef = nullptr; | 
|  | 1273 | switch (D.getDirectiveKind()) { | 
|  | 1274 | case OMPD_parallel: | 
|  | 1275 | TaskRedRef = cast<OMPParallelDirective>(D).getTaskReductionRefExpr(); | 
|  | 1276 | break; | 
|  | 1277 | case OMPD_for: | 
|  | 1278 | TaskRedRef = cast<OMPForDirective>(D).getTaskReductionRefExpr(); | 
|  | 1279 | break; | 
|  | 1280 | case OMPD_sections: | 
|  | 1281 | TaskRedRef = cast<OMPSectionsDirective>(D).getTaskReductionRefExpr(); | 
|  | 1282 | break; | 
|  | 1283 | case OMPD_parallel_for: | 
|  | 1284 | TaskRedRef = cast<OMPParallelForDirective>(D).getTaskReductionRefExpr(); | 
|  | 1285 | break; | 
|  | 1286 | case OMPD_parallel_master: | 
|  | 1287 | TaskRedRef = | 
|  | 1288 | cast<OMPParallelMasterDirective>(D).getTaskReductionRefExpr(); | 
|  | 1289 | break; | 
|  | 1290 | case OMPD_parallel_sections: | 
|  | 1291 | TaskRedRef = | 
|  | 1292 | cast<OMPParallelSectionsDirective>(D).getTaskReductionRefExpr(); | 
|  | 1293 | break; | 
|  | 1294 | case OMPD_target_parallel: | 
|  | 1295 | TaskRedRef = | 
|  | 1296 | cast<OMPTargetParallelDirective>(D).getTaskReductionRefExpr(); | 
|  | 1297 | break; | 
|  | 1298 | case OMPD_target_parallel_for: | 
|  | 1299 | TaskRedRef = | 
|  | 1300 | cast<OMPTargetParallelForDirective>(D).getTaskReductionRefExpr(); | 
|  | 1301 | break; | 
|  | 1302 | case OMPD_distribute_parallel_for: | 
|  | 1303 | TaskRedRef = | 
|  | 1304 | cast<OMPDistributeParallelForDirective>(D).getTaskReductionRefExpr(); | 
|  | 1305 | break; | 
|  | 1306 | case OMPD_teams_distribute_parallel_for: | 
|  | 1307 | TaskRedRef = cast<OMPTeamsDistributeParallelForDirective>(D) | 
|  | 1308 | .getTaskReductionRefExpr(); | 
|  | 1309 | break; | 
|  | 1310 | case OMPD_target_teams_distribute_parallel_for: | 
|  | 1311 | TaskRedRef = cast<OMPTargetTeamsDistributeParallelForDirective>(D) | 
|  | 1312 | .getTaskReductionRefExpr(); | 
|  | 1313 | break; | 
|  | 1314 | case OMPD_simd: | 
|  | 1315 | case OMPD_for_simd: | 
|  | 1316 | case OMPD_section: | 
|  | 1317 | case OMPD_single: | 
|  | 1318 | case OMPD_master: | 
|  | 1319 | case OMPD_critical: | 
|  | 1320 | case OMPD_parallel_for_simd: | 
|  | 1321 | case OMPD_task: | 
|  | 1322 | case OMPD_taskyield: | 
|  | 1323 | case OMPD_barrier: | 
|  | 1324 | case OMPD_taskwait: | 
|  | 1325 | case OMPD_taskgroup: | 
|  | 1326 | case OMPD_flush: | 
|  | 1327 | case OMPD_depobj: | 
|  | 1328 | case OMPD_scan: | 
|  | 1329 | case OMPD_ordered: | 
|  | 1330 | case OMPD_atomic: | 
|  | 1331 | case OMPD_teams: | 
|  | 1332 | case OMPD_target: | 
|  | 1333 | case OMPD_cancellation_point: | 
|  | 1334 | case OMPD_cancel: | 
|  | 1335 | case OMPD_target_data: | 
|  | 1336 | case OMPD_target_enter_data: | 
|  | 1337 | case OMPD_target_exit_data: | 
|  | 1338 | case OMPD_taskloop: | 
|  | 1339 | case OMPD_taskloop_simd: | 
|  | 1340 | case OMPD_master_taskloop: | 
|  | 1341 | case OMPD_master_taskloop_simd: | 
|  | 1342 | case OMPD_parallel_master_taskloop: | 
|  | 1343 | case OMPD_parallel_master_taskloop_simd: | 
|  | 1344 | case OMPD_distribute: | 
|  | 1345 | case OMPD_target_update: | 
|  | 1346 | case OMPD_distribute_parallel_for_simd: | 
|  | 1347 | case OMPD_distribute_simd: | 
|  | 1348 | case OMPD_target_parallel_for_simd: | 
|  | 1349 | case OMPD_target_simd: | 
|  | 1350 | case OMPD_teams_distribute: | 
|  | 1351 | case OMPD_teams_distribute_simd: | 
|  | 1352 | case OMPD_teams_distribute_parallel_for_simd: | 
|  | 1353 | case OMPD_target_teams: | 
|  | 1354 | case OMPD_target_teams_distribute: | 
|  | 1355 | case OMPD_target_teams_distribute_parallel_for_simd: | 
|  | 1356 | case OMPD_target_teams_distribute_simd: | 
|  | 1357 | case OMPD_declare_target: | 
|  | 1358 | case OMPD_end_declare_target: | 
|  | 1359 | case OMPD_threadprivate: | 
|  | 1360 | case OMPD_allocate: | 
|  | 1361 | case OMPD_declare_reduction: | 
|  | 1362 | case OMPD_declare_mapper: | 
|  | 1363 | case OMPD_declare_simd: | 
|  | 1364 | case OMPD_requires: | 
|  | 1365 | case OMPD_declare_variant: | 
|  | 1366 | case OMPD_begin_declare_variant: | 
|  | 1367 | case OMPD_end_declare_variant: | 
|  | 1368 | case OMPD_unknown: | 
|  | 1369 | llvm_unreachable("Enexpected directive with task reductions."); | 
|  | 1370 | } | 
|  | 1371 |  | 
|  | 1372 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(TaskRedRef)->getDecl()); | 
|  | 1373 | EmitVarDecl(*VD); | 
|  | 1374 | EmitStoreOfScalar(ReductionDesc, GetAddrOfLocalVar(VD), | 
|  | 1375 | /*Volatile=*/false, TaskRedRef->getType()); | 
|  | 1376 | } | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1377 | } | 
|  | 1378 |  | 
|  | 1379 | void CodeGenFunction::EmitOMPReductionClauseFinal( | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 1380 | const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1381 | if (!HaveInsertPoint()) | 
|  | 1382 | return; | 
| Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 1383 | llvm::SmallVector<const Expr *, 8> Privates; | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1384 | llvm::SmallVector<const Expr *, 8> LHSExprs; | 
|  | 1385 | llvm::SmallVector<const Expr *, 8> RHSExprs; | 
|  | 1386 | llvm::SmallVector<const Expr *, 8> ReductionOps; | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1387 | bool HasAtLeastOneReduction = false; | 
| Alexey Bataev | 8c2f4e0 | 2020-04-24 09:56:29 -0400 | [diff] [blame] | 1388 | bool IsReductionWithTaskMod = false; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1389 | for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1390 | HasAtLeastOneReduction = true; | 
| Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 1391 | Privates.append(C->privates().begin(), C->privates().end()); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1392 | LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); | 
|  | 1393 | RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); | 
|  | 1394 | ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end()); | 
| Alexey Bataev | 8c2f4e0 | 2020-04-24 09:56:29 -0400 | [diff] [blame] | 1395 | IsReductionWithTaskMod = | 
|  | 1396 | IsReductionWithTaskMod || C->getModifier() == OMPC_REDUCTION_task; | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1397 | } | 
|  | 1398 | if (HasAtLeastOneReduction) { | 
| Alexey Bataev | 8c2f4e0 | 2020-04-24 09:56:29 -0400 | [diff] [blame] | 1399 | if (IsReductionWithTaskMod) { | 
|  | 1400 | CGM.getOpenMPRuntime().emitTaskReductionFini( | 
|  | 1401 | *this, D.getBeginLoc(), | 
|  | 1402 | isOpenMPWorksharingDirective(D.getDirectiveKind())); | 
|  | 1403 | } | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 1404 | bool WithNowait = D.getSingleClause<OMPNowaitClause>() || | 
|  | 1405 | isOpenMPParallelDirective(D.getDirectiveKind()) || | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1406 | ReductionKind == OMPD_simd; | 
|  | 1407 | bool SimpleReduction = ReductionKind == OMPD_simd; | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1408 | // Emit nowait reduction if nowait clause is present or directive is a | 
|  | 1409 | // parallel directive (it always has implicit barrier). | 
|  | 1410 | CGM.getOpenMPRuntime().emitReduction( | 
| Stephen Kelly | 1c301dc | 2018-08-09 21:09:38 +0000 | [diff] [blame] | 1411 | *this, D.getEndLoc(), Privates, LHSExprs, RHSExprs, ReductionOps, | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 1412 | {WithNowait, SimpleReduction, ReductionKind}); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1413 | } | 
|  | 1414 | } | 
|  | 1415 |  | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 1416 | static void emitPostUpdateForReductionClause( | 
|  | 1417 | CodeGenFunction &CGF, const OMPExecutableDirective &D, | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1418 | const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) { | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 1419 | if (!CGF.HaveInsertPoint()) | 
|  | 1420 | return; | 
|  | 1421 | llvm::BasicBlock *DoneBB = nullptr; | 
|  | 1422 | for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1423 | if (const Expr *PostUpdate = C->getPostUpdateExpr()) { | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 1424 | if (!DoneBB) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1425 | if (llvm::Value *Cond = CondGen(CGF)) { | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 1426 | // If the first post-update expression is found, emit conditional | 
|  | 1427 | // block if it was requested. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1428 | llvm::BasicBlock *ThenBB = CGF.createBasicBlock(".omp.reduction.pu"); | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 1429 | DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done"); | 
|  | 1430 | CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB); | 
|  | 1431 | CGF.EmitBlock(ThenBB); | 
|  | 1432 | } | 
|  | 1433 | } | 
|  | 1434 | CGF.EmitIgnoredExpr(PostUpdate); | 
|  | 1435 | } | 
|  | 1436 | } | 
|  | 1437 | if (DoneBB) | 
|  | 1438 | CGF.EmitBlock(DoneBB, /*IsFinished=*/true); | 
|  | 1439 | } | 
|  | 1440 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 1441 | namespace { | 
|  | 1442 | /// Codegen lambda for appending distribute lower and upper bounds to outlined | 
|  | 1443 | /// parallel function. This is necessary for combined constructs such as | 
|  | 1444 | /// 'distribute parallel for' | 
|  | 1445 | typedef llvm::function_ref<void(CodeGenFunction &, | 
|  | 1446 | const OMPExecutableDirective &, | 
|  | 1447 | llvm::SmallVectorImpl<llvm::Value *> &)> | 
|  | 1448 | CodeGenBoundParametersTy; | 
|  | 1449 | } // anonymous namespace | 
|  | 1450 |  | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 1451 | static void | 
|  | 1452 | checkForLastprivateConditionalUpdate(CodeGenFunction &CGF, | 
|  | 1453 | const OMPExecutableDirective &S) { | 
|  | 1454 | if (CGF.getLangOpts().OpenMP < 50) | 
|  | 1455 | return; | 
|  | 1456 | llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> PrivateDecls; | 
|  | 1457 | for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) { | 
|  | 1458 | for (const Expr *Ref : C->varlists()) { | 
|  | 1459 | if (!Ref->getType()->isScalarType()) | 
|  | 1460 | continue; | 
|  | 1461 | const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts()); | 
|  | 1462 | if (!DRE) | 
|  | 1463 | continue; | 
|  | 1464 | PrivateDecls.insert(cast<VarDecl>(DRE->getDecl())); | 
|  | 1465 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref); | 
|  | 1466 | } | 
|  | 1467 | } | 
|  | 1468 | for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) { | 
|  | 1469 | for (const Expr *Ref : C->varlists()) { | 
|  | 1470 | if (!Ref->getType()->isScalarType()) | 
|  | 1471 | continue; | 
|  | 1472 | const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts()); | 
|  | 1473 | if (!DRE) | 
|  | 1474 | continue; | 
|  | 1475 | PrivateDecls.insert(cast<VarDecl>(DRE->getDecl())); | 
|  | 1476 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref); | 
|  | 1477 | } | 
|  | 1478 | } | 
|  | 1479 | for (const auto *C : S.getClausesOfKind<OMPLinearClause>()) { | 
|  | 1480 | for (const Expr *Ref : C->varlists()) { | 
|  | 1481 | if (!Ref->getType()->isScalarType()) | 
|  | 1482 | continue; | 
|  | 1483 | const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts()); | 
|  | 1484 | if (!DRE) | 
|  | 1485 | continue; | 
|  | 1486 | PrivateDecls.insert(cast<VarDecl>(DRE->getDecl())); | 
|  | 1487 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref); | 
|  | 1488 | } | 
|  | 1489 | } | 
|  | 1490 | // Privates should ne analyzed since they are not captured at all. | 
|  | 1491 | // Task reductions may be skipped - tasks are ignored. | 
|  | 1492 | // Firstprivates do not return value but may be passed by reference - no need | 
|  | 1493 | // to check for updated lastprivate conditional. | 
|  | 1494 | for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) { | 
|  | 1495 | for (const Expr *Ref : C->varlists()) { | 
|  | 1496 | if (!Ref->getType()->isScalarType()) | 
|  | 1497 | continue; | 
|  | 1498 | const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts()); | 
|  | 1499 | if (!DRE) | 
|  | 1500 | continue; | 
|  | 1501 | PrivateDecls.insert(cast<VarDecl>(DRE->getDecl())); | 
|  | 1502 | } | 
|  | 1503 | } | 
|  | 1504 | CGF.CGM.getOpenMPRuntime().checkAndEmitSharedLastprivateConditional( | 
|  | 1505 | CGF, S, PrivateDecls); | 
|  | 1506 | } | 
|  | 1507 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 1508 | static void emitCommonOMPParallelDirective( | 
|  | 1509 | CodeGenFunction &CGF, const OMPExecutableDirective &S, | 
|  | 1510 | OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, | 
|  | 1511 | const CodeGenBoundParametersTy &CodeGenBoundParameters) { | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 1512 | const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel); | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1513 | llvm::Function *OutlinedFn = | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1514 | CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction( | 
|  | 1515 | S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1516 | if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) { | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 1517 | CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1518 | llvm::Value *NumThreads = | 
|  | 1519 | CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(), | 
|  | 1520 | /*IgnoreResultAssign=*/true); | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 1521 | CGF.CGM.getOpenMPRuntime().emitNumThreadsClause( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 1522 | CGF, NumThreads, NumThreadsClause->getBeginLoc()); | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 1523 | } | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1524 | if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) { | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 1525 | CodeGenFunction::RunCleanupsScope ProcBindScope(CGF); | 
| Alexey Bataev | 7f210c6 | 2015-06-18 13:40:03 +0000 | [diff] [blame] | 1526 | CGF.CGM.getOpenMPRuntime().emitProcBindClause( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 1527 | CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getBeginLoc()); | 
| Alexey Bataev | 7f210c6 | 2015-06-18 13:40:03 +0000 | [diff] [blame] | 1528 | } | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 1529 | const Expr *IfCond = nullptr; | 
| Alexey Bataev | 7371aa3 | 2015-09-03 08:45:56 +0000 | [diff] [blame] | 1530 | for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { | 
|  | 1531 | if (C->getNameModifier() == OMPD_unknown || | 
|  | 1532 | C->getNameModifier() == OMPD_parallel) { | 
|  | 1533 | IfCond = C->getCondition(); | 
|  | 1534 | break; | 
|  | 1535 | } | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 1536 | } | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 1537 |  | 
| Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 1538 | OMPParallelScope Scope(CGF, S); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 1539 | llvm::SmallVector<llvm::Value *, 16> CapturedVars; | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 1540 | // Combining 'distribute' with 'for' requires sharing each 'distribute' chunk | 
|  | 1541 | // lower and upper bounds with the pragma 'for' chunking mechanism. | 
|  | 1542 | // The following lambda takes care of appending the lower and upper bound | 
|  | 1543 | // parameters when necessary | 
|  | 1544 | CodeGenBoundParameters(CGF, S, CapturedVars); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 1545 | CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 1546 | CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getBeginLoc(), OutlinedFn, | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 1547 | CapturedVars, IfCond); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1548 | } | 
|  | 1549 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 1550 | static void emitEmptyBoundParameters(CodeGenFunction &, | 
|  | 1551 | const OMPExecutableDirective &, | 
|  | 1552 | llvm::SmallVectorImpl<llvm::Value *> &) {} | 
|  | 1553 |  | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1554 | void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { | 
| Johannes Doerfert | 10fedd9 | 2019-12-26 11:23:38 -0600 | [diff] [blame] | 1555 | if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) { | 
|  | 1556 | // Check if we have any if clause associated with the directive. | 
|  | 1557 | llvm::Value *IfCond = nullptr; | 
|  | 1558 | if (const auto *C = S.getSingleClause<OMPIfClause>()) | 
|  | 1559 | IfCond = EmitScalarExpr(C->getCondition(), | 
|  | 1560 | /*IgnoreResultAssign=*/true); | 
|  | 1561 |  | 
|  | 1562 | llvm::Value *NumThreads = nullptr; | 
|  | 1563 | if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) | 
|  | 1564 | NumThreads = EmitScalarExpr(NumThreadsClause->getNumThreads(), | 
|  | 1565 | /*IgnoreResultAssign=*/true); | 
|  | 1566 |  | 
|  | 1567 | ProcBindKind ProcBind = OMP_PROC_BIND_default; | 
|  | 1568 | if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) | 
|  | 1569 | ProcBind = ProcBindClause->getProcBindKind(); | 
|  | 1570 |  | 
|  | 1571 | using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; | 
|  | 1572 |  | 
|  | 1573 | // The cleanup callback that finalizes all variabels at the given location, | 
|  | 1574 | // thus calls destructors etc. | 
|  | 1575 | auto FiniCB = [this](InsertPointTy IP) { | 
| Fady Ghanim | ba3f863 | 2020-02-19 13:50:26 -0600 | [diff] [blame] | 1576 | OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP); | 
| Johannes Doerfert | 10fedd9 | 2019-12-26 11:23:38 -0600 | [diff] [blame] | 1577 | }; | 
|  | 1578 |  | 
|  | 1579 | // Privatization callback that performs appropriate action for | 
|  | 1580 | // shared/private/firstprivate/lastprivate/copyin/... variables. | 
|  | 1581 | // | 
|  | 1582 | // TODO: This defaults to shared right now. | 
|  | 1583 | auto PrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP, | 
|  | 1584 | llvm::Value &Val, llvm::Value *&ReplVal) { | 
|  | 1585 | // The next line is appropriate only for variables (Val) with the | 
|  | 1586 | // data-sharing attribute "shared". | 
|  | 1587 | ReplVal = &Val; | 
|  | 1588 |  | 
|  | 1589 | return CodeGenIP; | 
|  | 1590 | }; | 
|  | 1591 |  | 
|  | 1592 | const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel); | 
|  | 1593 | const Stmt *ParallelRegionBodyStmt = CS->getCapturedStmt(); | 
|  | 1594 |  | 
|  | 1595 | auto BodyGenCB = [ParallelRegionBodyStmt, | 
|  | 1596 | this](InsertPointTy AllocaIP, InsertPointTy CodeGenIP, | 
|  | 1597 | llvm::BasicBlock &ContinuationBB) { | 
| Fady Ghanim | ba3f863 | 2020-02-19 13:50:26 -0600 | [diff] [blame] | 1598 | OMPBuilderCBHelpers::OutlinedRegionBodyRAII ORB(*this, AllocaIP, | 
|  | 1599 | ContinuationBB); | 
|  | 1600 | OMPBuilderCBHelpers::EmitOMPRegionBody(*this, ParallelRegionBodyStmt, | 
|  | 1601 | CodeGenIP, ContinuationBB); | 
| Johannes Doerfert | 10fedd9 | 2019-12-26 11:23:38 -0600 | [diff] [blame] | 1602 | }; | 
|  | 1603 |  | 
|  | 1604 | CGCapturedStmtInfo CGSI(*CS, CR_OpenMP); | 
|  | 1605 | CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI); | 
|  | 1606 | Builder.restoreIP(OMPBuilder->CreateParallel(Builder, BodyGenCB, PrivCB, | 
|  | 1607 | FiniCB, IfCond, NumThreads, | 
|  | 1608 | ProcBind, S.hasCancel())); | 
|  | 1609 | return; | 
|  | 1610 | } | 
|  | 1611 |  | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1612 | // Emit parallel region as a standalone region. | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 1613 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 1614 | Action.Enter(CGF); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1615 | OMPPrivateScope PrivateScope(CGF); | 
| Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 1616 | bool Copyins = CGF.EmitOMPCopyinClause(S); | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 1617 | (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); | 
|  | 1618 | if (Copyins) { | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 1619 | // Emit implicit barrier to synchronize threads and avoid data races on | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 1620 | // propagation master's thread values of threadprivate variables to local | 
|  | 1621 | // instances of that variables of all other implicit threads. | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 1622 | CGF.CGM.getOpenMPRuntime().emitBarrierCall( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 1623 | CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false, | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 1624 | /*ForceSimpleCall=*/true); | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 1625 | } | 
|  | 1626 | CGF.EmitOMPPrivateClause(S, PrivateScope); | 
|  | 1627 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 1628 | (void)PrivateScope.Privatize(); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 1629 | CGF.EmitStmt(S.getCapturedStmt(OMPD_parallel)->getCapturedStmt()); | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 1630 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1631 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 1632 | { | 
|  | 1633 | auto LPCRegion = | 
|  | 1634 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
|  | 1635 | emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen, | 
|  | 1636 | emitEmptyBoundParameters); | 
|  | 1637 | emitPostUpdateForReductionClause(*this, S, | 
|  | 1638 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 1639 | } | 
|  | 1640 | // Check for outer lastprivate conditional update. | 
|  | 1641 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 1642 | } | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 1643 |  | 
| Alexey Bataev | 8bbf2e3 | 2019-11-04 09:59:11 -0500 | [diff] [blame] | 1644 | static void emitBody(CodeGenFunction &CGF, const Stmt *S, const Stmt *NextLoop, | 
|  | 1645 | int MaxLevel, int Level = 0) { | 
|  | 1646 | assert(Level < MaxLevel && "Too deep lookup during loop body codegen."); | 
|  | 1647 | const Stmt *SimplifiedS = S->IgnoreContainers(); | 
|  | 1648 | if (const auto *CS = dyn_cast<CompoundStmt>(SimplifiedS)) { | 
|  | 1649 | PrettyStackTraceLoc CrashInfo( | 
|  | 1650 | CGF.getContext().getSourceManager(), CS->getLBracLoc(), | 
|  | 1651 | "LLVM IR generation of compound statement ('{}')"); | 
|  | 1652 |  | 
|  | 1653 | // Keep track of the current cleanup stack depth, including debug scopes. | 
|  | 1654 | CodeGenFunction::LexicalScope Scope(CGF, S->getSourceRange()); | 
|  | 1655 | for (const Stmt *CurStmt : CS->body()) | 
|  | 1656 | emitBody(CGF, CurStmt, NextLoop, MaxLevel, Level); | 
|  | 1657 | return; | 
|  | 1658 | } | 
|  | 1659 | if (SimplifiedS == NextLoop) { | 
|  | 1660 | if (const auto *For = dyn_cast<ForStmt>(SimplifiedS)) { | 
|  | 1661 | S = For->getBody(); | 
|  | 1662 | } else { | 
|  | 1663 | assert(isa<CXXForRangeStmt>(SimplifiedS) && | 
|  | 1664 | "Expected canonical for loop or range-based for loop."); | 
|  | 1665 | const auto *CXXFor = cast<CXXForRangeStmt>(SimplifiedS); | 
|  | 1666 | CGF.EmitStmt(CXXFor->getLoopVarStmt()); | 
|  | 1667 | S = CXXFor->getBody(); | 
|  | 1668 | } | 
|  | 1669 | if (Level + 1 < MaxLevel) { | 
|  | 1670 | NextLoop = OMPLoopDirective::tryToFindNextInnerLoop( | 
|  | 1671 | S, /*TryImperfectlyNestedLoops=*/true); | 
|  | 1672 | emitBody(CGF, S, NextLoop, MaxLevel, Level + 1); | 
|  | 1673 | return; | 
|  | 1674 | } | 
|  | 1675 | } | 
|  | 1676 | CGF.EmitStmt(S); | 
|  | 1677 | } | 
|  | 1678 |  | 
| Alexey Bataev | 0f34da1 | 2015-07-02 04:17:07 +0000 | [diff] [blame] | 1679 | void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, | 
|  | 1680 | JumpDest LoopExit) { | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1681 | RunCleanupsScope BodyScope(*this); | 
|  | 1682 | // Update counters values on current iteration. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1683 | for (const Expr *UE : D.updates()) | 
|  | 1684 | EmitIgnoredExpr(UE); | 
| Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 1685 | // Update the linear variables. | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 1686 | // In distribute directives only loop counters may be marked as linear, no | 
|  | 1687 | // need to generate the code for them. | 
|  | 1688 | if (!isOpenMPDistributeDirective(D.getDirectiveKind())) { | 
|  | 1689 | for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1690 | for (const Expr *UE : C->updates()) | 
|  | 1691 | EmitIgnoredExpr(UE); | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 1692 | } | 
| Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 1693 | } | 
|  | 1694 |  | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1695 | // On a continue in the body, jump to the end. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1696 | JumpDest Continue = getJumpDestInCurrentScope("omp.body.continue"); | 
| Alexey Bataev | 0f34da1 | 2015-07-02 04:17:07 +0000 | [diff] [blame] | 1697 | BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); | 
| Alexey Bataev | f8be476 | 2019-08-14 19:30:06 +0000 | [diff] [blame] | 1698 | for (const Expr *E : D.finals_conditions()) { | 
|  | 1699 | if (!E) | 
|  | 1700 | continue; | 
|  | 1701 | // Check that loop counter in non-rectangular nest fits into the iteration | 
|  | 1702 | // space. | 
|  | 1703 | llvm::BasicBlock *NextBB = createBasicBlock("omp.body.next"); | 
|  | 1704 | EmitBranchOnBoolExpr(E, NextBB, Continue.getBlock(), | 
|  | 1705 | getProfileCount(D.getBody())); | 
|  | 1706 | EmitBlock(NextBB); | 
|  | 1707 | } | 
| Alexey Bataev | bef93a9 | 2019-10-07 18:54:57 +0000 | [diff] [blame] | 1708 | // Emit loop variables for C++ range loops. | 
|  | 1709 | const Stmt *Body = | 
|  | 1710 | D.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers(); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1711 | // Emit loop body. | 
| Alexey Bataev | 8bbf2e3 | 2019-11-04 09:59:11 -0500 | [diff] [blame] | 1712 | emitBody(*this, Body, | 
|  | 1713 | OMPLoopDirective::tryToFindNextInnerLoop( | 
|  | 1714 | Body, /*TryImperfectlyNestedLoops=*/true), | 
|  | 1715 | D.getCollapsedNumber()); | 
|  | 1716 |  | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1717 | // The end (updates/cleanups). | 
|  | 1718 | EmitBlock(Continue.getBlock()); | 
|  | 1719 | BreakContinueStack.pop_back(); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1720 | } | 
|  | 1721 |  | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1722 | void CodeGenFunction::EmitOMPInnerLoop( | 
|  | 1723 | const Stmt &S, bool RequiresCleanup, const Expr *LoopCond, | 
|  | 1724 | const Expr *IncExpr, | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1725 | const llvm::function_ref<void(CodeGenFunction &)> BodyGen, | 
|  | 1726 | const llvm::function_ref<void(CodeGenFunction &)> PostIncGen) { | 
| Alexander Musman | d196ef2 | 2014-10-07 08:57:09 +0000 | [diff] [blame] | 1727 | auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end"); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1728 |  | 
|  | 1729 | // Start the loop with a block that tests the condition. | 
| Alexander Musman | d196ef2 | 2014-10-07 08:57:09 +0000 | [diff] [blame] | 1730 | auto CondBlock = createBasicBlock("omp.inner.for.cond"); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1731 | EmitBlock(CondBlock); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1732 | const SourceRange R = S.getSourceRange(); | 
| Amara Emerson | 652795d | 2016-11-10 14:44:30 +0000 | [diff] [blame] | 1733 | LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()), | 
|  | 1734 | SourceLocToDebugLoc(R.getEnd())); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1735 |  | 
|  | 1736 | // If there are any cleanups between here and the loop-exit scope, | 
|  | 1737 | // create a block to stage a loop exit along. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1738 | llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 1739 | if (RequiresCleanup) | 
| Alexander Musman | d196ef2 | 2014-10-07 08:57:09 +0000 | [diff] [blame] | 1740 | ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup"); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1741 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1742 | llvm::BasicBlock *LoopBody = createBasicBlock("omp.inner.for.body"); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1743 |  | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 1744 | // Emit condition. | 
| Justin Bogner | 66242d6 | 2015-04-23 23:06:47 +0000 | [diff] [blame] | 1745 | EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S)); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1746 | if (ExitBlock != LoopExit.getBlock()) { | 
|  | 1747 | EmitBlock(ExitBlock); | 
|  | 1748 | EmitBranchThroughCleanup(LoopExit); | 
|  | 1749 | } | 
|  | 1750 |  | 
|  | 1751 | EmitBlock(LoopBody); | 
| Justin Bogner | 66242d6 | 2015-04-23 23:06:47 +0000 | [diff] [blame] | 1752 | incrementProfileCounter(&S); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1753 |  | 
|  | 1754 | // Create a block for the increment. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1755 | JumpDest Continue = getJumpDestInCurrentScope("omp.inner.for.inc"); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1756 | BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); | 
|  | 1757 |  | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1758 | BodyGen(*this); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1759 |  | 
|  | 1760 | // Emit "IV = IV + 1" and a back-edge to the condition block. | 
|  | 1761 | EmitBlock(Continue.getBlock()); | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 1762 | EmitIgnoredExpr(IncExpr); | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 1763 | PostIncGen(*this); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1764 | BreakContinueStack.pop_back(); | 
|  | 1765 | EmitBranch(CondBlock); | 
|  | 1766 | LoopStack.pop(); | 
|  | 1767 | // Emit the fall-through block. | 
|  | 1768 | EmitBlock(LoopExit.getBlock()); | 
|  | 1769 | } | 
|  | 1770 |  | 
| Alexey Bataev | 8c3edfe | 2017-08-16 15:58:46 +0000 | [diff] [blame] | 1771 | bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1772 | if (!HaveInsertPoint()) | 
| Alexey Bataev | 8c3edfe | 2017-08-16 15:58:46 +0000 | [diff] [blame] | 1773 | return false; | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1774 | // Emit inits for the linear variables. | 
| Alexey Bataev | 8c3edfe | 2017-08-16 15:58:46 +0000 | [diff] [blame] | 1775 | bool HasLinears = false; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1776 | for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1777 | for (const Expr *Init : C->inits()) { | 
| Alexey Bataev | 8c3edfe | 2017-08-16 15:58:46 +0000 | [diff] [blame] | 1778 | HasLinears = true; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1779 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl()); | 
|  | 1780 | if (const auto *Ref = | 
|  | 1781 | dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) { | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 1782 | AutoVarEmission Emission = EmitAutoVarAlloca(*VD); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1783 | const auto *OrigVD = cast<VarDecl>(Ref->getDecl()); | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 1784 | DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 1785 | CapturedStmtInfo->lookup(OrigVD) != nullptr, | 
|  | 1786 | VD->getInit()->getType(), VK_LValue, | 
|  | 1787 | VD->getInit()->getExprLoc()); | 
|  | 1788 | EmitExprAsInit(&DRE, VD, MakeAddrLValue(Emission.getAllocatedAddress(), | 
|  | 1789 | VD->getType()), | 
|  | 1790 | /*capturedByInit=*/false); | 
|  | 1791 | EmitAutoVarCleanups(Emission); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1792 | } else { | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 1793 | EmitVarDecl(*VD); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1794 | } | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1795 | } | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1796 | // Emit the linear steps for the linear clauses. | 
|  | 1797 | // If a step is not constant, it is pre-calculated before the loop. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1798 | if (const auto *CS = cast_or_null<BinaryOperator>(C->getCalcStep())) | 
|  | 1799 | if (const auto *SaveRef = cast<DeclRefExpr>(CS->getLHS())) { | 
| Alexey Bataev | 3b5b5c4 | 2015-06-18 10:10:12 +0000 | [diff] [blame] | 1800 | EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl())); | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1801 | // Emit calculation of the linear step. | 
| Alexey Bataev | 3b5b5c4 | 2015-06-18 10:10:12 +0000 | [diff] [blame] | 1802 | EmitIgnoredExpr(CS); | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1803 | } | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1804 | } | 
| Alexey Bataev | 8c3edfe | 2017-08-16 15:58:46 +0000 | [diff] [blame] | 1805 | return HasLinears; | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1806 | } | 
|  | 1807 |  | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1808 | void CodeGenFunction::EmitOMPLinearClauseFinal( | 
|  | 1809 | const OMPLoopDirective &D, | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1810 | const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) { | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1811 | if (!HaveInsertPoint()) | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1812 | return; | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 1813 | llvm::BasicBlock *DoneBB = nullptr; | 
| Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 1814 | // Emit the final values of the linear variables. | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1815 | for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { | 
| Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 1816 | auto IC = C->varlist_begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1817 | for (const Expr *F : C->finals()) { | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 1818 | if (!DoneBB) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1819 | if (llvm::Value *Cond = CondGen(*this)) { | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 1820 | // If the first post-update expression is found, emit conditional | 
|  | 1821 | // block if it was requested. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1822 | llvm::BasicBlock *ThenBB = createBasicBlock(".omp.linear.pu"); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1823 | DoneBB = createBasicBlock(".omp.linear.pu.done"); | 
|  | 1824 | Builder.CreateCondBr(Cond, ThenBB, DoneBB); | 
|  | 1825 | EmitBlock(ThenBB); | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 1826 | } | 
|  | 1827 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1828 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl()); | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 1829 | DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1830 | CapturedStmtInfo->lookup(OrigVD) != nullptr, | 
| Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 1831 | (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 1832 | Address OrigAddr = EmitLValue(&DRE).getAddress(*this); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1833 | CodeGenFunction::OMPPrivateScope VarScope(*this); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1834 | VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; }); | 
| Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 1835 | (void)VarScope.Privatize(); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1836 | EmitIgnoredExpr(F); | 
| Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 1837 | ++IC; | 
| Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 1838 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1839 | if (const Expr *PostUpdate = C->getPostUpdateExpr()) | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1840 | EmitIgnoredExpr(PostUpdate); | 
| Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 1841 | } | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 1842 | if (DoneBB) | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1843 | EmitBlock(DoneBB, /*IsFinished=*/true); | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 1844 | } | 
|  | 1845 |  | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1846 | static void emitAlignedClause(CodeGenFunction &CGF, | 
|  | 1847 | const OMPExecutableDirective &D) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1848 | if (!CGF.HaveInsertPoint()) | 
|  | 1849 | return; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1850 | for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) { | 
| Erich Keane | f759395 | 2019-10-11 14:59:44 +0000 | [diff] [blame] | 1851 | llvm::APInt ClauseAlignment(64, 0); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1852 | if (const Expr *AlignmentExpr = Clause->getAlignment()) { | 
|  | 1853 | auto *AlignmentCI = | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1854 | cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr)); | 
| Erich Keane | f759395 | 2019-10-11 14:59:44 +0000 | [diff] [blame] | 1855 | ClauseAlignment = AlignmentCI->getValue(); | 
| Alexander Musman | 09184fe | 2014-09-30 05:29:28 +0000 | [diff] [blame] | 1856 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1857 | for (const Expr *E : Clause->varlists()) { | 
| Erich Keane | f759395 | 2019-10-11 14:59:44 +0000 | [diff] [blame] | 1858 | llvm::APInt Alignment(ClauseAlignment); | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1859 | if (Alignment == 0) { | 
|  | 1860 | // OpenMP [2.8.1, Description] | 
|  | 1861 | // If no optional parameter is specified, implementation-defined default | 
|  | 1862 | // alignments for SIMD instructions on the target platforms are assumed. | 
|  | 1863 | Alignment = | 
| Alexey Bataev | 0039651 | 2015-07-02 03:40:19 +0000 | [diff] [blame] | 1864 | CGF.getContext() | 
|  | 1865 | .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign( | 
|  | 1866 | E->getType()->getPointeeType())) | 
|  | 1867 | .getQuantity(); | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1868 | } | 
| Erich Keane | f759395 | 2019-10-11 14:59:44 +0000 | [diff] [blame] | 1869 | assert((Alignment == 0 || Alignment.isPowerOf2()) && | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1870 | "alignment is not power of 2"); | 
|  | 1871 | if (Alignment != 0) { | 
|  | 1872 | llvm::Value *PtrValue = CGF.EmitScalarExpr(E); | 
| Fangrui Song | 1d49eb0 | 2020-02-13 16:36:27 -0800 | [diff] [blame] | 1873 | CGF.emitAlignmentAssumption( | 
| Erich Keane | f759395 | 2019-10-11 14:59:44 +0000 | [diff] [blame] | 1874 | PtrValue, E, /*No second loc needed*/ SourceLocation(), | 
|  | 1875 | llvm::ConstantInt::get(CGF.getLLVMContext(), Alignment)); | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 1876 | } | 
| Alexander Musman | 09184fe | 2014-09-30 05:29:28 +0000 | [diff] [blame] | 1877 | } | 
|  | 1878 | } | 
|  | 1879 | } | 
|  | 1880 |  | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1881 | void CodeGenFunction::EmitOMPPrivateLoopCounters( | 
|  | 1882 | const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) { | 
|  | 1883 | if (!HaveInsertPoint()) | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1884 | return; | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1885 | auto I = S.private_counters().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1886 | for (const Expr *E : S.counters()) { | 
|  | 1887 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
|  | 1888 | const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()); | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 1889 | // Emit var without initialization. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1890 | AutoVarEmission VarEmission = EmitAutoVarAlloca(*PrivateVD); | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 1891 | EmitAutoVarCleanups(VarEmission); | 
|  | 1892 | LocalDeclMap.erase(PrivateVD); | 
|  | 1893 | (void)LoopScope.addPrivate(VD, [&VarEmission]() { | 
|  | 1894 | return VarEmission.getAllocatedAddress(); | 
| Alexey Bataev | 435ad7b | 2014-10-10 09:48:26 +0000 | [diff] [blame] | 1895 | }); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1896 | if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) || | 
|  | 1897 | VD->hasGlobalStorage()) { | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 1898 | (void)LoopScope.addPrivate(PrivateVD, [this, VD, E]() { | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 1899 | DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD), | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1900 | LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD), | 
|  | 1901 | E->getType(), VK_LValue, E->getExprLoc()); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 1902 | return EmitLValue(&DRE).getAddress(*this); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1903 | }); | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 1904 | } else { | 
|  | 1905 | (void)LoopScope.addPrivate(PrivateVD, [&VarEmission]() { | 
|  | 1906 | return VarEmission.getAllocatedAddress(); | 
|  | 1907 | }); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1908 | } | 
| Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 1909 | ++I; | 
| Alexey Bataev | 435ad7b | 2014-10-10 09:48:26 +0000 | [diff] [blame] | 1910 | } | 
| Alexey Bataev | f138fda | 2018-08-13 19:04:24 +0000 | [diff] [blame] | 1911 | // Privatize extra loop counters used in loops for ordered(n) clauses. | 
|  | 1912 | for (const auto *C : S.getClausesOfKind<OMPOrderedClause>()) { | 
|  | 1913 | if (!C->getNumForLoops()) | 
|  | 1914 | continue; | 
|  | 1915 | for (unsigned I = S.getCollapsedNumber(), | 
|  | 1916 | E = C->getLoopNumIterations().size(); | 
|  | 1917 | I < E; ++I) { | 
| Mike Rice | 0ed4666 | 2018-09-20 17:19:41 +0000 | [diff] [blame] | 1918 | const auto *DRE = cast<DeclRefExpr>(C->getLoopCounter(I)); | 
| Alexey Bataev | f138fda | 2018-08-13 19:04:24 +0000 | [diff] [blame] | 1919 | const auto *VD = cast<VarDecl>(DRE->getDecl()); | 
| Alexey Bataev | 0d8fcdf | 2019-03-14 20:36:00 +0000 | [diff] [blame] | 1920 | // Override only those variables that can be captured to avoid re-emission | 
|  | 1921 | // of the variables declared within the loops. | 
|  | 1922 | if (DRE->refersToEnclosingVariableOrCapture()) { | 
| Alexey Bataev | f138fda | 2018-08-13 19:04:24 +0000 | [diff] [blame] | 1923 | (void)LoopScope.addPrivate(VD, [this, DRE, VD]() { | 
|  | 1924 | return CreateMemTemp(DRE->getType(), VD->getName()); | 
|  | 1925 | }); | 
|  | 1926 | } | 
|  | 1927 | } | 
|  | 1928 | } | 
| Alexey Bataev | 435ad7b | 2014-10-10 09:48:26 +0000 | [diff] [blame] | 1929 | } | 
|  | 1930 |  | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 1931 | static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, | 
|  | 1932 | const Expr *Cond, llvm::BasicBlock *TrueBlock, | 
|  | 1933 | llvm::BasicBlock *FalseBlock, uint64_t TrueCount) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1934 | if (!CGF.HaveInsertPoint()) | 
|  | 1935 | return; | 
| Alexey Bataev | 6e8248f | 2015-06-11 10:53:56 +0000 | [diff] [blame] | 1936 | { | 
|  | 1937 | CodeGenFunction::OMPPrivateScope PreCondScope(CGF); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1938 | CGF.EmitOMPPrivateLoopCounters(S, PreCondScope); | 
| Alexey Bataev | 6e8248f | 2015-06-11 10:53:56 +0000 | [diff] [blame] | 1939 | (void)PreCondScope.Privatize(); | 
| Alexey Bataev | 6e8248f | 2015-06-11 10:53:56 +0000 | [diff] [blame] | 1940 | // Get initial values of real counters. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1941 | for (const Expr *I : S.inits()) { | 
| Alexey Bataev | 6e8248f | 2015-06-11 10:53:56 +0000 | [diff] [blame] | 1942 | CGF.EmitIgnoredExpr(I); | 
|  | 1943 | } | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 1944 | } | 
| Alexey Bataev | f8be476 | 2019-08-14 19:30:06 +0000 | [diff] [blame] | 1945 | // Create temp loop control variables with their init values to support | 
|  | 1946 | // non-rectangular loops. | 
|  | 1947 | CodeGenFunction::OMPMapVars PreCondVars; | 
|  | 1948 | for (const Expr * E: S.dependent_counters()) { | 
|  | 1949 | if (!E) | 
|  | 1950 | continue; | 
|  | 1951 | assert(!E->getType().getNonReferenceType()->isRecordType() && | 
|  | 1952 | "dependent counter must not be an iterator."); | 
|  | 1953 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
|  | 1954 | Address CounterAddr = | 
|  | 1955 | CGF.CreateMemTemp(VD->getType().getNonReferenceType()); | 
|  | 1956 | (void)PreCondVars.setVarAddr(CGF, VD, CounterAddr); | 
|  | 1957 | } | 
|  | 1958 | (void)PreCondVars.apply(CGF); | 
|  | 1959 | for (const Expr *E : S.dependent_inits()) { | 
|  | 1960 | if (!E) | 
|  | 1961 | continue; | 
|  | 1962 | CGF.EmitIgnoredExpr(E); | 
|  | 1963 | } | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 1964 | // Check that loop is executed at least one time. | 
|  | 1965 | CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount); | 
| Alexey Bataev | f8be476 | 2019-08-14 19:30:06 +0000 | [diff] [blame] | 1966 | PreCondVars.restore(CGF); | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 1967 | } | 
|  | 1968 |  | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1969 | void CodeGenFunction::EmitOMPLinearClause( | 
|  | 1970 | const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { | 
|  | 1971 | if (!HaveInsertPoint()) | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 1972 | return; | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1973 | llvm::DenseSet<const VarDecl *> SIMDLCVs; | 
|  | 1974 | if (isOpenMPSimdDirective(D.getDirectiveKind())) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1975 | const auto *LoopDirective = cast<OMPLoopDirective>(&D); | 
|  | 1976 | for (const Expr *C : LoopDirective->counters()) { | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1977 | SIMDLCVs.insert( | 
|  | 1978 | cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl()); | 
|  | 1979 | } | 
|  | 1980 | } | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 1981 | for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { | 
| Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 1982 | auto CurPrivate = C->privates().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1983 | for (const Expr *E : C->varlists()) { | 
|  | 1984 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
|  | 1985 | const auto *PrivateVD = | 
| Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 1986 | cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl()); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1987 | if (!SIMDLCVs.count(VD->getCanonicalDecl())) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1988 | bool IsRegistered = PrivateScope.addPrivate(VD, [this, PrivateVD]() { | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1989 | // Emit private VarDecl with copy init. | 
|  | 1990 | EmitVarDecl(*PrivateVD); | 
|  | 1991 | return GetAddrOfLocalVar(PrivateVD); | 
|  | 1992 | }); | 
|  | 1993 | assert(IsRegistered && "linear var already registered as private"); | 
|  | 1994 | // Silence the warning about unused variable. | 
|  | 1995 | (void)IsRegistered; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1996 | } else { | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1997 | EmitVarDecl(*PrivateVD); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 1998 | } | 
| Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 1999 | ++CurPrivate; | 
| Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 2000 | } | 
|  | 2001 | } | 
|  | 2002 | } | 
|  | 2003 |  | 
| Alexey Bataev | 45bfad5 | 2015-08-21 12:19:04 +0000 | [diff] [blame] | 2004 | static void emitSimdlenSafelenClause(CodeGenFunction &CGF, | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2005 | const OMPExecutableDirective &D, | 
|  | 2006 | bool IsMonotonic) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 2007 | if (!CGF.HaveInsertPoint()) | 
|  | 2008 | return; | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 2009 | if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) { | 
| Alexey Bataev | 45bfad5 | 2015-08-21 12:19:04 +0000 | [diff] [blame] | 2010 | RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(), | 
|  | 2011 | /*ignoreResult=*/true); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2012 | auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); | 
| Alexey Bataev | 45bfad5 | 2015-08-21 12:19:04 +0000 | [diff] [blame] | 2013 | CGF.LoopStack.setVectorizeWidth(Val->getZExtValue()); | 
|  | 2014 | // In presence of finite 'safelen', it may be unsafe to mark all | 
|  | 2015 | // the memory instructions parallel, because loop-carried | 
|  | 2016 | // dependences of 'safelen' iterations are possible. | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2017 | if (!IsMonotonic) | 
|  | 2018 | CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>()); | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 2019 | } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) { | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 2020 | RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(), | 
|  | 2021 | /*ignoreResult=*/true); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2022 | auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); | 
| Tyler Nowicki | da46d0e | 2015-07-14 23:03:09 +0000 | [diff] [blame] | 2023 | CGF.LoopStack.setVectorizeWidth(Val->getZExtValue()); | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 2024 | // In presence of finite 'safelen', it may be unsafe to mark all | 
|  | 2025 | // the memory instructions parallel, because loop-carried | 
|  | 2026 | // dependences of 'safelen' iterations are possible. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2027 | CGF.LoopStack.setParallel(/*Enable=*/false); | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 2028 | } | 
|  | 2029 | } | 
|  | 2030 |  | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2031 | void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D, | 
|  | 2032 | bool IsMonotonic) { | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2033 | // Walk clauses and process safelen/lastprivate. | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2034 | LoopStack.setParallel(!IsMonotonic); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2035 | LoopStack.setVectorizeEnable(); | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2036 | emitSimdlenSafelenClause(*this, D, IsMonotonic); | 
| Alexey Bataev | a781521 | 2020-02-03 12:08:16 -0500 | [diff] [blame] | 2037 | if (const auto *C = D.getSingleClause<OMPOrderClause>()) | 
|  | 2038 | if (C->getKind() == OMPC_ORDER_concurrent) | 
|  | 2039 | LoopStack.setParallel(/*Enable=*/true); | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2040 | } | 
|  | 2041 |  | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2042 | void CodeGenFunction::EmitOMPSimdFinal( | 
|  | 2043 | const OMPLoopDirective &D, | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2044 | const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) { | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 2045 | if (!HaveInsertPoint()) | 
|  | 2046 | return; | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2047 | llvm::BasicBlock *DoneBB = nullptr; | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2048 | auto IC = D.counters().begin(); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2049 | auto IPC = D.private_counters().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2050 | for (const Expr *F : D.finals()) { | 
|  | 2051 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl()); | 
|  | 2052 | const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl()); | 
|  | 2053 | const auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2054 | if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) || | 
|  | 2055 | OrigVD->hasGlobalStorage() || CED) { | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2056 | if (!DoneBB) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2057 | if (llvm::Value *Cond = CondGen(*this)) { | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2058 | // If the first post-update expression is found, emit conditional | 
|  | 2059 | // block if it was requested. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2060 | llvm::BasicBlock *ThenBB = createBasicBlock(".omp.final.then"); | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2061 | DoneBB = createBasicBlock(".omp.final.done"); | 
|  | 2062 | Builder.CreateCondBr(Cond, ThenBB, DoneBB); | 
|  | 2063 | EmitBlock(ThenBB); | 
|  | 2064 | } | 
|  | 2065 | } | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2066 | Address OrigAddr = Address::invalid(); | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 2067 | if (CED) { | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 2068 | OrigAddr = | 
|  | 2069 | EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress(*this); | 
| Alexey Bataev | ab4ea22 | 2018-03-07 18:17:06 +0000 | [diff] [blame] | 2070 | } else { | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 2071 | DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(PrivateVD), | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2072 | /*RefersToEnclosingVariableOrCapture=*/false, | 
|  | 2073 | (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc()); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 2074 | OrigAddr = EmitLValue(&DRE).getAddress(*this); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2075 | } | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2076 | OMPPrivateScope VarScope(*this); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2077 | VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; }); | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2078 | (void)VarScope.Privatize(); | 
|  | 2079 | EmitIgnoredExpr(F); | 
|  | 2080 | } | 
|  | 2081 | ++IC; | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2082 | ++IPC; | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2083 | } | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2084 | if (DoneBB) | 
|  | 2085 | EmitBlock(DoneBB, /*IsFinished=*/true); | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2086 | } | 
|  | 2087 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2088 | static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF, | 
|  | 2089 | const OMPLoopDirective &S, | 
|  | 2090 | CodeGenFunction::JumpDest LoopExit) { | 
|  | 2091 | CGF.EmitOMPLoopBody(S, LoopExit); | 
|  | 2092 | CGF.EmitStopPoint(&S); | 
| Hans Wennborg | ed129ae | 2017-04-27 17:02:25 +0000 | [diff] [blame] | 2093 | } | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2094 |  | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2095 | /// Emit a helper variable and return corresponding lvalue. | 
|  | 2096 | static LValue EmitOMPHelperVar(CodeGenFunction &CGF, | 
|  | 2097 | const DeclRefExpr *Helper) { | 
|  | 2098 | auto VDecl = cast<VarDecl>(Helper->getDecl()); | 
|  | 2099 | CGF.EmitVarDecl(*VDecl); | 
|  | 2100 | return CGF.EmitLValue(Helper); | 
|  | 2101 | } | 
|  | 2102 |  | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2103 | static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S, | 
|  | 2104 | const RegionCodeGenTy &SimdInitGen, | 
|  | 2105 | const RegionCodeGenTy &BodyCodeGen) { | 
| Alexey Bataev | 0860db9 | 2019-12-19 10:01:10 -0500 | [diff] [blame] | 2106 | auto &&ThenGen = [&S, &SimdInitGen, &BodyCodeGen](CodeGenFunction &CGF, | 
|  | 2107 | PrePostActionTy &) { | 
|  | 2108 | CGOpenMPRuntime::NontemporalDeclsRAII NontemporalsRegion(CGF.CGM, S); | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2109 | CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF); | 
|  | 2110 | SimdInitGen(CGF); | 
|  | 2111 |  | 
|  | 2112 | BodyCodeGen(CGF); | 
|  | 2113 | }; | 
|  | 2114 | auto &&ElseGen = [&BodyCodeGen](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2115 | CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF); | 
|  | 2116 | CGF.LoopStack.setVectorizeEnable(/*Enable=*/false); | 
|  | 2117 |  | 
|  | 2118 | BodyCodeGen(CGF); | 
|  | 2119 | }; | 
|  | 2120 | const Expr *IfCond = nullptr; | 
| Alexey Bataev | 18789bf | 2020-02-13 09:21:15 -0500 | [diff] [blame] | 2121 | if (isOpenMPSimdDirective(S.getDirectiveKind())) { | 
|  | 2122 | for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { | 
|  | 2123 | if (CGF.getLangOpts().OpenMP >= 50 && | 
|  | 2124 | (C->getNameModifier() == OMPD_unknown || | 
|  | 2125 | C->getNameModifier() == OMPD_simd)) { | 
|  | 2126 | IfCond = C->getCondition(); | 
|  | 2127 | break; | 
|  | 2128 | } | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2129 | } | 
|  | 2130 | } | 
|  | 2131 | if (IfCond) { | 
|  | 2132 | CGF.CGM.getOpenMPRuntime().emitIfClause(CGF, IfCond, ThenGen, ElseGen); | 
|  | 2133 | } else { | 
|  | 2134 | RegionCodeGenTy ThenRCG(ThenGen); | 
|  | 2135 | ThenRCG(CGF); | 
|  | 2136 | } | 
|  | 2137 | } | 
|  | 2138 |  | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2139 | static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, | 
|  | 2140 | PrePostActionTy &Action) { | 
|  | 2141 | Action.Enter(CGF); | 
|  | 2142 | assert(isOpenMPSimdDirective(S.getDirectiveKind()) && | 
|  | 2143 | "Expected simd directive"); | 
|  | 2144 | OMPLoopScope PreInitScope(CGF, S); | 
|  | 2145 | // if (PreCond) { | 
|  | 2146 | //   for (IV in 0..LastIteration) BODY; | 
|  | 2147 | //   <Final counter/linear vars updates>; | 
|  | 2148 | // } | 
|  | 2149 | // | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2150 | if (isOpenMPDistributeDirective(S.getDirectiveKind()) || | 
|  | 2151 | isOpenMPWorksharingDirective(S.getDirectiveKind()) || | 
|  | 2152 | isOpenMPTaskLoopDirective(S.getDirectiveKind())) { | 
|  | 2153 | (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable())); | 
|  | 2154 | (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable())); | 
|  | 2155 | } | 
| Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 2156 |  | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2157 | // Emit: if (PreCond) - begin. | 
|  | 2158 | // If the condition constant folds and can be elided, avoid emitting the | 
|  | 2159 | // whole loop. | 
|  | 2160 | bool CondConstant; | 
|  | 2161 | llvm::BasicBlock *ContBlock = nullptr; | 
|  | 2162 | if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { | 
|  | 2163 | if (!CondConstant) | 
|  | 2164 | return; | 
|  | 2165 | } else { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2166 | llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("simd.if.then"); | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2167 | ContBlock = CGF.createBasicBlock("simd.if.end"); | 
|  | 2168 | emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock, | 
|  | 2169 | CGF.getProfileCount(&S)); | 
|  | 2170 | CGF.EmitBlock(ThenBlock); | 
|  | 2171 | CGF.incrementProfileCounter(&S); | 
|  | 2172 | } | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 2173 |  | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2174 | // Emit the loop iteration variable. | 
|  | 2175 | const Expr *IVExpr = S.getIterationVariable(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2176 | const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2177 | CGF.EmitVarDecl(*IVDecl); | 
|  | 2178 | CGF.EmitIgnoredExpr(S.getInit()); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 2179 |  | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2180 | // Emit the iterations count variable. | 
|  | 2181 | // If it is not a variable, Sema decided to calculate iterations count on | 
|  | 2182 | // each iteration (e.g., it is foldable into a constant). | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2183 | if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2184 | CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); | 
|  | 2185 | // Emit calculation of the iterations count. | 
|  | 2186 | CGF.EmitIgnoredExpr(S.getCalcLastIteration()); | 
|  | 2187 | } | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 2188 |  | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2189 | emitAlignedClause(CGF, S); | 
|  | 2190 | (void)CGF.EmitOMPLinearClauseInit(S); | 
|  | 2191 | { | 
|  | 2192 | CodeGenFunction::OMPPrivateScope LoopScope(CGF); | 
|  | 2193 | CGF.EmitOMPPrivateLoopCounters(S, LoopScope); | 
|  | 2194 | CGF.EmitOMPLinearClause(S, LoopScope); | 
|  | 2195 | CGF.EmitOMPPrivateClause(S, LoopScope); | 
|  | 2196 | CGF.EmitOMPReductionClauseInit(S, LoopScope); | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 2197 | CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion( | 
|  | 2198 | CGF, S, CGF.EmitLValue(S.getIterationVariable())); | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2199 | bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); | 
|  | 2200 | (void)LoopScope.Privatize(); | 
| Alexey Bataev | 6070542 | 2018-10-30 15:50:12 +0000 | [diff] [blame] | 2201 | if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) | 
|  | 2202 | CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S); | 
| Alexey Bataev | d08c056 | 2019-11-19 12:07:54 -0500 | [diff] [blame] | 2203 |  | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2204 | emitCommonSimdLoop( | 
|  | 2205 | CGF, S, | 
|  | 2206 | [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2207 | CGF.EmitOMPSimdInit(S); | 
|  | 2208 | }, | 
|  | 2209 | [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2210 | CGF.EmitOMPInnerLoop( | 
|  | 2211 | S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(), | 
|  | 2212 | [&S](CodeGenFunction &CGF) { | 
|  | 2213 | CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest()); | 
|  | 2214 | CGF.EmitStopPoint(&S); | 
|  | 2215 | }, | 
|  | 2216 | [](CodeGenFunction &) {}); | 
|  | 2217 | }); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2218 | CGF.EmitOMPSimdFinal(S, [](CodeGenFunction &) { return nullptr; }); | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2219 | // Emit final copy of the lastprivate variables at the end of loops. | 
|  | 2220 | if (HasLastprivateClause) | 
|  | 2221 | CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true); | 
|  | 2222 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2223 | emitPostUpdateForReductionClause(CGF, S, | 
|  | 2224 | [](CodeGenFunction &) { return nullptr; }); | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2225 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2226 | CGF.EmitOMPLinearClauseFinal(S, [](CodeGenFunction &) { return nullptr; }); | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2227 | // Emit: if (PreCond) - end. | 
|  | 2228 | if (ContBlock) { | 
|  | 2229 | CGF.EmitBranch(ContBlock); | 
|  | 2230 | CGF.EmitBlock(ContBlock, true); | 
|  | 2231 | } | 
|  | 2232 | } | 
|  | 2233 |  | 
|  | 2234 | void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { | 
|  | 2235 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 2236 | emitOMPSimdRegion(CGF, S, Action); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 2237 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 2238 | { | 
|  | 2239 | auto LPCRegion = | 
|  | 2240 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
|  | 2241 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
|  | 2242 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); | 
|  | 2243 | } | 
|  | 2244 | // Check for outer lastprivate conditional update. | 
|  | 2245 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexander Musman | 515ad8c | 2014-05-22 08:54:05 +0000 | [diff] [blame] | 2246 | } | 
|  | 2247 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2248 | void CodeGenFunction::EmitOMPOuterLoop( | 
|  | 2249 | bool DynamicOrOrdered, bool IsMonotonic, const OMPLoopDirective &S, | 
|  | 2250 | CodeGenFunction::OMPPrivateScope &LoopScope, | 
|  | 2251 | const CodeGenFunction::OMPLoopArguments &LoopArgs, | 
|  | 2252 | const CodeGenFunction::CodeGenLoopTy &CodeGenLoop, | 
|  | 2253 | const CodeGenFunction::CodeGenOrderedTy &CodeGenOrdered) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2254 | CGOpenMPRuntime &RT = CGM.getOpenMPRuntime(); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2255 |  | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2256 | const Expr *IVExpr = S.getIterationVariable(); | 
|  | 2257 | const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); | 
|  | 2258 | const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); | 
|  | 2259 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2260 | JumpDest LoopExit = getJumpDestInCurrentScope("omp.dispatch.end"); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2261 |  | 
|  | 2262 | // Start the loop with a block that tests the condition. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2263 | llvm::BasicBlock *CondBlock = createBasicBlock("omp.dispatch.cond"); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2264 | EmitBlock(CondBlock); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2265 | const SourceRange R = S.getSourceRange(); | 
| Amara Emerson | 652795d | 2016-11-10 14:44:30 +0000 | [diff] [blame] | 2266 | LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()), | 
|  | 2267 | SourceLocToDebugLoc(R.getEnd())); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2268 |  | 
|  | 2269 | llvm::Value *BoolCondVal = nullptr; | 
| Alexey Bataev | d7589ffe | 2015-05-20 13:12:48 +0000 | [diff] [blame] | 2270 | if (!DynamicOrOrdered) { | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2271 | // UB = min(UB, GlobalUB) or | 
|  | 2272 | // UB = min(UB, PrevUB) for combined loop sharing constructs (e.g. | 
|  | 2273 | // 'distribute parallel for') | 
|  | 2274 | EmitIgnoredExpr(LoopArgs.EUB); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2275 | // IV = LB | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2276 | EmitIgnoredExpr(LoopArgs.Init); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2277 | // IV < UB | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2278 | BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2279 | } else { | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2280 | BoolCondVal = | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2281 | RT.emitForNext(*this, S.getBeginLoc(), IVSize, IVSigned, LoopArgs.IL, | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2282 | LoopArgs.LB, LoopArgs.UB, LoopArgs.ST); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2283 | } | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2284 |  | 
|  | 2285 | // If there are any cleanups between here and the loop-exit scope, | 
|  | 2286 | // create a block to stage a loop exit along. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2287 | llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2288 | if (LoopScope.requiresCleanups()) | 
|  | 2289 | ExitBlock = createBasicBlock("omp.dispatch.cleanup"); | 
|  | 2290 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2291 | llvm::BasicBlock *LoopBody = createBasicBlock("omp.dispatch.body"); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2292 | Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); | 
|  | 2293 | if (ExitBlock != LoopExit.getBlock()) { | 
|  | 2294 | EmitBlock(ExitBlock); | 
|  | 2295 | EmitBranchThroughCleanup(LoopExit); | 
|  | 2296 | } | 
|  | 2297 | EmitBlock(LoopBody); | 
|  | 2298 |  | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2299 | // Emit "IV = LB" (in case of static schedule, we have already calculated new | 
|  | 2300 | // LB for loop condition and emitted it above). | 
| Alexey Bataev | d7589ffe | 2015-05-20 13:12:48 +0000 | [diff] [blame] | 2301 | if (DynamicOrOrdered) | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2302 | EmitIgnoredExpr(LoopArgs.Init); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2303 |  | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2304 | // Create a block for the increment. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2305 | JumpDest Continue = getJumpDestInCurrentScope("omp.dispatch.inc"); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2306 | BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); | 
|  | 2307 |  | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2308 | emitCommonSimdLoop( | 
|  | 2309 | *this, S, | 
|  | 2310 | [&S, IsMonotonic](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2311 | // Generate !llvm.loop.parallel metadata for loads and stores for loops | 
|  | 2312 | // with dynamic/guided scheduling and without ordered clause. | 
| Alexey Bataev | a781521 | 2020-02-03 12:08:16 -0500 | [diff] [blame] | 2313 | if (!isOpenMPSimdDirective(S.getDirectiveKind())) { | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2314 | CGF.LoopStack.setParallel(!IsMonotonic); | 
| Alexey Bataev | a781521 | 2020-02-03 12:08:16 -0500 | [diff] [blame] | 2315 | if (const auto *C = S.getSingleClause<OMPOrderClause>()) | 
|  | 2316 | if (C->getKind() == OMPC_ORDER_concurrent) | 
|  | 2317 | CGF.LoopStack.setParallel(/*Enable=*/true); | 
|  | 2318 | } else { | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2319 | CGF.EmitOMPSimdInit(S, IsMonotonic); | 
| Alexey Bataev | a781521 | 2020-02-03 12:08:16 -0500 | [diff] [blame] | 2320 | } | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2321 | }, | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2322 | [&S, &LoopArgs, LoopExit, &CodeGenLoop, IVSize, IVSigned, &CodeGenOrdered, | 
|  | 2323 | &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2324 | SourceLocation Loc = S.getBeginLoc(); | 
|  | 2325 | // when 'distribute' is not combined with a 'for': | 
|  | 2326 | // while (idx <= UB) { BODY; ++idx; } | 
|  | 2327 | // when 'distribute' is combined with a 'for' | 
|  | 2328 | // (e.g. 'distribute parallel for') | 
|  | 2329 | // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; } | 
|  | 2330 | CGF.EmitOMPInnerLoop( | 
|  | 2331 | S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr, | 
|  | 2332 | [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) { | 
|  | 2333 | CodeGenLoop(CGF, S, LoopExit); | 
|  | 2334 | }, | 
|  | 2335 | [IVSize, IVSigned, Loc, &CodeGenOrdered](CodeGenFunction &CGF) { | 
|  | 2336 | CodeGenOrdered(CGF, Loc, IVSize, IVSigned); | 
|  | 2337 | }); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2338 | }); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2339 |  | 
|  | 2340 | EmitBlock(Continue.getBlock()); | 
|  | 2341 | BreakContinueStack.pop_back(); | 
| Alexey Bataev | d7589ffe | 2015-05-20 13:12:48 +0000 | [diff] [blame] | 2342 | if (!DynamicOrOrdered) { | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2343 | // Emit "LB = LB + Stride", "UB = UB + Stride". | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2344 | EmitIgnoredExpr(LoopArgs.NextLB); | 
|  | 2345 | EmitIgnoredExpr(LoopArgs.NextUB); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 2346 | } | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2347 |  | 
|  | 2348 | EmitBranch(CondBlock); | 
|  | 2349 | LoopStack.pop(); | 
|  | 2350 | // Emit the fall-through block. | 
|  | 2351 | EmitBlock(LoopExit.getBlock()); | 
|  | 2352 |  | 
|  | 2353 | // Tell the runtime we are done. | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 2354 | auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) { | 
|  | 2355 | if (!DynamicOrOrdered) | 
| Stephen Kelly | 1c301dc | 2018-08-09 21:09:38 +0000 | [diff] [blame] | 2356 | CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), | 
| Alexey Bataev | f43f714 | 2017-09-06 16:17:35 +0000 | [diff] [blame] | 2357 | S.getDirectiveKind()); | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 2358 | }; | 
|  | 2359 | OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2360 | } | 
|  | 2361 |  | 
|  | 2362 | void CodeGenFunction::EmitOMPForOuterLoop( | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 2363 | const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic, | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2364 | const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2365 | const OMPLoopArguments &LoopArgs, | 
|  | 2366 | const CodeGenDispatchBoundsTy &CGDispatchBounds) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2367 | CGOpenMPRuntime &RT = CGM.getOpenMPRuntime(); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2368 |  | 
|  | 2369 | // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime). | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 2370 | const bool DynamicOrOrdered = | 
|  | 2371 | Ordered || RT.isDynamic(ScheduleKind.Schedule); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2372 |  | 
|  | 2373 | assert((Ordered || | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 2374 | !RT.isStaticNonchunked(ScheduleKind.Schedule, | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2375 | LoopArgs.Chunk != nullptr)) && | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2376 | "static non-chunked schedule does not need outer loop"); | 
|  | 2377 |  | 
|  | 2378 | // Emit outer loop. | 
|  | 2379 | // | 
|  | 2380 | // OpenMP [2.7.1, Loop Construct, Description, table 2-1] | 
|  | 2381 | // When schedule(dynamic,chunk_size) is specified, the iterations are | 
|  | 2382 | // distributed to threads in the team in chunks as the threads request them. | 
|  | 2383 | // Each thread executes a chunk of iterations, then requests another chunk, | 
|  | 2384 | // until no chunks remain to be distributed. Each chunk contains chunk_size | 
|  | 2385 | // iterations, except for the last chunk to be distributed, which may have | 
|  | 2386 | // fewer iterations. When no chunk_size is specified, it defaults to 1. | 
|  | 2387 | // | 
|  | 2388 | // When schedule(guided,chunk_size) is specified, the iterations are assigned | 
|  | 2389 | // to threads in the team in chunks as the executing threads request them. | 
|  | 2390 | // Each thread executes a chunk of iterations, then requests another chunk, | 
|  | 2391 | // until no chunks remain to be assigned. For a chunk_size of 1, the size of | 
|  | 2392 | // each chunk is proportional to the number of unassigned iterations divided | 
|  | 2393 | // by the number of threads in the team, decreasing to 1. For a chunk_size | 
|  | 2394 | // with value k (greater than 1), the size of each chunk is determined in the | 
|  | 2395 | // same way, with the restriction that the chunks do not contain fewer than k | 
|  | 2396 | // iterations (except for the last chunk to be assigned, which may have fewer | 
|  | 2397 | // than k iterations). | 
|  | 2398 | // | 
|  | 2399 | // When schedule(auto) is specified, the decision regarding scheduling is | 
|  | 2400 | // delegated to the compiler and/or runtime system. The programmer gives the | 
|  | 2401 | // implementation the freedom to choose any possible mapping of iterations to | 
|  | 2402 | // threads in the team. | 
|  | 2403 | // | 
|  | 2404 | // When schedule(runtime) is specified, the decision regarding scheduling is | 
|  | 2405 | // deferred until run time, and the schedule and chunk size are taken from the | 
|  | 2406 | // run-sched-var ICV. If the ICV is set to auto, the schedule is | 
|  | 2407 | // implementation defined | 
|  | 2408 | // | 
|  | 2409 | // while(__kmpc_dispatch_next(&LB, &UB)) { | 
|  | 2410 | //   idx = LB; | 
|  | 2411 | //   while (idx <= UB) { BODY; ++idx; | 
|  | 2412 | //   __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only. | 
|  | 2413 | //   } // inner loop | 
|  | 2414 | // } | 
|  | 2415 | // | 
|  | 2416 | // OpenMP [2.7.1, Loop Construct, Description, table 2-1] | 
|  | 2417 | // When schedule(static, chunk_size) is specified, iterations are divided into | 
|  | 2418 | // chunks of size chunk_size, and the chunks are assigned to the threads in | 
|  | 2419 | // the team in a round-robin fashion in the order of the thread number. | 
|  | 2420 | // | 
|  | 2421 | // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) { | 
|  | 2422 | //   while (idx <= UB) { BODY; ++idx; } // inner loop | 
|  | 2423 | //   LB = LB + ST; | 
|  | 2424 | //   UB = UB + ST; | 
|  | 2425 | // } | 
|  | 2426 | // | 
|  | 2427 |  | 
|  | 2428 | const Expr *IVExpr = S.getIterationVariable(); | 
|  | 2429 | const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); | 
|  | 2430 | const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); | 
|  | 2431 |  | 
|  | 2432 | if (DynamicOrOrdered) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2433 | const std::pair<llvm::Value *, llvm::Value *> DispatchBounds = | 
|  | 2434 | CGDispatchBounds(*this, S, LoopArgs.LB, LoopArgs.UB); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2435 | llvm::Value *LBVal = DispatchBounds.first; | 
|  | 2436 | llvm::Value *UBVal = DispatchBounds.second; | 
|  | 2437 | CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal, | 
|  | 2438 | LoopArgs.Chunk}; | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2439 | RT.emitForDispatchInit(*this, S.getBeginLoc(), ScheduleKind, IVSize, | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2440 | IVSigned, Ordered, DipatchRTInputValues); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2441 | } else { | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 2442 | CGOpenMPRuntime::StaticRTInput StaticInit( | 
|  | 2443 | IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB, | 
|  | 2444 | LoopArgs.ST, LoopArgs.Chunk); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2445 | RT.emitForStaticInit(*this, S.getBeginLoc(), S.getDirectiveKind(), | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 2446 | ScheduleKind, StaticInit); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2447 | } | 
|  | 2448 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2449 | auto &&CodeGenOrdered = [Ordered](CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 2450 | const unsigned IVSize, | 
|  | 2451 | const bool IVSigned) { | 
|  | 2452 | if (Ordered) { | 
|  | 2453 | CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(CGF, Loc, IVSize, | 
|  | 2454 | IVSigned); | 
|  | 2455 | } | 
|  | 2456 | }; | 
|  | 2457 |  | 
|  | 2458 | OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST, | 
|  | 2459 | LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB); | 
|  | 2460 | OuterLoopArgs.IncExpr = S.getInc(); | 
|  | 2461 | OuterLoopArgs.Init = S.getInit(); | 
|  | 2462 | OuterLoopArgs.Cond = S.getCond(); | 
|  | 2463 | OuterLoopArgs.NextLB = S.getNextLowerBound(); | 
|  | 2464 | OuterLoopArgs.NextUB = S.getNextUpperBound(); | 
|  | 2465 | EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs, | 
|  | 2466 | emitOMPLoopBodyWithStopPoint, CodeGenOrdered); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2467 | } | 
|  | 2468 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2469 | static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc, | 
|  | 2470 | const unsigned IVSize, const bool IVSigned) {} | 
|  | 2471 |  | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2472 | void CodeGenFunction::EmitOMPDistributeOuterLoop( | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2473 | OpenMPDistScheduleClauseKind ScheduleKind, const OMPLoopDirective &S, | 
|  | 2474 | OMPPrivateScope &LoopScope, const OMPLoopArguments &LoopArgs, | 
|  | 2475 | const CodeGenLoopTy &CodeGenLoopContent) { | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2476 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2477 | CGOpenMPRuntime &RT = CGM.getOpenMPRuntime(); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2478 |  | 
|  | 2479 | // Emit outer loop. | 
|  | 2480 | // Same behavior as a OMPForOuterLoop, except that schedule cannot be | 
|  | 2481 | // dynamic | 
|  | 2482 | // | 
|  | 2483 |  | 
|  | 2484 | const Expr *IVExpr = S.getIterationVariable(); | 
|  | 2485 | const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); | 
|  | 2486 | const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); | 
|  | 2487 |  | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 2488 | CGOpenMPRuntime::StaticRTInput StaticInit( | 
|  | 2489 | IVSize, IVSigned, /* Ordered = */ false, LoopArgs.IL, LoopArgs.LB, | 
|  | 2490 | LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2491 | RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind, StaticInit); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 2492 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2493 | // for combined 'distribute' and 'for' the increment expression of distribute | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 2494 | // is stored in DistInc. For 'distribute' alone, it is in Inc. | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2495 | Expr *IncExpr; | 
|  | 2496 | if (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())) | 
|  | 2497 | IncExpr = S.getDistInc(); | 
|  | 2498 | else | 
|  | 2499 | IncExpr = S.getInc(); | 
|  | 2500 |  | 
|  | 2501 | // this routine is shared by 'omp distribute parallel for' and | 
|  | 2502 | // 'omp distribute': select the right EUB expression depending on the | 
|  | 2503 | // directive | 
|  | 2504 | OMPLoopArguments OuterLoopArgs; | 
|  | 2505 | OuterLoopArgs.LB = LoopArgs.LB; | 
|  | 2506 | OuterLoopArgs.UB = LoopArgs.UB; | 
|  | 2507 | OuterLoopArgs.ST = LoopArgs.ST; | 
|  | 2508 | OuterLoopArgs.IL = LoopArgs.IL; | 
|  | 2509 | OuterLoopArgs.Chunk = LoopArgs.Chunk; | 
|  | 2510 | OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 2511 | ? S.getCombinedEnsureUpperBound() | 
|  | 2512 | : S.getEnsureUpperBound(); | 
|  | 2513 | OuterLoopArgs.IncExpr = IncExpr; | 
|  | 2514 | OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 2515 | ? S.getCombinedInit() | 
|  | 2516 | : S.getInit(); | 
|  | 2517 | OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 2518 | ? S.getCombinedCond() | 
|  | 2519 | : S.getCond(); | 
|  | 2520 | OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 2521 | ? S.getCombinedNextLowerBound() | 
|  | 2522 | : S.getNextLowerBound(); | 
|  | 2523 | OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 2524 | ? S.getCombinedNextUpperBound() | 
|  | 2525 | : S.getNextUpperBound(); | 
|  | 2526 |  | 
|  | 2527 | EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, S, | 
|  | 2528 | LoopScope, OuterLoopArgs, CodeGenLoopContent, | 
|  | 2529 | emitEmptyOrdered); | 
|  | 2530 | } | 
|  | 2531 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2532 | static std::pair<LValue, LValue> | 
|  | 2533 | emitDistributeParallelForInnerBounds(CodeGenFunction &CGF, | 
|  | 2534 | const OMPExecutableDirective &S) { | 
|  | 2535 | const OMPLoopDirective &LS = cast<OMPLoopDirective>(S); | 
|  | 2536 | LValue LB = | 
|  | 2537 | EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable())); | 
|  | 2538 | LValue UB = | 
|  | 2539 | EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable())); | 
|  | 2540 |  | 
|  | 2541 | // When composing 'distribute' with 'for' (e.g. as in 'distribute | 
|  | 2542 | // parallel for') we need to use the 'distribute' | 
|  | 2543 | // chunk lower and upper bounds rather than the whole loop iteration | 
|  | 2544 | // space. These are parameters to the outlined function for 'parallel' | 
|  | 2545 | // and we copy the bounds of the previous schedule into the | 
|  | 2546 | // the current ones. | 
|  | 2547 | LValue PrevLB = CGF.EmitLValue(LS.getPrevLowerBoundVariable()); | 
|  | 2548 | LValue PrevUB = CGF.EmitLValue(LS.getPrevUpperBoundVariable()); | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 2549 | llvm::Value *PrevLBVal = CGF.EmitLoadOfScalar( | 
|  | 2550 | PrevLB, LS.getPrevLowerBoundVariable()->getExprLoc()); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2551 | PrevLBVal = CGF.EmitScalarConversion( | 
|  | 2552 | PrevLBVal, LS.getPrevLowerBoundVariable()->getType(), | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 2553 | LS.getIterationVariable()->getType(), | 
|  | 2554 | LS.getPrevLowerBoundVariable()->getExprLoc()); | 
|  | 2555 | llvm::Value *PrevUBVal = CGF.EmitLoadOfScalar( | 
|  | 2556 | PrevUB, LS.getPrevUpperBoundVariable()->getExprLoc()); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2557 | PrevUBVal = CGF.EmitScalarConversion( | 
|  | 2558 | PrevUBVal, LS.getPrevUpperBoundVariable()->getType(), | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 2559 | LS.getIterationVariable()->getType(), | 
|  | 2560 | LS.getPrevUpperBoundVariable()->getExprLoc()); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2561 |  | 
|  | 2562 | CGF.EmitStoreOfScalar(PrevLBVal, LB); | 
|  | 2563 | CGF.EmitStoreOfScalar(PrevUBVal, UB); | 
|  | 2564 |  | 
|  | 2565 | return {LB, UB}; | 
|  | 2566 | } | 
|  | 2567 |  | 
|  | 2568 | /// if the 'for' loop has a dispatch schedule (e.g. dynamic, guided) then | 
|  | 2569 | /// we need to use the LB and UB expressions generated by the worksharing | 
|  | 2570 | /// code generation support, whereas in non combined situations we would | 
|  | 2571 | /// just emit 0 and the LastIteration expression | 
|  | 2572 | /// This function is necessary due to the difference of the LB and UB | 
|  | 2573 | /// types for the RT emission routines for 'for_static_init' and | 
|  | 2574 | /// 'for_dispatch_init' | 
|  | 2575 | static std::pair<llvm::Value *, llvm::Value *> | 
|  | 2576 | emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF, | 
|  | 2577 | const OMPExecutableDirective &S, | 
|  | 2578 | Address LB, Address UB) { | 
|  | 2579 | const OMPLoopDirective &LS = cast<OMPLoopDirective>(S); | 
|  | 2580 | const Expr *IVExpr = LS.getIterationVariable(); | 
|  | 2581 | // when implementing a dynamic schedule for a 'for' combined with a | 
|  | 2582 | // 'distribute' (e.g. 'distribute parallel for'), the 'for' loop | 
|  | 2583 | // is not normalized as each team only executes its own assigned | 
|  | 2584 | // distribute chunk | 
|  | 2585 | QualType IteratorTy = IVExpr->getType(); | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 2586 | llvm::Value *LBVal = | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2587 | CGF.EmitLoadOfScalar(LB, /*Volatile=*/false, IteratorTy, S.getBeginLoc()); | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 2588 | llvm::Value *UBVal = | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2589 | CGF.EmitLoadOfScalar(UB, /*Volatile=*/false, IteratorTy, S.getBeginLoc()); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2590 | return {LBVal, UBVal}; | 
| Hans Wennborg | ed129ae | 2017-04-27 17:02:25 +0000 | [diff] [blame] | 2591 | } | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2592 |  | 
|  | 2593 | static void emitDistributeParallelForDistributeInnerBoundParams( | 
|  | 2594 | CodeGenFunction &CGF, const OMPExecutableDirective &S, | 
|  | 2595 | llvm::SmallVectorImpl<llvm::Value *> &CapturedVars) { | 
|  | 2596 | const auto &Dir = cast<OMPLoopDirective>(S); | 
|  | 2597 | LValue LB = | 
|  | 2598 | CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable())); | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 2599 | llvm::Value *LBCast = | 
|  | 2600 | CGF.Builder.CreateIntCast(CGF.Builder.CreateLoad(LB.getAddress(CGF)), | 
|  | 2601 | CGF.SizeTy, /*isSigned=*/false); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2602 | CapturedVars.push_back(LBCast); | 
|  | 2603 | LValue UB = | 
|  | 2604 | CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable())); | 
|  | 2605 |  | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 2606 | llvm::Value *UBCast = | 
|  | 2607 | CGF.Builder.CreateIntCast(CGF.Builder.CreateLoad(UB.getAddress(CGF)), | 
|  | 2608 | CGF.SizeTy, /*isSigned=*/false); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2609 | CapturedVars.push_back(UBCast); | 
| Hans Wennborg | ed129ae | 2017-04-27 17:02:25 +0000 | [diff] [blame] | 2610 | } | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2611 |  | 
|  | 2612 | static void | 
|  | 2613 | emitInnerParallelForWhenCombined(CodeGenFunction &CGF, | 
|  | 2614 | const OMPLoopDirective &S, | 
|  | 2615 | CodeGenFunction::JumpDest LoopExit) { | 
|  | 2616 | auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 2617 | PrePostActionTy &Action) { | 
|  | 2618 | Action.Enter(CGF); | 
| Alexey Bataev | dcb4b8fb | 2017-11-22 20:19:50 +0000 | [diff] [blame] | 2619 | bool HasCancel = false; | 
|  | 2620 | if (!isOpenMPSimdDirective(S.getDirectiveKind())) { | 
|  | 2621 | if (const auto *D = dyn_cast<OMPTeamsDistributeParallelForDirective>(&S)) | 
|  | 2622 | HasCancel = D->hasCancel(); | 
|  | 2623 | else if (const auto *D = dyn_cast<OMPDistributeParallelForDirective>(&S)) | 
|  | 2624 | HasCancel = D->hasCancel(); | 
| Alexey Bataev | 16e7988 | 2017-11-22 21:12:03 +0000 | [diff] [blame] | 2625 | else if (const auto *D = | 
|  | 2626 | dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&S)) | 
|  | 2627 | HasCancel = D->hasCancel(); | 
| Alexey Bataev | dcb4b8fb | 2017-11-22 20:19:50 +0000 | [diff] [blame] | 2628 | } | 
|  | 2629 | CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(), | 
|  | 2630 | HasCancel); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2631 | CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(), | 
|  | 2632 | emitDistributeParallelForInnerBounds, | 
|  | 2633 | emitDistributeParallelForDispatchBounds); | 
|  | 2634 | }; | 
|  | 2635 |  | 
|  | 2636 | emitCommonOMPParallelDirective( | 
| Alexey Bataev | dcb4b8fb | 2017-11-22 20:19:50 +0000 | [diff] [blame] | 2637 | CGF, S, | 
|  | 2638 | isOpenMPSimdDirective(S.getDirectiveKind()) ? OMPD_for_simd : OMPD_for, | 
|  | 2639 | CGInlinedWorksharingLoop, | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2640 | emitDistributeParallelForDistributeInnerBoundParams); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2641 | } | 
|  | 2642 |  | 
| Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 2643 | void CodeGenFunction::EmitOMPDistributeParallelForDirective( | 
|  | 2644 | const OMPDistributeParallelForDirective &S) { | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2645 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2646 | CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined, | 
|  | 2647 | S.getDistInc()); | 
|  | 2648 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 2649 | OMPLexicalScope Scope(*this, S, OMPD_parallel); | 
| Alexey Bataev | 10a5431 | 2017-11-27 16:54:08 +0000 | [diff] [blame] | 2650 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen); | 
| Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 2651 | } | 
|  | 2652 |  | 
| Kelvin Li | 4a39add | 2016-07-05 05:00:15 +0000 | [diff] [blame] | 2653 | void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective( | 
|  | 2654 | const OMPDistributeParallelForSimdDirective &S) { | 
| Alexey Bataev | 0b49f9e | 2017-11-27 19:38:58 +0000 | [diff] [blame] | 2655 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2656 | CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined, | 
|  | 2657 | S.getDistInc()); | 
|  | 2658 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 2659 | OMPLexicalScope Scope(*this, S, OMPD_parallel); | 
| Alexey Bataev | 0b49f9e | 2017-11-27 19:38:58 +0000 | [diff] [blame] | 2660 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen); | 
| Kelvin Li | 4a39add | 2016-07-05 05:00:15 +0000 | [diff] [blame] | 2661 | } | 
| Kelvin Li | 787f3fc | 2016-07-06 04:45:38 +0000 | [diff] [blame] | 2662 |  | 
|  | 2663 | void CodeGenFunction::EmitOMPDistributeSimdDirective( | 
|  | 2664 | const OMPDistributeSimdDirective &S) { | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 2665 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2666 | CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); | 
|  | 2667 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 2668 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 2669 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); | 
| Kelvin Li | 787f3fc | 2016-07-06 04:45:38 +0000 | [diff] [blame] | 2670 | } | 
|  | 2671 |  | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2672 | void CodeGenFunction::EmitOMPTargetSimdDeviceFunction( | 
|  | 2673 | CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S) { | 
|  | 2674 | // Emit SPMD target parallel for region as a standalone region. | 
|  | 2675 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 2676 | emitOMPSimdRegion(CGF, S, Action); | 
|  | 2677 | }; | 
|  | 2678 | llvm::Function *Fn; | 
|  | 2679 | llvm::Constant *Addr; | 
|  | 2680 | // Emit target region as a standalone region. | 
|  | 2681 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 2682 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 2683 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 2684 | } | 
|  | 2685 |  | 
| Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 2686 | void CodeGenFunction::EmitOMPTargetSimdDirective( | 
|  | 2687 | const OMPTargetSimdDirective &S) { | 
| Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 2688 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 2689 | emitOMPSimdRegion(CGF, S, Action); | 
|  | 2690 | }; | 
|  | 2691 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
| Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 2692 | } | 
|  | 2693 |  | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2694 | namespace { | 
|  | 2695 | struct ScheduleKindModifiersTy { | 
|  | 2696 | OpenMPScheduleClauseKind Kind; | 
|  | 2697 | OpenMPScheduleClauseModifier M1; | 
|  | 2698 | OpenMPScheduleClauseModifier M2; | 
|  | 2699 | ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind, | 
|  | 2700 | OpenMPScheduleClauseModifier M1, | 
|  | 2701 | OpenMPScheduleClauseModifier M2) | 
|  | 2702 | : Kind(Kind), M1(M1), M2(M2) {} | 
|  | 2703 | }; | 
|  | 2704 | } // namespace | 
|  | 2705 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2706 | bool CodeGenFunction::EmitOMPWorksharingLoop( | 
|  | 2707 | const OMPLoopDirective &S, Expr *EUB, | 
|  | 2708 | const CodeGenLoopBoundsTy &CodeGenLoopBounds, | 
|  | 2709 | const CodeGenDispatchBoundsTy &CGDispatchBounds) { | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2710 | // Emit the loop iteration variable. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2711 | const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable()); | 
|  | 2712 | const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl()); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2713 | EmitVarDecl(*IVDecl); | 
|  | 2714 |  | 
|  | 2715 | // Emit the iterations count variable. | 
|  | 2716 | // If it is not a variable, Sema decided to calculate iterations count on each | 
|  | 2717 | // iteration (e.g., it is foldable into a constant). | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2718 | if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2719 | EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); | 
|  | 2720 | // Emit calculation of the iterations count. | 
|  | 2721 | EmitIgnoredExpr(S.getCalcLastIteration()); | 
|  | 2722 | } | 
|  | 2723 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2724 | CGOpenMPRuntime &RT = CGM.getOpenMPRuntime(); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2725 |  | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 2726 | bool HasLastprivateClause; | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2727 | // Check pre-condition. | 
|  | 2728 | { | 
| Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 2729 | OMPLoopScope PreInitScope(*this, S); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2730 | // Skip the entire loop if we don't meet the precondition. | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 2731 | // If the condition constant folds and can be elided, avoid emitting the | 
|  | 2732 | // whole loop. | 
|  | 2733 | bool CondConstant; | 
|  | 2734 | llvm::BasicBlock *ContBlock = nullptr; | 
|  | 2735 | if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { | 
|  | 2736 | if (!CondConstant) | 
|  | 2737 | return false; | 
|  | 2738 | } else { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2739 | llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then"); | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 2740 | ContBlock = createBasicBlock("omp.precond.end"); | 
|  | 2741 | emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock, | 
| Justin Bogner | 66242d6 | 2015-04-23 23:06:47 +0000 | [diff] [blame] | 2742 | getProfileCount(&S)); | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 2743 | EmitBlock(ThenBlock); | 
| Justin Bogner | 66242d6 | 2015-04-23 23:06:47 +0000 | [diff] [blame] | 2744 | incrementProfileCounter(&S); | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 2745 | } | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2746 |  | 
| Alexey Bataev | ea33dee | 2018-02-15 23:39:43 +0000 | [diff] [blame] | 2747 | RunCleanupsScope DoacrossCleanupScope(*this); | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 2748 | bool Ordered = false; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2749 | if (const auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) { | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 2750 | if (OrderedClause->getNumForLoops()) | 
| Alexey Bataev | f138fda | 2018-08-13 19:04:24 +0000 | [diff] [blame] | 2751 | RT.emitDoacrossInit(*this, S, OrderedClause->getLoopNumIterations()); | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 2752 | else | 
|  | 2753 | Ordered = true; | 
|  | 2754 | } | 
|  | 2755 |  | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2756 | llvm::DenseSet<const Expr *> EmittedFinals; | 
| Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 2757 | emitAlignedClause(*this, S); | 
| Alexey Bataev | 8c3edfe | 2017-08-16 15:58:46 +0000 | [diff] [blame] | 2758 | bool HasLinears = EmitOMPLinearClauseInit(S); | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2759 | // Emit helper vars inits. | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2760 |  | 
|  | 2761 | std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S); | 
|  | 2762 | LValue LB = Bounds.first; | 
|  | 2763 | LValue UB = Bounds.second; | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2764 | LValue ST = | 
|  | 2765 | EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); | 
|  | 2766 | LValue IL = | 
|  | 2767 | EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); | 
|  | 2768 |  | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2769 | // Emit 'then' code. | 
|  | 2770 | { | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2771 | OMPPrivateScope LoopScope(*this); | 
| Alexey Bataev | 8c3edfe | 2017-08-16 15:58:46 +0000 | [diff] [blame] | 2772 | if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) { | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 2773 | // Emit implicit barrier to synchronize threads and avoid data races on | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 2774 | // initialization of firstprivate variables and post-update of | 
|  | 2775 | // lastprivate variables. | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 2776 | CGM.getOpenMPRuntime().emitBarrierCall( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2777 | *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false, | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 2778 | /*ForceSimpleCall=*/true); | 
| Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 2779 | } | 
| Alexey Bataev | 50a6458 | 2015-04-22 12:24:45 +0000 | [diff] [blame] | 2780 | EmitOMPPrivateClause(S, LoopScope); | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 2781 | CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion( | 
|  | 2782 | *this, S, EmitLValue(S.getIterationVariable())); | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 2783 | HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope); | 
| Alexey Bataev | 7ebe5fd | 2015-04-22 13:43:03 +0000 | [diff] [blame] | 2784 | EmitOMPReductionClauseInit(S, LoopScope); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2785 | EmitOMPPrivateLoopCounters(S, LoopScope); | 
|  | 2786 | EmitOMPLinearClause(S, LoopScope); | 
| Alexander Musman | 7931b98 | 2015-03-16 07:14:41 +0000 | [diff] [blame] | 2787 | (void)LoopScope.Privatize(); | 
| Alexey Bataev | 6070542 | 2018-10-30 15:50:12 +0000 | [diff] [blame] | 2788 | if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) | 
|  | 2789 | CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2790 |  | 
|  | 2791 | // Detect the loop schedule kind and chunk. | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 2792 | const Expr *ChunkExpr = nullptr; | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 2793 | OpenMPScheduleTy ScheduleKind; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2794 | if (const auto *C = S.getSingleClause<OMPScheduleClause>()) { | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 2795 | ScheduleKind.Schedule = C->getScheduleKind(); | 
|  | 2796 | ScheduleKind.M1 = C->getFirstScheduleModifier(); | 
|  | 2797 | ScheduleKind.M2 = C->getSecondScheduleModifier(); | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 2798 | ChunkExpr = C->getChunkSize(); | 
| Gheorghe-Teodor Bercea | 8233af9 | 2018-09-27 20:29:00 +0000 | [diff] [blame] | 2799 | } else { | 
|  | 2800 | // Default behaviour for schedule clause. | 
|  | 2801 | CGM.getOpenMPRuntime().getDefaultScheduleAndChunk( | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 2802 | *this, S, ScheduleKind.Schedule, ChunkExpr); | 
|  | 2803 | } | 
|  | 2804 | bool HasChunkSizeOne = false; | 
|  | 2805 | llvm::Value *Chunk = nullptr; | 
|  | 2806 | if (ChunkExpr) { | 
|  | 2807 | Chunk = EmitScalarExpr(ChunkExpr); | 
|  | 2808 | Chunk = EmitScalarConversion(Chunk, ChunkExpr->getType(), | 
|  | 2809 | S.getIterationVariable()->getType(), | 
|  | 2810 | S.getBeginLoc()); | 
| Fangrui Song | 407659a | 2018-11-30 23:41:18 +0000 | [diff] [blame] | 2811 | Expr::EvalResult Result; | 
|  | 2812 | if (ChunkExpr->EvaluateAsInt(Result, getContext())) { | 
|  | 2813 | llvm::APSInt EvaluatedChunk = Result.Val.getInt(); | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 2814 | HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1); | 
| Fangrui Song | 407659a | 2018-11-30 23:41:18 +0000 | [diff] [blame] | 2815 | } | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 2816 | } | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2817 | const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); | 
|  | 2818 | const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2819 | // OpenMP 4.5, 2.7.1 Loop Construct, Description. | 
|  | 2820 | // If the static schedule kind is specified or if the ordered clause is | 
|  | 2821 | // specified, and if no monotonic modifier is specified, the effect will | 
|  | 2822 | // be as if the monotonic modifier was specified. | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 2823 | bool StaticChunkedOne = RT.isStaticChunked(ScheduleKind.Schedule, | 
|  | 2824 | /* Chunked */ Chunk != nullptr) && HasChunkSizeOne && | 
|  | 2825 | isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()); | 
|  | 2826 | if ((RT.isStaticNonchunked(ScheduleKind.Schedule, | 
|  | 2827 | /* Chunked */ Chunk != nullptr) || | 
|  | 2828 | StaticChunkedOne) && | 
| Alexey Bataev | d7589ffe | 2015-05-20 13:12:48 +0000 | [diff] [blame] | 2829 | !Ordered) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2830 | JumpDest LoopExit = | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2831 | getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit")); | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2832 | emitCommonSimdLoop( | 
|  | 2833 | *this, S, | 
|  | 2834 | [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
| Alexey Bataev | a781521 | 2020-02-03 12:08:16 -0500 | [diff] [blame] | 2835 | if (isOpenMPSimdDirective(S.getDirectiveKind())) { | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2836 | CGF.EmitOMPSimdInit(S, /*IsMonotonic=*/true); | 
| Alexey Bataev | a781521 | 2020-02-03 12:08:16 -0500 | [diff] [blame] | 2837 | } else if (const auto *C = S.getSingleClause<OMPOrderClause>()) { | 
|  | 2838 | if (C->getKind() == OMPC_ORDER_concurrent) | 
|  | 2839 | CGF.LoopStack.setParallel(/*Enable=*/true); | 
|  | 2840 | } | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 2841 | }, | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2842 | [IVSize, IVSigned, Ordered, IL, LB, UB, ST, StaticChunkedOne, Chunk, | 
|  | 2843 | &S, ScheduleKind, LoopExit, | 
|  | 2844 | &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 2845 | // OpenMP [2.7.1, Loop Construct, Description, table 2-1] | 
|  | 2846 | // When no chunk_size is specified, the iteration space is divided | 
|  | 2847 | // into chunks that are approximately equal in size, and at most | 
|  | 2848 | // one chunk is distributed to each thread. Note that the size of | 
|  | 2849 | // the chunks is unspecified in this case. | 
|  | 2850 | CGOpenMPRuntime::StaticRTInput StaticInit( | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 2851 | IVSize, IVSigned, Ordered, IL.getAddress(CGF), | 
|  | 2852 | LB.getAddress(CGF), UB.getAddress(CGF), ST.getAddress(CGF), | 
| Alexey Bataev | 103f3c9e | 2019-11-20 15:59:03 -0500 | [diff] [blame] | 2853 | StaticChunkedOne ? Chunk : nullptr); | 
|  | 2854 | CGF.CGM.getOpenMPRuntime().emitForStaticInit( | 
|  | 2855 | CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind, | 
|  | 2856 | StaticInit); | 
|  | 2857 | // UB = min(UB, GlobalUB); | 
|  | 2858 | if (!StaticChunkedOne) | 
|  | 2859 | CGF.EmitIgnoredExpr(S.getEnsureUpperBound()); | 
|  | 2860 | // IV = LB; | 
|  | 2861 | CGF.EmitIgnoredExpr(S.getInit()); | 
|  | 2862 | // For unchunked static schedule generate: | 
|  | 2863 | // | 
|  | 2864 | // while (idx <= UB) { | 
|  | 2865 | //   BODY; | 
|  | 2866 | //   ++idx; | 
|  | 2867 | // } | 
|  | 2868 | // | 
|  | 2869 | // For static schedule with chunk one: | 
|  | 2870 | // | 
|  | 2871 | // while (IV <= PrevUB) { | 
|  | 2872 | //   BODY; | 
|  | 2873 | //   IV += ST; | 
|  | 2874 | // } | 
|  | 2875 | CGF.EmitOMPInnerLoop( | 
|  | 2876 | S, LoopScope.requiresCleanups(), | 
|  | 2877 | StaticChunkedOne ? S.getCombinedParForInDistCond() | 
|  | 2878 | : S.getCond(), | 
|  | 2879 | StaticChunkedOne ? S.getDistInc() : S.getInc(), | 
|  | 2880 | [&S, LoopExit](CodeGenFunction &CGF) { | 
|  | 2881 | CGF.EmitOMPLoopBody(S, LoopExit); | 
|  | 2882 | CGF.EmitStopPoint(&S); | 
|  | 2883 | }, | 
|  | 2884 | [](CodeGenFunction &) {}); | 
|  | 2885 | }); | 
| Alexey Bataev | 0f34da1 | 2015-07-02 04:17:07 +0000 | [diff] [blame] | 2886 | EmitBlock(LoopExit.getBlock()); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2887 | // Tell the runtime we are done. | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 2888 | auto &&CodeGen = [&S](CodeGenFunction &CGF) { | 
| Stephen Kelly | 1c301dc | 2018-08-09 21:09:38 +0000 | [diff] [blame] | 2889 | CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), | 
| Alexey Bataev | f43f714 | 2017-09-06 16:17:35 +0000 | [diff] [blame] | 2890 | S.getDirectiveKind()); | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 2891 | }; | 
|  | 2892 | OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2893 | } else { | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 2894 | const bool IsMonotonic = | 
|  | 2895 | Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static || | 
|  | 2896 | ScheduleKind.Schedule == OMPC_SCHEDULE_unknown || | 
|  | 2897 | ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic || | 
|  | 2898 | ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic; | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2899 | // Emit the outer loop, which requests its work chunk [LB..UB] from | 
|  | 2900 | // runtime and runs the inner loop to process it. | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 2901 | const OMPLoopArguments LoopArguments( | 
|  | 2902 | LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this), | 
|  | 2903 | IL.getAddress(*this), Chunk, EUB); | 
| Alexey Bataev | a6f2a14 | 2015-12-31 06:52:34 +0000 | [diff] [blame] | 2904 | EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered, | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2905 | LoopArguments, CGDispatchBounds); | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 2906 | } | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2907 | if (isOpenMPSimdDirective(S.getDirectiveKind())) { | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2908 | EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) { | 
|  | 2909 | return CGF.Builder.CreateIsNotNull( | 
|  | 2910 | CGF.EmitLoadOfScalar(IL, S.getBeginLoc())); | 
|  | 2911 | }); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2912 | } | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 2913 | EmitOMPReductionClauseFinal( | 
|  | 2914 | S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind()) | 
|  | 2915 | ? /*Parallel and Simd*/ OMPD_parallel_for_simd | 
|  | 2916 | : /*Parallel only*/ OMPD_parallel); | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 2917 | // Emit post-update of the reduction variables if IsLastIter != 0. | 
|  | 2918 | emitPostUpdateForReductionClause( | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2919 | *this, S, [IL, &S](CodeGenFunction &CGF) { | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 2920 | return CGF.Builder.CreateIsNotNull( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2921 | CGF.EmitLoadOfScalar(IL, S.getBeginLoc())); | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 2922 | }); | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 2923 | // Emit final copy of the lastprivate variables if IsLastIter != 0. | 
|  | 2924 | if (HasLastprivateClause) | 
|  | 2925 | EmitOMPLastprivateClauseFinal( | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 2926 | S, isOpenMPSimdDirective(S.getDirectiveKind()), | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2927 | Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc()))); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2928 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2929 | EmitOMPLinearClauseFinal(S, [IL, &S](CodeGenFunction &CGF) { | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2930 | return CGF.Builder.CreateIsNotNull( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2931 | CGF.EmitLoadOfScalar(IL, S.getBeginLoc())); | 
| Alexey Bataev | ef549a8 | 2016-03-09 09:49:09 +0000 | [diff] [blame] | 2932 | }); | 
| Alexey Bataev | ea33dee | 2018-02-15 23:39:43 +0000 | [diff] [blame] | 2933 | DoacrossCleanupScope.ForceCleanup(); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2934 | // We're now done with the loop, so jump to the continuation block. | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 2935 | if (ContBlock) { | 
|  | 2936 | EmitBranch(ContBlock); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2937 | EmitBlock(ContBlock, /*IsFinished=*/true); | 
| Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 2938 | } | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2939 | } | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 2940 | return HasLastprivateClause; | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2941 | } | 
|  | 2942 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2943 | /// The following two functions generate expressions for the loop lower | 
|  | 2944 | /// and upper bounds in case of static and dynamic (dispatch) schedule | 
|  | 2945 | /// of the associated 'for' or 'distribute' loop. | 
|  | 2946 | static std::pair<LValue, LValue> | 
|  | 2947 | emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2948 | const auto &LS = cast<OMPLoopDirective>(S); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2949 | LValue LB = | 
|  | 2950 | EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable())); | 
|  | 2951 | LValue UB = | 
|  | 2952 | EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable())); | 
|  | 2953 | return {LB, UB}; | 
|  | 2954 | } | 
|  | 2955 |  | 
|  | 2956 | /// When dealing with dispatch schedules (e.g. dynamic, guided) we do not | 
|  | 2957 | /// consider the lower and upper bound expressions generated by the | 
|  | 2958 | /// worksharing loop support, but we use 0 and the iteration space size as | 
|  | 2959 | /// constants | 
|  | 2960 | static std::pair<llvm::Value *, llvm::Value *> | 
|  | 2961 | emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S, | 
|  | 2962 | Address LB, Address UB) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2963 | const auto &LS = cast<OMPLoopDirective>(S); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2964 | const Expr *IVExpr = LS.getIterationVariable(); | 
|  | 2965 | const unsigned IVSize = CGF.getContext().getTypeSize(IVExpr->getType()); | 
|  | 2966 | llvm::Value *LBVal = CGF.Builder.getIntN(IVSize, 0); | 
|  | 2967 | llvm::Value *UBVal = CGF.EmitScalarExpr(LS.getLastIteration()); | 
|  | 2968 | return {LBVal, UBVal}; | 
|  | 2969 | } | 
|  | 2970 |  | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2971 | void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { | 
| Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 2972 | bool HasLastprivates = false; | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 2973 | auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF, | 
|  | 2974 | PrePostActionTy &) { | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 2975 | OMPCancelStackRAII CancelRegion(CGF, OMPD_for, S.hasCancel()); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2976 | HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), | 
|  | 2977 | emitForLoopBounds, | 
|  | 2978 | emitDispatchForLoopBounds); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 2979 | }; | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 2980 | { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 2981 | auto LPCRegion = | 
|  | 2982 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 2983 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 2984 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, | 
|  | 2985 | S.hasCancel()); | 
|  | 2986 | } | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 2987 |  | 
|  | 2988 | // Emit an implicit barrier at the end. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 2989 | if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 2990 | CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for); | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 2991 | // Check for outer lastprivate conditional update. | 
|  | 2992 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 2993 | } | 
| Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 2994 |  | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 2995 | void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 2996 | bool HasLastprivates = false; | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 2997 | auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF, | 
|  | 2998 | PrePostActionTy &) { | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 2999 | HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), | 
|  | 3000 | emitForLoopBounds, | 
|  | 3001 | emitDispatchForLoopBounds); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 3002 | }; | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 3003 | { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3004 | auto LPCRegion = | 
|  | 3005 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3006 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 3007 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); | 
|  | 3008 | } | 
| Alexey Bataev | cbdcbb7 | 2015-06-17 07:45:51 +0000 | [diff] [blame] | 3009 |  | 
|  | 3010 | // Emit an implicit barrier at the end. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3011 | if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3012 | CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for); | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3013 | // Check for outer lastprivate conditional update. | 
|  | 3014 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexander Musman | f82886e | 2014-09-18 05:12:34 +0000 | [diff] [blame] | 3015 | } | 
|  | 3016 |  | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 3017 | static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, | 
|  | 3018 | const Twine &Name, | 
|  | 3019 | llvm::Value *Init = nullptr) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3020 | LValue LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty); | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 3021 | if (Init) | 
| Akira Hatanaka | 642f799 | 2016-10-18 19:05:41 +0000 | [diff] [blame] | 3022 | CGF.EmitStoreThroughLValue(RValue::get(Init), LVal, /*isInit*/ true); | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 3023 | return LVal; | 
| Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 3024 | } | 
|  | 3025 |  | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 3026 | void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3027 | const Stmt *CapturedStmt = S.getInnermostCapturedStmt()->getCapturedStmt(); | 
|  | 3028 | const auto *CS = dyn_cast<CompoundStmt>(CapturedStmt); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3029 | bool HasLastprivates = false; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3030 | auto &&CodeGen = [&S, CapturedStmt, CS, | 
|  | 3031 | &HasLastprivates](CodeGenFunction &CGF, PrePostActionTy &) { | 
| Melanie Blower | 2ba4e3a | 2020-04-10 13:34:46 -0700 | [diff] [blame] | 3032 | const ASTContext &C = CGF.getContext(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3033 | QualType KmpInt32Ty = | 
|  | 3034 | C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3035 | // Emit helper vars inits. | 
|  | 3036 | LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.", | 
|  | 3037 | CGF.Builder.getInt32(0)); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3038 | llvm::ConstantInt *GlobalUBVal = CS != nullptr | 
|  | 3039 | ? CGF.Builder.getInt32(CS->size() - 1) | 
|  | 3040 | : CGF.Builder.getInt32(0); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3041 | LValue UB = | 
|  | 3042 | createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal); | 
|  | 3043 | LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.", | 
|  | 3044 | CGF.Builder.getInt32(1)); | 
|  | 3045 | LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.", | 
|  | 3046 | CGF.Builder.getInt32(0)); | 
|  | 3047 | // Loop counter. | 
|  | 3048 | LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv."); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3049 | OpaqueValueExpr IVRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3050 | CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3051 | OpaqueValueExpr UBRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3052 | CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB); | 
|  | 3053 | // Generate condition for loop. | 
| Melanie Blower | 2ba4e3a | 2020-04-10 13:34:46 -0700 | [diff] [blame] | 3054 | BinaryOperator *Cond = BinaryOperator::Create( | 
|  | 3055 | C, &IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue, OK_Ordinary, | 
|  | 3056 | S.getBeginLoc(), FPOptions(C.getLangOpts())); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3057 | // Increment for loop counter. | 
| Melanie Blower | f5360d4 | 2020-05-01 10:32:06 -0700 | [diff] [blame] | 3058 | UnaryOperator *Inc = UnaryOperator::Create( | 
|  | 3059 | C, &IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary, | 
|  | 3060 | S.getBeginLoc(), true, FPOptions(C.getLangOpts())); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3061 | auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) { | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3062 | // Iterate through all sections and emit a switch construct: | 
|  | 3063 | // switch (IV) { | 
|  | 3064 | //   case 0: | 
|  | 3065 | //     <SectionStmt[0]>; | 
|  | 3066 | //     break; | 
|  | 3067 | // ... | 
|  | 3068 | //   case <NumSection> - 1: | 
|  | 3069 | //     <SectionStmt[<NumSection> - 1]>; | 
|  | 3070 | //     break; | 
|  | 3071 | // } | 
|  | 3072 | // .omp.sections.exit: | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3073 | llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".omp.sections.exit"); | 
|  | 3074 | llvm::SwitchInst *SwitchStmt = | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3075 | CGF.Builder.CreateSwitch(CGF.EmitLoadOfScalar(IV, S.getBeginLoc()), | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3076 | ExitBB, CS == nullptr ? 1 : CS->size()); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3077 | if (CS) { | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3078 | unsigned CaseNumber = 0; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3079 | for (const Stmt *SubStmt : CS->children()) { | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3080 | auto CaseBB = CGF.createBasicBlock(".omp.sections.case"); | 
|  | 3081 | CGF.EmitBlock(CaseBB); | 
|  | 3082 | SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB); | 
| Benjamin Kramer | 642f173 | 2015-07-02 21:03:14 +0000 | [diff] [blame] | 3083 | CGF.EmitStmt(SubStmt); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3084 | CGF.EmitBranch(ExitBB); | 
| Benjamin Kramer | 642f173 | 2015-07-02 21:03:14 +0000 | [diff] [blame] | 3085 | ++CaseNumber; | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3086 | } | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3087 | } else { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3088 | llvm::BasicBlock *CaseBB = CGF.createBasicBlock(".omp.sections.case"); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3089 | CGF.EmitBlock(CaseBB); | 
|  | 3090 | SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3091 | CGF.EmitStmt(CapturedStmt); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3092 | CGF.EmitBranch(ExitBB); | 
| Alexey Bataev | 2cb9b95 | 2015-04-24 03:37:03 +0000 | [diff] [blame] | 3093 | } | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3094 | CGF.EmitBlock(ExitBB, /*IsFinished=*/true); | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 3095 | }; | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3096 |  | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3097 | CodeGenFunction::OMPPrivateScope LoopScope(CGF); | 
|  | 3098 | if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) { | 
| Alexey Bataev | 9efc03b | 2015-04-27 04:34:03 +0000 | [diff] [blame] | 3099 | // Emit implicit barrier to synchronize threads and avoid data races on | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 3100 | // initialization of firstprivate variables and post-update of lastprivate | 
|  | 3101 | // variables. | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3102 | CGF.CGM.getOpenMPRuntime().emitBarrierCall( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3103 | CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false, | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3104 | /*ForceSimpleCall=*/true); | 
| Alexey Bataev | 9efc03b | 2015-04-27 04:34:03 +0000 | [diff] [blame] | 3105 | } | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3106 | CGF.EmitOMPPrivateClause(S, LoopScope); | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 3107 | CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion(CGF, S, IV); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3108 | HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); | 
|  | 3109 | CGF.EmitOMPReductionClauseInit(S, LoopScope); | 
|  | 3110 | (void)LoopScope.Privatize(); | 
| Alexey Bataev | 6070542 | 2018-10-30 15:50:12 +0000 | [diff] [blame] | 3111 | if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) | 
|  | 3112 | CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S); | 
| Alexey Bataev | 2cb9b95 | 2015-04-24 03:37:03 +0000 | [diff] [blame] | 3113 |  | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3114 | // Emit static non-chunked loop. | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 3115 | OpenMPScheduleTy ScheduleKind; | 
|  | 3116 | ScheduleKind.Schedule = OMPC_SCHEDULE_static; | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 3117 | CGOpenMPRuntime::StaticRTInput StaticInit( | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 3118 | /*IVSize=*/32, /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(CGF), | 
|  | 3119 | LB.getAddress(CGF), UB.getAddress(CGF), ST.getAddress(CGF)); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3120 | CGF.CGM.getOpenMPRuntime().emitForStaticInit( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3121 | CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind, StaticInit); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3122 | // UB = min(UB, GlobalUB); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3123 | llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, S.getBeginLoc()); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3124 | llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect( | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3125 | CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal); | 
|  | 3126 | CGF.EmitStoreOfScalar(MinUBGlobalUB, UB); | 
|  | 3127 | // IV = LB; | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3128 | CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getBeginLoc()), IV); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3129 | // while (idx <= UB) { BODY; ++idx; } | 
| Melanie Blower | f5360d4 | 2020-05-01 10:32:06 -0700 | [diff] [blame] | 3130 | CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, Cond, Inc, BodyGen, | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3131 | [](CodeGenFunction &) {}); | 
|  | 3132 | // Tell the runtime we are done. | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 3133 | auto &&CodeGen = [&S](CodeGenFunction &CGF) { | 
| Stephen Kelly | 1c301dc | 2018-08-09 21:09:38 +0000 | [diff] [blame] | 3134 | CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), | 
| Alexey Bataev | f43f714 | 2017-09-06 16:17:35 +0000 | [diff] [blame] | 3135 | S.getDirectiveKind()); | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 3136 | }; | 
|  | 3137 | CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen); | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 3138 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); | 
| Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 3139 | // Emit post-update of the reduction variables if IsLastIter != 0. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3140 | emitPostUpdateForReductionClause(CGF, S, [IL, &S](CodeGenFunction &CGF) { | 
|  | 3141 | return CGF.Builder.CreateIsNotNull( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3142 | CGF.EmitLoadOfScalar(IL, S.getBeginLoc())); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3143 | }); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3144 |  | 
|  | 3145 | // Emit final copy of the lastprivate variables if IsLastIter != 0. | 
|  | 3146 | if (HasLastprivates) | 
|  | 3147 | CGF.EmitOMPLastprivateClauseFinal( | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 3148 | S, /*NoFinals=*/false, | 
|  | 3149 | CGF.Builder.CreateIsNotNull( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3150 | CGF.EmitLoadOfScalar(IL, S.getBeginLoc()))); | 
| Alexey Bataev | 68adb7d | 2015-04-14 03:29:22 +0000 | [diff] [blame] | 3151 | }; | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3152 |  | 
|  | 3153 | bool HasCancel = false; | 
|  | 3154 | if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S)) | 
|  | 3155 | HasCancel = OSD->hasCancel(); | 
|  | 3156 | else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S)) | 
|  | 3157 | HasCancel = OPSD->hasCancel(); | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 3158 | OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel); | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3159 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen, | 
|  | 3160 | HasCancel); | 
|  | 3161 | // Emit barrier for lastprivates only if 'sections' directive has 'nowait' | 
|  | 3162 | // clause. Otherwise the barrier will be generated by the codegen for the | 
|  | 3163 | // directive. | 
|  | 3164 | if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) { | 
| Alexey Bataev | 2cb9b95 | 2015-04-24 03:37:03 +0000 | [diff] [blame] | 3165 | // Emit implicit barrier to synchronize threads and avoid data races on | 
|  | 3166 | // initialization of firstprivate variables. | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3167 | CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), | 
| Alexey Bataev | 3015bcc | 2016-01-22 08:56:50 +0000 | [diff] [blame] | 3168 | OMPD_unknown); | 
| Alexey Bataev | 2cb9b95 | 2015-04-24 03:37:03 +0000 | [diff] [blame] | 3169 | } | 
| Alexey Bataev | 68adb7d | 2015-04-14 03:29:22 +0000 | [diff] [blame] | 3170 | } | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 3171 |  | 
| Alexey Bataev | 68adb7d | 2015-04-14 03:29:22 +0000 | [diff] [blame] | 3172 | void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) { | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 3173 | { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3174 | auto LPCRegion = | 
|  | 3175 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3176 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 3177 | EmitSections(S); | 
|  | 3178 | } | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 3179 | // Emit an implicit barrier at the end. | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 3180 | if (!S.getSingleClause<OMPNowaitClause>()) { | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3181 | CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 3182 | OMPD_sections); | 
| Alexey Bataev | f268568 | 2015-03-30 04:30:22 +0000 | [diff] [blame] | 3183 | } | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3184 | // Check for outer lastprivate conditional update. | 
|  | 3185 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexey Bataev | 2df54a0 | 2015-03-12 08:53:29 +0000 | [diff] [blame] | 3186 | } | 
|  | 3187 |  | 
|  | 3188 | void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) { | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 3189 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3190 | CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3191 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3192 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 3193 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen, | 
|  | 3194 | S.hasCancel()); | 
| Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 3195 | } | 
|  | 3196 |  | 
| Alexey Bataev | 6956e2e | 2015-02-05 06:35:41 +0000 | [diff] [blame] | 3197 | void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 3198 | llvm::SmallVector<const Expr *, 8> CopyprivateVars; | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 3199 | llvm::SmallVector<const Expr *, 8> DestExprs; | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 3200 | llvm::SmallVector<const Expr *, 8> SrcExprs; | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 3201 | llvm::SmallVector<const Expr *, 8> AssignmentOps; | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3202 | // Check if there are any 'copyprivate' clauses associated with this | 
| Alexey Bataev | cd8b6a2 | 2016-02-15 08:07:17 +0000 | [diff] [blame] | 3203 | // 'single' construct. | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 3204 | // Build a list of copyprivate variables along with helper expressions | 
|  | 3205 | // (<source>, <destination>, <destination>=<source> expressions) | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 3206 | for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) { | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 3207 | CopyprivateVars.append(C->varlists().begin(), C->varlists().end()); | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 3208 | DestExprs.append(C->destination_exprs().begin(), | 
|  | 3209 | C->destination_exprs().end()); | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 3210 | SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end()); | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 3211 | AssignmentOps.append(C->assignment_ops().begin(), | 
|  | 3212 | C->assignment_ops().end()); | 
|  | 3213 | } | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 3214 | // Emit code for 'single' region along with 'copyprivate' clauses | 
|  | 3215 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3216 | Action.Enter(CGF); | 
|  | 3217 | OMPPrivateScope SingleScope(CGF); | 
|  | 3218 | (void)CGF.EmitOMPFirstprivateClause(S, SingleScope); | 
|  | 3219 | CGF.EmitOMPPrivateClause(S, SingleScope); | 
|  | 3220 | (void)SingleScope.Privatize(); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3221 | CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 3222 | }; | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 3223 | { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3224 | auto LPCRegion = | 
|  | 3225 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3226 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3227 | CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getBeginLoc(), | 
| Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 3228 | CopyprivateVars, DestExprs, | 
|  | 3229 | SrcExprs, AssignmentOps); | 
|  | 3230 | } | 
|  | 3231 | // Emit an implicit barrier at the end (to avoid data race on firstprivate | 
|  | 3232 | // init or if no 'nowait' clause was specified and no 'copyprivate' clause). | 
| Alexey Bataev | 417089f | 2016-02-17 13:19:37 +0000 | [diff] [blame] | 3233 | if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) { | 
| Alexey Bataev | 5521d78 | 2015-04-24 04:21:15 +0000 | [diff] [blame] | 3234 | CGM.getOpenMPRuntime().emitBarrierCall( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3235 | *this, S.getBeginLoc(), | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 3236 | S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single); | 
| Alexey Bataev | f268568 | 2015-03-30 04:30:22 +0000 | [diff] [blame] | 3237 | } | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3238 | // Check for outer lastprivate conditional update. | 
|  | 3239 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexey Bataev | d1e40fb | 2014-06-26 12:05:45 +0000 | [diff] [blame] | 3240 | } | 
|  | 3241 |  | 
| cchen | 47d6094 | 2019-12-05 13:43:48 -0500 | [diff] [blame] | 3242 | static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S) { | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 3243 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3244 | Action.Enter(CGF); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3245 | CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3246 | }; | 
| cchen | 47d6094 | 2019-12-05 13:43:48 -0500 | [diff] [blame] | 3247 | CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc()); | 
|  | 3248 | } | 
|  | 3249 |  | 
|  | 3250 | void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3251 | if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) { | 
|  | 3252 | using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; | 
|  | 3253 |  | 
|  | 3254 | const CapturedStmt *CS = S.getInnermostCapturedStmt(); | 
|  | 3255 | const Stmt *MasterRegionBodyStmt = CS->getCapturedStmt(); | 
|  | 3256 |  | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3257 | auto FiniCB = [this](InsertPointTy IP) { | 
| Fady Ghanim | ba3f863 | 2020-02-19 13:50:26 -0600 | [diff] [blame] | 3258 | OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP); | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3259 | }; | 
|  | 3260 |  | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3261 | auto BodyGenCB = [MasterRegionBodyStmt, this](InsertPointTy AllocaIP, | 
|  | 3262 | InsertPointTy CodeGenIP, | 
|  | 3263 | llvm::BasicBlock &FiniBB) { | 
| Fady Ghanim | ba3f863 | 2020-02-19 13:50:26 -0600 | [diff] [blame] | 3264 | OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB); | 
|  | 3265 | OMPBuilderCBHelpers::EmitOMPRegionBody(*this, MasterRegionBodyStmt, | 
|  | 3266 | CodeGenIP, FiniBB); | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3267 | }; | 
| Fady Ghanim | ba3f863 | 2020-02-19 13:50:26 -0600 | [diff] [blame] | 3268 |  | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3269 | CGCapturedStmtInfo CGSI(*CS, CR_OpenMP); | 
|  | 3270 | CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI); | 
|  | 3271 | Builder.restoreIP(OMPBuilder->CreateMaster(Builder, BodyGenCB, FiniCB)); | 
|  | 3272 |  | 
|  | 3273 | return; | 
|  | 3274 | } | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3275 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| cchen | 47d6094 | 2019-12-05 13:43:48 -0500 | [diff] [blame] | 3276 | emitMaster(*this, S); | 
| Alexander Musman | 80c2289 | 2014-07-17 08:54:58 +0000 | [diff] [blame] | 3277 | } | 
|  | 3278 |  | 
| Alexey Bataev | 3a3bf0b | 2014-09-22 10:01:53 +0000 | [diff] [blame] | 3279 | void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3280 | if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) { | 
|  | 3281 | using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; | 
|  | 3282 |  | 
|  | 3283 | const CapturedStmt *CS = S.getInnermostCapturedStmt(); | 
|  | 3284 | const Stmt *CriticalRegionBodyStmt = CS->getCapturedStmt(); | 
|  | 3285 | const Expr *Hint = nullptr; | 
|  | 3286 | if (const auto *HintClause = S.getSingleClause<OMPHintClause>()) | 
|  | 3287 | Hint = HintClause->getHint(); | 
|  | 3288 |  | 
|  | 3289 | // TODO: This is slightly different from what's currently being done in | 
|  | 3290 | // clang. Fix the Int32Ty to IntPtrTy (pointer width size) when everything | 
|  | 3291 | // about typing is final. | 
|  | 3292 | llvm::Value *HintInst = nullptr; | 
|  | 3293 | if (Hint) | 
|  | 3294 | HintInst = | 
|  | 3295 | Builder.CreateIntCast(EmitScalarExpr(Hint), CGM.Int32Ty, false); | 
|  | 3296 |  | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3297 | auto FiniCB = [this](InsertPointTy IP) { | 
| Fady Ghanim | ba3f863 | 2020-02-19 13:50:26 -0600 | [diff] [blame] | 3298 | OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP); | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3299 | }; | 
|  | 3300 |  | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3301 | auto BodyGenCB = [CriticalRegionBodyStmt, this](InsertPointTy AllocaIP, | 
|  | 3302 | InsertPointTy CodeGenIP, | 
|  | 3303 | llvm::BasicBlock &FiniBB) { | 
| Fady Ghanim | ba3f863 | 2020-02-19 13:50:26 -0600 | [diff] [blame] | 3304 | OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB); | 
|  | 3305 | OMPBuilderCBHelpers::EmitOMPRegionBody(*this, CriticalRegionBodyStmt, | 
|  | 3306 | CodeGenIP, FiniBB); | 
| Fady Ghanim | 7438059a | 2020-02-15 00:42:23 -0600 | [diff] [blame] | 3307 | }; | 
|  | 3308 |  | 
|  | 3309 | CGCapturedStmtInfo CGSI(*CS, CR_OpenMP); | 
|  | 3310 | CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI); | 
|  | 3311 | Builder.restoreIP(OMPBuilder->CreateCritical( | 
|  | 3312 | Builder, BodyGenCB, FiniCB, S.getDirectiveName().getAsString(), | 
|  | 3313 | HintInst)); | 
|  | 3314 |  | 
|  | 3315 | return; | 
|  | 3316 | } | 
|  | 3317 |  | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 3318 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3319 | Action.Enter(CGF); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3320 | CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3321 | }; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3322 | const Expr *Hint = nullptr; | 
|  | 3323 | if (const auto *HintClause = S.getSingleClause<OMPHintClause>()) | 
| Alexey Bataev | fc57d16 | 2015-12-15 10:55:09 +0000 | [diff] [blame] | 3324 | Hint = HintClause->getHint(); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3325 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Alexey Bataev | fc57d16 | 2015-12-15 10:55:09 +0000 | [diff] [blame] | 3326 | CGM.getOpenMPRuntime().emitCriticalRegion(*this, | 
|  | 3327 | S.getDirectiveName().getAsString(), | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3328 | CodeGen, S.getBeginLoc(), Hint); | 
| Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 3329 | } | 
|  | 3330 |  | 
| Alexey Bataev | 671605e | 2015-04-13 05:28:11 +0000 | [diff] [blame] | 3331 | void CodeGenFunction::EmitOMPParallelForDirective( | 
|  | 3332 | const OMPParallelForDirective &S) { | 
|  | 3333 | // Emit directive as a combined directive that consists of two implicit | 
|  | 3334 | // directives: 'parallel' with 'for' directive. | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 3335 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3336 | Action.Enter(CGF); | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 3337 | OMPCancelStackRAII CancelRegion(CGF, OMPD_parallel_for, S.hasCancel()); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 3338 | CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, | 
|  | 3339 | emitDispatchForLoopBounds); | 
| Alexey Bataev | 671605e | 2015-04-13 05:28:11 +0000 | [diff] [blame] | 3340 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3341 | { | 
|  | 3342 | auto LPCRegion = | 
|  | 3343 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
|  | 3344 | emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen, | 
|  | 3345 | emitEmptyBoundParameters); | 
|  | 3346 | } | 
|  | 3347 | // Check for outer lastprivate conditional update. | 
|  | 3348 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 3349 | } | 
|  | 3350 |  | 
| Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 3351 | void CodeGenFunction::EmitOMPParallelForSimdDirective( | 
| Alexey Bataev | 3b5b5c4 | 2015-06-18 10:10:12 +0000 | [diff] [blame] | 3352 | const OMPParallelForSimdDirective &S) { | 
|  | 3353 | // Emit directive as a combined directive that consists of two implicit | 
|  | 3354 | // directives: 'parallel' with 'for' directive. | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 3355 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3356 | Action.Enter(CGF); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 3357 | CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, | 
|  | 3358 | emitDispatchForLoopBounds); | 
| Alexey Bataev | 3b5b5c4 | 2015-06-18 10:10:12 +0000 | [diff] [blame] | 3359 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3360 | { | 
|  | 3361 | auto LPCRegion = | 
|  | 3362 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
|  | 3363 | emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen, | 
|  | 3364 | emitEmptyBoundParameters); | 
|  | 3365 | } | 
|  | 3366 | // Check for outer lastprivate conditional update. | 
|  | 3367 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 3368 | } | 
|  | 3369 |  | 
| cchen | 47d6094 | 2019-12-05 13:43:48 -0500 | [diff] [blame] | 3370 | void CodeGenFunction::EmitOMPParallelMasterDirective( | 
|  | 3371 | const OMPParallelMasterDirective &S) { | 
|  | 3372 | // Emit directive as a combined directive that consists of two implicit | 
|  | 3373 | // directives: 'parallel' with 'master' directive. | 
|  | 3374 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3375 | Action.Enter(CGF); | 
|  | 3376 | OMPPrivateScope PrivateScope(CGF); | 
|  | 3377 | bool Copyins = CGF.EmitOMPCopyinClause(S); | 
|  | 3378 | (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); | 
|  | 3379 | if (Copyins) { | 
|  | 3380 | // Emit implicit barrier to synchronize threads and avoid data races on | 
|  | 3381 | // propagation master's thread values of threadprivate variables to local | 
|  | 3382 | // instances of that variables of all other implicit threads. | 
|  | 3383 | CGF.CGM.getOpenMPRuntime().emitBarrierCall( | 
|  | 3384 | CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false, | 
|  | 3385 | /*ForceSimpleCall=*/true); | 
|  | 3386 | } | 
|  | 3387 | CGF.EmitOMPPrivateClause(S, PrivateScope); | 
|  | 3388 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 3389 | (void)PrivateScope.Privatize(); | 
|  | 3390 | emitMaster(CGF, S); | 
|  | 3391 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); | 
|  | 3392 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3393 | { | 
|  | 3394 | auto LPCRegion = | 
|  | 3395 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
|  | 3396 | emitCommonOMPParallelDirective(*this, S, OMPD_master, CodeGen, | 
|  | 3397 | emitEmptyBoundParameters); | 
|  | 3398 | emitPostUpdateForReductionClause(*this, S, | 
|  | 3399 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 3400 | } | 
|  | 3401 | // Check for outer lastprivate conditional update. | 
|  | 3402 | checkForLastprivateConditionalUpdate(*this, S); | 
| cchen | 47d6094 | 2019-12-05 13:43:48 -0500 | [diff] [blame] | 3403 | } | 
|  | 3404 |  | 
| Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 3405 | void CodeGenFunction::EmitOMPParallelSectionsDirective( | 
| Alexey Bataev | 68adb7d | 2015-04-14 03:29:22 +0000 | [diff] [blame] | 3406 | const OMPParallelSectionsDirective &S) { | 
|  | 3407 | // Emit directive as a combined directive that consists of two implicit | 
|  | 3408 | // directives: 'parallel' with 'sections' directive. | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 3409 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3410 | Action.Enter(CGF); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 3411 | CGF.EmitSections(S); | 
|  | 3412 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3413 | { | 
|  | 3414 | auto LPCRegion = | 
|  | 3415 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
|  | 3416 | emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen, | 
|  | 3417 | emitEmptyBoundParameters); | 
|  | 3418 | } | 
|  | 3419 | // Check for outer lastprivate conditional update. | 
|  | 3420 | checkForLastprivateConditionalUpdate(*this, S); | 
| Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 3421 | } | 
|  | 3422 |  | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3423 | void CodeGenFunction::EmitOMPTaskBasedDirective( | 
|  | 3424 | const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion, | 
|  | 3425 | const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen, | 
|  | 3426 | OMPTaskDataTy &Data) { | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 3427 | // Emit outlined function for task construct. | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3428 | const CapturedStmt *CS = S.getCapturedStmt(CapturedRegion); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3429 | auto I = CS->getCapturedDecl()->param_begin(); | 
|  | 3430 | auto PartId = std::next(I); | 
|  | 3431 | auto TaskT = std::next(I, 4); | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 3432 | // Check if the task is final | 
|  | 3433 | if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) { | 
|  | 3434 | // If the condition constant folds and can be elided, try to avoid emitting | 
|  | 3435 | // the condition and the dead arm of the if/else. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3436 | const Expr *Cond = Clause->getCondition(); | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 3437 | bool CondConstant; | 
|  | 3438 | if (ConstantFoldsToSimpleInteger(Cond, CondConstant)) | 
|  | 3439 | Data.Final.setInt(CondConstant); | 
|  | 3440 | else | 
|  | 3441 | Data.Final.setPointer(EvaluateExprAsBool(Cond)); | 
|  | 3442 | } else { | 
|  | 3443 | // By default the task is not final. | 
|  | 3444 | Data.Final.setInt(/*IntVal=*/false); | 
|  | 3445 | } | 
| Alexey Bataev | 1e1e286 | 2016-05-10 12:21:02 +0000 | [diff] [blame] | 3446 | // Check if the task has 'priority' clause. | 
|  | 3447 | if (const auto *Clause = S.getSingleClause<OMPPriorityClause>()) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3448 | const Expr *Prio = Clause->getPriority(); | 
| Alexey Bataev | 5140e74 | 2016-07-19 04:21:09 +0000 | [diff] [blame] | 3449 | Data.Priority.setInt(/*IntVal=*/true); | 
| Alexey Bataev | ad537bb | 2016-05-30 09:06:50 +0000 | [diff] [blame] | 3450 | Data.Priority.setPointer(EmitScalarConversion( | 
|  | 3451 | EmitScalarExpr(Prio), Prio->getType(), | 
|  | 3452 | getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1), | 
|  | 3453 | Prio->getExprLoc())); | 
| Alexey Bataev | 1e1e286 | 2016-05-10 12:21:02 +0000 | [diff] [blame] | 3454 | } | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 3455 | // The first function argument for tasks is a thread id, the second one is a | 
|  | 3456 | // part id (0 for tied tasks, >=0 for untied task). | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3457 | llvm::DenseSet<const VarDecl *> EmittedAsPrivate; | 
|  | 3458 | // Get list of private variables. | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 3459 | for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) { | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3460 | auto IRef = C->varlist_begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3461 | for (const Expr *IInit : C->private_copies()) { | 
|  | 3462 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3463 | if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3464 | Data.PrivateVars.push_back(*IRef); | 
|  | 3465 | Data.PrivateCopies.push_back(IInit); | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3466 | } | 
|  | 3467 | ++IRef; | 
|  | 3468 | } | 
|  | 3469 | } | 
|  | 3470 | EmittedAsPrivate.clear(); | 
|  | 3471 | // Get list of firstprivate variables. | 
| Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 3472 | for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) { | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3473 | auto IRef = C->varlist_begin(); | 
|  | 3474 | auto IElemInitRef = C->inits().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3475 | for (const Expr *IInit : C->private_copies()) { | 
|  | 3476 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3477 | if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3478 | Data.FirstprivateVars.push_back(*IRef); | 
|  | 3479 | Data.FirstprivateCopies.push_back(IInit); | 
|  | 3480 | Data.FirstprivateInits.push_back(*IElemInitRef); | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3481 | } | 
| Richard Trieu | cc3949d | 2016-02-18 22:34:54 +0000 | [diff] [blame] | 3482 | ++IRef; | 
|  | 3483 | ++IElemInitRef; | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3484 | } | 
|  | 3485 | } | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 3486 | // Get list of lastprivate variables (for taskloops). | 
|  | 3487 | llvm::DenseMap<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs; | 
|  | 3488 | for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) { | 
|  | 3489 | auto IRef = C->varlist_begin(); | 
|  | 3490 | auto ID = C->destination_exprs().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3491 | for (const Expr *IInit : C->private_copies()) { | 
|  | 3492 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 3493 | if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { | 
|  | 3494 | Data.LastprivateVars.push_back(*IRef); | 
|  | 3495 | Data.LastprivateCopies.push_back(IInit); | 
|  | 3496 | } | 
|  | 3497 | LastprivateDstsOrigs.insert( | 
|  | 3498 | {cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()), | 
|  | 3499 | cast<DeclRefExpr>(*IRef)}); | 
|  | 3500 | ++IRef; | 
|  | 3501 | ++ID; | 
|  | 3502 | } | 
|  | 3503 | } | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3504 | SmallVector<const Expr *, 4> LHSs; | 
|  | 3505 | SmallVector<const Expr *, 4> RHSs; | 
|  | 3506 | for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) { | 
| Alexey Bataev | 8c2f4e0 | 2020-04-24 09:56:29 -0400 | [diff] [blame] | 3507 | Data.ReductionVars.append(C->varlist_begin(), C->varlist_end()); | 
|  | 3508 | Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end()); | 
|  | 3509 | Data.ReductionCopies.append(C->privates().begin(), C->privates().end()); | 
|  | 3510 | Data.ReductionOps.append(C->reduction_ops().begin(), | 
|  | 3511 | C->reduction_ops().end()); | 
|  | 3512 | LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); | 
|  | 3513 | RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3514 | } | 
|  | 3515 | Data.Reductions = CGM.getOpenMPRuntime().emitTaskReductionInit( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3516 | *this, S.getBeginLoc(), LHSs, RHSs, Data); | 
| Alexey Bataev | 1d2353d | 2015-06-24 11:01:36 +0000 | [diff] [blame] | 3517 | // Build list of dependences. | 
| Alexey Bataev | be99c61 | 2020-04-06 11:21:43 -0400 | [diff] [blame] | 3518 | for (const auto *C : S.getClausesOfKind<OMPDependClause>()) { | 
|  | 3519 | OMPTaskDataTy::DependData &DD = | 
|  | 3520 | Data.Dependences.emplace_back(C->getDependencyKind(), C->getModifier()); | 
|  | 3521 | DD.DepExprs.append(C->varlist_begin(), C->varlist_end()); | 
|  | 3522 | } | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3523 | auto &&CodeGen = [&Data, &S, CS, &BodyGen, &LastprivateDstsOrigs, | 
|  | 3524 | CapturedRegion](CodeGenFunction &CGF, | 
|  | 3525 | PrePostActionTy &Action) { | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3526 | // Set proper addresses for generated private copies. | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3527 | OMPPrivateScope Scope(CGF); | 
| Alexey Bataev | b3998a0 | 2020-03-09 08:55:57 -0400 | [diff] [blame] | 3528 | llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> FirstprivatePtrs; | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 3529 | if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() || | 
|  | 3530 | !Data.LastprivateVars.empty()) { | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 3531 | llvm::FunctionType *CopyFnTy = llvm::FunctionType::get( | 
|  | 3532 | CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true); | 
| Alexey Bataev | 3c595a6 | 2017-08-14 15:01:03 +0000 | [diff] [blame] | 3533 | enum { PrivatesParam = 2, CopyFnParam = 3 }; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3534 | llvm::Value *CopyFn = CGF.Builder.CreateLoad( | 
|  | 3535 | CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam))); | 
|  | 3536 | llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar( | 
|  | 3537 | CS->getCapturedDecl()->getParam(PrivatesParam))); | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 3538 | // Map privates. | 
|  | 3539 | llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs; | 
|  | 3540 | llvm::SmallVector<llvm::Value *, 16> CallArgs; | 
|  | 3541 | CallArgs.push_back(PrivatesPtr); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3542 | for (const Expr *E : Data.PrivateVars) { | 
|  | 3543 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 3544 | Address PrivatePtr = CGF.CreateMemTemp( | 
|  | 3545 | CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr"); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3546 | PrivatePtrs.emplace_back(VD, PrivatePtr); | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 3547 | CallArgs.push_back(PrivatePtr.getPointer()); | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3548 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3549 | for (const Expr *E : Data.FirstprivateVars) { | 
|  | 3550 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 3551 | Address PrivatePtr = | 
|  | 3552 | CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), | 
|  | 3553 | ".firstpriv.ptr.addr"); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3554 | PrivatePtrs.emplace_back(VD, PrivatePtr); | 
| Alexey Bataev | b3998a0 | 2020-03-09 08:55:57 -0400 | [diff] [blame] | 3555 | FirstprivatePtrs.emplace_back(VD, PrivatePtr); | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 3556 | CallArgs.push_back(PrivatePtr.getPointer()); | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3557 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3558 | for (const Expr *E : Data.LastprivateVars) { | 
|  | 3559 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 3560 | Address PrivatePtr = | 
|  | 3561 | CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), | 
|  | 3562 | ".lastpriv.ptr.addr"); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3563 | PrivatePtrs.emplace_back(VD, PrivatePtr); | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 3564 | CallArgs.push_back(PrivatePtr.getPointer()); | 
|  | 3565 | } | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 3566 | CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall( | 
|  | 3567 | CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3568 | for (const auto &Pair : LastprivateDstsOrigs) { | 
|  | 3569 | const auto *OrigVD = cast<VarDecl>(Pair.second->getDecl()); | 
| Bruno Ricci | 5fc4db7 | 2018-12-21 14:10:18 +0000 | [diff] [blame] | 3570 | DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(OrigVD), | 
|  | 3571 | /*RefersToEnclosingVariableOrCapture=*/ | 
|  | 3572 | CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr, | 
|  | 3573 | Pair.second->getType(), VK_LValue, | 
|  | 3574 | Pair.second->getExprLoc()); | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 3575 | Scope.addPrivate(Pair.first, [&CGF, &DRE]() { | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 3576 | return CGF.EmitLValue(&DRE).getAddress(CGF); | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 3577 | }); | 
|  | 3578 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3579 | for (const auto &Pair : PrivatePtrs) { | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 3580 | Address Replacement(CGF.Builder.CreateLoad(Pair.second), | 
|  | 3581 | CGF.getContext().getDeclAlign(Pair.first)); | 
|  | 3582 | Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; }); | 
|  | 3583 | } | 
| Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 3584 | } | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3585 | if (Data.Reductions) { | 
| Alexey Bataev | b3998a0 | 2020-03-09 08:55:57 -0400 | [diff] [blame] | 3586 | OMPPrivateScope FirstprivateScope(CGF); | 
|  | 3587 | for (const auto &Pair : FirstprivatePtrs) { | 
|  | 3588 | Address Replacement(CGF.Builder.CreateLoad(Pair.second), | 
|  | 3589 | CGF.getContext().getDeclAlign(Pair.first)); | 
|  | 3590 | FirstprivateScope.addPrivate(Pair.first, | 
|  | 3591 | [Replacement]() { return Replacement; }); | 
|  | 3592 | } | 
|  | 3593 | (void)FirstprivateScope.Privatize(); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3594 | OMPLexicalScope LexScope(CGF, S, CapturedRegion); | 
| Alexey Bataev | e9bfa1d | 2020-04-23 13:27:03 -0400 | [diff] [blame] | 3595 | ReductionCodeGen RedCG(Data.ReductionVars, Data.ReductionVars, | 
|  | 3596 | Data.ReductionCopies, Data.ReductionOps); | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3597 | llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad( | 
|  | 3598 | CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9))); | 
|  | 3599 | for (unsigned Cnt = 0, E = Data.ReductionVars.size(); Cnt < E; ++Cnt) { | 
| Alexey Bataev | e9bfa1d | 2020-04-23 13:27:03 -0400 | [diff] [blame] | 3600 | RedCG.emitSharedOrigLValue(CGF, Cnt); | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3601 | RedCG.emitAggregateType(CGF, Cnt); | 
| Alexey Bataev | 2e0cbe50 | 2018-03-08 15:24:08 +0000 | [diff] [blame] | 3602 | // FIXME: This must removed once the runtime library is fixed. | 
|  | 3603 | // Emit required threadprivate variables for | 
| Raphael Isemann | b23ccec | 2018-12-10 12:37:46 +0000 | [diff] [blame] | 3604 | // initializer/combiner/finalizer. | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3605 | CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(), | 
| Alexey Bataev | 2e0cbe50 | 2018-03-08 15:24:08 +0000 | [diff] [blame] | 3606 | RedCG, Cnt); | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3607 | Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3608 | CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3609 | Replacement = | 
|  | 3610 | Address(CGF.EmitScalarConversion( | 
|  | 3611 | Replacement.getPointer(), CGF.getContext().VoidPtrTy, | 
|  | 3612 | CGF.getContext().getPointerType( | 
|  | 3613 | Data.ReductionCopies[Cnt]->getType()), | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3614 | Data.ReductionCopies[Cnt]->getExprLoc()), | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3615 | Replacement.getAlignment()); | 
|  | 3616 | Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement); | 
|  | 3617 | Scope.addPrivate(RedCG.getBaseDecl(Cnt), | 
|  | 3618 | [Replacement]() { return Replacement; }); | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 3619 | } | 
|  | 3620 | } | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3621 | // Privatize all private variables except for in_reduction items. | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 3622 | (void)Scope.Privatize(); | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3623 | SmallVector<const Expr *, 4> InRedVars; | 
|  | 3624 | SmallVector<const Expr *, 4> InRedPrivs; | 
|  | 3625 | SmallVector<const Expr *, 4> InRedOps; | 
|  | 3626 | SmallVector<const Expr *, 4> TaskgroupDescriptors; | 
|  | 3627 | for (const auto *C : S.getClausesOfKind<OMPInReductionClause>()) { | 
|  | 3628 | auto IPriv = C->privates().begin(); | 
|  | 3629 | auto IRed = C->reduction_ops().begin(); | 
|  | 3630 | auto ITD = C->taskgroup_descriptors().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3631 | for (const Expr *Ref : C->varlists()) { | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3632 | InRedVars.emplace_back(Ref); | 
|  | 3633 | InRedPrivs.emplace_back(*IPriv); | 
|  | 3634 | InRedOps.emplace_back(*IRed); | 
|  | 3635 | TaskgroupDescriptors.emplace_back(*ITD); | 
|  | 3636 | std::advance(IPriv, 1); | 
|  | 3637 | std::advance(IRed, 1); | 
|  | 3638 | std::advance(ITD, 1); | 
|  | 3639 | } | 
|  | 3640 | } | 
|  | 3641 | // Privatize in_reduction items here, because taskgroup descriptors must be | 
|  | 3642 | // privatized earlier. | 
|  | 3643 | OMPPrivateScope InRedScope(CGF); | 
|  | 3644 | if (!InRedVars.empty()) { | 
| Alexey Bataev | e9bfa1d | 2020-04-23 13:27:03 -0400 | [diff] [blame] | 3645 | ReductionCodeGen RedCG(InRedVars, InRedVars, InRedPrivs, InRedOps); | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3646 | for (unsigned Cnt = 0, E = InRedVars.size(); Cnt < E; ++Cnt) { | 
| Alexey Bataev | e9bfa1d | 2020-04-23 13:27:03 -0400 | [diff] [blame] | 3647 | RedCG.emitSharedOrigLValue(CGF, Cnt); | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3648 | RedCG.emitAggregateType(CGF, Cnt); | 
|  | 3649 | // The taskgroup descriptor variable is always implicit firstprivate and | 
| Raphael Isemann | b23ccec | 2018-12-10 12:37:46 +0000 | [diff] [blame] | 3650 | // privatized already during processing of the firstprivates. | 
| Alexey Bataev | 2e0cbe50 | 2018-03-08 15:24:08 +0000 | [diff] [blame] | 3651 | // FIXME: This must removed once the runtime library is fixed. | 
|  | 3652 | // Emit required threadprivate variables for | 
| Raphael Isemann | b23ccec | 2018-12-10 12:37:46 +0000 | [diff] [blame] | 3653 | // initializer/combiner/finalizer. | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3654 | CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(), | 
| Alexey Bataev | 2e0cbe50 | 2018-03-08 15:24:08 +0000 | [diff] [blame] | 3655 | RedCG, Cnt); | 
| Alexey Bataev | 0fca766 | 2020-03-27 11:15:17 -0400 | [diff] [blame] | 3656 | llvm::Value *ReductionsPtr; | 
|  | 3657 | if (const Expr *TRExpr = TaskgroupDescriptors[Cnt]) { | 
|  | 3658 | ReductionsPtr = CGF.EmitLoadOfScalar(CGF.EmitLValue(TRExpr), | 
|  | 3659 | TRExpr->getExprLoc()); | 
|  | 3660 | } else { | 
|  | 3661 | ReductionsPtr = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); | 
|  | 3662 | } | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3663 | Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3664 | CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3665 | Replacement = Address( | 
|  | 3666 | CGF.EmitScalarConversion( | 
|  | 3667 | Replacement.getPointer(), CGF.getContext().VoidPtrTy, | 
|  | 3668 | CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()), | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3669 | InRedPrivs[Cnt]->getExprLoc()), | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3670 | Replacement.getAlignment()); | 
|  | 3671 | Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement); | 
|  | 3672 | InRedScope.addPrivate(RedCG.getBaseDecl(Cnt), | 
|  | 3673 | [Replacement]() { return Replacement; }); | 
| Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 3674 | } | 
|  | 3675 | } | 
|  | 3676 | (void)InRedScope.Privatize(); | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 3677 |  | 
|  | 3678 | Action.Enter(CGF); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3679 | BodyGen(CGF); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 3680 | }; | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 3681 | llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3682 | S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied, | 
|  | 3683 | Data.NumberOfParts); | 
| Alexey Bataev | 5bbcead | 2019-10-14 17:17:41 +0000 | [diff] [blame] | 3684 | OMPLexicalScope Scope(*this, S, llvm::None, | 
| Alexey Bataev | 6120582 | 2019-12-04 09:50:21 -0500 | [diff] [blame] | 3685 | !isOpenMPParallelDirective(S.getDirectiveKind()) && | 
|  | 3686 | !isOpenMPSimdDirective(S.getDirectiveKind())); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3687 | TaskGen(*this, OutlinedFn, Data); | 
|  | 3688 | } | 
|  | 3689 |  | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3690 | static ImplicitParamDecl * | 
|  | 3691 | createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data, | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3692 | QualType Ty, CapturedDecl *CD, | 
|  | 3693 | SourceLocation Loc) { | 
|  | 3694 | auto *OrigVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty, | 
|  | 3695 | ImplicitParamDecl::Other); | 
|  | 3696 | auto *OrigRef = DeclRefExpr::Create( | 
|  | 3697 | C, NestedNameSpecifierLoc(), SourceLocation(), OrigVD, | 
|  | 3698 | /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue); | 
|  | 3699 | auto *PrivateVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty, | 
|  | 3700 | ImplicitParamDecl::Other); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3701 | auto *PrivateRef = DeclRefExpr::Create( | 
|  | 3702 | C, NestedNameSpecifierLoc(), SourceLocation(), PrivateVD, | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3703 | /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3704 | QualType ElemType = C.getBaseElementType(Ty); | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3705 | auto *InitVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, ElemType, | 
|  | 3706 | ImplicitParamDecl::Other); | 
|  | 3707 | auto *InitRef = DeclRefExpr::Create( | 
|  | 3708 | C, NestedNameSpecifierLoc(), SourceLocation(), InitVD, | 
|  | 3709 | /*RefersToEnclosingVariableOrCapture=*/false, Loc, ElemType, VK_LValue); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3710 | PrivateVD->setInitStyle(VarDecl::CInit); | 
|  | 3711 | PrivateVD->setInit(ImplicitCastExpr::Create(C, ElemType, CK_LValueToRValue, | 
|  | 3712 | InitRef, /*BasePath=*/nullptr, | 
|  | 3713 | VK_RValue)); | 
|  | 3714 | Data.FirstprivateVars.emplace_back(OrigRef); | 
|  | 3715 | Data.FirstprivateCopies.emplace_back(PrivateRef); | 
|  | 3716 | Data.FirstprivateInits.emplace_back(InitRef); | 
|  | 3717 | return OrigVD; | 
|  | 3718 | } | 
|  | 3719 |  | 
|  | 3720 | void CodeGenFunction::EmitOMPTargetTaskBasedDirective( | 
|  | 3721 | const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen, | 
|  | 3722 | OMPTargetDataInfo &InputInfo) { | 
|  | 3723 | // Emit outlined function for task construct. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3724 | const CapturedStmt *CS = S.getCapturedStmt(OMPD_task); | 
|  | 3725 | Address CapturedStruct = GenerateCapturedStmtArgument(*CS); | 
|  | 3726 | QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); | 
|  | 3727 | auto I = CS->getCapturedDecl()->param_begin(); | 
|  | 3728 | auto PartId = std::next(I); | 
|  | 3729 | auto TaskT = std::next(I, 4); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3730 | OMPTaskDataTy Data; | 
|  | 3731 | // The task is not final. | 
|  | 3732 | Data.Final.setInt(/*IntVal=*/false); | 
|  | 3733 | // Get list of firstprivate variables. | 
|  | 3734 | for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) { | 
|  | 3735 | auto IRef = C->varlist_begin(); | 
|  | 3736 | auto IElemInitRef = C->inits().begin(); | 
|  | 3737 | for (auto *IInit : C->private_copies()) { | 
|  | 3738 | Data.FirstprivateVars.push_back(*IRef); | 
|  | 3739 | Data.FirstprivateCopies.push_back(IInit); | 
|  | 3740 | Data.FirstprivateInits.push_back(*IElemInitRef); | 
|  | 3741 | ++IRef; | 
|  | 3742 | ++IElemInitRef; | 
|  | 3743 | } | 
|  | 3744 | } | 
|  | 3745 | OMPPrivateScope TargetScope(*this); | 
|  | 3746 | VarDecl *BPVD = nullptr; | 
|  | 3747 | VarDecl *PVD = nullptr; | 
|  | 3748 | VarDecl *SVD = nullptr; | 
|  | 3749 | if (InputInfo.NumberOfTargetItems > 0) { | 
|  | 3750 | auto *CD = CapturedDecl::Create( | 
|  | 3751 | getContext(), getContext().getTranslationUnitDecl(), /*NumParams=*/0); | 
|  | 3752 | llvm::APInt ArrSize(/*numBits=*/32, InputInfo.NumberOfTargetItems); | 
|  | 3753 | QualType BaseAndPointersType = getContext().getConstantArrayType( | 
| Richard Smith | 772e266 | 2019-10-04 01:25:59 +0000 | [diff] [blame] | 3754 | getContext().VoidPtrTy, ArrSize, nullptr, ArrayType::Normal, | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3755 | /*IndexTypeQuals=*/0); | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3756 | BPVD = createImplicitFirstprivateForType( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3757 | getContext(), Data, BaseAndPointersType, CD, S.getBeginLoc()); | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3758 | PVD = createImplicitFirstprivateForType( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3759 | getContext(), Data, BaseAndPointersType, CD, S.getBeginLoc()); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3760 | QualType SizesType = getContext().getConstantArrayType( | 
| Alexey Bataev | a90fc66 | 2019-06-25 16:00:43 +0000 | [diff] [blame] | 3761 | getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1), | 
| Richard Smith | 772e266 | 2019-10-04 01:25:59 +0000 | [diff] [blame] | 3762 | ArrSize, nullptr, ArrayType::Normal, | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3763 | /*IndexTypeQuals=*/0); | 
| Alexey Bataev | a9b9cc0 | 2018-01-23 18:12:38 +0000 | [diff] [blame] | 3764 | SVD = createImplicitFirstprivateForType(getContext(), Data, SizesType, CD, | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3765 | S.getBeginLoc()); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3766 | TargetScope.addPrivate( | 
|  | 3767 | BPVD, [&InputInfo]() { return InputInfo.BasePointersArray; }); | 
|  | 3768 | TargetScope.addPrivate(PVD, | 
|  | 3769 | [&InputInfo]() { return InputInfo.PointersArray; }); | 
|  | 3770 | TargetScope.addPrivate(SVD, | 
|  | 3771 | [&InputInfo]() { return InputInfo.SizesArray; }); | 
|  | 3772 | } | 
|  | 3773 | (void)TargetScope.Privatize(); | 
|  | 3774 | // Build list of dependences. | 
| Alexey Bataev | be99c61 | 2020-04-06 11:21:43 -0400 | [diff] [blame] | 3775 | for (const auto *C : S.getClausesOfKind<OMPDependClause>()) { | 
|  | 3776 | OMPTaskDataTy::DependData &DD = | 
|  | 3777 | Data.Dependences.emplace_back(C->getDependencyKind(), C->getModifier()); | 
|  | 3778 | DD.DepExprs.append(C->varlist_begin(), C->varlist_end()); | 
|  | 3779 | } | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3780 | auto &&CodeGen = [&Data, &S, CS, &BodyGen, BPVD, PVD, SVD, | 
|  | 3781 | &InputInfo](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3782 | // Set proper addresses for generated private copies. | 
|  | 3783 | OMPPrivateScope Scope(CGF); | 
|  | 3784 | if (!Data.FirstprivateVars.empty()) { | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 3785 | llvm::FunctionType *CopyFnTy = llvm::FunctionType::get( | 
|  | 3786 | CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3787 | enum { PrivatesParam = 2, CopyFnParam = 3 }; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3788 | llvm::Value *CopyFn = CGF.Builder.CreateLoad( | 
|  | 3789 | CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam))); | 
|  | 3790 | llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar( | 
|  | 3791 | CS->getCapturedDecl()->getParam(PrivatesParam))); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3792 | // Map privates. | 
|  | 3793 | llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs; | 
|  | 3794 | llvm::SmallVector<llvm::Value *, 16> CallArgs; | 
|  | 3795 | CallArgs.push_back(PrivatesPtr); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3796 | for (const Expr *E : Data.FirstprivateVars) { | 
|  | 3797 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3798 | Address PrivatePtr = | 
|  | 3799 | CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), | 
|  | 3800 | ".firstpriv.ptr.addr"); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3801 | PrivatePtrs.emplace_back(VD, PrivatePtr); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3802 | CallArgs.push_back(PrivatePtr.getPointer()); | 
|  | 3803 | } | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 3804 | CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall( | 
|  | 3805 | CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3806 | for (const auto &Pair : PrivatePtrs) { | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3807 | Address Replacement(CGF.Builder.CreateLoad(Pair.second), | 
|  | 3808 | CGF.getContext().getDeclAlign(Pair.first)); | 
|  | 3809 | Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; }); | 
|  | 3810 | } | 
|  | 3811 | } | 
|  | 3812 | // Privatize all private variables except for in_reduction items. | 
|  | 3813 | (void)Scope.Privatize(); | 
| Alexey Bataev | 8451efa | 2018-01-15 19:06:12 +0000 | [diff] [blame] | 3814 | if (InputInfo.NumberOfTargetItems > 0) { | 
|  | 3815 | InputInfo.BasePointersArray = CGF.Builder.CreateConstArrayGEP( | 
| James Y Knight | 751fe28 | 2019-02-09 22:22:28 +0000 | [diff] [blame] | 3816 | CGF.GetAddrOfLocalVar(BPVD), /*Index=*/0); | 
| Alexey Bataev | 8451efa | 2018-01-15 19:06:12 +0000 | [diff] [blame] | 3817 | InputInfo.PointersArray = CGF.Builder.CreateConstArrayGEP( | 
| James Y Knight | 751fe28 | 2019-02-09 22:22:28 +0000 | [diff] [blame] | 3818 | CGF.GetAddrOfLocalVar(PVD), /*Index=*/0); | 
| Alexey Bataev | 8451efa | 2018-01-15 19:06:12 +0000 | [diff] [blame] | 3819 | InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP( | 
| James Y Knight | 751fe28 | 2019-02-09 22:22:28 +0000 | [diff] [blame] | 3820 | CGF.GetAddrOfLocalVar(SVD), /*Index=*/0); | 
| Alexey Bataev | 8451efa | 2018-01-15 19:06:12 +0000 | [diff] [blame] | 3821 | } | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3822 |  | 
|  | 3823 | Action.Enter(CGF); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3824 | OMPLexicalScope LexScope(CGF, S, OMPD_task, /*EmitPreInitStmt=*/false); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3825 | BodyGen(CGF); | 
|  | 3826 | }; | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 3827 | llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3828 | S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, /*Tied=*/true, | 
|  | 3829 | Data.NumberOfParts); | 
|  | 3830 | llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<OMPNowaitClause>() ? 1 : 0); | 
|  | 3831 | IntegerLiteral IfCond(getContext(), TrueOrFalse, | 
|  | 3832 | getContext().getIntTypeForBitwidth(32, /*Signed=*/0), | 
|  | 3833 | SourceLocation()); | 
|  | 3834 |  | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3835 | CGM.getOpenMPRuntime().emitTaskCall(*this, S.getBeginLoc(), S, OutlinedFn, | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 3836 | SharedsTy, CapturedStruct, &IfCond, Data); | 
|  | 3837 | } | 
|  | 3838 |  | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3839 | void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { | 
|  | 3840 | // Emit outlined function for task construct. | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3841 | const CapturedStmt *CS = S.getCapturedStmt(OMPD_task); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3842 | Address CapturedStruct = GenerateCapturedStmtArgument(*CS); | 
|  | 3843 | QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 3844 | const Expr *IfCond = nullptr; | 
| Alexey Bataev | 7371aa3 | 2015-09-03 08:45:56 +0000 | [diff] [blame] | 3845 | for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { | 
|  | 3846 | if (C->getNameModifier() == OMPD_unknown || | 
|  | 3847 | C->getNameModifier() == OMPD_task) { | 
|  | 3848 | IfCond = C->getCondition(); | 
|  | 3849 | break; | 
|  | 3850 | } | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 3851 | } | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3852 |  | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 3853 | OMPTaskDataTy Data; | 
|  | 3854 | // Check if we should emit tied or untied task. | 
|  | 3855 | Data.Tied = !S.getSingleClause<OMPUntiedClause>(); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3856 | auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 3857 | CGF.EmitStmt(CS->getCapturedStmt()); | 
|  | 3858 | }; | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 3859 | auto &&TaskGen = [&S, SharedsTy, CapturedStruct, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 3860 | IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn, | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 3861 | const OMPTaskDataTy &Data) { | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3862 | CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getBeginLoc(), S, OutlinedFn, | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 3863 | SharedsTy, CapturedStruct, IfCond, | 
|  | 3864 | Data); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 3865 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 3866 | auto LPCRegion = | 
|  | 3867 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3868 | EmitOMPTaskBasedDirective(S, OMPD_task, BodyGen, TaskGen, Data); | 
| Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 3869 | } | 
|  | 3870 |  | 
| Alexey Bataev | 9f797f3 | 2015-02-05 05:57:51 +0000 | [diff] [blame] | 3871 | void CodeGenFunction::EmitOMPTaskyieldDirective( | 
|  | 3872 | const OMPTaskyieldDirective &S) { | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3873 | CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getBeginLoc()); | 
| Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 3874 | } | 
|  | 3875 |  | 
| Alexey Bataev | 8f7c1b0 | 2014-12-05 04:09:23 +0000 | [diff] [blame] | 3876 | void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) { | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3877 | CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_barrier); | 
| Alexey Bataev | 4d1dfea | 2014-07-18 09:11:51 +0000 | [diff] [blame] | 3878 | } | 
|  | 3879 |  | 
| Alexey Bataev | 8b8e202 | 2015-04-27 05:22:09 +0000 | [diff] [blame] | 3880 | void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) { | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3881 | CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getBeginLoc()); | 
| Alexey Bataev | 2df347a | 2014-07-18 10:17:07 +0000 | [diff] [blame] | 3882 | } | 
|  | 3883 |  | 
| Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 3884 | void CodeGenFunction::EmitOMPTaskgroupDirective( | 
|  | 3885 | const OMPTaskgroupDirective &S) { | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 3886 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 3887 | Action.Enter(CGF); | 
| Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 3888 | if (const Expr *E = S.getReductionRef()) { | 
|  | 3889 | SmallVector<const Expr *, 4> LHSs; | 
|  | 3890 | SmallVector<const Expr *, 4> RHSs; | 
|  | 3891 | OMPTaskDataTy Data; | 
|  | 3892 | for (const auto *C : S.getClausesOfKind<OMPTaskReductionClause>()) { | 
| Alexey Bataev | 8c2f4e0 | 2020-04-24 09:56:29 -0400 | [diff] [blame] | 3893 | Data.ReductionVars.append(C->varlist_begin(), C->varlist_end()); | 
|  | 3894 | Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end()); | 
|  | 3895 | Data.ReductionCopies.append(C->privates().begin(), C->privates().end()); | 
|  | 3896 | Data.ReductionOps.append(C->reduction_ops().begin(), | 
|  | 3897 | C->reduction_ops().end()); | 
|  | 3898 | LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); | 
|  | 3899 | RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); | 
| Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 3900 | } | 
|  | 3901 | llvm::Value *ReductionDesc = | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3902 | CGF.CGM.getOpenMPRuntime().emitTaskReductionInit(CGF, S.getBeginLoc(), | 
| Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 3903 | LHSs, RHSs, Data); | 
|  | 3904 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
|  | 3905 | CGF.EmitVarDecl(*VD); | 
|  | 3906 | CGF.EmitStoreOfScalar(ReductionDesc, CGF.GetAddrOfLocalVar(VD), | 
|  | 3907 | /*Volatile=*/false, E->getType()); | 
|  | 3908 | } | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3909 | CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); | 
| Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 3910 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 3911 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 3912 | CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getBeginLoc()); | 
| Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 3913 | } | 
|  | 3914 |  | 
| Alexey Bataev | cc37cc1 | 2014-11-20 04:34:54 +0000 | [diff] [blame] | 3915 | void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) { | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 3916 | llvm::AtomicOrdering AO = S.getSingleClause<OMPFlushClause>() | 
|  | 3917 | ? llvm::AtomicOrdering::NotAtomic | 
|  | 3918 | : llvm::AtomicOrdering::AcquireRelease; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3919 | CGM.getOpenMPRuntime().emitFlush( | 
|  | 3920 | *this, | 
|  | 3921 | [&S]() -> ArrayRef<const Expr *> { | 
|  | 3922 | if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>()) | 
|  | 3923 | return llvm::makeArrayRef(FlushClause->varlist_begin(), | 
|  | 3924 | FlushClause->varlist_end()); | 
|  | 3925 | return llvm::None; | 
|  | 3926 | }(), | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 3927 | S.getBeginLoc(), AO); | 
| Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 3928 | } | 
|  | 3929 |  | 
| Alexey Bataev | e46f0fe | 2020-03-04 14:37:51 -0500 | [diff] [blame] | 3930 | void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) { | 
|  | 3931 | const auto *DO = S.getSingleClause<OMPDepobjClause>(); | 
|  | 3932 | LValue DOLVal = EmitLValue(DO->getDepobj()); | 
|  | 3933 | if (const auto *DC = S.getSingleClause<OMPDependClause>()) { | 
| Alexey Bataev | be99c61 | 2020-04-06 11:21:43 -0400 | [diff] [blame] | 3934 | OMPTaskDataTy::DependData Dependencies(DC->getDependencyKind(), | 
|  | 3935 | DC->getModifier()); | 
|  | 3936 | Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end()); | 
|  | 3937 | Address DepAddr = CGM.getOpenMPRuntime().emitDepobjDependClause( | 
|  | 3938 | *this, Dependencies, DC->getBeginLoc()); | 
| Alexey Bataev | e46f0fe | 2020-03-04 14:37:51 -0500 | [diff] [blame] | 3939 | EmitStoreOfScalar(DepAddr.getPointer(), DOLVal); | 
| Alexey Bataev | b27ff4d | 2020-03-04 16:15:28 -0500 | [diff] [blame] | 3940 | return; | 
|  | 3941 | } | 
|  | 3942 | if (const auto *DC = S.getSingleClause<OMPDestroyClause>()) { | 
|  | 3943 | CGM.getOpenMPRuntime().emitDestroyClause(*this, DOLVal, DC->getBeginLoc()); | 
|  | 3944 | return; | 
| Alexey Bataev | e46f0fe | 2020-03-04 14:37:51 -0500 | [diff] [blame] | 3945 | } | 
| Alexey Bataev | 8d7b118 | 2020-03-05 13:45:28 -0500 | [diff] [blame] | 3946 | if (const auto *UC = S.getSingleClause<OMPUpdateClause>()) { | 
|  | 3947 | CGM.getOpenMPRuntime().emitUpdateClause( | 
|  | 3948 | *this, DOLVal, UC->getDependencyKind(), UC->getBeginLoc()); | 
|  | 3949 | return; | 
|  | 3950 | } | 
| Alexey Bataev | e46f0fe | 2020-03-04 14:37:51 -0500 | [diff] [blame] | 3951 | } | 
| Alexey Bataev | c112e94 | 2020-02-28 09:52:15 -0500 | [diff] [blame] | 3952 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 3953 | void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S, | 
|  | 3954 | const CodeGenLoopTy &CodeGenLoop, | 
|  | 3955 | Expr *IncExpr) { | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 3956 | // Emit the loop iteration variable. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3957 | const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable()); | 
|  | 3958 | const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl()); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 3959 | EmitVarDecl(*IVDecl); | 
|  | 3960 |  | 
|  | 3961 | // Emit the iterations count variable. | 
|  | 3962 | // If it is not a variable, Sema decided to calculate iterations count on each | 
|  | 3963 | // iteration (e.g., it is foldable into a constant). | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3964 | if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 3965 | EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); | 
|  | 3966 | // Emit calculation of the iterations count. | 
|  | 3967 | EmitIgnoredExpr(S.getCalcLastIteration()); | 
|  | 3968 | } | 
|  | 3969 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3970 | CGOpenMPRuntime &RT = CGM.getOpenMPRuntime(); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 3971 |  | 
| Carlo Bertolli | 962bb80 | 2017-01-03 18:24:42 +0000 | [diff] [blame] | 3972 | bool HasLastprivateClause = false; | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 3973 | // Check pre-condition. | 
|  | 3974 | { | 
| Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3975 | OMPLoopScope PreInitScope(*this, S); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 3976 | // Skip the entire loop if we don't meet the precondition. | 
|  | 3977 | // If the condition constant folds and can be elided, avoid emitting the | 
|  | 3978 | // whole loop. | 
|  | 3979 | bool CondConstant; | 
|  | 3980 | llvm::BasicBlock *ContBlock = nullptr; | 
|  | 3981 | if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { | 
|  | 3982 | if (!CondConstant) | 
|  | 3983 | return; | 
|  | 3984 | } else { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 3985 | llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then"); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 3986 | ContBlock = createBasicBlock("omp.precond.end"); | 
|  | 3987 | emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock, | 
|  | 3988 | getProfileCount(&S)); | 
|  | 3989 | EmitBlock(ThenBlock); | 
|  | 3990 | incrementProfileCounter(&S); | 
|  | 3991 | } | 
|  | 3992 |  | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 3993 | emitAlignedClause(*this, S); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 3994 | // Emit 'then' code. | 
|  | 3995 | { | 
|  | 3996 | // Emit helper vars inits. | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 3997 |  | 
|  | 3998 | LValue LB = EmitOMPHelperVar( | 
|  | 3999 | *this, cast<DeclRefExpr>( | 
|  | 4000 | (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 4001 | ? S.getCombinedLowerBoundVariable() | 
|  | 4002 | : S.getLowerBoundVariable()))); | 
|  | 4003 | LValue UB = EmitOMPHelperVar( | 
|  | 4004 | *this, cast<DeclRefExpr>( | 
|  | 4005 | (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 4006 | ? S.getCombinedUpperBoundVariable() | 
|  | 4007 | : S.getUpperBoundVariable()))); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4008 | LValue ST = | 
|  | 4009 | EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); | 
|  | 4010 | LValue IL = | 
|  | 4011 | EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); | 
|  | 4012 |  | 
|  | 4013 | OMPPrivateScope LoopScope(*this); | 
| Carlo Bertolli | 962bb80 | 2017-01-03 18:24:42 +0000 | [diff] [blame] | 4014 | if (EmitOMPFirstprivateClause(S, LoopScope)) { | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4015 | // Emit implicit barrier to synchronize threads and avoid data races | 
|  | 4016 | // on initialization of firstprivate variables and post-update of | 
| Carlo Bertolli | 962bb80 | 2017-01-03 18:24:42 +0000 | [diff] [blame] | 4017 | // lastprivate variables. | 
|  | 4018 | CGM.getOpenMPRuntime().emitBarrierCall( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4019 | *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false, | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4020 | /*ForceSimpleCall=*/true); | 
| Carlo Bertolli | 962bb80 | 2017-01-03 18:24:42 +0000 | [diff] [blame] | 4021 | } | 
|  | 4022 | EmitOMPPrivateClause(S, LoopScope); | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4023 | if (isOpenMPSimdDirective(S.getDirectiveKind()) && | 
| Alexey Bataev | 999277a | 2017-12-06 14:31:09 +0000 | [diff] [blame] | 4024 | !isOpenMPParallelDirective(S.getDirectiveKind()) && | 
|  | 4025 | !isOpenMPTeamsDirective(S.getDirectiveKind())) | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4026 | EmitOMPReductionClauseInit(S, LoopScope); | 
| Carlo Bertolli | 962bb80 | 2017-01-03 18:24:42 +0000 | [diff] [blame] | 4027 | HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope); | 
| Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 4028 | EmitOMPPrivateLoopCounters(S, LoopScope); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4029 | (void)LoopScope.Privatize(); | 
| Alexey Bataev | 6070542 | 2018-10-30 15:50:12 +0000 | [diff] [blame] | 4030 | if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) | 
|  | 4031 | CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4032 |  | 
|  | 4033 | // Detect the distribute schedule kind and chunk. | 
|  | 4034 | llvm::Value *Chunk = nullptr; | 
|  | 4035 | OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4036 | if (const auto *C = S.getSingleClause<OMPDistScheduleClause>()) { | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4037 | ScheduleKind = C->getDistScheduleKind(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4038 | if (const Expr *Ch = C->getChunkSize()) { | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4039 | Chunk = EmitScalarExpr(Ch); | 
|  | 4040 | Chunk = EmitScalarConversion(Chunk, Ch->getType(), | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4041 | S.getIterationVariable()->getType(), | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4042 | S.getBeginLoc()); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4043 | } | 
| Gheorghe-Teodor Bercea | 02650d4 | 2018-09-27 19:22:56 +0000 | [diff] [blame] | 4044 | } else { | 
|  | 4045 | // Default behaviour for dist_schedule clause. | 
|  | 4046 | CGM.getOpenMPRuntime().getDefaultDistScheduleAndChunk( | 
|  | 4047 | *this, S, ScheduleKind, Chunk); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4048 | } | 
|  | 4049 | const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); | 
|  | 4050 | const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); | 
|  | 4051 |  | 
|  | 4052 | // OpenMP [2.10.8, distribute Construct, Description] | 
|  | 4053 | // If dist_schedule is specified, kind must be static. If specified, | 
|  | 4054 | // iterations are divided into chunks of size chunk_size, chunks are | 
|  | 4055 | // assigned to the teams of the league in a round-robin fashion in the | 
|  | 4056 | // order of the team number. When no chunk_size is specified, the | 
|  | 4057 | // iteration space is divided into chunks that are approximately equal | 
|  | 4058 | // in size, and at most one chunk is distributed to each team of the | 
|  | 4059 | // league. The size of the chunks is unspecified in this case. | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 4060 | bool StaticChunked = RT.isStaticChunked( | 
|  | 4061 | ScheduleKind, /* Chunked */ Chunk != nullptr) && | 
|  | 4062 | isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4063 | if (RT.isStaticNonchunked(ScheduleKind, | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 4064 | /* Chunked */ Chunk != nullptr) || | 
|  | 4065 | StaticChunked) { | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 4066 | CGOpenMPRuntime::StaticRTInput StaticInit( | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 4067 | IVSize, IVSigned, /* Ordered = */ false, IL.getAddress(*this), | 
|  | 4068 | LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this), | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 4069 | StaticChunked ? Chunk : nullptr); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4070 | RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind, | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 4071 | StaticInit); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4072 | JumpDest LoopExit = | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4073 | getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit")); | 
|  | 4074 | // UB = min(UB, GlobalUB); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 4075 | EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 4076 | ? S.getCombinedEnsureUpperBound() | 
|  | 4077 | : S.getEnsureUpperBound()); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4078 | // IV = LB; | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 4079 | EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 4080 | ? S.getCombinedInit() | 
|  | 4081 | : S.getInit()); | 
|  | 4082 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4083 | const Expr *Cond = | 
|  | 4084 | isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) | 
|  | 4085 | ? S.getCombinedCond() | 
|  | 4086 | : S.getCond(); | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 4087 |  | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 4088 | if (StaticChunked) | 
|  | 4089 | Cond = S.getCombinedDistCond(); | 
|  | 4090 |  | 
|  | 4091 | // For static unchunked schedules generate: | 
|  | 4092 | // | 
|  | 4093 | //  1. For distribute alone, codegen | 
|  | 4094 | //    while (idx <= UB) { | 
|  | 4095 | //      BODY; | 
|  | 4096 | //      ++idx; | 
|  | 4097 | //    } | 
|  | 4098 | // | 
|  | 4099 | //  2. When combined with 'for' (e.g. as in 'distribute parallel for') | 
|  | 4100 | //    while (idx <= UB) { | 
|  | 4101 | //      <CodeGen rest of pragma>(LB, UB); | 
|  | 4102 | //      idx += ST; | 
|  | 4103 | //    } | 
|  | 4104 | // | 
|  | 4105 | // For static chunk one schedule generate: | 
|  | 4106 | // | 
|  | 4107 | // while (IV <= GlobalUB) { | 
|  | 4108 | //   <CodeGen rest of pragma>(LB, UB); | 
|  | 4109 | //   LB += ST; | 
|  | 4110 | //   UB += ST; | 
|  | 4111 | //   UB = min(UB, GlobalUB); | 
|  | 4112 | //   IV = LB; | 
|  | 4113 | // } | 
|  | 4114 | // | 
| Alexey Bataev | 779a180 | 2019-12-06 12:21:31 -0500 | [diff] [blame] | 4115 | emitCommonSimdLoop( | 
|  | 4116 | *this, S, | 
|  | 4117 | [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 4118 | if (isOpenMPSimdDirective(S.getDirectiveKind())) | 
|  | 4119 | CGF.EmitOMPSimdInit(S, /*IsMonotonic=*/true); | 
|  | 4120 | }, | 
|  | 4121 | [&S, &LoopScope, Cond, IncExpr, LoopExit, &CodeGenLoop, | 
|  | 4122 | StaticChunked](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 4123 | CGF.EmitOMPInnerLoop( | 
|  | 4124 | S, LoopScope.requiresCleanups(), Cond, IncExpr, | 
|  | 4125 | [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) { | 
|  | 4126 | CodeGenLoop(CGF, S, LoopExit); | 
|  | 4127 | }, | 
|  | 4128 | [&S, StaticChunked](CodeGenFunction &CGF) { | 
|  | 4129 | if (StaticChunked) { | 
|  | 4130 | CGF.EmitIgnoredExpr(S.getCombinedNextLowerBound()); | 
|  | 4131 | CGF.EmitIgnoredExpr(S.getCombinedNextUpperBound()); | 
|  | 4132 | CGF.EmitIgnoredExpr(S.getCombinedEnsureUpperBound()); | 
|  | 4133 | CGF.EmitIgnoredExpr(S.getCombinedInit()); | 
|  | 4134 | } | 
|  | 4135 | }); | 
|  | 4136 | }); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4137 | EmitBlock(LoopExit.getBlock()); | 
|  | 4138 | // Tell the runtime we are done. | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 4139 | RT.emitForStaticFinish(*this, S.getEndLoc(), S.getDirectiveKind()); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4140 | } else { | 
|  | 4141 | // Emit the outer loop, which requests its work chunk [LB..UB] from | 
|  | 4142 | // runtime and runs the inner loop to process it. | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 4143 | const OMPLoopArguments LoopArguments = { | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 4144 | LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this), | 
|  | 4145 | IL.getAddress(*this), Chunk}; | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 4146 | EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments, | 
|  | 4147 | CodeGenLoop); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4148 | } | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4149 | if (isOpenMPSimdDirective(S.getDirectiveKind())) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4150 | EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) { | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4151 | return CGF.Builder.CreateIsNotNull( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4152 | CGF.EmitLoadOfScalar(IL, S.getBeginLoc())); | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4153 | }); | 
|  | 4154 | } | 
| Carlo Bertolli | beda214 | 2018-02-22 19:38:14 +0000 | [diff] [blame] | 4155 | if (isOpenMPSimdDirective(S.getDirectiveKind()) && | 
|  | 4156 | !isOpenMPParallelDirective(S.getDirectiveKind()) && | 
|  | 4157 | !isOpenMPTeamsDirective(S.getDirectiveKind())) { | 
| Jonas Hahnfeld | 5aaaece | 2018-10-02 19:12:47 +0000 | [diff] [blame] | 4158 | EmitOMPReductionClauseFinal(S, OMPD_simd); | 
| Carlo Bertolli | beda214 | 2018-02-22 19:38:14 +0000 | [diff] [blame] | 4159 | // Emit post-update of the reduction variables if IsLastIter != 0. | 
|  | 4160 | emitPostUpdateForReductionClause( | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4161 | *this, S, [IL, &S](CodeGenFunction &CGF) { | 
| Carlo Bertolli | beda214 | 2018-02-22 19:38:14 +0000 | [diff] [blame] | 4162 | return CGF.Builder.CreateIsNotNull( | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4163 | CGF.EmitLoadOfScalar(IL, S.getBeginLoc())); | 
| Carlo Bertolli | beda214 | 2018-02-22 19:38:14 +0000 | [diff] [blame] | 4164 | }); | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4165 | } | 
| Carlo Bertolli | 962bb80 | 2017-01-03 18:24:42 +0000 | [diff] [blame] | 4166 | // Emit final copy of the lastprivate variables if IsLastIter != 0. | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4167 | if (HasLastprivateClause) { | 
| Carlo Bertolli | 962bb80 | 2017-01-03 18:24:42 +0000 | [diff] [blame] | 4168 | EmitOMPLastprivateClauseFinal( | 
|  | 4169 | S, /*NoFinals=*/false, | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4170 | Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc()))); | 
| Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 4171 | } | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4172 | } | 
|  | 4173 |  | 
|  | 4174 | // We're now done with the loop, so jump to the continuation block. | 
|  | 4175 | if (ContBlock) { | 
|  | 4176 | EmitBranch(ContBlock); | 
|  | 4177 | EmitBlock(ContBlock, true); | 
|  | 4178 | } | 
|  | 4179 | } | 
|  | 4180 | } | 
|  | 4181 |  | 
| Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 4182 | void CodeGenFunction::EmitOMPDistributeDirective( | 
|  | 4183 | const OMPDistributeDirective &S) { | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 4184 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 4185 | CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 4186 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 4187 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Alexey Bataev | 10a5431 | 2017-11-27 16:54:08 +0000 | [diff] [blame] | 4188 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen); | 
| Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 4189 | } | 
|  | 4190 |  | 
| Alexey Bataev | 5f600d6 | 2015-09-29 03:48:57 +0000 | [diff] [blame] | 4191 | static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM, | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 4192 | const CapturedStmt *S, | 
|  | 4193 | SourceLocation Loc) { | 
| Alexey Bataev | 5f600d6 | 2015-09-29 03:48:57 +0000 | [diff] [blame] | 4194 | CodeGenFunction CGF(CGM, /*suppressNewContext=*/true); | 
|  | 4195 | CodeGenFunction::CGCapturedStmtInfo CapStmtInfo; | 
|  | 4196 | CGF.CapturedStmtInfo = &CapStmtInfo; | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 4197 | llvm::Function *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S, Loc); | 
| Alexey Bataev | c0f879b | 2018-04-10 20:10:53 +0000 | [diff] [blame] | 4198 | Fn->setDoesNotRecurse(); | 
| Alexey Bataev | 5f600d6 | 2015-09-29 03:48:57 +0000 | [diff] [blame] | 4199 | return Fn; | 
|  | 4200 | } | 
|  | 4201 |  | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 4202 | void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) { | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 4203 | if (S.hasClausesOfKind<OMPDependClause>()) { | 
|  | 4204 | assert(!S.getAssociatedStmt() && | 
|  | 4205 | "No associated statement must be in ordered depend construct."); | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4206 | for (const auto *DC : S.getClausesOfKind<OMPDependClause>()) | 
|  | 4207 | CGM.getOpenMPRuntime().emitDoacrossOrdered(*this, DC); | 
| Alexey Bataev | 8ef3141 | 2015-12-18 07:58:25 +0000 | [diff] [blame] | 4208 | return; | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4209 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4210 | const auto *C = S.getSingleClause<OMPSIMDClause>(); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 4211 | auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF, | 
|  | 4212 | PrePostActionTy &Action) { | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 4213 | const CapturedStmt *CS = S.getInnermostCapturedStmt(); | 
| Alexey Bataev | 5f600d6 | 2015-09-29 03:48:57 +0000 | [diff] [blame] | 4214 | if (C) { | 
| Alexey Bataev | 5f600d6 | 2015-09-29 03:48:57 +0000 | [diff] [blame] | 4215 | llvm::SmallVector<llvm::Value *, 16> CapturedVars; | 
|  | 4216 | CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); | 
| Alexey Bataev | c33ba8c | 2020-01-17 14:05:40 -0500 | [diff] [blame] | 4217 | llvm::Function *OutlinedFn = | 
|  | 4218 | emitOutlinedOrderedFunction(CGM, CS, S.getBeginLoc()); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4219 | CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(), | 
| Alexey Bataev | 3c595a6 | 2017-08-14 15:01:03 +0000 | [diff] [blame] | 4220 | OutlinedFn, CapturedVars); | 
| Alexey Bataev | 5f600d6 | 2015-09-29 03:48:57 +0000 | [diff] [blame] | 4221 | } else { | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 4222 | Action.Enter(CGF); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 4223 | CGF.EmitStmt(CS->getCapturedStmt()); | 
| Alexey Bataev | 5f600d6 | 2015-09-29 03:48:57 +0000 | [diff] [blame] | 4224 | } | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 4225 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 4226 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4227 | CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getBeginLoc(), !C); | 
| Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 4228 | } | 
|  | 4229 |  | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4230 | static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val, | 
| Filipe Cabecinhas | 7af183d | 2015-08-11 04:19:28 +0000 | [diff] [blame] | 4231 | QualType SrcType, QualType DestType, | 
|  | 4232 | SourceLocation Loc) { | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4233 | assert(CGF.hasScalarEvaluationKind(DestType) && | 
|  | 4234 | "DestType must have scalar evaluation kind."); | 
|  | 4235 | assert(!Val.isAggregate() && "Must be a scalar or complex."); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4236 | return Val.isScalar() ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, | 
|  | 4237 | DestType, Loc) | 
|  | 4238 | : CGF.EmitComplexToScalarConversion( | 
|  | 4239 | Val.getComplexVal(), SrcType, DestType, Loc); | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4240 | } | 
|  | 4241 |  | 
|  | 4242 | static CodeGenFunction::ComplexPairTy | 
|  | 4243 | convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, | 
| Filipe Cabecinhas | 7af183d | 2015-08-11 04:19:28 +0000 | [diff] [blame] | 4244 | QualType DestType, SourceLocation Loc) { | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4245 | assert(CGF.getEvaluationKind(DestType) == TEK_Complex && | 
|  | 4246 | "DestType must have complex evaluation kind."); | 
|  | 4247 | CodeGenFunction::ComplexPairTy ComplexVal; | 
|  | 4248 | if (Val.isScalar()) { | 
|  | 4249 | // Convert the input element to the element type of the complex. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4250 | QualType DestElementType = | 
|  | 4251 | DestType->castAs<ComplexType>()->getElementType(); | 
|  | 4252 | llvm::Value *ScalarVal = CGF.EmitScalarConversion( | 
|  | 4253 | Val.getScalarVal(), SrcType, DestElementType, Loc); | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4254 | ComplexVal = CodeGenFunction::ComplexPairTy( | 
|  | 4255 | ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType())); | 
|  | 4256 | } else { | 
|  | 4257 | assert(Val.isComplex() && "Must be a scalar or complex."); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4258 | QualType SrcElementType = SrcType->castAs<ComplexType>()->getElementType(); | 
|  | 4259 | QualType DestElementType = | 
|  | 4260 | DestType->castAs<ComplexType>()->getElementType(); | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4261 | ComplexVal.first = CGF.EmitScalarConversion( | 
| Filipe Cabecinhas | 7af183d | 2015-08-11 04:19:28 +0000 | [diff] [blame] | 4262 | Val.getComplexVal().first, SrcElementType, DestElementType, Loc); | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4263 | ComplexVal.second = CGF.EmitScalarConversion( | 
| Filipe Cabecinhas | 7af183d | 2015-08-11 04:19:28 +0000 | [diff] [blame] | 4264 | Val.getComplexVal().second, SrcElementType, DestElementType, Loc); | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4265 | } | 
|  | 4266 | return ComplexVal; | 
|  | 4267 | } | 
|  | 4268 |  | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4269 | static void emitSimpleAtomicStore(CodeGenFunction &CGF, llvm::AtomicOrdering AO, | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4270 | LValue LVal, RValue RVal) { | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4271 | if (LVal.isGlobalReg()) | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4272 | CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal); | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4273 | else | 
|  | 4274 | CGF.EmitAtomicStore(RVal, LVal, AO, LVal.isVolatile(), /*isInit=*/false); | 
|  | 4275 | } | 
|  | 4276 |  | 
|  | 4277 | static RValue emitSimpleAtomicLoad(CodeGenFunction &CGF, | 
|  | 4278 | llvm::AtomicOrdering AO, LValue LVal, | 
|  | 4279 | SourceLocation Loc) { | 
|  | 4280 | if (LVal.isGlobalReg()) | 
|  | 4281 | return CGF.EmitLoadOfLValue(LVal, Loc); | 
|  | 4282 | return CGF.EmitAtomicLoad( | 
|  | 4283 | LVal, Loc, llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO), | 
|  | 4284 | LVal.isVolatile()); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4285 | } | 
|  | 4286 |  | 
| Alexey Bataev | 8524d15 | 2016-01-21 12:35:58 +0000 | [diff] [blame] | 4287 | void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal, | 
|  | 4288 | QualType RValTy, SourceLocation Loc) { | 
|  | 4289 | switch (getEvaluationKind(LVal.getType())) { | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4290 | case TEK_Scalar: | 
| Alexey Bataev | 8524d15 | 2016-01-21 12:35:58 +0000 | [diff] [blame] | 4291 | EmitStoreThroughLValue(RValue::get(convertToScalarValue( | 
|  | 4292 | *this, RVal, RValTy, LVal.getType(), Loc)), | 
|  | 4293 | LVal); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4294 | break; | 
|  | 4295 | case TEK_Complex: | 
| Alexey Bataev | 8524d15 | 2016-01-21 12:35:58 +0000 | [diff] [blame] | 4296 | EmitStoreOfComplex( | 
|  | 4297 | convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal, | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4298 | /*isInit=*/false); | 
|  | 4299 | break; | 
|  | 4300 | case TEK_Aggregate: | 
|  | 4301 | llvm_unreachable("Must be a scalar or complex."); | 
|  | 4302 | } | 
|  | 4303 | } | 
|  | 4304 |  | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4305 | static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4306 | const Expr *X, const Expr *V, | 
|  | 4307 | SourceLocation Loc) { | 
|  | 4308 | // v = x; | 
|  | 4309 | assert(V->isLValue() && "V of 'omp atomic read' is not lvalue"); | 
|  | 4310 | assert(X->isLValue() && "X of 'omp atomic read' is not lvalue"); | 
|  | 4311 | LValue XLValue = CGF.EmitLValue(X); | 
|  | 4312 | LValue VLValue = CGF.EmitLValue(V); | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4313 | RValue Res = emitSimpleAtomicLoad(CGF, AO, XLValue, Loc); | 
|  | 4314 | // OpenMP, 2.17.7, atomic Construct | 
|  | 4315 | // If the read or capture clause is specified and the acquire, acq_rel, or | 
|  | 4316 | // seq_cst clause is specified then the strong flush on exit from the atomic | 
|  | 4317 | // operation is also an acquire flush. | 
|  | 4318 | switch (AO) { | 
|  | 4319 | case llvm::AtomicOrdering::Acquire: | 
|  | 4320 | case llvm::AtomicOrdering::AcquireRelease: | 
|  | 4321 | case llvm::AtomicOrdering::SequentiallyConsistent: | 
|  | 4322 | CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc, | 
|  | 4323 | llvm::AtomicOrdering::Acquire); | 
|  | 4324 | break; | 
|  | 4325 | case llvm::AtomicOrdering::Monotonic: | 
|  | 4326 | case llvm::AtomicOrdering::Release: | 
|  | 4327 | break; | 
|  | 4328 | case llvm::AtomicOrdering::NotAtomic: | 
|  | 4329 | case llvm::AtomicOrdering::Unordered: | 
|  | 4330 | llvm_unreachable("Unexpected ordering."); | 
|  | 4331 | } | 
| Alexey Bataev | 8524d15 | 2016-01-21 12:35:58 +0000 | [diff] [blame] | 4332 | CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc); | 
| Alexey Bataev | f117f2c | 2020-01-28 11:19:45 -0500 | [diff] [blame] | 4333 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V); | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4334 | } | 
|  | 4335 |  | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4336 | static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, | 
|  | 4337 | llvm::AtomicOrdering AO, const Expr *X, | 
|  | 4338 | const Expr *E, SourceLocation Loc) { | 
| Alexey Bataev | b832926 | 2015-02-27 06:33:30 +0000 | [diff] [blame] | 4339 | // x = expr; | 
|  | 4340 | assert(X->isLValue() && "X of 'omp atomic write' is not lvalue"); | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4341 | emitSimpleAtomicStore(CGF, AO, CGF.EmitLValue(X), CGF.EmitAnyExpr(E)); | 
| Alexey Bataev | f117f2c | 2020-01-28 11:19:45 -0500 | [diff] [blame] | 4342 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X); | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4343 | // OpenMP, 2.17.7, atomic Construct | 
|  | 4344 | // If the write, update, or capture clause is specified and the release, | 
|  | 4345 | // acq_rel, or seq_cst clause is specified then the strong flush on entry to | 
|  | 4346 | // the atomic operation is also a release flush. | 
|  | 4347 | switch (AO) { | 
|  | 4348 | case llvm::AtomicOrdering::Release: | 
|  | 4349 | case llvm::AtomicOrdering::AcquireRelease: | 
|  | 4350 | case llvm::AtomicOrdering::SequentiallyConsistent: | 
|  | 4351 | CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc, | 
|  | 4352 | llvm::AtomicOrdering::Release); | 
|  | 4353 | break; | 
|  | 4354 | case llvm::AtomicOrdering::Acquire: | 
|  | 4355 | case llvm::AtomicOrdering::Monotonic: | 
|  | 4356 | break; | 
|  | 4357 | case llvm::AtomicOrdering::NotAtomic: | 
|  | 4358 | case llvm::AtomicOrdering::Unordered: | 
|  | 4359 | llvm_unreachable("Unexpected ordering."); | 
|  | 4360 | } | 
| Alexey Bataev | b832926 | 2015-02-27 06:33:30 +0000 | [diff] [blame] | 4361 | } | 
|  | 4362 |  | 
| Benjamin Kramer | 439ee9d | 2015-05-01 13:59:53 +0000 | [diff] [blame] | 4363 | static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X, | 
|  | 4364 | RValue Update, | 
|  | 4365 | BinaryOperatorKind BO, | 
|  | 4366 | llvm::AtomicOrdering AO, | 
|  | 4367 | bool IsXLHSInRHSPart) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4368 | ASTContext &Context = CGF.getContext(); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4369 | // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x' | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4370 | // expression is simple and atomic is allowed for the given type for the | 
|  | 4371 | // target platform. | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4372 | if (BO == BO_Comma || !Update.isScalar() || | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 4373 | !Update.getScalarVal()->getType()->isIntegerTy() || !X.isSimple() || | 
|  | 4374 | (!isa<llvm::ConstantInt>(Update.getScalarVal()) && | 
|  | 4375 | (Update.getScalarVal()->getType() != | 
|  | 4376 | X.getAddress(CGF).getElementType())) || | 
|  | 4377 | !X.getAddress(CGF).getElementType()->isIntegerTy() || | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4378 | !Context.getTargetInfo().hasBuiltinAtomic( | 
|  | 4379 | Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment()))) | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4380 | return std::make_pair(false, RValue::get(nullptr)); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4381 |  | 
|  | 4382 | llvm::AtomicRMWInst::BinOp RMWOp; | 
|  | 4383 | switch (BO) { | 
|  | 4384 | case BO_Add: | 
|  | 4385 | RMWOp = llvm::AtomicRMWInst::Add; | 
|  | 4386 | break; | 
|  | 4387 | case BO_Sub: | 
|  | 4388 | if (!IsXLHSInRHSPart) | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4389 | return std::make_pair(false, RValue::get(nullptr)); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4390 | RMWOp = llvm::AtomicRMWInst::Sub; | 
|  | 4391 | break; | 
|  | 4392 | case BO_And: | 
|  | 4393 | RMWOp = llvm::AtomicRMWInst::And; | 
|  | 4394 | break; | 
|  | 4395 | case BO_Or: | 
|  | 4396 | RMWOp = llvm::AtomicRMWInst::Or; | 
|  | 4397 | break; | 
|  | 4398 | case BO_Xor: | 
|  | 4399 | RMWOp = llvm::AtomicRMWInst::Xor; | 
|  | 4400 | break; | 
|  | 4401 | case BO_LT: | 
|  | 4402 | RMWOp = X.getType()->hasSignedIntegerRepresentation() | 
|  | 4403 | ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min | 
|  | 4404 | : llvm::AtomicRMWInst::Max) | 
|  | 4405 | : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin | 
|  | 4406 | : llvm::AtomicRMWInst::UMax); | 
|  | 4407 | break; | 
|  | 4408 | case BO_GT: | 
|  | 4409 | RMWOp = X.getType()->hasSignedIntegerRepresentation() | 
|  | 4410 | ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max | 
|  | 4411 | : llvm::AtomicRMWInst::Min) | 
|  | 4412 | : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax | 
|  | 4413 | : llvm::AtomicRMWInst::UMin); | 
|  | 4414 | break; | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4415 | case BO_Assign: | 
|  | 4416 | RMWOp = llvm::AtomicRMWInst::Xchg; | 
|  | 4417 | break; | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4418 | case BO_Mul: | 
|  | 4419 | case BO_Div: | 
|  | 4420 | case BO_Rem: | 
|  | 4421 | case BO_Shl: | 
|  | 4422 | case BO_Shr: | 
|  | 4423 | case BO_LAnd: | 
|  | 4424 | case BO_LOr: | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4425 | return std::make_pair(false, RValue::get(nullptr)); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4426 | case BO_PtrMemD: | 
|  | 4427 | case BO_PtrMemI: | 
|  | 4428 | case BO_LE: | 
|  | 4429 | case BO_GE: | 
|  | 4430 | case BO_EQ: | 
|  | 4431 | case BO_NE: | 
| Richard Smith | c70f1d6 | 2017-12-14 15:16:18 +0000 | [diff] [blame] | 4432 | case BO_Cmp: | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4433 | case BO_AddAssign: | 
|  | 4434 | case BO_SubAssign: | 
|  | 4435 | case BO_AndAssign: | 
|  | 4436 | case BO_OrAssign: | 
|  | 4437 | case BO_XorAssign: | 
|  | 4438 | case BO_MulAssign: | 
|  | 4439 | case BO_DivAssign: | 
|  | 4440 | case BO_RemAssign: | 
|  | 4441 | case BO_ShlAssign: | 
|  | 4442 | case BO_ShrAssign: | 
|  | 4443 | case BO_Comma: | 
|  | 4444 | llvm_unreachable("Unsupported atomic update operation"); | 
|  | 4445 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4446 | llvm::Value *UpdateVal = Update.getScalarVal(); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4447 | if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) { | 
|  | 4448 | UpdateVal = CGF.Builder.CreateIntCast( | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 4449 | IC, X.getAddress(CGF).getElementType(), | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4450 | X.getType()->hasSignedIntegerRepresentation()); | 
|  | 4451 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4452 | llvm::Value *Res = | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 4453 | CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(CGF), UpdateVal, AO); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4454 | return std::make_pair(true, RValue::get(Res)); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4455 | } | 
|  | 4456 |  | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4457 | std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr( | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4458 | LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, | 
|  | 4459 | llvm::AtomicOrdering AO, SourceLocation Loc, | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4460 | const llvm::function_ref<RValue(RValue)> CommonGen) { | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4461 | // Update expressions are allowed to have the following forms: | 
|  | 4462 | // x binop= expr; -> xrval + expr; | 
|  | 4463 | // x++, ++x -> xrval + 1; | 
|  | 4464 | // x--, --x -> xrval - 1; | 
|  | 4465 | // x = x binop expr; -> xrval binop expr | 
|  | 4466 | // x = expr Op x; - > expr binop xrval; | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4467 | auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart); | 
|  | 4468 | if (!Res.first) { | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4469 | if (X.isGlobalReg()) { | 
|  | 4470 | // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop | 
|  | 4471 | // 'xrval'. | 
|  | 4472 | EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X); | 
|  | 4473 | } else { | 
|  | 4474 | // Perform compare-and-swap procedure. | 
|  | 4475 | EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified()); | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4476 | } | 
|  | 4477 | } | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4478 | return Res; | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4479 | } | 
|  | 4480 |  | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4481 | static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF, | 
|  | 4482 | llvm::AtomicOrdering AO, const Expr *X, | 
|  | 4483 | const Expr *E, const Expr *UE, | 
|  | 4484 | bool IsXLHSInRHSPart, SourceLocation Loc) { | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4485 | assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) && | 
|  | 4486 | "Update expr in 'atomic update' must be a binary operator."); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4487 | const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts()); | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4488 | // Update expressions are allowed to have the following forms: | 
|  | 4489 | // x binop= expr; -> xrval + expr; | 
|  | 4490 | // x++, ++x -> xrval + 1; | 
|  | 4491 | // x--, --x -> xrval - 1; | 
|  | 4492 | // x = x binop expr; -> xrval binop expr | 
|  | 4493 | // x = expr Op x; - > expr binop xrval; | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 4494 | assert(X->isLValue() && "X of 'omp atomic update' is not lvalue"); | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4495 | LValue XLValue = CGF.EmitLValue(X); | 
|  | 4496 | RValue ExprRValue = CGF.EmitAnyExpr(E); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4497 | const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts()); | 
|  | 4498 | const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts()); | 
|  | 4499 | const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS; | 
|  | 4500 | const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS; | 
|  | 4501 | auto &&Gen = [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) { | 
|  | 4502 | CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); | 
|  | 4503 | CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue); | 
|  | 4504 | return CGF.EmitAnyExpr(UE); | 
|  | 4505 | }; | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4506 | (void)CGF.EmitOMPAtomicSimpleUpdateExpr( | 
|  | 4507 | XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen); | 
| Alexey Bataev | f117f2c | 2020-01-28 11:19:45 -0500 | [diff] [blame] | 4508 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X); | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4509 | // OpenMP, 2.17.7, atomic Construct | 
|  | 4510 | // If the write, update, or capture clause is specified and the release, | 
|  | 4511 | // acq_rel, or seq_cst clause is specified then the strong flush on entry to | 
|  | 4512 | // the atomic operation is also a release flush. | 
|  | 4513 | switch (AO) { | 
|  | 4514 | case llvm::AtomicOrdering::Release: | 
|  | 4515 | case llvm::AtomicOrdering::AcquireRelease: | 
|  | 4516 | case llvm::AtomicOrdering::SequentiallyConsistent: | 
|  | 4517 | CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc, | 
|  | 4518 | llvm::AtomicOrdering::Release); | 
|  | 4519 | break; | 
|  | 4520 | case llvm::AtomicOrdering::Acquire: | 
|  | 4521 | case llvm::AtomicOrdering::Monotonic: | 
|  | 4522 | break; | 
|  | 4523 | case llvm::AtomicOrdering::NotAtomic: | 
|  | 4524 | case llvm::AtomicOrdering::Unordered: | 
|  | 4525 | llvm_unreachable("Unexpected ordering."); | 
|  | 4526 | } | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4527 | } | 
|  | 4528 |  | 
|  | 4529 | static RValue convertToType(CodeGenFunction &CGF, RValue Value, | 
| Filipe Cabecinhas | 7af183d | 2015-08-11 04:19:28 +0000 | [diff] [blame] | 4530 | QualType SourceType, QualType ResType, | 
|  | 4531 | SourceLocation Loc) { | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4532 | switch (CGF.getEvaluationKind(ResType)) { | 
|  | 4533 | case TEK_Scalar: | 
| Filipe Cabecinhas | 7af183d | 2015-08-11 04:19:28 +0000 | [diff] [blame] | 4534 | return RValue::get( | 
|  | 4535 | convertToScalarValue(CGF, Value, SourceType, ResType, Loc)); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4536 | case TEK_Complex: { | 
| Filipe Cabecinhas | 7af183d | 2015-08-11 04:19:28 +0000 | [diff] [blame] | 4537 | auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4538 | return RValue::getComplex(Res.first, Res.second); | 
|  | 4539 | } | 
|  | 4540 | case TEK_Aggregate: | 
|  | 4541 | break; | 
|  | 4542 | } | 
|  | 4543 | llvm_unreachable("Must be a scalar or complex."); | 
|  | 4544 | } | 
|  | 4545 |  | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4546 | static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, | 
|  | 4547 | llvm::AtomicOrdering AO, | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4548 | bool IsPostfixUpdate, const Expr *V, | 
|  | 4549 | const Expr *X, const Expr *E, | 
|  | 4550 | const Expr *UE, bool IsXLHSInRHSPart, | 
|  | 4551 | SourceLocation Loc) { | 
|  | 4552 | assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue"); | 
|  | 4553 | assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue"); | 
|  | 4554 | RValue NewVVal; | 
|  | 4555 | LValue VLValue = CGF.EmitLValue(V); | 
|  | 4556 | LValue XLValue = CGF.EmitLValue(X); | 
|  | 4557 | RValue ExprRValue = CGF.EmitAnyExpr(E); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4558 | QualType NewVValType; | 
|  | 4559 | if (UE) { | 
|  | 4560 | // 'x' is updated with some additional value. | 
|  | 4561 | assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) && | 
|  | 4562 | "Update expr in 'atomic capture' must be a binary operator."); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4563 | const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts()); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4564 | // Update expressions are allowed to have the following forms: | 
|  | 4565 | // x binop= expr; -> xrval + expr; | 
|  | 4566 | // x++, ++x -> xrval + 1; | 
|  | 4567 | // x--, --x -> xrval - 1; | 
|  | 4568 | // x = x binop expr; -> xrval binop expr | 
|  | 4569 | // x = expr Op x; - > expr binop xrval; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4570 | const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts()); | 
|  | 4571 | const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts()); | 
|  | 4572 | const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS; | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4573 | NewVValType = XRValExpr->getType(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4574 | const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS; | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4575 | auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr, | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4576 | IsPostfixUpdate](RValue XRValue) { | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4577 | CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); | 
|  | 4578 | CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue); | 
|  | 4579 | RValue Res = CGF.EmitAnyExpr(UE); | 
|  | 4580 | NewVVal = IsPostfixUpdate ? XRValue : Res; | 
|  | 4581 | return Res; | 
|  | 4582 | }; | 
|  | 4583 | auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr( | 
|  | 4584 | XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen); | 
| Alexey Bataev | f117f2c | 2020-01-28 11:19:45 -0500 | [diff] [blame] | 4585 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4586 | if (Res.first) { | 
|  | 4587 | // 'atomicrmw' instruction was generated. | 
|  | 4588 | if (IsPostfixUpdate) { | 
|  | 4589 | // Use old value from 'atomicrmw'. | 
|  | 4590 | NewVVal = Res.second; | 
|  | 4591 | } else { | 
|  | 4592 | // 'atomicrmw' does not provide new value, so evaluate it using old | 
|  | 4593 | // value of 'x'. | 
|  | 4594 | CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); | 
|  | 4595 | CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second); | 
|  | 4596 | NewVVal = CGF.EmitAnyExpr(UE); | 
|  | 4597 | } | 
|  | 4598 | } | 
|  | 4599 | } else { | 
|  | 4600 | // 'x' is simply rewritten with some 'expr'. | 
|  | 4601 | NewVValType = X->getType().getNonReferenceType(); | 
|  | 4602 | ExprRValue = convertToType(CGF, ExprRValue, E->getType(), | 
| Filipe Cabecinhas | 7af183d | 2015-08-11 04:19:28 +0000 | [diff] [blame] | 4603 | X->getType().getNonReferenceType(), Loc); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4604 | auto &&Gen = [&NewVVal, ExprRValue](RValue XRValue) { | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4605 | NewVVal = XRValue; | 
|  | 4606 | return ExprRValue; | 
|  | 4607 | }; | 
|  | 4608 | // Try to perform atomicrmw xchg, otherwise simple exchange. | 
|  | 4609 | auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr( | 
|  | 4610 | XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO, | 
|  | 4611 | Loc, Gen); | 
| Alexey Bataev | f117f2c | 2020-01-28 11:19:45 -0500 | [diff] [blame] | 4612 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4613 | if (Res.first) { | 
|  | 4614 | // 'atomicrmw' instruction was generated. | 
|  | 4615 | NewVVal = IsPostfixUpdate ? Res.second : ExprRValue; | 
|  | 4616 | } | 
|  | 4617 | } | 
|  | 4618 | // Emit post-update store to 'v' of old/new 'x' value. | 
| Alexey Bataev | 8524d15 | 2016-01-21 12:35:58 +0000 | [diff] [blame] | 4619 | CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc); | 
| Alexey Bataev | f117f2c | 2020-01-28 11:19:45 -0500 | [diff] [blame] | 4620 | CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V); | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4621 | // OpenMP, 2.17.7, atomic Construct | 
|  | 4622 | // If the write, update, or capture clause is specified and the release, | 
|  | 4623 | // acq_rel, or seq_cst clause is specified then the strong flush on entry to | 
|  | 4624 | // the atomic operation is also a release flush. | 
|  | 4625 | // If the read or capture clause is specified and the acquire, acq_rel, or | 
|  | 4626 | // seq_cst clause is specified then the strong flush on exit from the atomic | 
|  | 4627 | // operation is also an acquire flush. | 
|  | 4628 | switch (AO) { | 
|  | 4629 | case llvm::AtomicOrdering::Release: | 
|  | 4630 | CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc, | 
|  | 4631 | llvm::AtomicOrdering::Release); | 
|  | 4632 | break; | 
|  | 4633 | case llvm::AtomicOrdering::Acquire: | 
|  | 4634 | CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc, | 
|  | 4635 | llvm::AtomicOrdering::Acquire); | 
|  | 4636 | break; | 
|  | 4637 | case llvm::AtomicOrdering::AcquireRelease: | 
|  | 4638 | case llvm::AtomicOrdering::SequentiallyConsistent: | 
|  | 4639 | CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc, | 
|  | 4640 | llvm::AtomicOrdering::AcquireRelease); | 
|  | 4641 | break; | 
|  | 4642 | case llvm::AtomicOrdering::Monotonic: | 
|  | 4643 | break; | 
|  | 4644 | case llvm::AtomicOrdering::NotAtomic: | 
|  | 4645 | case llvm::AtomicOrdering::Unordered: | 
|  | 4646 | llvm_unreachable("Unexpected ordering."); | 
|  | 4647 | } | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4648 | } | 
|  | 4649 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4650 | static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4651 | llvm::AtomicOrdering AO, bool IsPostfixUpdate, | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4652 | const Expr *X, const Expr *V, const Expr *E, | 
|  | 4653 | const Expr *UE, bool IsXLHSInRHSPart, | 
|  | 4654 | SourceLocation Loc) { | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4655 | switch (Kind) { | 
|  | 4656 | case OMPC_read: | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4657 | emitOMPAtomicReadExpr(CGF, AO, X, V, Loc); | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4658 | break; | 
|  | 4659 | case OMPC_write: | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4660 | emitOMPAtomicWriteExpr(CGF, AO, X, E, Loc); | 
| Alexey Bataev | b832926 | 2015-02-27 06:33:30 +0000 | [diff] [blame] | 4661 | break; | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4662 | case OMPC_unknown: | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4663 | case OMPC_update: | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4664 | emitOMPAtomicUpdateExpr(CGF, AO, X, E, UE, IsXLHSInRHSPart, Loc); | 
| Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 4665 | break; | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4666 | case OMPC_capture: | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4667 | emitOMPAtomicCaptureExpr(CGF, AO, IsPostfixUpdate, V, X, E, UE, | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4668 | IsXLHSInRHSPart, Loc); | 
|  | 4669 | break; | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4670 | case OMPC_if: | 
|  | 4671 | case OMPC_final: | 
|  | 4672 | case OMPC_num_threads: | 
|  | 4673 | case OMPC_private: | 
|  | 4674 | case OMPC_firstprivate: | 
|  | 4675 | case OMPC_lastprivate: | 
|  | 4676 | case OMPC_reduction: | 
| Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 4677 | case OMPC_task_reduction: | 
| Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 4678 | case OMPC_in_reduction: | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4679 | case OMPC_safelen: | 
| Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 4680 | case OMPC_simdlen: | 
| Alexey Bataev | 9cc10fc | 2019-03-12 18:52:33 +0000 | [diff] [blame] | 4681 | case OMPC_allocator: | 
| Alexey Bataev | e04483e | 2019-03-27 14:14:31 +0000 | [diff] [blame] | 4682 | case OMPC_allocate: | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4683 | case OMPC_collapse: | 
|  | 4684 | case OMPC_default: | 
|  | 4685 | case OMPC_seq_cst: | 
| Alexey Bataev | ea9166b | 2020-02-06 16:30:23 -0500 | [diff] [blame] | 4686 | case OMPC_acq_rel: | 
| Alexey Bataev | 04a830f | 2020-02-10 14:30:39 -0500 | [diff] [blame] | 4687 | case OMPC_acquire: | 
| Alexey Bataev | 9559834 | 2020-02-10 15:49:05 -0500 | [diff] [blame] | 4688 | case OMPC_release: | 
| Alexey Bataev | 9a8defc | 2020-02-11 11:10:43 -0500 | [diff] [blame] | 4689 | case OMPC_relaxed: | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4690 | case OMPC_shared: | 
|  | 4691 | case OMPC_linear: | 
|  | 4692 | case OMPC_aligned: | 
|  | 4693 | case OMPC_copyin: | 
|  | 4694 | case OMPC_copyprivate: | 
|  | 4695 | case OMPC_flush: | 
| Alexey Bataev | c112e94 | 2020-02-28 09:52:15 -0500 | [diff] [blame] | 4696 | case OMPC_depobj: | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4697 | case OMPC_proc_bind: | 
|  | 4698 | case OMPC_schedule: | 
|  | 4699 | case OMPC_ordered: | 
|  | 4700 | case OMPC_nowait: | 
|  | 4701 | case OMPC_untied: | 
|  | 4702 | case OMPC_threadprivate: | 
| Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 4703 | case OMPC_depend: | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4704 | case OMPC_mergeable: | 
| Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 4705 | case OMPC_device: | 
| Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 4706 | case OMPC_threads: | 
| Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 4707 | case OMPC_simd: | 
| Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 4708 | case OMPC_map: | 
| Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 4709 | case OMPC_num_teams: | 
| Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 4710 | case OMPC_thread_limit: | 
| Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 4711 | case OMPC_priority: | 
| Alexey Bataev | 1fd4aed | 2015-12-07 12:52:51 +0000 | [diff] [blame] | 4712 | case OMPC_grainsize: | 
| Alexey Bataev | b825de1 | 2015-12-07 10:51:44 +0000 | [diff] [blame] | 4713 | case OMPC_nogroup: | 
| Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 4714 | case OMPC_num_tasks: | 
| Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 4715 | case OMPC_hint: | 
| Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 4716 | case OMPC_dist_schedule: | 
| Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 4717 | case OMPC_defaultmap: | 
| Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 4718 | case OMPC_uniform: | 
| Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 4719 | case OMPC_to: | 
| Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 4720 | case OMPC_from: | 
| Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 4721 | case OMPC_use_device_ptr: | 
| Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 4722 | case OMPC_is_device_ptr: | 
| Kelvin Li | 1408f91 | 2018-09-26 04:28:39 +0000 | [diff] [blame] | 4723 | case OMPC_unified_address: | 
| Alexey Bataev | 94c5064 | 2018-10-01 14:26:31 +0000 | [diff] [blame] | 4724 | case OMPC_unified_shared_memory: | 
| Patrick Lyster | 6bdf63b | 2018-10-03 20:07:58 +0000 | [diff] [blame] | 4725 | case OMPC_reverse_offload: | 
| Patrick Lyster | 3fe9e39 | 2018-10-11 14:41:10 +0000 | [diff] [blame] | 4726 | case OMPC_dynamic_allocators: | 
| Patrick Lyster | 7a2a27c | 2018-11-02 12:18:11 +0000 | [diff] [blame] | 4727 | case OMPC_atomic_default_mem_order: | 
| Alexey Bataev | 729e242 | 2019-08-23 16:11:14 +0000 | [diff] [blame] | 4728 | case OMPC_device_type: | 
| Alexey Bataev | dba792c | 2019-09-23 18:13:31 +0000 | [diff] [blame] | 4729 | case OMPC_match: | 
| Alexey Bataev | b6e7084 | 2019-12-16 15:54:17 -0500 | [diff] [blame] | 4730 | case OMPC_nontemporal: | 
| Alexey Bataev | cb8e691 | 2020-01-31 16:09:26 -0500 | [diff] [blame] | 4731 | case OMPC_order: | 
| Alexey Bataev | 375437a | 2020-03-02 14:21:20 -0500 | [diff] [blame] | 4732 | case OMPC_destroy: | 
| Alexey Bataev | 0f0564b | 2020-03-17 09:17:42 -0400 | [diff] [blame] | 4733 | case OMPC_detach: | 
| Alexey Bataev | 06dea73 | 2020-03-20 09:41:22 -0400 | [diff] [blame] | 4734 | case OMPC_inclusive: | 
| Alexey Bataev | 63828a3 | 2020-03-23 10:41:08 -0400 | [diff] [blame] | 4735 | case OMPC_exclusive: | 
| Alexey Bataev | b5be1c5 | 2020-04-21 13:21:00 -0400 | [diff] [blame] | 4736 | case OMPC_uses_allocators: | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4737 | llvm_unreachable("Clause is not allowed in 'omp atomic'."); | 
|  | 4738 | } | 
|  | 4739 | } | 
|  | 4740 |  | 
|  | 4741 | void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4742 | llvm::AtomicOrdering AO = llvm::AtomicOrdering::Monotonic; | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame] | 4743 | bool MemOrderingSpecified = false; | 
|  | 4744 | if (S.getSingleClause<OMPSeqCstClause>()) { | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4745 | AO = llvm::AtomicOrdering::SequentiallyConsistent; | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame] | 4746 | MemOrderingSpecified = true; | 
|  | 4747 | } else if (S.getSingleClause<OMPAcqRelClause>()) { | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4748 | AO = llvm::AtomicOrdering::AcquireRelease; | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame] | 4749 | MemOrderingSpecified = true; | 
|  | 4750 | } else if (S.getSingleClause<OMPAcquireClause>()) { | 
| Alexey Bataev | 04a830f | 2020-02-10 14:30:39 -0500 | [diff] [blame] | 4751 | AO = llvm::AtomicOrdering::Acquire; | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame] | 4752 | MemOrderingSpecified = true; | 
|  | 4753 | } else if (S.getSingleClause<OMPReleaseClause>()) { | 
| Alexey Bataev | 9559834 | 2020-02-10 15:49:05 -0500 | [diff] [blame] | 4754 | AO = llvm::AtomicOrdering::Release; | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame] | 4755 | MemOrderingSpecified = true; | 
|  | 4756 | } else if (S.getSingleClause<OMPRelaxedClause>()) { | 
| Alexey Bataev | 9a8defc | 2020-02-11 11:10:43 -0500 | [diff] [blame] | 4757 | AO = llvm::AtomicOrdering::Monotonic; | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame] | 4758 | MemOrderingSpecified = true; | 
|  | 4759 | } | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4760 | OpenMPClauseKind Kind = OMPC_unknown; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4761 | for (const OMPClause *C : S.clauses()) { | 
| Alexey Bataev | 9a8defc | 2020-02-11 11:10:43 -0500 | [diff] [blame] | 4762 | // Find first clause (skip seq_cst|acq_rel|aqcuire|release|relaxed clause, | 
|  | 4763 | // if it is first). | 
| Alexey Bataev | ea9166b | 2020-02-06 16:30:23 -0500 | [diff] [blame] | 4764 | if (C->getClauseKind() != OMPC_seq_cst && | 
| Alexey Bataev | 04a830f | 2020-02-10 14:30:39 -0500 | [diff] [blame] | 4765 | C->getClauseKind() != OMPC_acq_rel && | 
| Alexey Bataev | 9559834 | 2020-02-10 15:49:05 -0500 | [diff] [blame] | 4766 | C->getClauseKind() != OMPC_acquire && | 
| Alexey Bataev | 9a8defc | 2020-02-11 11:10:43 -0500 | [diff] [blame] | 4767 | C->getClauseKind() != OMPC_release && | 
|  | 4768 | C->getClauseKind() != OMPC_relaxed) { | 
| Alexey Bataev | b57056f | 2015-01-22 06:17:56 +0000 | [diff] [blame] | 4769 | Kind = C->getClauseKind(); | 
|  | 4770 | break; | 
|  | 4771 | } | 
|  | 4772 | } | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame] | 4773 | if (!MemOrderingSpecified) { | 
|  | 4774 | llvm::AtomicOrdering DefaultOrder = | 
|  | 4775 | CGM.getOpenMPRuntime().getDefaultMemoryOrdering(); | 
|  | 4776 | if (DefaultOrder == llvm::AtomicOrdering::Monotonic || | 
|  | 4777 | DefaultOrder == llvm::AtomicOrdering::SequentiallyConsistent || | 
|  | 4778 | (DefaultOrder == llvm::AtomicOrdering::AcquireRelease && | 
|  | 4779 | Kind == OMPC_capture)) { | 
|  | 4780 | AO = DefaultOrder; | 
|  | 4781 | } else if (DefaultOrder == llvm::AtomicOrdering::AcquireRelease) { | 
|  | 4782 | if (Kind == OMPC_unknown || Kind == OMPC_update || Kind == OMPC_write) { | 
|  | 4783 | AO = llvm::AtomicOrdering::Release; | 
|  | 4784 | } else if (Kind == OMPC_read) { | 
|  | 4785 | assert(Kind == OMPC_read && "Unexpected atomic kind."); | 
|  | 4786 | AO = llvm::AtomicOrdering::Acquire; | 
|  | 4787 | } | 
|  | 4788 | } | 
|  | 4789 | } | 
| Alexey Bataev | 10fec57 | 2015-03-11 04:48:56 +0000 | [diff] [blame] | 4790 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4791 | const Stmt *CS = S.getInnermostCapturedStmt()->IgnoreContainers(); | 
| Bill Wendling | 7c44da2 | 2018-10-31 03:48:47 +0000 | [diff] [blame] | 4792 | if (const auto *FE = dyn_cast<FullExpr>(CS)) | 
|  | 4793 | enterFullExpression(FE); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4794 | // Processing for statements under 'atomic capture'. | 
|  | 4795 | if (const auto *Compound = dyn_cast<CompoundStmt>(CS)) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4796 | for (const Stmt *C : Compound->body()) { | 
| Bill Wendling | 7c44da2 | 2018-10-31 03:48:47 +0000 | [diff] [blame] | 4797 | if (const auto *FE = dyn_cast<FullExpr>(C)) | 
|  | 4798 | enterFullExpression(FE); | 
| Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 4799 | } | 
|  | 4800 | } | 
| Alexey Bataev | 10fec57 | 2015-03-11 04:48:56 +0000 | [diff] [blame] | 4801 |  | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4802 | auto &&CodeGen = [&S, Kind, AO, CS](CodeGenFunction &CGF, | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 4803 | PrePostActionTy &) { | 
| Alexey Bataev | 33c5640 | 2015-12-14 09:26:19 +0000 | [diff] [blame] | 4804 | CGF.EmitStopPoint(CS); | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 4805 | emitOMPAtomicExpr(CGF, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(), | 
|  | 4806 | S.getExpr(), S.getUpdateExpr(), S.isXLHSInRHSPart(), | 
|  | 4807 | S.getBeginLoc()); | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 4808 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 4809 | OMPLexicalScope Scope(*this, S, OMPD_unknown); | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 4810 | CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen); | 
| Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 4811 | } | 
|  | 4812 |  | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4813 | static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, | 
|  | 4814 | const OMPExecutableDirective &S, | 
|  | 4815 | const RegionCodeGenTy &CodeGen) { | 
|  | 4816 | assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind())); | 
|  | 4817 | CodeGenModule &CGM = CGF.CGM; | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 4818 |  | 
| Alexey Bataev | 4f4bf7c | 2018-03-15 15:47:20 +0000 | [diff] [blame] | 4819 | // On device emit this construct as inlined code. | 
|  | 4820 | if (CGM.getLangOpts().OpenMPIsDevice) { | 
|  | 4821 | OMPLexicalScope Scope(CGF, S, OMPD_target); | 
|  | 4822 | CGM.getOpenMPRuntime().emitInlinedDirective( | 
|  | 4823 | CGF, OMPD_target, [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
| Alexey Bataev | 4ac68a2 | 2018-05-16 15:08:32 +0000 | [diff] [blame] | 4824 | CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); | 
| Alexey Bataev | 4f4bf7c | 2018-03-15 15:47:20 +0000 | [diff] [blame] | 4825 | }); | 
|  | 4826 | return; | 
|  | 4827 | } | 
|  | 4828 |  | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 4829 | auto LPCRegion = | 
|  | 4830 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(CGF, S); | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 4831 | llvm::Function *Fn = nullptr; | 
|  | 4832 | llvm::Constant *FnID = nullptr; | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 4833 |  | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 4834 | const Expr *IfCond = nullptr; | 
| Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 4835 | // Check for the at most one if clause associated with the target region. | 
|  | 4836 | for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { | 
|  | 4837 | if (C->getNameModifier() == OMPD_unknown || | 
|  | 4838 | C->getNameModifier() == OMPD_target) { | 
|  | 4839 | IfCond = C->getCondition(); | 
|  | 4840 | break; | 
|  | 4841 | } | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 4842 | } | 
|  | 4843 |  | 
|  | 4844 | // Check if we have any device clause associated with the directive. | 
| Alexey Bataev | f3c857f | 2020-03-18 17:52:41 -0400 | [diff] [blame] | 4845 | llvm::PointerIntPair<const Expr *, 2, OpenMPDeviceClauseModifier> Device( | 
|  | 4846 | nullptr, OMPC_DEVICE_unknown); | 
|  | 4847 | if (auto *C = S.getSingleClause<OMPDeviceClause>()) | 
|  | 4848 | Device.setPointerAndInt(C->getDevice(), C->getModifier()); | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 4849 |  | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 4850 | // Check if we have an if clause whose conditional always evaluates to false | 
|  | 4851 | // or if we do not have any targets specified. If so the target region is not | 
|  | 4852 | // an offload entry point. | 
|  | 4853 | bool IsOffloadEntry = true; | 
|  | 4854 | if (IfCond) { | 
|  | 4855 | bool Val; | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4856 | if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val) | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 4857 | IsOffloadEntry = false; | 
|  | 4858 | } | 
|  | 4859 | if (CGM.getLangOpts().OMPTargetTriples.empty()) | 
|  | 4860 | IsOffloadEntry = false; | 
|  | 4861 |  | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4862 | assert(CGF.CurFuncDecl && "No parent declaration for target region!"); | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 4863 | StringRef ParentName; | 
|  | 4864 | // In case we have Ctors/Dtors we use the complete type variant to produce | 
|  | 4865 | // the mangling of the device outlined kernel. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4866 | if (const auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl)) | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 4867 | ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete)); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4868 | else if (const auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl)) | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 4869 | ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete)); | 
|  | 4870 | else | 
|  | 4871 | ParentName = | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4872 | CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl))); | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 4873 |  | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4874 | // Emit target region as a standalone region. | 
|  | 4875 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID, | 
|  | 4876 | IsOffloadEntry, CodeGen); | 
| Alexey Bataev | 8451efa | 2018-01-15 19:06:12 +0000 | [diff] [blame] | 4877 | OMPLexicalScope Scope(CGF, S, OMPD_task); | 
| Alexey Bataev | ec7946e | 2019-09-23 14:06:51 +0000 | [diff] [blame] | 4878 | auto &&SizeEmitter = | 
|  | 4879 | [IsOffloadEntry](CodeGenFunction &CGF, | 
|  | 4880 | const OMPLoopDirective &D) -> llvm::Value * { | 
|  | 4881 | if (IsOffloadEntry) { | 
|  | 4882 | OMPLoopScope(CGF, D); | 
|  | 4883 | // Emit calculation of the iterations count. | 
|  | 4884 | llvm::Value *NumIterations = CGF.EmitScalarExpr(D.getNumIterations()); | 
|  | 4885 | NumIterations = CGF.Builder.CreateIntCast(NumIterations, CGF.Int64Ty, | 
|  | 4886 | /*isSigned=*/false); | 
|  | 4887 | return NumIterations; | 
|  | 4888 | } | 
|  | 4889 | return nullptr; | 
| Alexey Bataev | 7bb3353 | 2019-01-07 21:30:43 +0000 | [diff] [blame] | 4890 | }; | 
| Alexey Bataev | ec7946e | 2019-09-23 14:06:51 +0000 | [diff] [blame] | 4891 | CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device, | 
|  | 4892 | SizeEmitter); | 
| Alexey Bataev | 0bd520b | 2014-09-19 08:19:49 +0000 | [diff] [blame] | 4893 | } | 
|  | 4894 |  | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4895 | static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S, | 
|  | 4896 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 4897 | Action.Enter(CGF); | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4898 | CodeGenFunction::OMPPrivateScope PrivateScope(CGF); | 
|  | 4899 | (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); | 
|  | 4900 | CGF.EmitOMPPrivateClause(S, PrivateScope); | 
|  | 4901 | (void)PrivateScope.Privatize(); | 
| Alexey Bataev | 6070542 | 2018-10-30 15:50:12 +0000 | [diff] [blame] | 4902 | if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) | 
|  | 4903 | CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S); | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4904 |  | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 4905 | CGF.EmitStmt(S.getCapturedStmt(OMPD_target)->getCapturedStmt()); | 
| Arpith Chacko Jacob | 43a8b7b | 2017-01-16 15:26:02 +0000 | [diff] [blame] | 4906 | } | 
|  | 4907 |  | 
|  | 4908 | void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM, | 
|  | 4909 | StringRef ParentName, | 
|  | 4910 | const OMPTargetDirective &S) { | 
|  | 4911 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 4912 | emitTargetRegion(CGF, S, Action); | 
|  | 4913 | }; | 
|  | 4914 | llvm::Function *Fn; | 
|  | 4915 | llvm::Constant *Addr; | 
|  | 4916 | // Emit target region as a standalone region. | 
|  | 4917 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 4918 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 4919 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 4920 | } | 
|  | 4921 |  | 
|  | 4922 | void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) { | 
|  | 4923 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 4924 | emitTargetRegion(CGF, S, Action); | 
|  | 4925 | }; | 
|  | 4926 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
|  | 4927 | } | 
|  | 4928 |  | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 4929 | static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, | 
|  | 4930 | const OMPExecutableDirective &S, | 
|  | 4931 | OpenMPDirectiveKind InnermostKind, | 
|  | 4932 | const RegionCodeGenTy &CodeGen) { | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 4933 | const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams); | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 4934 | llvm::Function *OutlinedFn = | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4935 | CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction( | 
|  | 4936 | S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); | 
| Samuel Antao | b68e2db | 2016-03-03 16:20:23 +0000 | [diff] [blame] | 4937 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4938 | const auto *NT = S.getSingleClause<OMPNumTeamsClause>(); | 
|  | 4939 | const auto *TL = S.getSingleClause<OMPThreadLimitClause>(); | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 4940 | if (NT || TL) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4941 | const Expr *NumTeams = NT ? NT->getNumTeams() : nullptr; | 
|  | 4942 | const Expr *ThreadLimit = TL ? TL->getThreadLimit() : nullptr; | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 4943 |  | 
| Carlo Bertolli | c687225 | 2016-04-04 15:55:02 +0000 | [diff] [blame] | 4944 | CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit, | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4945 | S.getBeginLoc()); | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 4946 | } | 
|  | 4947 |  | 
| Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 4948 | OMPTeamsScope Scope(CGF, S); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 4949 | llvm::SmallVector<llvm::Value *, 16> CapturedVars; | 
|  | 4950 | CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 4951 | CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getBeginLoc(), OutlinedFn, | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 4952 | CapturedVars); | 
|  | 4953 | } | 
|  | 4954 |  | 
|  | 4955 | void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) { | 
| Kelvin Li | 51336dd | 2016-12-15 17:55:32 +0000 | [diff] [blame] | 4956 | // Emit teams region as a standalone region. | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 4957 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 4958 | Action.Enter(CGF); | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 4959 | OMPPrivateScope PrivateScope(CGF); | 
| Carlo Bertolli | 6ad7b5a | 2016-03-03 22:09:40 +0000 | [diff] [blame] | 4960 | (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); | 
|  | 4961 | CGF.EmitOMPPrivateClause(S, PrivateScope); | 
| Arpith Chacko Jacob | fc711b1 | 2017-02-16 16:48:49 +0000 | [diff] [blame] | 4962 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 4963 | (void)PrivateScope.Privatize(); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 4964 | CGF.EmitStmt(S.getCapturedStmt(OMPD_teams)->getCapturedStmt()); | 
| Arpith Chacko Jacob | fc711b1 | 2017-02-16 16:48:49 +0000 | [diff] [blame] | 4965 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 4966 | }; | 
| Alexey Bataev | 2139ed6 | 2017-11-16 18:20:21 +0000 | [diff] [blame] | 4967 | emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4968 | emitPostUpdateForReductionClause(*this, S, | 
|  | 4969 | [](CodeGenFunction &) { return nullptr; }); | 
| Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 4970 | } | 
| Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 4971 |  | 
| Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 4972 | static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action, | 
|  | 4973 | const OMPTargetTeamsDirective &S) { | 
|  | 4974 | auto *CS = S.getCapturedStmt(OMPD_teams); | 
|  | 4975 | Action.Enter(CGF); | 
| Alexey Bataev | f9fc42e | 2017-11-22 14:25:55 +0000 | [diff] [blame] | 4976 | // Emit teams region as a standalone region. | 
|  | 4977 | auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 4978 | Action.Enter(CGF); | 
| Alexey Bataev | f9fc42e | 2017-11-22 14:25:55 +0000 | [diff] [blame] | 4979 | CodeGenFunction::OMPPrivateScope PrivateScope(CGF); | 
|  | 4980 | (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); | 
|  | 4981 | CGF.EmitOMPPrivateClause(S, PrivateScope); | 
|  | 4982 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 4983 | (void)PrivateScope.Privatize(); | 
| Alexey Bataev | 6070542 | 2018-10-30 15:50:12 +0000 | [diff] [blame] | 4984 | if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) | 
|  | 4985 | CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S); | 
| Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 4986 | CGF.EmitStmt(CS->getCapturedStmt()); | 
| Alexey Bataev | f9fc42e | 2017-11-22 14:25:55 +0000 | [diff] [blame] | 4987 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
| Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 4988 | }; | 
|  | 4989 | emitCommonOMPTeamsDirective(CGF, S, OMPD_teams, CodeGen); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 4990 | emitPostUpdateForReductionClause(CGF, S, | 
|  | 4991 | [](CodeGenFunction &) { return nullptr; }); | 
| Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 4992 | } | 
|  | 4993 |  | 
|  | 4994 | void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction( | 
|  | 4995 | CodeGenModule &CGM, StringRef ParentName, | 
|  | 4996 | const OMPTargetTeamsDirective &S) { | 
|  | 4997 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 4998 | emitTargetTeamsRegion(CGF, Action, S); | 
|  | 4999 | }; | 
|  | 5000 | llvm::Function *Fn; | 
|  | 5001 | llvm::Constant *Addr; | 
|  | 5002 | // Emit target region as a standalone region. | 
|  | 5003 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 5004 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 5005 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 5006 | } | 
|  | 5007 |  | 
|  | 5008 | void CodeGenFunction::EmitOMPTargetTeamsDirective( | 
|  | 5009 | const OMPTargetTeamsDirective &S) { | 
|  | 5010 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5011 | emitTargetTeamsRegion(CGF, Action, S); | 
|  | 5012 | }; | 
|  | 5013 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
|  | 5014 | } | 
|  | 5015 |  | 
| Alexey Bataev | dfa430f | 2017-12-08 15:03:50 +0000 | [diff] [blame] | 5016 | static void | 
|  | 5017 | emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action, | 
|  | 5018 | const OMPTargetTeamsDistributeDirective &S) { | 
|  | 5019 | Action.Enter(CGF); | 
|  | 5020 | auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5021 | CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); | 
|  | 5022 | }; | 
|  | 5023 |  | 
|  | 5024 | // Emit teams region as a standalone region. | 
|  | 5025 | auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5026 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5027 | Action.Enter(CGF); | 
| Alexey Bataev | dfa430f | 2017-12-08 15:03:50 +0000 | [diff] [blame] | 5028 | CodeGenFunction::OMPPrivateScope PrivateScope(CGF); | 
|  | 5029 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5030 | (void)PrivateScope.Privatize(); | 
|  | 5031 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute, | 
|  | 5032 | CodeGenDistribute); | 
|  | 5033 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
|  | 5034 | }; | 
|  | 5035 | emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute, CodeGen); | 
|  | 5036 | emitPostUpdateForReductionClause(CGF, S, | 
|  | 5037 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 5038 | } | 
|  | 5039 |  | 
|  | 5040 | void CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction( | 
|  | 5041 | CodeGenModule &CGM, StringRef ParentName, | 
|  | 5042 | const OMPTargetTeamsDistributeDirective &S) { | 
|  | 5043 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5044 | emitTargetTeamsDistributeRegion(CGF, Action, S); | 
|  | 5045 | }; | 
|  | 5046 | llvm::Function *Fn; | 
|  | 5047 | llvm::Constant *Addr; | 
|  | 5048 | // Emit target region as a standalone region. | 
|  | 5049 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 5050 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 5051 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 5052 | } | 
|  | 5053 |  | 
|  | 5054 | void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective( | 
|  | 5055 | const OMPTargetTeamsDistributeDirective &S) { | 
|  | 5056 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5057 | emitTargetTeamsDistributeRegion(CGF, Action, S); | 
|  | 5058 | }; | 
|  | 5059 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
|  | 5060 | } | 
|  | 5061 |  | 
| Alexey Bataev | fbe17fb | 2017-12-13 19:45:06 +0000 | [diff] [blame] | 5062 | static void emitTargetTeamsDistributeSimdRegion( | 
|  | 5063 | CodeGenFunction &CGF, PrePostActionTy &Action, | 
|  | 5064 | const OMPTargetTeamsDistributeSimdDirective &S) { | 
|  | 5065 | Action.Enter(CGF); | 
|  | 5066 | auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5067 | CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); | 
|  | 5068 | }; | 
|  | 5069 |  | 
|  | 5070 | // Emit teams region as a standalone region. | 
|  | 5071 | auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5072 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5073 | Action.Enter(CGF); | 
| Alexey Bataev | fbe17fb | 2017-12-13 19:45:06 +0000 | [diff] [blame] | 5074 | CodeGenFunction::OMPPrivateScope PrivateScope(CGF); | 
|  | 5075 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5076 | (void)PrivateScope.Privatize(); | 
|  | 5077 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute, | 
|  | 5078 | CodeGenDistribute); | 
|  | 5079 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
|  | 5080 | }; | 
|  | 5081 | emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_simd, CodeGen); | 
|  | 5082 | emitPostUpdateForReductionClause(CGF, S, | 
|  | 5083 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 5084 | } | 
|  | 5085 |  | 
|  | 5086 | void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction( | 
|  | 5087 | CodeGenModule &CGM, StringRef ParentName, | 
|  | 5088 | const OMPTargetTeamsDistributeSimdDirective &S) { | 
|  | 5089 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5090 | emitTargetTeamsDistributeSimdRegion(CGF, Action, S); | 
|  | 5091 | }; | 
|  | 5092 | llvm::Function *Fn; | 
|  | 5093 | llvm::Constant *Addr; | 
|  | 5094 | // Emit target region as a standalone region. | 
|  | 5095 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 5096 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 5097 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 5098 | } | 
|  | 5099 |  | 
|  | 5100 | void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective( | 
|  | 5101 | const OMPTargetTeamsDistributeSimdDirective &S) { | 
|  | 5102 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5103 | emitTargetTeamsDistributeSimdRegion(CGF, Action, S); | 
|  | 5104 | }; | 
|  | 5105 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
|  | 5106 | } | 
|  | 5107 |  | 
| Carlo Bertolli | ba1487b | 2017-10-04 14:12:09 +0000 | [diff] [blame] | 5108 | void CodeGenFunction::EmitOMPTeamsDistributeDirective( | 
|  | 5109 | const OMPTeamsDistributeDirective &S) { | 
|  | 5110 |  | 
|  | 5111 | auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5112 | CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); | 
|  | 5113 | }; | 
|  | 5114 |  | 
|  | 5115 | // Emit teams region as a standalone region. | 
|  | 5116 | auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5117 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5118 | Action.Enter(CGF); | 
| Carlo Bertolli | ba1487b | 2017-10-04 14:12:09 +0000 | [diff] [blame] | 5119 | OMPPrivateScope PrivateScope(CGF); | 
|  | 5120 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5121 | (void)PrivateScope.Privatize(); | 
|  | 5122 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute, | 
|  | 5123 | CodeGenDistribute); | 
|  | 5124 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
|  | 5125 | }; | 
| Alexey Bataev | 95c6dd4 | 2017-11-29 15:14:16 +0000 | [diff] [blame] | 5126 | emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen); | 
| Carlo Bertolli | ba1487b | 2017-10-04 14:12:09 +0000 | [diff] [blame] | 5127 | emitPostUpdateForReductionClause(*this, S, | 
|  | 5128 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 5129 | } | 
|  | 5130 |  | 
| Alexey Bataev | 999277a | 2017-12-06 14:31:09 +0000 | [diff] [blame] | 5131 | void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective( | 
|  | 5132 | const OMPTeamsDistributeSimdDirective &S) { | 
|  | 5133 | auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5134 | CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); | 
|  | 5135 | }; | 
|  | 5136 |  | 
|  | 5137 | // Emit teams region as a standalone region. | 
|  | 5138 | auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5139 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5140 | Action.Enter(CGF); | 
| Alexey Bataev | 999277a | 2017-12-06 14:31:09 +0000 | [diff] [blame] | 5141 | OMPPrivateScope PrivateScope(CGF); | 
|  | 5142 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5143 | (void)PrivateScope.Privatize(); | 
|  | 5144 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd, | 
|  | 5145 | CodeGenDistribute); | 
|  | 5146 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
|  | 5147 | }; | 
|  | 5148 | emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_simd, CodeGen); | 
|  | 5149 | emitPostUpdateForReductionClause(*this, S, | 
|  | 5150 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 5151 | } | 
|  | 5152 |  | 
| Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 5153 | void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective( | 
|  | 5154 | const OMPTeamsDistributeParallelForDirective &S) { | 
|  | 5155 | auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5156 | CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined, | 
|  | 5157 | S.getDistInc()); | 
|  | 5158 | }; | 
|  | 5159 |  | 
|  | 5160 | // Emit teams region as a standalone region. | 
|  | 5161 | auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5162 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5163 | Action.Enter(CGF); | 
| Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 5164 | OMPPrivateScope PrivateScope(CGF); | 
|  | 5165 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5166 | (void)PrivateScope.Privatize(); | 
| Alexey Bataev | 10a5431 | 2017-11-27 16:54:08 +0000 | [diff] [blame] | 5167 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute, | 
|  | 5168 | CodeGenDistribute); | 
| Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 5169 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
|  | 5170 | }; | 
|  | 5171 | emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for, CodeGen); | 
|  | 5172 | emitPostUpdateForReductionClause(*this, S, | 
|  | 5173 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 5174 | } | 
|  | 5175 |  | 
| Carlo Bertolli | 56a2aa4 | 2017-12-04 20:57:19 +0000 | [diff] [blame] | 5176 | void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective( | 
|  | 5177 | const OMPTeamsDistributeParallelForSimdDirective &S) { | 
|  | 5178 | auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5179 | CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined, | 
|  | 5180 | S.getDistInc()); | 
|  | 5181 | }; | 
|  | 5182 |  | 
|  | 5183 | // Emit teams region as a standalone region. | 
|  | 5184 | auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5185 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5186 | Action.Enter(CGF); | 
| Carlo Bertolli | 56a2aa4 | 2017-12-04 20:57:19 +0000 | [diff] [blame] | 5187 | OMPPrivateScope PrivateScope(CGF); | 
|  | 5188 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5189 | (void)PrivateScope.Privatize(); | 
|  | 5190 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective( | 
|  | 5191 | CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false); | 
|  | 5192 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
|  | 5193 | }; | 
| Alexey Bataev | 0b97894 | 2019-12-11 15:26:38 -0500 | [diff] [blame] | 5194 | emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for_simd, | 
|  | 5195 | CodeGen); | 
| Carlo Bertolli | 56a2aa4 | 2017-12-04 20:57:19 +0000 | [diff] [blame] | 5196 | emitPostUpdateForReductionClause(*this, S, | 
|  | 5197 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 5198 | } | 
|  | 5199 |  | 
| Carlo Bertolli | 52978c3 | 2018-01-03 21:12:44 +0000 | [diff] [blame] | 5200 | static void emitTargetTeamsDistributeParallelForRegion( | 
|  | 5201 | CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S, | 
|  | 5202 | PrePostActionTy &Action) { | 
| Carlo Bertolli | 7971209 | 2018-02-28 20:48:35 +0000 | [diff] [blame] | 5203 | Action.Enter(CGF); | 
| Carlo Bertolli | 52978c3 | 2018-01-03 21:12:44 +0000 | [diff] [blame] | 5204 | auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5205 | CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined, | 
|  | 5206 | S.getDistInc()); | 
|  | 5207 | }; | 
|  | 5208 |  | 
|  | 5209 | // Emit teams region as a standalone region. | 
|  | 5210 | auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5211 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5212 | Action.Enter(CGF); | 
| Carlo Bertolli | 52978c3 | 2018-01-03 21:12:44 +0000 | [diff] [blame] | 5213 | CodeGenFunction::OMPPrivateScope PrivateScope(CGF); | 
|  | 5214 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5215 | (void)PrivateScope.Privatize(); | 
|  | 5216 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective( | 
|  | 5217 | CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false); | 
|  | 5218 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
|  | 5219 | }; | 
|  | 5220 |  | 
|  | 5221 | emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for, | 
|  | 5222 | CodeGenTeams); | 
|  | 5223 | emitPostUpdateForReductionClause(CGF, S, | 
|  | 5224 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 5225 | } | 
|  | 5226 |  | 
|  | 5227 | void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction( | 
|  | 5228 | CodeGenModule &CGM, StringRef ParentName, | 
|  | 5229 | const OMPTargetTeamsDistributeParallelForDirective &S) { | 
|  | 5230 | // Emit SPMD target teams distribute parallel for region as a standalone | 
|  | 5231 | // region. | 
|  | 5232 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5233 | emitTargetTeamsDistributeParallelForRegion(CGF, S, Action); | 
|  | 5234 | }; | 
|  | 5235 | llvm::Function *Fn; | 
|  | 5236 | llvm::Constant *Addr; | 
|  | 5237 | // Emit target region as a standalone region. | 
|  | 5238 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 5239 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 5240 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 5241 | } | 
|  | 5242 |  | 
|  | 5243 | void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective( | 
|  | 5244 | const OMPTargetTeamsDistributeParallelForDirective &S) { | 
|  | 5245 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5246 | emitTargetTeamsDistributeParallelForRegion(CGF, S, Action); | 
|  | 5247 | }; | 
|  | 5248 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
|  | 5249 | } | 
|  | 5250 |  | 
| Alexey Bataev | 647dd84 | 2018-01-15 20:59:40 +0000 | [diff] [blame] | 5251 | static void emitTargetTeamsDistributeParallelForSimdRegion( | 
|  | 5252 | CodeGenFunction &CGF, | 
|  | 5253 | const OMPTargetTeamsDistributeParallelForSimdDirective &S, | 
|  | 5254 | PrePostActionTy &Action) { | 
| Carlo Bertolli | 7971209 | 2018-02-28 20:48:35 +0000 | [diff] [blame] | 5255 | Action.Enter(CGF); | 
| Alexey Bataev | 647dd84 | 2018-01-15 20:59:40 +0000 | [diff] [blame] | 5256 | auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5257 | CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined, | 
|  | 5258 | S.getDistInc()); | 
|  | 5259 | }; | 
|  | 5260 |  | 
|  | 5261 | // Emit teams region as a standalone region. | 
|  | 5262 | auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF, | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5263 | PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5264 | Action.Enter(CGF); | 
| Alexey Bataev | 647dd84 | 2018-01-15 20:59:40 +0000 | [diff] [blame] | 5265 | CodeGenFunction::OMPPrivateScope PrivateScope(CGF); | 
|  | 5266 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5267 | (void)PrivateScope.Privatize(); | 
|  | 5268 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective( | 
|  | 5269 | CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false); | 
|  | 5270 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); | 
|  | 5271 | }; | 
|  | 5272 |  | 
|  | 5273 | emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for_simd, | 
|  | 5274 | CodeGenTeams); | 
|  | 5275 | emitPostUpdateForReductionClause(CGF, S, | 
|  | 5276 | [](CodeGenFunction &) { return nullptr; }); | 
|  | 5277 | } | 
|  | 5278 |  | 
|  | 5279 | void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction( | 
|  | 5280 | CodeGenModule &CGM, StringRef ParentName, | 
|  | 5281 | const OMPTargetTeamsDistributeParallelForSimdDirective &S) { | 
|  | 5282 | // Emit SPMD target teams distribute parallel for simd region as a standalone | 
|  | 5283 | // region. | 
|  | 5284 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5285 | emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action); | 
|  | 5286 | }; | 
|  | 5287 | llvm::Function *Fn; | 
|  | 5288 | llvm::Constant *Addr; | 
|  | 5289 | // Emit target region as a standalone region. | 
|  | 5290 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 5291 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 5292 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 5293 | } | 
|  | 5294 |  | 
|  | 5295 | void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective( | 
|  | 5296 | const OMPTargetTeamsDistributeParallelForSimdDirective &S) { | 
|  | 5297 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5298 | emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action); | 
|  | 5299 | }; | 
|  | 5300 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
|  | 5301 | } | 
|  | 5302 |  | 
| Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 5303 | void CodeGenFunction::EmitOMPCancellationPointDirective( | 
|  | 5304 | const OMPCancellationPointDirective &S) { | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 5305 | CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getBeginLoc(), | 
| Alexey Bataev | 0f34da1 | 2015-07-02 04:17:07 +0000 | [diff] [blame] | 5306 | S.getCancelRegion()); | 
| Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 5307 | } | 
|  | 5308 |  | 
| Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 5309 | void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) { | 
| Alexey Bataev | 87933c7 | 2015-09-18 08:07:34 +0000 | [diff] [blame] | 5310 | const Expr *IfCond = nullptr; | 
|  | 5311 | for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { | 
|  | 5312 | if (C->getNameModifier() == OMPD_unknown || | 
|  | 5313 | C->getNameModifier() == OMPD_cancel) { | 
|  | 5314 | IfCond = C->getCondition(); | 
|  | 5315 | break; | 
|  | 5316 | } | 
|  | 5317 | } | 
| Johannes Doerfert | 10fedd9 | 2019-12-26 11:23:38 -0600 | [diff] [blame] | 5318 | if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) { | 
|  | 5319 | // TODO: This check is necessary as we only generate `omp parallel` through | 
|  | 5320 | // the OpenMPIRBuilder for now. | 
|  | 5321 | if (S.getCancelRegion() == OMPD_parallel) { | 
|  | 5322 | llvm::Value *IfCondition = nullptr; | 
|  | 5323 | if (IfCond) | 
|  | 5324 | IfCondition = EmitScalarExpr(IfCond, | 
|  | 5325 | /*IgnoreResultAssign=*/true); | 
|  | 5326 | return Builder.restoreIP( | 
|  | 5327 | OMPBuilder->CreateCancel(Builder, IfCondition, S.getCancelRegion())); | 
|  | 5328 | } | 
|  | 5329 | } | 
|  | 5330 |  | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 5331 | CGM.getOpenMPRuntime().emitCancelCall(*this, S.getBeginLoc(), IfCond, | 
| Alexey Bataev | 7d5d33e | 2015-07-06 05:50:32 +0000 | [diff] [blame] | 5332 | S.getCancelRegion()); | 
| Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 5333 | } | 
|  | 5334 |  | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 5335 | CodeGenFunction::JumpDest | 
|  | 5336 | CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) { | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 5337 | if (Kind == OMPD_parallel || Kind == OMPD_task || | 
| Alexey Bataev | e0ca479 | 2020-02-12 16:12:53 -0500 | [diff] [blame] | 5338 | Kind == OMPD_target_parallel || Kind == OMPD_taskloop || | 
|  | 5339 | Kind == OMPD_master_taskloop || Kind == OMPD_parallel_master_taskloop) | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 5340 | return ReturnBlock; | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5341 | assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections || | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 5342 | Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for || | 
|  | 5343 | Kind == OMPD_distribute_parallel_for || | 
| Alexey Bataev | dcb4b8fb | 2017-11-22 20:19:50 +0000 | [diff] [blame] | 5344 | Kind == OMPD_target_parallel_for || | 
| Alexey Bataev | 16e7988 | 2017-11-22 21:12:03 +0000 | [diff] [blame] | 5345 | Kind == OMPD_teams_distribute_parallel_for || | 
|  | 5346 | Kind == OMPD_target_teams_distribute_parallel_for); | 
| Alexey Bataev | 957d856 | 2016-11-17 15:12:05 +0000 | [diff] [blame] | 5347 | return OMPCancelStack.getExitBlock(); | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 5348 | } | 
| Michael Wong | 65f367f | 2015-07-21 13:44:28 +0000 | [diff] [blame] | 5349 |  | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5350 | void CodeGenFunction::EmitOMPUseDevicePtrClause( | 
|  | 5351 | const OMPClause &NC, OMPPrivateScope &PrivateScope, | 
|  | 5352 | const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) { | 
|  | 5353 | const auto &C = cast<OMPUseDevicePtrClause>(NC); | 
|  | 5354 | auto OrigVarIt = C.varlist_begin(); | 
|  | 5355 | auto InitIt = C.inits().begin(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5356 | for (const Expr *PvtVarIt : C.private_copies()) { | 
|  | 5357 | const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl()); | 
|  | 5358 | const auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl()); | 
|  | 5359 | const auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl()); | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5360 |  | 
|  | 5361 | // In order to identify the right initializer we need to match the | 
|  | 5362 | // declaration used by the mapping logic. In some cases we may get | 
|  | 5363 | // OMPCapturedExprDecl that refers to the original declaration. | 
|  | 5364 | const ValueDecl *MatchingVD = OrigVD; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5365 | if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) { | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5366 | // OMPCapturedExprDecl are used to privative fields of the current | 
|  | 5367 | // structure. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5368 | const auto *ME = cast<MemberExpr>(OED->getInit()); | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5369 | assert(isa<CXXThisExpr>(ME->getBase()) && | 
|  | 5370 | "Base should be the current struct!"); | 
|  | 5371 | MatchingVD = ME->getMemberDecl(); | 
|  | 5372 | } | 
|  | 5373 |  | 
|  | 5374 | // If we don't have information about the current list item, move on to | 
|  | 5375 | // the next one. | 
|  | 5376 | auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD); | 
|  | 5377 | if (InitAddrIt == CaptureDeviceAddrMap.end()) | 
|  | 5378 | continue; | 
|  | 5379 |  | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5380 | bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, OrigVD, | 
|  | 5381 | InitAddrIt, InitVD, | 
|  | 5382 | PvtVD]() { | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5383 | // Initialize the temporary initialization variable with the address we | 
|  | 5384 | // get from the runtime library. We have to cast the source address | 
|  | 5385 | // because it is always a void *. References are materialized in the | 
|  | 5386 | // privatization scope, so the initialization here disregards the fact | 
|  | 5387 | // the original variable is a reference. | 
|  | 5388 | QualType AddrQTy = | 
|  | 5389 | getContext().getPointerType(OrigVD->getType().getNonReferenceType()); | 
|  | 5390 | llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy); | 
|  | 5391 | Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy); | 
|  | 5392 | setAddrOfLocalVar(InitVD, InitAddr); | 
|  | 5393 |  | 
|  | 5394 | // Emit private declaration, it will be initialized by the value we | 
|  | 5395 | // declaration we just added to the local declarations map. | 
|  | 5396 | EmitDecl(*PvtVD); | 
|  | 5397 |  | 
|  | 5398 | // The initialization variables reached its purpose in the emission | 
| Alexander Kornienko | 2a8c18d | 2018-04-06 15:14:32 +0000 | [diff] [blame] | 5399 | // of the previous declaration, so we don't need it anymore. | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5400 | LocalDeclMap.erase(InitVD); | 
|  | 5401 |  | 
|  | 5402 | // Return the address of the private variable. | 
|  | 5403 | return GetAddrOfLocalVar(PvtVD); | 
|  | 5404 | }); | 
|  | 5405 | assert(IsRegistered && "firstprivate var already registered as private"); | 
|  | 5406 | // Silence the warning about unused variable. | 
|  | 5407 | (void)IsRegistered; | 
|  | 5408 |  | 
|  | 5409 | ++OrigVarIt; | 
|  | 5410 | ++InitIt; | 
|  | 5411 | } | 
|  | 5412 | } | 
|  | 5413 |  | 
| Michael Wong | 65f367f | 2015-07-21 13:44:28 +0000 | [diff] [blame] | 5414 | // Generate the instructions for '#pragma omp target data' directive. | 
|  | 5415 | void CodeGenFunction::EmitOMPTargetDataDirective( | 
|  | 5416 | const OMPTargetDataDirective &S) { | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5417 | CGOpenMPRuntime::TargetDataInfo Info(/*RequiresDevicePointerInfo=*/true); | 
|  | 5418 |  | 
|  | 5419 | // Create a pre/post action to signal the privatization of the device pointer. | 
|  | 5420 | // This action can be replaced by the OpenMP runtime code generation to | 
|  | 5421 | // deactivate privatization. | 
|  | 5422 | bool PrivatizeDevicePointers = false; | 
|  | 5423 | class DevicePointerPrivActionTy : public PrePostActionTy { | 
|  | 5424 | bool &PrivatizeDevicePointers; | 
|  | 5425 |  | 
|  | 5426 | public: | 
|  | 5427 | explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers) | 
|  | 5428 | : PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {} | 
|  | 5429 | void Enter(CodeGenFunction &CGF) override { | 
|  | 5430 | PrivatizeDevicePointers = true; | 
|  | 5431 | } | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 5432 | }; | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5433 | DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers); | 
|  | 5434 |  | 
|  | 5435 | auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers]( | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5436 | CodeGenFunction &CGF, PrePostActionTy &Action) { | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5437 | auto &&InnermostCodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5438 | CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5439 | }; | 
|  | 5440 |  | 
| Alexander Kornienko | 2a8c18d | 2018-04-06 15:14:32 +0000 | [diff] [blame] | 5441 | // Codegen that selects whether to generate the privatization code or not. | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5442 | auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers, | 
|  | 5443 | &InnermostCodeGen](CodeGenFunction &CGF, | 
|  | 5444 | PrePostActionTy &Action) { | 
|  | 5445 | RegionCodeGenTy RCG(InnermostCodeGen); | 
|  | 5446 | PrivatizeDevicePointers = false; | 
|  | 5447 |  | 
|  | 5448 | // Call the pre-action to change the status of PrivatizeDevicePointers if | 
|  | 5449 | // needed. | 
|  | 5450 | Action.Enter(CGF); | 
|  | 5451 |  | 
|  | 5452 | if (PrivatizeDevicePointers) { | 
|  | 5453 | OMPPrivateScope PrivateScope(CGF); | 
|  | 5454 | // Emit all instances of the use_device_ptr clause. | 
|  | 5455 | for (const auto *C : S.getClausesOfKind<OMPUseDevicePtrClause>()) | 
|  | 5456 | CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope, | 
|  | 5457 | Info.CaptureDeviceAddrMap); | 
|  | 5458 | (void)PrivateScope.Privatize(); | 
|  | 5459 | RCG(CGF); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5460 | } else { | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5461 | RCG(CGF); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5462 | } | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5463 | }; | 
|  | 5464 |  | 
|  | 5465 | // Forward the provided action to the privatization codegen. | 
|  | 5466 | RegionCodeGenTy PrivRCG(PrivCodeGen); | 
|  | 5467 | PrivRCG.setAction(Action); | 
|  | 5468 |  | 
|  | 5469 | // Notwithstanding the body of the region is emitted as inlined directive, | 
|  | 5470 | // we don't use an inline scope as changes in the references inside the | 
|  | 5471 | // region are expected to be visible outside, so we do not privative them. | 
|  | 5472 | OMPLexicalScope Scope(CGF, S); | 
|  | 5473 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data, | 
|  | 5474 | PrivRCG); | 
|  | 5475 | }; | 
|  | 5476 |  | 
|  | 5477 | RegionCodeGenTy RCG(CodeGen); | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 5478 |  | 
|  | 5479 | // If we don't have target devices, don't bother emitting the data mapping | 
|  | 5480 | // code. | 
|  | 5481 | if (CGM.getLangOpts().OMPTargetTriples.empty()) { | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5482 | RCG(*this); | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 5483 | return; | 
|  | 5484 | } | 
|  | 5485 |  | 
|  | 5486 | // Check if we have any if clause associated with the directive. | 
|  | 5487 | const Expr *IfCond = nullptr; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5488 | if (const auto *C = S.getSingleClause<OMPIfClause>()) | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 5489 | IfCond = C->getCondition(); | 
|  | 5490 |  | 
|  | 5491 | // Check if we have any device clause associated with the directive. | 
|  | 5492 | const Expr *Device = nullptr; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5493 | if (const auto *C = S.getSingleClause<OMPDeviceClause>()) | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 5494 | Device = C->getDevice(); | 
|  | 5495 |  | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 5496 | // Set the action to signal privatization of device pointers. | 
|  | 5497 | RCG.setAction(PrivAction); | 
|  | 5498 |  | 
|  | 5499 | // Emit region code. | 
|  | 5500 | CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, RCG, | 
|  | 5501 | Info); | 
| Michael Wong | 65f367f | 2015-07-21 13:44:28 +0000 | [diff] [blame] | 5502 | } | 
| Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 5503 |  | 
| Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 5504 | void CodeGenFunction::EmitOMPTargetEnterDataDirective( | 
|  | 5505 | const OMPTargetEnterDataDirective &S) { | 
| Samuel Antao | bd0ae2e | 2016-04-27 23:07:29 +0000 | [diff] [blame] | 5506 | // If we don't have target devices, don't bother emitting the data mapping | 
|  | 5507 | // code. | 
|  | 5508 | if (CGM.getLangOpts().OMPTargetTriples.empty()) | 
|  | 5509 | return; | 
|  | 5510 |  | 
|  | 5511 | // Check if we have any if clause associated with the directive. | 
|  | 5512 | const Expr *IfCond = nullptr; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5513 | if (const auto *C = S.getSingleClause<OMPIfClause>()) | 
| Samuel Antao | bd0ae2e | 2016-04-27 23:07:29 +0000 | [diff] [blame] | 5514 | IfCond = C->getCondition(); | 
|  | 5515 |  | 
|  | 5516 | // Check if we have any device clause associated with the directive. | 
|  | 5517 | const Expr *Device = nullptr; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5518 | if (const auto *C = S.getSingleClause<OMPDeviceClause>()) | 
| Samuel Antao | bd0ae2e | 2016-04-27 23:07:29 +0000 | [diff] [blame] | 5519 | Device = C->getDevice(); | 
|  | 5520 |  | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5521 | OMPLexicalScope Scope(*this, S, OMPD_task); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 5522 | CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device); | 
| Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 5523 | } | 
|  | 5524 |  | 
| Samuel Antao | 7259076 | 2016-01-19 20:04:50 +0000 | [diff] [blame] | 5525 | void CodeGenFunction::EmitOMPTargetExitDataDirective( | 
|  | 5526 | const OMPTargetExitDataDirective &S) { | 
| Samuel Antao | 8dd6628 | 2016-04-27 23:14:30 +0000 | [diff] [blame] | 5527 | // If we don't have target devices, don't bother emitting the data mapping | 
|  | 5528 | // code. | 
|  | 5529 | if (CGM.getLangOpts().OMPTargetTriples.empty()) | 
|  | 5530 | return; | 
|  | 5531 |  | 
|  | 5532 | // Check if we have any if clause associated with the directive. | 
|  | 5533 | const Expr *IfCond = nullptr; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5534 | if (const auto *C = S.getSingleClause<OMPIfClause>()) | 
| Samuel Antao | 8dd6628 | 2016-04-27 23:14:30 +0000 | [diff] [blame] | 5535 | IfCond = C->getCondition(); | 
|  | 5536 |  | 
|  | 5537 | // Check if we have any device clause associated with the directive. | 
|  | 5538 | const Expr *Device = nullptr; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5539 | if (const auto *C = S.getSingleClause<OMPDeviceClause>()) | 
| Samuel Antao | 8dd6628 | 2016-04-27 23:14:30 +0000 | [diff] [blame] | 5540 | Device = C->getDevice(); | 
|  | 5541 |  | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5542 | OMPLexicalScope Scope(*this, S, OMPD_task); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 5543 | CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device); | 
| Samuel Antao | 7259076 | 2016-01-19 20:04:50 +0000 | [diff] [blame] | 5544 | } | 
|  | 5545 |  | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 5546 | static void emitTargetParallelRegion(CodeGenFunction &CGF, | 
|  | 5547 | const OMPTargetParallelDirective &S, | 
|  | 5548 | PrePostActionTy &Action) { | 
|  | 5549 | // Get the captured statement associated with the 'parallel' region. | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5550 | const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel); | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 5551 | Action.Enter(CGF); | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5552 | auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
| Alexey Bataev | 63cc8e9 | 2018-03-20 14:45:59 +0000 | [diff] [blame] | 5553 | Action.Enter(CGF); | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 5554 | CodeGenFunction::OMPPrivateScope PrivateScope(CGF); | 
|  | 5555 | (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); | 
|  | 5556 | CGF.EmitOMPPrivateClause(S, PrivateScope); | 
|  | 5557 | CGF.EmitOMPReductionClauseInit(S, PrivateScope); | 
|  | 5558 | (void)PrivateScope.Privatize(); | 
| Alexey Bataev | 6070542 | 2018-10-30 15:50:12 +0000 | [diff] [blame] | 5559 | if (isOpenMPTargetExecutionDirective(S.getDirectiveKind())) | 
|  | 5560 | CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S); | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 5561 | // TODO: Add support for clauses. | 
|  | 5562 | CGF.EmitStmt(CS->getCapturedStmt()); | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 5563 | CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 5564 | }; | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 5565 | emitCommonOMPParallelDirective(CGF, S, OMPD_parallel, CodeGen, | 
|  | 5566 | emitEmptyBoundParameters); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5567 | emitPostUpdateForReductionClause(CGF, S, | 
|  | 5568 | [](CodeGenFunction &) { return nullptr; }); | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 5569 | } | 
|  | 5570 |  | 
|  | 5571 | void CodeGenFunction::EmitOMPTargetParallelDeviceFunction( | 
|  | 5572 | CodeGenModule &CGM, StringRef ParentName, | 
|  | 5573 | const OMPTargetParallelDirective &S) { | 
|  | 5574 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5575 | emitTargetParallelRegion(CGF, S, Action); | 
|  | 5576 | }; | 
|  | 5577 | llvm::Function *Fn; | 
|  | 5578 | llvm::Constant *Addr; | 
|  | 5579 | // Emit target region as a standalone region. | 
|  | 5580 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 5581 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 5582 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 5583 | } | 
|  | 5584 |  | 
| Arpith Chacko Jacob | e955b3d | 2016-01-26 18:48:41 +0000 | [diff] [blame] | 5585 | void CodeGenFunction::EmitOMPTargetParallelDirective( | 
|  | 5586 | const OMPTargetParallelDirective &S) { | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 5587 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5588 | emitTargetParallelRegion(CGF, S, Action); | 
|  | 5589 | }; | 
|  | 5590 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
| Arpith Chacko Jacob | e955b3d | 2016-01-26 18:48:41 +0000 | [diff] [blame] | 5591 | } | 
|  | 5592 |  | 
| Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 5593 | static void emitTargetParallelForRegion(CodeGenFunction &CGF, | 
|  | 5594 | const OMPTargetParallelForDirective &S, | 
|  | 5595 | PrePostActionTy &Action) { | 
|  | 5596 | Action.Enter(CGF); | 
|  | 5597 | // Emit directive as a combined directive that consists of two implicit | 
|  | 5598 | // directives: 'parallel' with 'for' directive. | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5599 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5600 | Action.Enter(CGF); | 
| Alexey Bataev | 2139ed6 | 2017-11-16 18:20:21 +0000 | [diff] [blame] | 5601 | CodeGenFunction::OMPCancelStackRAII CancelRegion( | 
|  | 5602 | CGF, OMPD_target_parallel_for, S.hasCancel()); | 
| Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 5603 | CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, | 
|  | 5604 | emitDispatchForLoopBounds); | 
|  | 5605 | }; | 
|  | 5606 | emitCommonOMPParallelDirective(CGF, S, OMPD_for, CodeGen, | 
|  | 5607 | emitEmptyBoundParameters); | 
|  | 5608 | } | 
|  | 5609 |  | 
|  | 5610 | void CodeGenFunction::EmitOMPTargetParallelForDeviceFunction( | 
|  | 5611 | CodeGenModule &CGM, StringRef ParentName, | 
|  | 5612 | const OMPTargetParallelForDirective &S) { | 
|  | 5613 | // Emit SPMD target parallel for region as a standalone region. | 
|  | 5614 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5615 | emitTargetParallelForRegion(CGF, S, Action); | 
|  | 5616 | }; | 
|  | 5617 | llvm::Function *Fn; | 
|  | 5618 | llvm::Constant *Addr; | 
|  | 5619 | // Emit target region as a standalone region. | 
|  | 5620 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 5621 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 5622 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 5623 | } | 
|  | 5624 |  | 
| Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 5625 | void CodeGenFunction::EmitOMPTargetParallelForDirective( | 
|  | 5626 | const OMPTargetParallelForDirective &S) { | 
| Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 5627 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5628 | emitTargetParallelForRegion(CGF, S, Action); | 
|  | 5629 | }; | 
|  | 5630 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
| Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 5631 | } | 
|  | 5632 |  | 
| Alexey Bataev | 5d7edca | 2017-11-09 17:32:15 +0000 | [diff] [blame] | 5633 | static void | 
|  | 5634 | emitTargetParallelForSimdRegion(CodeGenFunction &CGF, | 
|  | 5635 | const OMPTargetParallelForSimdDirective &S, | 
|  | 5636 | PrePostActionTy &Action) { | 
|  | 5637 | Action.Enter(CGF); | 
|  | 5638 | // Emit directive as a combined directive that consists of two implicit | 
|  | 5639 | // directives: 'parallel' with 'for' directive. | 
| Alexey Bataev | c99042b | 2018-03-15 18:10:54 +0000 | [diff] [blame] | 5640 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5641 | Action.Enter(CGF); | 
| Alexey Bataev | 5d7edca | 2017-11-09 17:32:15 +0000 | [diff] [blame] | 5642 | CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, | 
|  | 5643 | emitDispatchForLoopBounds); | 
|  | 5644 | }; | 
|  | 5645 | emitCommonOMPParallelDirective(CGF, S, OMPD_simd, CodeGen, | 
|  | 5646 | emitEmptyBoundParameters); | 
|  | 5647 | } | 
|  | 5648 |  | 
|  | 5649 | void CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction( | 
|  | 5650 | CodeGenModule &CGM, StringRef ParentName, | 
|  | 5651 | const OMPTargetParallelForSimdDirective &S) { | 
|  | 5652 | // Emit SPMD target parallel for region as a standalone region. | 
|  | 5653 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5654 | emitTargetParallelForSimdRegion(CGF, S, Action); | 
|  | 5655 | }; | 
|  | 5656 | llvm::Function *Fn; | 
|  | 5657 | llvm::Constant *Addr; | 
|  | 5658 | // Emit target region as a standalone region. | 
|  | 5659 | CGM.getOpenMPRuntime().emitTargetOutlinedFunction( | 
|  | 5660 | S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); | 
|  | 5661 | assert(Fn && Addr && "Target device function emission failed."); | 
|  | 5662 | } | 
|  | 5663 |  | 
|  | 5664 | void CodeGenFunction::EmitOMPTargetParallelForSimdDirective( | 
|  | 5665 | const OMPTargetParallelForSimdDirective &S) { | 
|  | 5666 | auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5667 | emitTargetParallelForSimdRegion(CGF, S, Action); | 
|  | 5668 | }; | 
|  | 5669 | emitCommonOMPTargetDirective(*this, S, CodeGen); | 
|  | 5670 | } | 
|  | 5671 |  | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5672 | /// Emit a helper variable and return corresponding lvalue. | 
|  | 5673 | static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper, | 
|  | 5674 | const ImplicitParamDecl *PVD, | 
|  | 5675 | CodeGenFunction::OMPPrivateScope &Privates) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5676 | const auto *VDecl = cast<VarDecl>(Helper->getDecl()); | 
|  | 5677 | Privates.addPrivate(VDecl, | 
|  | 5678 | [&CGF, PVD]() { return CGF.GetAddrOfLocalVar(PVD); }); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5679 | } | 
|  | 5680 |  | 
|  | 5681 | void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) { | 
|  | 5682 | assert(isOpenMPTaskLoopDirective(S.getDirectiveKind())); | 
|  | 5683 | // Emit outlined function for task construct. | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5684 | const CapturedStmt *CS = S.getCapturedStmt(OMPD_taskloop); | 
| Alexey Bataev | 172f146 | 2020-03-12 12:52:02 -0400 | [diff] [blame] | 5685 | Address CapturedStruct = Address::invalid(); | 
|  | 5686 | { | 
|  | 5687 | OMPLexicalScope Scope(*this, S, OMPD_taskloop, /*EmitPreInitStmt=*/false); | 
|  | 5688 | CapturedStruct = GenerateCapturedStmtArgument(*CS); | 
|  | 5689 | } | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5690 | QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5691 | const Expr *IfCond = nullptr; | 
|  | 5692 | for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { | 
|  | 5693 | if (C->getNameModifier() == OMPD_unknown || | 
|  | 5694 | C->getNameModifier() == OMPD_taskloop) { | 
|  | 5695 | IfCond = C->getCondition(); | 
|  | 5696 | break; | 
|  | 5697 | } | 
|  | 5698 | } | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 5699 |  | 
|  | 5700 | OMPTaskDataTy Data; | 
|  | 5701 | // Check if taskloop must be emitted without taskgroup. | 
|  | 5702 | Data.Nogroup = S.getSingleClause<OMPNogroupClause>(); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5703 | // TODO: Check if we should emit tied or untied task. | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 5704 | Data.Tied = true; | 
|  | 5705 | // Set scheduling for taskloop | 
| Alexey Bataev | 2b19a6f | 2016-04-28 09:15:06 +0000 | [diff] [blame] | 5706 | if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) { | 
|  | 5707 | // grainsize clause | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 5708 | Data.Schedule.setInt(/*IntVal=*/false); | 
|  | 5709 | Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize())); | 
| Alexey Bataev | 2b19a6f | 2016-04-28 09:15:06 +0000 | [diff] [blame] | 5710 | } else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) { | 
|  | 5711 | // num_tasks clause | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 5712 | Data.Schedule.setInt(/*IntVal=*/true); | 
|  | 5713 | Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks())); | 
| Alexey Bataev | 2b19a6f | 2016-04-28 09:15:06 +0000 | [diff] [blame] | 5714 | } | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5715 |  | 
|  | 5716 | auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5717 | // if (PreCond) { | 
|  | 5718 | //   for (IV in 0..LastIteration) BODY; | 
|  | 5719 | //   <Final counter/linear vars updates>; | 
|  | 5720 | // } | 
|  | 5721 | // | 
|  | 5722 |  | 
|  | 5723 | // Emit: if (PreCond) - begin. | 
|  | 5724 | // If the condition constant folds and can be elided, avoid emitting the | 
|  | 5725 | // whole loop. | 
|  | 5726 | bool CondConstant; | 
|  | 5727 | llvm::BasicBlock *ContBlock = nullptr; | 
|  | 5728 | OMPLoopScope PreInitScope(CGF, S); | 
|  | 5729 | if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { | 
|  | 5730 | if (!CondConstant) | 
|  | 5731 | return; | 
|  | 5732 | } else { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5733 | llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("taskloop.if.then"); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5734 | ContBlock = CGF.createBasicBlock("taskloop.if.end"); | 
|  | 5735 | emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock, | 
|  | 5736 | CGF.getProfileCount(&S)); | 
|  | 5737 | CGF.EmitBlock(ThenBlock); | 
|  | 5738 | CGF.incrementProfileCounter(&S); | 
|  | 5739 | } | 
|  | 5740 |  | 
| Alexey Bataev | 6120582 | 2019-12-04 09:50:21 -0500 | [diff] [blame] | 5741 | (void)CGF.EmitOMPLinearClauseInit(S); | 
| Alexey Bataev | 1e73ef3 | 2016-04-28 12:14:51 +0000 | [diff] [blame] | 5742 |  | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5743 | OMPPrivateScope LoopScope(CGF); | 
|  | 5744 | // Emit helper vars inits. | 
|  | 5745 | enum { LowerBound = 5, UpperBound, Stride, LastIter }; | 
|  | 5746 | auto *I = CS->getCapturedDecl()->param_begin(); | 
|  | 5747 | auto *LBP = std::next(I, LowerBound); | 
|  | 5748 | auto *UBP = std::next(I, UpperBound); | 
|  | 5749 | auto *STP = std::next(I, Stride); | 
|  | 5750 | auto *LIP = std::next(I, LastIter); | 
|  | 5751 | mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP, | 
|  | 5752 | LoopScope); | 
|  | 5753 | mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP, | 
|  | 5754 | LoopScope); | 
|  | 5755 | mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope); | 
|  | 5756 | mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP, | 
|  | 5757 | LoopScope); | 
|  | 5758 | CGF.EmitOMPPrivateLoopCounters(S, LoopScope); | 
| Alexey Bataev | 14a388f | 2019-10-25 10:27:13 -0400 | [diff] [blame] | 5759 | CGF.EmitOMPLinearClause(S, LoopScope); | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 5760 | bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5761 | (void)LoopScope.Privatize(); | 
|  | 5762 | // Emit the loop iteration variable. | 
|  | 5763 | const Expr *IVExpr = S.getIterationVariable(); | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5764 | const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5765 | CGF.EmitVarDecl(*IVDecl); | 
|  | 5766 | CGF.EmitIgnoredExpr(S.getInit()); | 
|  | 5767 |  | 
|  | 5768 | // Emit the iterations count variable. | 
|  | 5769 | // If it is not a variable, Sema decided to calculate iterations count on | 
|  | 5770 | // each iteration (e.g., it is foldable into a constant). | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5771 | if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5772 | CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); | 
|  | 5773 | // Emit calculation of the iterations count. | 
|  | 5774 | CGF.EmitIgnoredExpr(S.getCalcLastIteration()); | 
|  | 5775 | } | 
|  | 5776 |  | 
| Alexey Bataev | 6120582 | 2019-12-04 09:50:21 -0500 | [diff] [blame] | 5777 | { | 
|  | 5778 | OMPLexicalScope Scope(CGF, S, OMPD_taskloop, /*EmitPreInitStmt=*/false); | 
|  | 5779 | emitCommonSimdLoop( | 
|  | 5780 | CGF, S, | 
|  | 5781 | [&S](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5782 | if (isOpenMPSimdDirective(S.getDirectiveKind())) | 
|  | 5783 | CGF.EmitOMPSimdInit(S); | 
|  | 5784 | }, | 
|  | 5785 | [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) { | 
|  | 5786 | CGF.EmitOMPInnerLoop( | 
|  | 5787 | S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(), | 
|  | 5788 | [&S](CodeGenFunction &CGF) { | 
|  | 5789 | CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest()); | 
|  | 5790 | CGF.EmitStopPoint(&S); | 
|  | 5791 | }, | 
|  | 5792 | [](CodeGenFunction &) {}); | 
|  | 5793 | }); | 
|  | 5794 | } | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5795 | // Emit: if (PreCond) - end. | 
|  | 5796 | if (ContBlock) { | 
|  | 5797 | CGF.EmitBranch(ContBlock); | 
|  | 5798 | CGF.EmitBlock(ContBlock, true); | 
|  | 5799 | } | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 5800 | // Emit final copy of the lastprivate variables if IsLastIter != 0. | 
|  | 5801 | if (HasLastprivateClause) { | 
|  | 5802 | CGF.EmitOMPLastprivateClauseFinal( | 
|  | 5803 | S, isOpenMPSimdDirective(S.getDirectiveKind()), | 
|  | 5804 | CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar( | 
|  | 5805 | CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false, | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 5806 | (*LIP)->getType(), S.getBeginLoc()))); | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 5807 | } | 
| Alexey Bataev | 14a388f | 2019-10-25 10:27:13 -0400 | [diff] [blame] | 5808 | CGF.EmitOMPLinearClauseFinal(S, [LIP, &S](CodeGenFunction &CGF) { | 
|  | 5809 | return CGF.Builder.CreateIsNotNull( | 
|  | 5810 | CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false, | 
|  | 5811 | (*LIP)->getType(), S.getBeginLoc())); | 
|  | 5812 | }); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5813 | }; | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 5814 | auto &&TaskGen = [&S, SharedsTy, CapturedStruct, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 5815 | IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn, | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 5816 | const OMPTaskDataTy &Data) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5817 | auto &&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond, | 
|  | 5818 | &Data](CodeGenFunction &CGF, PrePostActionTy &) { | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5819 | OMPLoopScope PreInitScope(CGF, S); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 5820 | CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getBeginLoc(), S, | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 5821 | OutlinedFn, SharedsTy, | 
|  | 5822 | CapturedStruct, IfCond, Data); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5823 | }; | 
|  | 5824 | CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop, | 
|  | 5825 | CodeGen); | 
|  | 5826 | }; | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5827 | if (Data.Nogroup) { | 
|  | 5828 | EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen, Data); | 
|  | 5829 | } else { | 
| Alexey Bataev | 3344603 | 2017-07-12 18:09:32 +0000 | [diff] [blame] | 5830 | CGM.getOpenMPRuntime().emitTaskgroupRegion( | 
|  | 5831 | *this, | 
|  | 5832 | [&S, &BodyGen, &TaskGen, &Data](CodeGenFunction &CGF, | 
|  | 5833 | PrePostActionTy &Action) { | 
|  | 5834 | Action.Enter(CGF); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5835 | CGF.EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen, | 
|  | 5836 | Data); | 
| Alexey Bataev | 3344603 | 2017-07-12 18:09:32 +0000 | [diff] [blame] | 5837 | }, | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 5838 | S.getBeginLoc()); | 
| Alexey Bataev | 3344603 | 2017-07-12 18:09:32 +0000 | [diff] [blame] | 5839 | } | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5840 | } | 
|  | 5841 |  | 
| Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 5842 | void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 5843 | auto LPCRegion = | 
|  | 5844 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 5845 | EmitOMPTaskLoopBasedDirective(S); | 
| Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 5846 | } | 
|  | 5847 |  | 
| Alexey Bataev | 0a6ed84 | 2015-12-03 09:40:15 +0000 | [diff] [blame] | 5848 | void CodeGenFunction::EmitOMPTaskLoopSimdDirective( | 
|  | 5849 | const OMPTaskLoopSimdDirective &S) { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 5850 | auto LPCRegion = | 
|  | 5851 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 6120582 | 2019-12-04 09:50:21 -0500 | [diff] [blame] | 5852 | OMPLexicalScope Scope(*this, S); | 
| Alexey Bataev | 1e73ef3 | 2016-04-28 12:14:51 +0000 | [diff] [blame] | 5853 | EmitOMPTaskLoopBasedDirective(S); | 
| Alexey Bataev | 0a6ed84 | 2015-12-03 09:40:15 +0000 | [diff] [blame] | 5854 | } | 
| Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 5855 |  | 
| Alexey Bataev | 60e51c4 | 2019-10-10 20:13:02 +0000 | [diff] [blame] | 5856 | void CodeGenFunction::EmitOMPMasterTaskLoopDirective( | 
|  | 5857 | const OMPMasterTaskLoopDirective &S) { | 
|  | 5858 | auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5859 | Action.Enter(CGF); | 
|  | 5860 | EmitOMPTaskLoopBasedDirective(S); | 
|  | 5861 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 5862 | auto LPCRegion = | 
|  | 5863 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 60e51c4 | 2019-10-10 20:13:02 +0000 | [diff] [blame] | 5864 | OMPLexicalScope Scope(*this, S, llvm::None, /*EmitPreInitStmt=*/false); | 
|  | 5865 | CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getBeginLoc()); | 
|  | 5866 | } | 
|  | 5867 |  | 
| Alexey Bataev | b8552ab | 2019-10-18 16:47:35 +0000 | [diff] [blame] | 5868 | void CodeGenFunction::EmitOMPMasterTaskLoopSimdDirective( | 
|  | 5869 | const OMPMasterTaskLoopSimdDirective &S) { | 
|  | 5870 | auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5871 | Action.Enter(CGF); | 
|  | 5872 | EmitOMPTaskLoopBasedDirective(S); | 
|  | 5873 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 5874 | auto LPCRegion = | 
|  | 5875 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 6120582 | 2019-12-04 09:50:21 -0500 | [diff] [blame] | 5876 | OMPLexicalScope Scope(*this, S); | 
| Alexey Bataev | b8552ab | 2019-10-18 16:47:35 +0000 | [diff] [blame] | 5877 | CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getBeginLoc()); | 
|  | 5878 | } | 
|  | 5879 |  | 
| Alexey Bataev | 5bbcead | 2019-10-14 17:17:41 +0000 | [diff] [blame] | 5880 | void CodeGenFunction::EmitOMPParallelMasterTaskLoopDirective( | 
|  | 5881 | const OMPParallelMasterTaskLoopDirective &S) { | 
|  | 5882 | auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5883 | auto &&TaskLoopCodeGen = [&S](CodeGenFunction &CGF, | 
|  | 5884 | PrePostActionTy &Action) { | 
|  | 5885 | Action.Enter(CGF); | 
|  | 5886 | CGF.EmitOMPTaskLoopBasedDirective(S); | 
|  | 5887 | }; | 
| Alexey Bataev | 18789bf | 2020-02-13 09:21:15 -0500 | [diff] [blame] | 5888 | OMPLexicalScope Scope(CGF, S, OMPD_parallel, /*EmitPreInitStmt=*/false); | 
| Alexey Bataev | 5bbcead | 2019-10-14 17:17:41 +0000 | [diff] [blame] | 5889 | CGM.getOpenMPRuntime().emitMasterRegion(CGF, TaskLoopCodeGen, | 
|  | 5890 | S.getBeginLoc()); | 
|  | 5891 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 5892 | auto LPCRegion = | 
|  | 5893 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 5bbcead | 2019-10-14 17:17:41 +0000 | [diff] [blame] | 5894 | emitCommonOMPParallelDirective(*this, S, OMPD_master_taskloop, CodeGen, | 
|  | 5895 | emitEmptyBoundParameters); | 
|  | 5896 | } | 
|  | 5897 |  | 
| Alexey Bataev | 14a388f | 2019-10-25 10:27:13 -0400 | [diff] [blame] | 5898 | void CodeGenFunction::EmitOMPParallelMasterTaskLoopSimdDirective( | 
|  | 5899 | const OMPParallelMasterTaskLoopSimdDirective &S) { | 
|  | 5900 | auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
|  | 5901 | auto &&TaskLoopCodeGen = [&S](CodeGenFunction &CGF, | 
|  | 5902 | PrePostActionTy &Action) { | 
|  | 5903 | Action.Enter(CGF); | 
|  | 5904 | CGF.EmitOMPTaskLoopBasedDirective(S); | 
|  | 5905 | }; | 
|  | 5906 | OMPLexicalScope Scope(CGF, S, OMPD_parallel, /*EmitPreInitStmt=*/false); | 
|  | 5907 | CGM.getOpenMPRuntime().emitMasterRegion(CGF, TaskLoopCodeGen, | 
|  | 5908 | S.getBeginLoc()); | 
|  | 5909 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 5910 | auto LPCRegion = | 
|  | 5911 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); | 
| Alexey Bataev | 14a388f | 2019-10-25 10:27:13 -0400 | [diff] [blame] | 5912 | emitCommonOMPParallelDirective(*this, S, OMPD_master_taskloop_simd, CodeGen, | 
|  | 5913 | emitEmptyBoundParameters); | 
|  | 5914 | } | 
|  | 5915 |  | 
| Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 5916 | // Generate the instructions for '#pragma omp target update' directive. | 
|  | 5917 | void CodeGenFunction::EmitOMPTargetUpdateDirective( | 
|  | 5918 | const OMPTargetUpdateDirective &S) { | 
| Samuel Antao | 8d2d730 | 2016-05-26 18:30:22 +0000 | [diff] [blame] | 5919 | // If we don't have target devices, don't bother emitting the data mapping | 
|  | 5920 | // code. | 
|  | 5921 | if (CGM.getLangOpts().OMPTargetTriples.empty()) | 
|  | 5922 | return; | 
|  | 5923 |  | 
|  | 5924 | // Check if we have any if clause associated with the directive. | 
|  | 5925 | const Expr *IfCond = nullptr; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5926 | if (const auto *C = S.getSingleClause<OMPIfClause>()) | 
| Samuel Antao | 8d2d730 | 2016-05-26 18:30:22 +0000 | [diff] [blame] | 5927 | IfCond = C->getCondition(); | 
|  | 5928 |  | 
|  | 5929 | // Check if we have any device clause associated with the directive. | 
|  | 5930 | const Expr *Device = nullptr; | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5931 | if (const auto *C = S.getSingleClause<OMPDeviceClause>()) | 
| Samuel Antao | 8d2d730 | 2016-05-26 18:30:22 +0000 | [diff] [blame] | 5932 | Device = C->getDevice(); | 
|  | 5933 |  | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5934 | OMPLexicalScope Scope(*this, S, OMPD_task); | 
| Alexey Bataev | d2202ca | 2017-12-27 17:58:32 +0000 | [diff] [blame] | 5935 | CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device); | 
| Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 5936 | } | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 5937 |  | 
|  | 5938 | void CodeGenFunction::EmitSimpleOMPExecutableDirective( | 
|  | 5939 | const OMPExecutableDirective &D) { | 
|  | 5940 | if (!D.hasAssociatedStmt() || !D.getAssociatedStmt()) | 
|  | 5941 | return; | 
| Akira Hatanaka | 9f37c0e | 2019-12-03 13:07:22 -0800 | [diff] [blame] | 5942 | auto &&CodeGen = [&D](CodeGenFunction &CGF, PrePostActionTy &Action) { | 
| Alexey Bataev | b3998a0 | 2020-03-09 08:55:57 -0400 | [diff] [blame] | 5943 | OMPPrivateScope GlobalsScope(CGF); | 
|  | 5944 | if (isOpenMPTaskingDirective(D.getDirectiveKind())) { | 
|  | 5945 | // Capture global firstprivates to avoid crash. | 
|  | 5946 | for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) { | 
|  | 5947 | for (const Expr *Ref : C->varlists()) { | 
|  | 5948 | const auto *DRE = cast<DeclRefExpr>(Ref->IgnoreParenImpCasts()); | 
|  | 5949 | if (!DRE) | 
|  | 5950 | continue; | 
|  | 5951 | const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()); | 
|  | 5952 | if (!VD || VD->hasLocalStorage()) | 
|  | 5953 | continue; | 
|  | 5954 | if (!CGF.LocalDeclMap.count(VD)) { | 
|  | 5955 | LValue GlobLVal = CGF.EmitLValue(Ref); | 
|  | 5956 | GlobalsScope.addPrivate( | 
|  | 5957 | VD, [&GlobLVal, &CGF]() { return GlobLVal.getAddress(CGF); }); | 
|  | 5958 | } | 
|  | 5959 | } | 
|  | 5960 | } | 
|  | 5961 | } | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 5962 | if (isOpenMPSimdDirective(D.getDirectiveKind())) { | 
| Alexey Bataev | b3998a0 | 2020-03-09 08:55:57 -0400 | [diff] [blame] | 5963 | (void)GlobalsScope.Privatize(); | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 5964 | emitOMPSimdRegion(CGF, cast<OMPLoopDirective>(D), Action); | 
|  | 5965 | } else { | 
|  | 5966 | if (const auto *LD = dyn_cast<OMPLoopDirective>(&D)) { | 
| Alexey Bataev | ddf3db9 | 2018-04-13 17:31:06 +0000 | [diff] [blame] | 5967 | for (const Expr *E : LD->counters()) { | 
| Simon Pilgrim | 93431f9 | 2020-01-11 16:00:17 +0000 | [diff] [blame] | 5968 | const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); | 
| Alexey Bataev | 6ab5bb1 | 2018-10-29 15:01:58 +0000 | [diff] [blame] | 5969 | if (!VD->hasLocalStorage() && !CGF.LocalDeclMap.count(VD)) { | 
|  | 5970 | LValue GlobLVal = CGF.EmitLValue(E); | 
| Alexey Bataev | b3998a0 | 2020-03-09 08:55:57 -0400 | [diff] [blame] | 5971 | GlobalsScope.addPrivate( | 
| Akira Hatanaka | f139ae3 | 2019-12-03 15:17:01 -0800 | [diff] [blame] | 5972 | VD, [&GlobLVal, &CGF]() { return GlobLVal.getAddress(CGF); }); | 
| Alexey Bataev | 6ab5bb1 | 2018-10-29 15:01:58 +0000 | [diff] [blame] | 5973 | } | 
| Bjorn Pettersson | 6c2d83b | 2018-10-30 08:49:26 +0000 | [diff] [blame] | 5974 | if (isa<OMPCapturedExprDecl>(VD)) { | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 5975 | // Emit only those that were not explicitly referenced in clauses. | 
|  | 5976 | if (!CGF.LocalDeclMap.count(VD)) | 
|  | 5977 | CGF.EmitVarDecl(*VD); | 
|  | 5978 | } | 
|  | 5979 | } | 
| Alexey Bataev | f138fda | 2018-08-13 19:04:24 +0000 | [diff] [blame] | 5980 | for (const auto *C : D.getClausesOfKind<OMPOrderedClause>()) { | 
|  | 5981 | if (!C->getNumForLoops()) | 
|  | 5982 | continue; | 
|  | 5983 | for (unsigned I = LD->getCollapsedNumber(), | 
|  | 5984 | E = C->getLoopNumIterations().size(); | 
|  | 5985 | I < E; ++I) { | 
|  | 5986 | if (const auto *VD = dyn_cast<OMPCapturedExprDecl>( | 
| Mike Rice | 0ed4666 | 2018-09-20 17:19:41 +0000 | [diff] [blame] | 5987 | cast<DeclRefExpr>(C->getLoopCounter(I))->getDecl())) { | 
| Alexey Bataev | f138fda | 2018-08-13 19:04:24 +0000 | [diff] [blame] | 5988 | // Emit only those that were not explicitly referenced in clauses. | 
|  | 5989 | if (!CGF.LocalDeclMap.count(VD)) | 
|  | 5990 | CGF.EmitVarDecl(*VD); | 
|  | 5991 | } | 
|  | 5992 | } | 
|  | 5993 | } | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 5994 | } | 
| Alexey Bataev | b3998a0 | 2020-03-09 08:55:57 -0400 | [diff] [blame] | 5995 | (void)GlobalsScope.Privatize(); | 
| Alexey Bataev | 475a744 | 2018-01-12 19:39:11 +0000 | [diff] [blame] | 5996 | CGF.EmitStmt(D.getInnermostCapturedStmt()->getCapturedStmt()); | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 5997 | } | 
|  | 5998 | }; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 5999 | { | 
|  | 6000 | auto LPCRegion = | 
|  | 6001 | CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, D); | 
|  | 6002 | OMPSimdLexicalScope Scope(*this, D); | 
|  | 6003 | CGM.getOpenMPRuntime().emitInlinedDirective( | 
|  | 6004 | *this, | 
|  | 6005 | isOpenMPSimdDirective(D.getDirectiveKind()) ? OMPD_simd | 
|  | 6006 | : D.getDirectiveKind(), | 
|  | 6007 | CodeGen); | 
|  | 6008 | } | 
|  | 6009 | // Check for outer lastprivate conditional update. | 
|  | 6010 | checkForLastprivateConditionalUpdate(*this, D); | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 6011 | } |