| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 1 | //===----- CGOpenMPRuntime.h - Interface to OpenMP Runtimes -----*- C++ -*-===// | 
|  | 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 provides a class for OpenMP runtime code generation. | 
|  | 10 | // | 
|  | 11 | //===----------------------------------------------------------------------===// | 
|  | 12 |  | 
| Benjamin Kramer | 2f5db8b | 2014-08-13 16:25:19 +0000 | [diff] [blame] | 13 | #ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H | 
|  | 14 | #define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 15 |  | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 16 | #include "CGValue.h" | 
| Richard Trieu | f8b8b39 | 2019-01-11 01:32:35 +0000 | [diff] [blame] | 17 | #include "clang/AST/DeclOpenMP.h" | 
| Jordan Rupprecht | 5269091 | 2019-10-01 22:30:10 +0000 | [diff] [blame] | 18 | #include "clang/AST/GlobalDecl.h" | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 19 | #include "clang/AST/Type.h" | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 20 | #include "clang/Basic/OpenMPKinds.h" | 
| Chandler Carruth | 0d9593d | 2015-01-14 11:29:14 +0000 | [diff] [blame] | 21 | #include "clang/Basic/SourceLocation.h" | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 22 | #include "llvm/ADT/DenseMap.h" | 
| Alexey Bataev | 4558842 | 2020-01-07 14:11:45 -0500 | [diff] [blame] | 23 | #include "llvm/ADT/SmallPtrSet.h" | 
| Alexey Bataev | 3a3bf0b | 2014-09-22 10:01:53 +0000 | [diff] [blame] | 24 | #include "llvm/ADT/StringMap.h" | 
| Alexey Bataev | 2a6f3f5 | 2018-11-07 19:11:14 +0000 | [diff] [blame] | 25 | #include "llvm/ADT/StringSet.h" | 
| Johannes Doerfert | 6c5d1f40 | 2019-12-25 18:15:36 -0600 | [diff] [blame] | 26 | #include "llvm/Frontend/OpenMP/OMPConstants.h" | 
| Benjamin Kramer | 8fdba91 | 2016-02-02 14:24:21 +0000 | [diff] [blame] | 27 | #include "llvm/IR/Function.h" | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 28 | #include "llvm/IR/ValueHandle.h" | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame^] | 29 | #include "llvm/Support/AtomicOrdering.h" | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 30 |  | 
|  | 31 | namespace llvm { | 
|  | 32 | class ArrayType; | 
|  | 33 | class Constant; | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 34 | class FunctionType; | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 35 | class GlobalVariable; | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 36 | class StructType; | 
|  | 37 | class Type; | 
|  | 38 | class Value; | 
|  | 39 | } // namespace llvm | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 40 |  | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 41 | namespace clang { | 
| Alexey Bataev | cc37cc1 | 2014-11-20 04:34:54 +0000 | [diff] [blame] | 42 | class Expr; | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 43 | class OMPDependClause; | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 44 | class OMPExecutableDirective; | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 45 | class OMPLoopDirective; | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 46 | class VarDecl; | 
| Alexey Bataev | c5b1d32 | 2016-03-04 09:22:22 +0000 | [diff] [blame] | 47 | class OMPDeclareReductionDecl; | 
|  | 48 | class IdentifierInfo; | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 49 |  | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 50 | namespace CodeGen { | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 51 | class Address; | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 52 | class CodeGenFunction; | 
|  | 53 | class CodeGenModule; | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 54 |  | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 55 | /// A basic class for pre|post-action for advanced codegen sequence for OpenMP | 
|  | 56 | /// region. | 
|  | 57 | class PrePostActionTy { | 
|  | 58 | public: | 
|  | 59 | explicit PrePostActionTy() {} | 
|  | 60 | virtual void Enter(CodeGenFunction &CGF) {} | 
|  | 61 | virtual void Exit(CodeGenFunction &CGF) {} | 
|  | 62 | virtual ~PrePostActionTy() {} | 
|  | 63 | }; | 
|  | 64 |  | 
|  | 65 | /// Class provides a way to call simple version of codegen for OpenMP region, or | 
|  | 66 | /// an advanced with possible pre|post-actions in codegen. | 
|  | 67 | class RegionCodeGenTy final { | 
|  | 68 | intptr_t CodeGen; | 
|  | 69 | typedef void (*CodeGenTy)(intptr_t, CodeGenFunction &, PrePostActionTy &); | 
|  | 70 | CodeGenTy Callback; | 
|  | 71 | mutable PrePostActionTy *PrePostAction; | 
|  | 72 | RegionCodeGenTy() = delete; | 
|  | 73 | RegionCodeGenTy &operator=(const RegionCodeGenTy &) = delete; | 
|  | 74 | template <typename Callable> | 
|  | 75 | static void CallbackFn(intptr_t CodeGen, CodeGenFunction &CGF, | 
|  | 76 | PrePostActionTy &Action) { | 
|  | 77 | return (*reinterpret_cast<Callable *>(CodeGen))(CGF, Action); | 
|  | 78 | } | 
|  | 79 |  | 
|  | 80 | public: | 
|  | 81 | template <typename Callable> | 
|  | 82 | RegionCodeGenTy( | 
|  | 83 | Callable &&CodeGen, | 
| Justin Lebar | 027eb71 | 2020-02-10 23:23:44 -0800 | [diff] [blame] | 84 | std::enable_if_t<!std::is_same<std::remove_reference_t<Callable>, | 
|  | 85 | RegionCodeGenTy>::value> * = nullptr) | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 86 | : CodeGen(reinterpret_cast<intptr_t>(&CodeGen)), | 
| Justin Lebar | 027eb71 | 2020-02-10 23:23:44 -0800 | [diff] [blame] | 87 | Callback(CallbackFn<std::remove_reference_t<Callable>>), | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 88 | PrePostAction(nullptr) {} | 
|  | 89 | void setAction(PrePostActionTy &Action) const { PrePostAction = &Action; } | 
|  | 90 | void operator()(CodeGenFunction &CGF) const; | 
|  | 91 | }; | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 92 |  | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 93 | struct OMPTaskDataTy final { | 
|  | 94 | SmallVector<const Expr *, 4> PrivateVars; | 
|  | 95 | SmallVector<const Expr *, 4> PrivateCopies; | 
|  | 96 | SmallVector<const Expr *, 4> FirstprivateVars; | 
|  | 97 | SmallVector<const Expr *, 4> FirstprivateCopies; | 
|  | 98 | SmallVector<const Expr *, 4> FirstprivateInits; | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 99 | SmallVector<const Expr *, 4> LastprivateVars; | 
|  | 100 | SmallVector<const Expr *, 4> LastprivateCopies; | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 101 | SmallVector<const Expr *, 4> ReductionVars; | 
|  | 102 | SmallVector<const Expr *, 4> ReductionCopies; | 
|  | 103 | SmallVector<const Expr *, 4> ReductionOps; | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 104 | SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 4> Dependences; | 
|  | 105 | llvm::PointerIntPair<llvm::Value *, 1, bool> Final; | 
|  | 106 | llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule; | 
| Alexey Bataev | 1e1e286 | 2016-05-10 12:21:02 +0000 | [diff] [blame] | 107 | llvm::PointerIntPair<llvm::Value *, 1, bool> Priority; | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 108 | llvm::Value *Reductions = nullptr; | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 109 | unsigned NumberOfParts = 0; | 
|  | 110 | bool Tied = true; | 
|  | 111 | bool Nogroup = false; | 
|  | 112 | }; | 
|  | 113 |  | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 114 | /// Class intended to support codegen of all kind of the reduction clauses. | 
|  | 115 | class ReductionCodeGen { | 
|  | 116 | private: | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 117 | /// Data required for codegen of reduction clauses. | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 118 | struct ReductionData { | 
|  | 119 | /// Reference to the original shared item. | 
|  | 120 | const Expr *Ref = nullptr; | 
|  | 121 | /// Helper expression for generation of private copy. | 
|  | 122 | const Expr *Private = nullptr; | 
|  | 123 | /// Helper expression for generation reduction operation. | 
|  | 124 | const Expr *ReductionOp = nullptr; | 
|  | 125 | ReductionData(const Expr *Ref, const Expr *Private, const Expr *ReductionOp) | 
|  | 126 | : Ref(Ref), Private(Private), ReductionOp(ReductionOp) {} | 
|  | 127 | }; | 
|  | 128 | /// List of reduction-based clauses. | 
|  | 129 | SmallVector<ReductionData, 4> ClausesData; | 
|  | 130 |  | 
|  | 131 | /// List of addresses of original shared variables/expressions. | 
|  | 132 | SmallVector<std::pair<LValue, LValue>, 4> SharedAddresses; | 
|  | 133 | /// Sizes of the reduction items in chars. | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 134 | SmallVector<std::pair<llvm::Value *, llvm::Value *>, 4> Sizes; | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 135 | /// Base declarations for the reduction items. | 
|  | 136 | SmallVector<const VarDecl *, 4> BaseDecls; | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 137 |  | 
| Alexander Kornienko | 2a8c18d | 2018-04-06 15:14:32 +0000 | [diff] [blame] | 138 | /// Emits lvalue for shared expression. | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 139 | LValue emitSharedLValue(CodeGenFunction &CGF, const Expr *E); | 
|  | 140 | /// Emits upper bound for shared expression (if array section). | 
|  | 141 | LValue emitSharedLValueUB(CodeGenFunction &CGF, const Expr *E); | 
|  | 142 | /// Performs aggregate initialization. | 
|  | 143 | /// \param N Number of reduction item in the common list. | 
|  | 144 | /// \param PrivateAddr Address of the corresponding private item. | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 145 | /// \param SharedLVal Address of the original shared variable. | 
|  | 146 | /// \param DRD Declare reduction construct used for reduction item. | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 147 | void emitAggregateInitialization(CodeGenFunction &CGF, unsigned N, | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 148 | Address PrivateAddr, LValue SharedLVal, | 
|  | 149 | const OMPDeclareReductionDecl *DRD); | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 150 |  | 
|  | 151 | public: | 
|  | 152 | ReductionCodeGen(ArrayRef<const Expr *> Shareds, | 
|  | 153 | ArrayRef<const Expr *> Privates, | 
|  | 154 | ArrayRef<const Expr *> ReductionOps); | 
|  | 155 | /// Emits lvalue for a reduction item. | 
|  | 156 | /// \param N Number of the reduction item. | 
|  | 157 | void emitSharedLValue(CodeGenFunction &CGF, unsigned N); | 
|  | 158 | /// Emits the code for the variable-modified type, if required. | 
|  | 159 | /// \param N Number of the reduction item. | 
|  | 160 | void emitAggregateType(CodeGenFunction &CGF, unsigned N); | 
|  | 161 | /// Emits the code for the variable-modified type, if required. | 
|  | 162 | /// \param N Number of the reduction item. | 
|  | 163 | /// \param Size Size of the type in chars. | 
|  | 164 | void emitAggregateType(CodeGenFunction &CGF, unsigned N, llvm::Value *Size); | 
|  | 165 | /// Performs initialization of the private copy for the reduction item. | 
|  | 166 | /// \param N Number of the reduction item. | 
|  | 167 | /// \param PrivateAddr Address of the corresponding private item. | 
|  | 168 | /// \param DefaultInit Default initialization sequence that should be | 
|  | 169 | /// performed if no reduction specific initialization is found. | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 170 | /// \param SharedLVal Address of the original shared variable. | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 171 | void | 
|  | 172 | emitInitialization(CodeGenFunction &CGF, unsigned N, Address PrivateAddr, | 
|  | 173 | LValue SharedLVal, | 
|  | 174 | llvm::function_ref<bool(CodeGenFunction &)> DefaultInit); | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 175 | /// Returns true if the private copy requires cleanups. | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 176 | bool needCleanups(unsigned N); | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 177 | /// Emits cleanup code for the reduction item. | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 178 | /// \param N Number of the reduction item. | 
|  | 179 | /// \param PrivateAddr Address of the corresponding private item. | 
|  | 180 | void emitCleanups(CodeGenFunction &CGF, unsigned N, Address PrivateAddr); | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 181 | /// Adjusts \p PrivatedAddr for using instead of the original variable | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 182 | /// address in normal operations. | 
|  | 183 | /// \param N Number of the reduction item. | 
|  | 184 | /// \param PrivateAddr Address of the corresponding private item. | 
|  | 185 | Address adjustPrivateAddress(CodeGenFunction &CGF, unsigned N, | 
|  | 186 | Address PrivateAddr); | 
|  | 187 | /// Returns LValue for the reduction item. | 
|  | 188 | LValue getSharedLValue(unsigned N) const { return SharedAddresses[N].first; } | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 189 | /// Returns the size of the reduction item (in chars and total number of | 
|  | 190 | /// elements in the item), or nullptr, if the size is a constant. | 
|  | 191 | std::pair<llvm::Value *, llvm::Value *> getSizes(unsigned N) const { | 
|  | 192 | return Sizes[N]; | 
|  | 193 | } | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 194 | /// Returns the base declaration of the reduction item. | 
|  | 195 | const VarDecl *getBaseDecl(unsigned N) const { return BaseDecls[N]; } | 
| Alexey Bataev | 1c44e15 | 2018-03-06 18:59:43 +0000 | [diff] [blame] | 196 | /// Returns the base declaration of the reduction item. | 
|  | 197 | const Expr *getRefExpr(unsigned N) const { return ClausesData[N].Ref; } | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 198 | /// Returns true if the initialization of the reduction item uses initializer | 
|  | 199 | /// from declare reduction construct. | 
|  | 200 | bool usesReductionInitializer(unsigned N) const; | 
| Alexey Bataev | 5c40bec | 2017-07-13 13:36:14 +0000 | [diff] [blame] | 201 | }; | 
|  | 202 |  | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 203 | class CGOpenMPRuntime { | 
| Alexey Bataev | 4f4bf7c | 2018-03-15 15:47:20 +0000 | [diff] [blame] | 204 | public: | 
|  | 205 | /// Allows to disable automatic handling of functions used in target regions | 
|  | 206 | /// as those marked as `omp declare target`. | 
|  | 207 | class DisableAutoDeclareTargetRAII { | 
|  | 208 | CodeGenModule &CGM; | 
|  | 209 | bool SavedShouldMarkAsGlobal; | 
|  | 210 |  | 
|  | 211 | public: | 
|  | 212 | DisableAutoDeclareTargetRAII(CodeGenModule &CGM); | 
|  | 213 | ~DisableAutoDeclareTargetRAII(); | 
|  | 214 | }; | 
|  | 215 |  | 
| Alexey Bataev | 0860db9 | 2019-12-19 10:01:10 -0500 | [diff] [blame] | 216 | /// Manages list of nontemporal decls for the specified directive. | 
|  | 217 | class NontemporalDeclsRAII { | 
|  | 218 | CodeGenModule &CGM; | 
|  | 219 | const bool NeedToPush; | 
|  | 220 |  | 
|  | 221 | public: | 
|  | 222 | NontemporalDeclsRAII(CodeGenModule &CGM, const OMPLoopDirective &S); | 
|  | 223 | ~NontemporalDeclsRAII(); | 
|  | 224 | }; | 
|  | 225 |  | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 226 | /// Maps the expression for the lastprivate variable to the global copy used | 
|  | 227 | /// to store new value because original variables are not mapped in inner | 
|  | 228 | /// parallel regions. Only private copies are captured but we need also to | 
|  | 229 | /// store private copy in shared address. | 
|  | 230 | /// Also, stores the expression for the private loop counter and it | 
|  | 231 | /// threaprivate name. | 
|  | 232 | struct LastprivateConditionalData { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 233 | llvm::MapVector<CanonicalDeclPtr<const Decl>, SmallString<16>> | 
|  | 234 | DeclToUniqueName; | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 235 | LValue IVLVal; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 236 | llvm::Function *Fn = nullptr; | 
|  | 237 | bool Disabled = false; | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 238 | }; | 
|  | 239 | /// Manages list of lastprivate conditional decls for the specified directive. | 
|  | 240 | class LastprivateConditionalRAII { | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 241 | enum class ActionToDo { | 
|  | 242 | DoNotPush, | 
|  | 243 | PushAsLastprivateConditional, | 
|  | 244 | DisableLastprivateConditional, | 
|  | 245 | }; | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 246 | CodeGenModule &CGM; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 247 | ActionToDo Action = ActionToDo::DoNotPush; | 
|  | 248 |  | 
|  | 249 | /// Check and try to disable analysis of inner regions for changes in | 
|  | 250 | /// lastprivate conditional. | 
|  | 251 | void tryToDisableInnerAnalysis(const OMPExecutableDirective &S, | 
|  | 252 | llvm::DenseSet<CanonicalDeclPtr<const Decl>> | 
|  | 253 | &NeedToAddForLPCsAsDisabled) const; | 
|  | 254 |  | 
|  | 255 | LastprivateConditionalRAII(CodeGenFunction &CGF, | 
|  | 256 | const OMPExecutableDirective &S); | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 257 |  | 
|  | 258 | public: | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 259 | explicit LastprivateConditionalRAII(CodeGenFunction &CGF, | 
|  | 260 | const OMPExecutableDirective &S, | 
|  | 261 | LValue IVLVal); | 
|  | 262 | static LastprivateConditionalRAII disable(CodeGenFunction &CGF, | 
|  | 263 | const OMPExecutableDirective &S); | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 264 | ~LastprivateConditionalRAII(); | 
|  | 265 | }; | 
|  | 266 |  | 
| Arpith Chacko Jacob | 5c309e4 | 2016-03-22 01:48:56 +0000 | [diff] [blame] | 267 | protected: | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 268 | CodeGenModule &CGM; | 
| Alexey Bataev | 18fa232 | 2018-05-02 14:20:50 +0000 | [diff] [blame] | 269 | StringRef FirstSeparator, Separator; | 
|  | 270 |  | 
|  | 271 | /// Constructor allowing to redefine the name separator for the variables. | 
|  | 272 | explicit CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator, | 
|  | 273 | StringRef Separator); | 
| Arpith Chacko Jacob | 5c309e4 | 2016-03-22 01:48:56 +0000 | [diff] [blame] | 274 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 275 | /// Creates offloading entry for the provided entry ID \a ID, | 
| Samuel Antao | f83efdb | 2017-01-05 16:02:49 +0000 | [diff] [blame] | 276 | /// address \a Addr, size \a Size, and flags \a Flags. | 
| Arpith Chacko Jacob | 5c309e4 | 2016-03-22 01:48:56 +0000 | [diff] [blame] | 277 | virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr, | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 278 | uint64_t Size, int32_t Flags, | 
|  | 279 | llvm::GlobalValue::LinkageTypes Linkage); | 
| Arpith Chacko Jacob | 5c309e4 | 2016-03-22 01:48:56 +0000 | [diff] [blame] | 280 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 281 | /// Helper to emit outlined function for 'target' directive. | 
| Arpith Chacko Jacob | 5c309e4 | 2016-03-22 01:48:56 +0000 | [diff] [blame] | 282 | /// \param D Directive to emit. | 
|  | 283 | /// \param ParentName Name of the function that encloses the target region. | 
|  | 284 | /// \param OutlinedFn Outlined function value to be defined by this call. | 
|  | 285 | /// \param OutlinedFnID Outlined function ID value to be defined by this call. | 
|  | 286 | /// \param IsOffloadEntry True if the outlined function is an offload entry. | 
|  | 287 | /// \param CodeGen Lambda codegen specific to an accelerator device. | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 288 | /// An outlined function may not be an entry if, e.g. the if clause always | 
| Arpith Chacko Jacob | 5c309e4 | 2016-03-22 01:48:56 +0000 | [diff] [blame] | 289 | /// evaluates to false. | 
|  | 290 | virtual void emitTargetOutlinedFunctionHelper(const OMPExecutableDirective &D, | 
|  | 291 | StringRef ParentName, | 
|  | 292 | llvm::Function *&OutlinedFn, | 
|  | 293 | llvm::Constant *&OutlinedFnID, | 
|  | 294 | bool IsOffloadEntry, | 
|  | 295 | const RegionCodeGenTy &CodeGen); | 
|  | 296 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 297 | /// Emits object of ident_t type with info for source location. | 
| Arpith Chacko Jacob | bb36fe8 | 2017-01-10 15:42:51 +0000 | [diff] [blame] | 298 | /// \param Flags Flags for OpenMP location. | 
|  | 299 | /// | 
|  | 300 | llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 301 | unsigned Flags = 0); | 
|  | 302 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 303 | /// Returns pointer to ident_t type. | 
| Arpith Chacko Jacob | bb36fe8 | 2017-01-10 15:42:51 +0000 | [diff] [blame] | 304 | llvm::Type *getIdentTyPointerTy(); | 
|  | 305 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 306 | /// Gets thread id value for the current thread. | 
| Arpith Chacko Jacob | bb36fe8 | 2017-01-10 15:42:51 +0000 | [diff] [blame] | 307 | /// | 
|  | 308 | llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc); | 
|  | 309 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 310 | /// Get the function name of an outlined region. | 
| Arpith Chacko Jacob | bb36fe8 | 2017-01-10 15:42:51 +0000 | [diff] [blame] | 311 | //  The name can be customized depending on the target. | 
|  | 312 | // | 
|  | 313 | virtual StringRef getOutlinedHelperName() const { return ".omp_outlined."; } | 
|  | 314 |  | 
| Alexey Bataev | 3c595a6 | 2017-08-14 15:01:03 +0000 | [diff] [blame] | 315 | /// Emits \p Callee function call with arguments \p Args with location \p Loc. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 316 | void emitCall(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 317 | llvm::FunctionCallee Callee, | 
| Alexey Bataev | 7ef47a6 | 2018-02-22 18:33:31 +0000 | [diff] [blame] | 318 | ArrayRef<llvm::Value *> Args = llvm::None) const; | 
| Alexey Bataev | 3c595a6 | 2017-08-14 15:01:03 +0000 | [diff] [blame] | 319 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 320 | /// Emits address of the word in a memory where current thread id is | 
| Alexey Bataev | b7f3cba | 2018-03-19 17:04:07 +0000 | [diff] [blame] | 321 | /// stored. | 
|  | 322 | virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc); | 
|  | 323 |  | 
| Alexey Bataev | fd006c4 | 2018-10-05 15:08:53 +0000 | [diff] [blame] | 324 | void setLocThreadIdInsertPt(CodeGenFunction &CGF, | 
|  | 325 | bool AtCurrentPoint = false); | 
|  | 326 | void clearLocThreadIdInsertPt(CodeGenFunction &CGF); | 
|  | 327 |  | 
| Alexey Bataev | ceeaa48 | 2018-11-21 21:04:34 +0000 | [diff] [blame] | 328 | /// Check if the default location must be constant. | 
|  | 329 | /// Default is false to support OMPT/OMPD. | 
|  | 330 | virtual bool isDefaultLocationConstant() const { return false; } | 
|  | 331 |  | 
|  | 332 | /// Returns additional flags that can be stored in reserved_2 field of the | 
|  | 333 | /// default location. | 
|  | 334 | virtual unsigned getDefaultLocationReserved2Flags() const { return 0; } | 
|  | 335 |  | 
| Alexey Bataev | c2cd2d4 | 2019-10-10 17:28:10 +0000 | [diff] [blame] | 336 | /// Tries to emit declare variant function for \p OldGD from \p NewGD. | 
|  | 337 | /// \param OrigAddr LLVM IR value for \p OldGD. | 
|  | 338 | /// \param IsForDefinition true, if requested emission for the definition of | 
|  | 339 | /// \p OldGD. | 
|  | 340 | /// \returns true, was able to emit a definition function for \p OldGD, which | 
|  | 341 | /// points to \p NewGD. | 
|  | 342 | virtual bool tryEmitDeclareVariant(const GlobalDecl &NewGD, | 
|  | 343 | const GlobalDecl &OldGD, | 
|  | 344 | llvm::GlobalValue *OrigAddr, | 
|  | 345 | bool IsForDefinition); | 
|  | 346 |  | 
| Alexey Bataev | c3028ca | 2018-12-04 15:03:25 +0000 | [diff] [blame] | 347 | /// Returns default flags for the barriers depending on the directive, for | 
|  | 348 | /// which this barier is going to be emitted. | 
|  | 349 | static unsigned getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind); | 
|  | 350 |  | 
| Alexey Bataev | a116602 | 2018-11-27 21:24:54 +0000 | [diff] [blame] | 351 | /// Get the LLVM type for the critical name. | 
|  | 352 | llvm::ArrayType *getKmpCriticalNameTy() const {return KmpCriticalNameTy;} | 
|  | 353 |  | 
|  | 354 | /// Returns corresponding lock object for the specified critical region | 
|  | 355 | /// name. If the lock object does not exist it is created, otherwise the | 
|  | 356 | /// reference to the existing copy is returned. | 
|  | 357 | /// \param CriticalName Name of the critical region. | 
|  | 358 | /// | 
|  | 359 | llvm::Value *getCriticalRegionLock(StringRef CriticalName); | 
|  | 360 |  | 
| Arpith Chacko Jacob | 5c309e4 | 2016-03-22 01:48:56 +0000 | [diff] [blame] | 361 | private: | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 362 | /// Default const ident_t object used for initialization of all other | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 363 | /// ident_t objects. | 
| Alexey Bataev | c5b1d32 | 2016-03-04 09:22:22 +0000 | [diff] [blame] | 364 | llvm::Constant *DefaultOpenMPPSource = nullptr; | 
| Alexey Bataev | ceeaa48 | 2018-11-21 21:04:34 +0000 | [diff] [blame] | 365 | using FlagsTy = std::pair<unsigned, unsigned>; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 366 | /// Map of flags and corresponding default locations. | 
| Alexey Bataev | ceeaa48 | 2018-11-21 21:04:34 +0000 | [diff] [blame] | 367 | using OpenMPDefaultLocMapTy = llvm::DenseMap<FlagsTy, llvm::Value *>; | 
| Alexey Bataev | 15007ba | 2014-05-07 06:18:01 +0000 | [diff] [blame] | 368 | OpenMPDefaultLocMapTy OpenMPDefaultLocMap; | 
| Alexey Bataev | 50b3c95 | 2016-02-19 10:38:26 +0000 | [diff] [blame] | 369 | Address getOrCreateDefaultLocation(unsigned Flags); | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 370 |  | 
| Alexey Bataev | a4fa0b8 | 2018-04-16 17:59:34 +0000 | [diff] [blame] | 371 | QualType IdentQTy; | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 372 | llvm::StructType *IdentTy = nullptr; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 373 | /// Map for SourceLocation and OpenMP runtime library debug locations. | 
| Alexey Bataev | f002aca | 2014-05-30 05:48:40 +0000 | [diff] [blame] | 374 | typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy; | 
|  | 375 | OpenMPDebugLocMapTy OpenMPDebugLocMap; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 376 | /// The type for a microtask which gets passed to __kmpc_fork_call(). | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 377 | /// Original representation is: | 
|  | 378 | /// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...); | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 379 | llvm::FunctionType *Kmpc_MicroTy = nullptr; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 380 | /// Stores debug location and ThreadID for the function. | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 381 | struct DebugLocThreadIdTy { | 
|  | 382 | llvm::Value *DebugLoc; | 
|  | 383 | llvm::Value *ThreadID; | 
| Alexey Bataev | fd006c4 | 2018-10-05 15:08:53 +0000 | [diff] [blame] | 384 | /// Insert point for the service instructions. | 
|  | 385 | llvm::AssertingVH<llvm::Instruction> ServiceInsertPt = nullptr; | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 386 | }; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 387 | /// Map of local debug location, ThreadId and functions. | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 388 | typedef llvm::DenseMap<llvm::Function *, DebugLocThreadIdTy> | 
|  | 389 | OpenMPLocThreadIDMapTy; | 
|  | 390 | OpenMPLocThreadIDMapTy OpenMPLocThreadIDMap; | 
| Alexey Bataev | c5b1d32 | 2016-03-04 09:22:22 +0000 | [diff] [blame] | 391 | /// Map of UDRs and corresponding combiner/initializer. | 
|  | 392 | typedef llvm::DenseMap<const OMPDeclareReductionDecl *, | 
|  | 393 | std::pair<llvm::Function *, llvm::Function *>> | 
|  | 394 | UDRMapTy; | 
|  | 395 | UDRMapTy UDRMap; | 
|  | 396 | /// Map of functions and locally defined UDRs. | 
|  | 397 | typedef llvm::DenseMap<llvm::Function *, | 
|  | 398 | SmallVector<const OMPDeclareReductionDecl *, 4>> | 
|  | 399 | FunctionUDRMapTy; | 
|  | 400 | FunctionUDRMapTy FunctionUDRMap; | 
| Michael Kruse | d47b943 | 2019-08-05 18:43:21 +0000 | [diff] [blame] | 401 | /// Map from the user-defined mapper declaration to its corresponding | 
|  | 402 | /// functions. | 
|  | 403 | llvm::DenseMap<const OMPDeclareMapperDecl *, llvm::Function *> UDMMap; | 
|  | 404 | /// Map of functions and their local user-defined mappers. | 
|  | 405 | using FunctionUDMMapTy = | 
|  | 406 | llvm::DenseMap<llvm::Function *, | 
|  | 407 | SmallVector<const OMPDeclareMapperDecl *, 4>>; | 
|  | 408 | FunctionUDMMapTy FunctionUDMMap; | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 409 | /// Maps local variables marked as lastprivate conditional to their internal | 
|  | 410 | /// types. | 
|  | 411 | llvm::DenseMap<llvm::Function *, | 
|  | 412 | llvm::DenseMap<CanonicalDeclPtr<const Decl>, | 
|  | 413 | std::tuple<QualType, const FieldDecl *, | 
|  | 414 | const FieldDecl *, LValue>>> | 
|  | 415 | LastprivateConditionalToTypes; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 416 | /// Type kmp_critical_name, originally defined as typedef kmp_int32 | 
| Alexey Bataev | 3a3bf0b | 2014-09-22 10:01:53 +0000 | [diff] [blame] | 417 | /// kmp_critical_name[8]; | 
|  | 418 | llvm::ArrayType *KmpCriticalNameTy; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 419 | /// An ordered map of auto-generated variables to their unique names. | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 420 | /// It stores variables with the following names: 1) ".gomp_critical_user_" + | 
|  | 421 | /// <critical_section_name> + ".var" for "omp critical" directives; 2) | 
|  | 422 | /// <mangled_name_for_global_var> + ".cache." for cache for threadprivate | 
|  | 423 | /// variables. | 
|  | 424 | llvm::StringMap<llvm::AssertingVH<llvm::Constant>, llvm::BumpPtrAllocator> | 
|  | 425 | InternalVars; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 426 | /// Type typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); | 
| Alexey Bataev | c5b1d32 | 2016-03-04 09:22:22 +0000 | [diff] [blame] | 427 | llvm::Type *KmpRoutineEntryPtrTy = nullptr; | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 428 | QualType KmpRoutineEntryPtrQTy; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 429 | /// Type typedef struct kmp_task { | 
| Alexey Bataev | 8fc69dc | 2015-05-18 07:54:53 +0000 | [diff] [blame] | 430 | ///    void *              shareds; /**< pointer to block of pointers to | 
|  | 431 | ///    shared vars   */ | 
|  | 432 | ///    kmp_routine_entry_t routine; /**< pointer to routine to call for | 
|  | 433 | ///    executing task */ | 
|  | 434 | ///    kmp_int32           part_id; /**< part id for the task */ | 
|  | 435 | ///    kmp_routine_entry_t destructors; /* pointer to function to invoke | 
|  | 436 | ///    deconstructors of firstprivate C++ objects */ | 
|  | 437 | /// } kmp_task_t; | 
|  | 438 | QualType KmpTaskTQTy; | 
| Alexey Bataev | e213f3e | 2017-10-11 15:29:40 +0000 | [diff] [blame] | 439 | /// Saved kmp_task_t for task directive. | 
|  | 440 | QualType SavedKmpTaskTQTy; | 
|  | 441 | /// Saved kmp_task_t for taskloop-based directive. | 
|  | 442 | QualType SavedKmpTaskloopTQTy; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 443 | /// Type typedef struct kmp_depend_info { | 
| Alexey Bataev | 1d2353d | 2015-06-24 11:01:36 +0000 | [diff] [blame] | 444 | ///    kmp_intptr_t               base_addr; | 
|  | 445 | ///    size_t                     len; | 
|  | 446 | ///    struct { | 
|  | 447 | ///             bool                   in:1; | 
|  | 448 | ///             bool                   out:1; | 
|  | 449 | ///    } flags; | 
|  | 450 | /// } kmp_depend_info_t; | 
|  | 451 | QualType KmpDependInfoTy; | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 452 | /// struct kmp_dim {  // loop bounds info casted to kmp_int64 | 
|  | 453 | ///  kmp_int64 lo; // lower | 
|  | 454 | ///  kmp_int64 up; // upper | 
|  | 455 | ///  kmp_int64 st; // stride | 
|  | 456 | /// }; | 
|  | 457 | QualType KmpDimTy; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 458 | /// Type struct __tgt_offload_entry{ | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 459 | ///   void      *addr;       // Pointer to the offload entry info. | 
|  | 460 | ///                          // (function or global) | 
|  | 461 | ///   char      *name;       // Name of the function or global. | 
|  | 462 | ///   size_t     size;       // Size of the entry info (0 if it a function). | 
| Alexey Bataev | 4c11703 | 2020-01-09 09:28:59 -0500 | [diff] [blame] | 463 | ///   int32_t flags; | 
|  | 464 | ///   int32_t reserved; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 465 | /// }; | 
|  | 466 | QualType TgtOffloadEntryQTy; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 467 | /// Entity that registers the offloading constants that were emitted so | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 468 | /// far. | 
|  | 469 | class OffloadEntriesInfoManagerTy { | 
|  | 470 | CodeGenModule &CGM; | 
| Alexey Bataev | 1d2353d | 2015-06-24 11:01:36 +0000 | [diff] [blame] | 471 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 472 | /// Number of entries registered so far. | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 473 | unsigned OffloadingEntriesNum = 0; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 474 |  | 
|  | 475 | public: | 
| Samuel Antao | f83efdb | 2017-01-05 16:02:49 +0000 | [diff] [blame] | 476 | /// Base class of the entries info. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 477 | class OffloadEntryInfo { | 
|  | 478 | public: | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 479 | /// Kind of a given entry. | 
| Reid Kleckner | dc78f95 | 2016-01-11 20:55:16 +0000 | [diff] [blame] | 480 | enum OffloadingEntryInfoKinds : unsigned { | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 481 | /// Entry is a target region. | 
|  | 482 | OffloadingEntryInfoTargetRegion = 0, | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 483 | /// Entry is a declare target variable. | 
|  | 484 | OffloadingEntryInfoDeviceGlobalVar = 1, | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 485 | /// Invalid entry info. | 
|  | 486 | OffloadingEntryInfoInvalid = ~0u | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 487 | }; | 
|  | 488 |  | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 489 | protected: | 
|  | 490 | OffloadEntryInfo() = delete; | 
|  | 491 | explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind) : Kind(Kind) {} | 
| Samuel Antao | f83efdb | 2017-01-05 16:02:49 +0000 | [diff] [blame] | 492 | explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order, | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 493 | uint32_t Flags) | 
| Samuel Antao | f83efdb | 2017-01-05 16:02:49 +0000 | [diff] [blame] | 494 | : Flags(Flags), Order(Order), Kind(Kind) {} | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 495 | ~OffloadEntryInfo() = default; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 496 |  | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 497 | public: | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 498 | bool isValid() const { return Order != ~0u; } | 
|  | 499 | unsigned getOrder() const { return Order; } | 
|  | 500 | OffloadingEntryInfoKinds getKind() const { return Kind; } | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 501 | uint32_t getFlags() const { return Flags; } | 
|  | 502 | void setFlags(uint32_t NewFlags) { Flags = NewFlags; } | 
|  | 503 | llvm::Constant *getAddress() const { | 
|  | 504 | return cast_or_null<llvm::Constant>(Addr); | 
|  | 505 | } | 
|  | 506 | void setAddress(llvm::Constant *V) { | 
|  | 507 | assert(!Addr.pointsToAliveValue() && "Address has been set before!"); | 
|  | 508 | Addr = V; | 
|  | 509 | } | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 510 | static bool classof(const OffloadEntryInfo *Info) { return true; } | 
|  | 511 |  | 
| Samuel Antao | f83efdb | 2017-01-05 16:02:49 +0000 | [diff] [blame] | 512 | private: | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 513 | /// Address of the entity that has to be mapped for offloading. | 
|  | 514 | llvm::WeakTrackingVH Addr; | 
|  | 515 |  | 
| Samuel Antao | f83efdb | 2017-01-05 16:02:49 +0000 | [diff] [blame] | 516 | /// Flags associated with the device global. | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 517 | uint32_t Flags = 0u; | 
| Samuel Antao | f83efdb | 2017-01-05 16:02:49 +0000 | [diff] [blame] | 518 |  | 
|  | 519 | /// Order this entry was emitted. | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 520 | unsigned Order = ~0u; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 521 |  | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 522 | OffloadingEntryInfoKinds Kind = OffloadingEntryInfoInvalid; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 523 | }; | 
|  | 524 |  | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 525 | /// Return true if a there are no entries defined. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 526 | bool empty() const; | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 527 | /// Return number of entries defined so far. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 528 | unsigned size() const { return OffloadingEntriesNum; } | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 529 | OffloadEntriesInfoManagerTy(CodeGenModule &CGM) : CGM(CGM) {} | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 530 |  | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 531 | // | 
|  | 532 | // Target region entries related. | 
|  | 533 | // | 
|  | 534 |  | 
|  | 535 | /// Kind of the target registry entry. | 
|  | 536 | enum OMPTargetRegionEntryKind : uint32_t { | 
|  | 537 | /// Mark the entry as target region. | 
|  | 538 | OMPTargetRegionEntryTargetRegion = 0x0, | 
|  | 539 | /// Mark the entry as a global constructor. | 
|  | 540 | OMPTargetRegionEntryCtor = 0x02, | 
|  | 541 | /// Mark the entry as a global destructor. | 
|  | 542 | OMPTargetRegionEntryDtor = 0x04, | 
|  | 543 | }; | 
|  | 544 |  | 
|  | 545 | /// Target region entries info. | 
|  | 546 | class OffloadEntryInfoTargetRegion final : public OffloadEntryInfo { | 
|  | 547 | /// Address that can be used as the ID of the entry. | 
|  | 548 | llvm::Constant *ID = nullptr; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 549 |  | 
|  | 550 | public: | 
|  | 551 | OffloadEntryInfoTargetRegion() | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 552 | : OffloadEntryInfo(OffloadingEntryInfoTargetRegion) {} | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 553 | explicit OffloadEntryInfoTargetRegion(unsigned Order, | 
|  | 554 | llvm::Constant *Addr, | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 555 | llvm::Constant *ID, | 
|  | 556 | OMPTargetRegionEntryKind Flags) | 
|  | 557 | : OffloadEntryInfo(OffloadingEntryInfoTargetRegion, Order, Flags), | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 558 | ID(ID) { | 
|  | 559 | setAddress(Addr); | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 560 | } | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 561 |  | 
|  | 562 | llvm::Constant *getID() const { return ID; } | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 563 | void setID(llvm::Constant *V) { | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 564 | assert(!ID && "ID has been set before!"); | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 565 | ID = V; | 
|  | 566 | } | 
|  | 567 | static bool classof(const OffloadEntryInfo *Info) { | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 568 | return Info->getKind() == OffloadingEntryInfoTargetRegion; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 569 | } | 
|  | 570 | }; | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 571 |  | 
|  | 572 | /// Initialize target region entry. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 573 | void initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, | 
|  | 574 | StringRef ParentName, unsigned LineNum, | 
| Samuel Antao | 2de62b0 | 2016-02-13 23:35:10 +0000 | [diff] [blame] | 575 | unsigned Order); | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 576 | /// Register target region entry. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 577 | void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, | 
|  | 578 | StringRef ParentName, unsigned LineNum, | 
| Samuel Antao | f83efdb | 2017-01-05 16:02:49 +0000 | [diff] [blame] | 579 | llvm::Constant *Addr, llvm::Constant *ID, | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 580 | OMPTargetRegionEntryKind Flags); | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 581 | /// Return true if a target region entry with the provided information | 
|  | 582 | /// exists. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 583 | bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, | 
| Samuel Antao | 2de62b0 | 2016-02-13 23:35:10 +0000 | [diff] [blame] | 584 | StringRef ParentName, unsigned LineNum) const; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 585 | /// brief Applies action \a Action on all registered entries. | 
|  | 586 | typedef llvm::function_ref<void(unsigned, unsigned, StringRef, unsigned, | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 587 | const OffloadEntryInfoTargetRegion &)> | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 588 | OffloadTargetRegionEntryInfoActTy; | 
|  | 589 | void actOnTargetRegionEntriesInfo( | 
|  | 590 | const OffloadTargetRegionEntryInfoActTy &Action); | 
|  | 591 |  | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 592 | // | 
|  | 593 | // Device global variable entries related. | 
|  | 594 | // | 
|  | 595 |  | 
|  | 596 | /// Kind of the global variable entry.. | 
|  | 597 | enum OMPTargetGlobalVarEntryKind : uint32_t { | 
|  | 598 | /// Mark the entry as a to declare target. | 
|  | 599 | OMPTargetGlobalVarEntryTo = 0x0, | 
| Alexey Bataev | c52f01d | 2018-07-16 20:05:25 +0000 | [diff] [blame] | 600 | /// Mark the entry as a to declare target link. | 
|  | 601 | OMPTargetGlobalVarEntryLink = 0x1, | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 602 | }; | 
|  | 603 |  | 
|  | 604 | /// Device global variable entries info. | 
|  | 605 | class OffloadEntryInfoDeviceGlobalVar final : public OffloadEntryInfo { | 
|  | 606 | /// Type of the global variable. | 
|  | 607 | CharUnits VarSize; | 
|  | 608 | llvm::GlobalValue::LinkageTypes Linkage; | 
|  | 609 |  | 
|  | 610 | public: | 
|  | 611 | OffloadEntryInfoDeviceGlobalVar() | 
|  | 612 | : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar) {} | 
|  | 613 | explicit OffloadEntryInfoDeviceGlobalVar(unsigned Order, | 
|  | 614 | OMPTargetGlobalVarEntryKind Flags) | 
|  | 615 | : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags) {} | 
|  | 616 | explicit OffloadEntryInfoDeviceGlobalVar( | 
|  | 617 | unsigned Order, llvm::Constant *Addr, CharUnits VarSize, | 
|  | 618 | OMPTargetGlobalVarEntryKind Flags, | 
|  | 619 | llvm::GlobalValue::LinkageTypes Linkage) | 
|  | 620 | : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags), | 
|  | 621 | VarSize(VarSize), Linkage(Linkage) { | 
|  | 622 | setAddress(Addr); | 
|  | 623 | } | 
|  | 624 |  | 
|  | 625 | CharUnits getVarSize() const { return VarSize; } | 
|  | 626 | void setVarSize(CharUnits Size) { VarSize = Size; } | 
|  | 627 | llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; } | 
|  | 628 | void setLinkage(llvm::GlobalValue::LinkageTypes LT) { Linkage = LT; } | 
|  | 629 | static bool classof(const OffloadEntryInfo *Info) { | 
|  | 630 | return Info->getKind() == OffloadingEntryInfoDeviceGlobalVar; | 
|  | 631 | } | 
|  | 632 | }; | 
|  | 633 |  | 
|  | 634 | /// Initialize device global variable entry. | 
|  | 635 | void initializeDeviceGlobalVarEntryInfo(StringRef Name, | 
|  | 636 | OMPTargetGlobalVarEntryKind Flags, | 
|  | 637 | unsigned Order); | 
|  | 638 |  | 
|  | 639 | /// Register device global variable entry. | 
|  | 640 | void | 
|  | 641 | registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr, | 
|  | 642 | CharUnits VarSize, | 
|  | 643 | OMPTargetGlobalVarEntryKind Flags, | 
|  | 644 | llvm::GlobalValue::LinkageTypes Linkage); | 
|  | 645 | /// Checks if the variable with the given name has been registered already. | 
|  | 646 | bool hasDeviceGlobalVarEntryInfo(StringRef VarName) const { | 
|  | 647 | return OffloadEntriesDeviceGlobalVar.count(VarName) > 0; | 
|  | 648 | } | 
|  | 649 | /// Applies action \a Action on all registered entries. | 
|  | 650 | typedef llvm::function_ref<void(StringRef, | 
|  | 651 | const OffloadEntryInfoDeviceGlobalVar &)> | 
|  | 652 | OffloadDeviceGlobalVarEntryInfoActTy; | 
|  | 653 | void actOnDeviceGlobalVarEntriesInfo( | 
|  | 654 | const OffloadDeviceGlobalVarEntryInfoActTy &Action); | 
|  | 655 |  | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 656 | private: | 
|  | 657 | // Storage for target region entries kind. The storage is to be indexed by | 
| Samuel Antao | 2de62b0 | 2016-02-13 23:35:10 +0000 | [diff] [blame] | 658 | // file ID, device ID, parent function name and line number. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 659 | typedef llvm::DenseMap<unsigned, OffloadEntryInfoTargetRegion> | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 660 | OffloadEntriesTargetRegionPerLine; | 
|  | 661 | typedef llvm::StringMap<OffloadEntriesTargetRegionPerLine> | 
|  | 662 | OffloadEntriesTargetRegionPerParentName; | 
|  | 663 | typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerParentName> | 
|  | 664 | OffloadEntriesTargetRegionPerFile; | 
|  | 665 | typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerFile> | 
|  | 666 | OffloadEntriesTargetRegionPerDevice; | 
|  | 667 | typedef OffloadEntriesTargetRegionPerDevice OffloadEntriesTargetRegionTy; | 
|  | 668 | OffloadEntriesTargetRegionTy OffloadEntriesTargetRegion; | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 669 | /// Storage for device global variable entries kind. The storage is to be | 
|  | 670 | /// indexed by mangled name. | 
|  | 671 | typedef llvm::StringMap<OffloadEntryInfoDeviceGlobalVar> | 
|  | 672 | OffloadEntriesDeviceGlobalVarTy; | 
|  | 673 | OffloadEntriesDeviceGlobalVarTy OffloadEntriesDeviceGlobalVar; | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 674 | }; | 
|  | 675 | OffloadEntriesInfoManagerTy OffloadEntriesInfoManager; | 
|  | 676 |  | 
| Alexey Bataev | 4f4bf7c | 2018-03-15 15:47:20 +0000 | [diff] [blame] | 677 | bool ShouldMarkAsGlobal = true; | 
| Alexey Bataev | 4558842 | 2020-01-07 14:11:45 -0500 | [diff] [blame] | 678 | /// List of the emitted declarations. | 
|  | 679 | llvm::DenseSet<CanonicalDeclPtr<const Decl>> AlreadyEmittedTargetDecls; | 
| Alexey Bataev | 2a6f3f5 | 2018-11-07 19:11:14 +0000 | [diff] [blame] | 680 | /// List of the global variables with their addresses that should not be | 
|  | 681 | /// emitted for the target. | 
|  | 682 | llvm::StringMap<llvm::WeakTrackingVH> EmittedNonTargetVariables; | 
| Alexey Bataev | 4f4bf7c | 2018-03-15 15:47:20 +0000 | [diff] [blame] | 683 |  | 
| Alexey Bataev | bf8fe71 | 2018-08-07 16:14:36 +0000 | [diff] [blame] | 684 | /// List of variables that can become declare target implicitly and, thus, | 
|  | 685 | /// must be emitted. | 
|  | 686 | llvm::SmallDenseSet<const VarDecl *> DeferredGlobalVariables; | 
|  | 687 |  | 
| Alexey Bataev | 2df5f12 | 2019-10-01 20:18:32 +0000 | [diff] [blame] | 688 | /// Mapping of the original functions to their variants and original global | 
|  | 689 | /// decl. | 
|  | 690 | llvm::MapVector<CanonicalDeclPtr<const FunctionDecl>, | 
|  | 691 | std::pair<GlobalDecl, GlobalDecl>> | 
|  | 692 | DeferredVariantFunction; | 
|  | 693 |  | 
| Alexey Bataev | 0860db9 | 2019-12-19 10:01:10 -0500 | [diff] [blame] | 694 | using NontemporalDeclsSet = llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>>; | 
|  | 695 | /// Stack for list of declarations in current context marked as nontemporal. | 
|  | 696 | /// The set is the union of all current stack elements. | 
|  | 697 | llvm::SmallVector<NontemporalDeclsSet, 4> NontemporalDeclsStack; | 
|  | 698 |  | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 699 | /// Stack for list of addresses of declarations in current context marked as | 
|  | 700 | /// lastprivate conditional. The set is the union of all current stack | 
|  | 701 | /// elements. | 
|  | 702 | llvm::SmallVector<LastprivateConditionalData, 4> LastprivateConditionalStack; | 
|  | 703 |  | 
| Gheorghe-Teodor Bercea | 66cdbb47 | 2019-05-21 19:42:01 +0000 | [diff] [blame] | 704 | /// Flag for keeping track of weather a requires unified_shared_memory | 
|  | 705 | /// directive is present. | 
|  | 706 | bool HasRequiresUnifiedSharedMemory = false; | 
|  | 707 |  | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame^] | 708 | /// Atomic ordering from the omp requires directive. | 
|  | 709 | llvm::AtomicOrdering RequiresAtomicOrdering = llvm::AtomicOrdering::Monotonic; | 
|  | 710 |  | 
| Gheorghe-Teodor Bercea | 66cdbb47 | 2019-05-21 19:42:01 +0000 | [diff] [blame] | 711 | /// Flag for keeping track of weather a target region has been emitted. | 
|  | 712 | bool HasEmittedTargetRegion = false; | 
|  | 713 |  | 
|  | 714 | /// Flag for keeping track of weather a device routine has been emitted. | 
|  | 715 | /// Device routines are specific to the | 
|  | 716 | bool HasEmittedDeclareTargetRegion = false; | 
|  | 717 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 718 | /// Loads all the offload entries information from the host IR | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 719 | /// metadata. | 
|  | 720 | void loadOffloadInfoMetadata(); | 
|  | 721 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 722 | /// Returns __tgt_offload_entry type. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 723 | QualType getTgtOffloadEntryQTy(); | 
|  | 724 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 725 | /// Start scanning from statement \a S and and emit all target regions | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 726 | /// found along the way. | 
|  | 727 | /// \param S Starting statement. | 
|  | 728 | /// \param ParentName Name of the function declaration that is being scanned. | 
|  | 729 | void scanForTargetRegionsFunctions(const Stmt *S, StringRef ParentName); | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 730 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 731 | /// Build type kmp_routine_entry_t (if not built yet). | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 732 | void emitKmpRoutineEntryT(QualType KmpInt32Ty); | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 733 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 734 | /// Returns pointer to kmpc_micro type. | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 735 | llvm::Type *getKmpc_MicroPointerTy(); | 
|  | 736 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 737 | /// Returns specified OpenMP runtime function. | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 738 | /// \param Function OpenMP runtime function. | 
|  | 739 | /// \return Specified function. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 740 | llvm::FunctionCallee createRuntimeFunction(unsigned Function); | 
| Alexey Bataev | 3a3bf0b | 2014-09-22 10:01:53 +0000 | [diff] [blame] | 741 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 742 | /// Returns __kmpc_for_static_init_* runtime function for the specified | 
| Alexander Musman | 21212e4 | 2015-03-13 10:38:23 +0000 | [diff] [blame] | 743 | /// size \a IVSize and sign \a IVSigned. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 744 | llvm::FunctionCallee createForStaticInitFunction(unsigned IVSize, | 
|  | 745 | bool IVSigned); | 
| Alexander Musman | 21212e4 | 2015-03-13 10:38:23 +0000 | [diff] [blame] | 746 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 747 | /// Returns __kmpc_dispatch_init_* runtime function for the specified | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 748 | /// size \a IVSize and sign \a IVSigned. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 749 | llvm::FunctionCallee createDispatchInitFunction(unsigned IVSize, | 
|  | 750 | bool IVSigned); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 751 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 752 | /// Returns __kmpc_dispatch_next_* runtime function for the specified | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 753 | /// size \a IVSize and sign \a IVSigned. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 754 | llvm::FunctionCallee createDispatchNextFunction(unsigned IVSize, | 
|  | 755 | bool IVSigned); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 756 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 757 | /// Returns __kmpc_dispatch_fini_* runtime function for the specified | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 758 | /// size \a IVSize and sign \a IVSigned. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 759 | llvm::FunctionCallee createDispatchFiniFunction(unsigned IVSize, | 
|  | 760 | bool IVSigned); | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 761 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 762 | /// If the specified mangled name is not in the module, create and | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 763 | /// return threadprivate cache object. This object is a pointer's worth of | 
|  | 764 | /// storage that's reserved for use by the OpenMP runtime. | 
| NAKAMURA Takumi | cdcbfba | 2014-11-11 07:58:06 +0000 | [diff] [blame] | 765 | /// \param VD Threadprivate variable. | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 766 | /// \return Cache variable for the specified threadprivate. | 
|  | 767 | llvm::Constant *getOrCreateThreadPrivateCache(const VarDecl *VD); | 
|  | 768 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 769 | /// Gets (if variable with the given name already exist) or creates | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 770 | /// internal global variable with the specified Name. The created variable has | 
|  | 771 | /// linkage CommonLinkage by default and is initialized by null value. | 
|  | 772 | /// \param Ty Type of the global variable. If it is exist already the type | 
|  | 773 | /// must be the same. | 
|  | 774 | /// \param Name Name of the variable. | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 775 | llvm::Constant *getOrCreateInternalVariable(llvm::Type *Ty, | 
| Alexey Bataev | 1af5bd5 | 2019-03-05 17:47:18 +0000 | [diff] [blame] | 776 | const llvm::Twine &Name, | 
|  | 777 | unsigned AddressSpace = 0); | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 778 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 779 | /// Set of threadprivate variables with the generated initializer. | 
| Alexey Bataev | 2a6f3f5 | 2018-11-07 19:11:14 +0000 | [diff] [blame] | 780 | llvm::StringSet<> ThreadPrivateWithDefinition; | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 781 |  | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 782 | /// Set of declare target variables with the generated initializer. | 
| Alexey Bataev | 2a6f3f5 | 2018-11-07 19:11:14 +0000 | [diff] [blame] | 783 | llvm::StringSet<> DeclareTargetWithDefinition; | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 784 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 785 | /// Emits initialization code for the threadprivate variables. | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 786 | /// \param VDAddr Address of the global variable \a VD. | 
|  | 787 | /// \param Ctor Pointer to a global init function for \a VD. | 
|  | 788 | /// \param CopyCtor Pointer to a global copy function for \a VD. | 
|  | 789 | /// \param Dtor Pointer to a global destructor function for \a VD. | 
|  | 790 | /// \param Loc Location of threadprivate declaration. | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 791 | void emitThreadPrivateVarInit(CodeGenFunction &CGF, Address VDAddr, | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 792 | llvm::Value *Ctor, llvm::Value *CopyCtor, | 
|  | 793 | llvm::Value *Dtor, SourceLocation Loc); | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 794 |  | 
| Michael Kruse | d47b943 | 2019-08-05 18:43:21 +0000 | [diff] [blame] | 795 | /// Emit the array initialization or deletion portion for user-defined mapper | 
|  | 796 | /// code generation. | 
|  | 797 | void emitUDMapperArrayInitOrDel(CodeGenFunction &MapperCGF, | 
|  | 798 | llvm::Value *Handle, llvm::Value *BasePtr, | 
|  | 799 | llvm::Value *Ptr, llvm::Value *Size, | 
|  | 800 | llvm::Value *MapType, CharUnits ElementSize, | 
|  | 801 | llvm::BasicBlock *ExitBB, bool IsInit); | 
|  | 802 |  | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 803 | struct TaskResultTy { | 
|  | 804 | llvm::Value *NewTask = nullptr; | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 805 | llvm::Function *TaskEntry = nullptr; | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 806 | llvm::Value *NewTaskNewTaskTTy = nullptr; | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 807 | LValue TDBase; | 
| Alexey Bataev | a4fa0b8 | 2018-04-16 17:59:34 +0000 | [diff] [blame] | 808 | const RecordDecl *KmpTaskTQTyRD = nullptr; | 
| Alexey Bataev | f93095a | 2016-05-05 08:46:22 +0000 | [diff] [blame] | 809 | llvm::Value *TaskDupFn = nullptr; | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 810 | }; | 
|  | 811 | /// Emit task region for the task directive. The task region is emitted in | 
|  | 812 | /// several steps: | 
|  | 813 | /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 | 
|  | 814 | /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, | 
|  | 815 | /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the | 
|  | 816 | /// function: | 
|  | 817 | /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) { | 
|  | 818 | ///   TaskFunction(gtid, tt->part_id, tt->shareds); | 
|  | 819 | ///   return 0; | 
|  | 820 | /// } | 
|  | 821 | /// 2. Copy a list of shared variables to field shareds of the resulting | 
|  | 822 | /// structure kmp_task_t returned by the previous call (if any). | 
|  | 823 | /// 3. Copy a pointer to destructions function to field destructions of the | 
|  | 824 | /// resulting structure kmp_task_t. | 
|  | 825 | /// \param D Current task directive. | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 826 | /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32 | 
|  | 827 | /// /*part_id*/, captured_struct */*__context*/); | 
|  | 828 | /// \param SharedsTy A type which contains references the shared variables. | 
|  | 829 | /// \param Shareds Context with the list of shared variables from the \p | 
|  | 830 | /// TaskFunction. | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 831 | /// \param Data Additional data for task generation like tiednsee, final | 
|  | 832 | /// state, list of privates etc. | 
|  | 833 | TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 834 | const OMPExecutableDirective &D, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 835 | llvm::Function *TaskFunction, QualType SharedsTy, | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 836 | Address Shareds, const OMPTaskDataTy &Data); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 837 |  | 
| Alexey Bataev | 1af5bd5 | 2019-03-05 17:47:18 +0000 | [diff] [blame] | 838 | /// Returns default address space for the constant firstprivates, 0 by | 
|  | 839 | /// default. | 
|  | 840 | virtual unsigned getDefaultFirstprivateAddressSpace() const { return 0; } | 
|  | 841 |  | 
| Alexey Bataev | ec7946e | 2019-09-23 14:06:51 +0000 | [diff] [blame] | 842 | /// Emit code that pushes the trip count of loops associated with constructs | 
|  | 843 | /// 'target teams distribute' and 'teams distribute parallel for'. | 
|  | 844 | /// \param SizeEmitter Emits the int64 value for the number of iterations of | 
|  | 845 | /// the associated loop. | 
|  | 846 | void emitTargetNumIterationsCall( | 
|  | 847 | CodeGenFunction &CGF, const OMPExecutableDirective &D, | 
|  | 848 | llvm::Value *DeviceID, | 
|  | 849 | llvm::function_ref<llvm::Value *(CodeGenFunction &CGF, | 
|  | 850 | const OMPLoopDirective &D)> | 
|  | 851 | SizeEmitter); | 
|  | 852 |  | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 853 | /// Emit update for lastprivate conditional data. | 
|  | 854 | void emitLastprivateConditionalUpdate(CodeGenFunction &CGF, LValue IVLVal, | 
|  | 855 | StringRef UniqueDeclName, LValue LVal, | 
|  | 856 | SourceLocation Loc); | 
|  | 857 |  | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 858 | public: | 
| Alexey Bataev | 18fa232 | 2018-05-02 14:20:50 +0000 | [diff] [blame] | 859 | explicit CGOpenMPRuntime(CodeGenModule &CGM) | 
|  | 860 | : CGOpenMPRuntime(CGM, ".", ".") {} | 
| Angel Garcia Gomez | 637d1e6 | 2015-10-20 13:23:58 +0000 | [diff] [blame] | 861 | virtual ~CGOpenMPRuntime() {} | 
| Alexey Bataev | 9179755 | 2015-03-18 04:13:55 +0000 | [diff] [blame] | 862 | virtual void clear(); | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 863 |  | 
| Alexey Bataev | d08c056 | 2019-11-19 12:07:54 -0500 | [diff] [blame] | 864 | /// Emits code for OpenMP 'if' clause using specified \a CodeGen | 
|  | 865 | /// function. Here is the logic: | 
|  | 866 | /// if (Cond) { | 
|  | 867 | ///   ThenGen(); | 
|  | 868 | /// } else { | 
|  | 869 | ///   ElseGen(); | 
|  | 870 | /// } | 
|  | 871 | void emitIfClause(CodeGenFunction &CGF, const Expr *Cond, | 
|  | 872 | const RegionCodeGenTy &ThenGen, | 
|  | 873 | const RegionCodeGenTy &ElseGen); | 
|  | 874 |  | 
| Alexey Bataev | 5c42736 | 2019-04-10 19:11:33 +0000 | [diff] [blame] | 875 | /// Checks if the \p Body is the \a CompoundStmt and returns its child | 
|  | 876 | /// statement iff there is only one that is not evaluatable at the compile | 
|  | 877 | /// time. | 
|  | 878 | static const Stmt *getSingleCompoundChild(ASTContext &Ctx, const Stmt *Body); | 
|  | 879 |  | 
| Alexey Bataev | 18fa232 | 2018-05-02 14:20:50 +0000 | [diff] [blame] | 880 | /// Get the platform-specific name separator. | 
|  | 881 | std::string getName(ArrayRef<StringRef> Parts) const; | 
|  | 882 |  | 
| Alexey Bataev | c5b1d32 | 2016-03-04 09:22:22 +0000 | [diff] [blame] | 883 | /// Emit code for the specified user defined reduction construct. | 
|  | 884 | virtual void emitUserDefinedReduction(CodeGenFunction *CGF, | 
|  | 885 | const OMPDeclareReductionDecl *D); | 
| Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 886 | /// Get combiner/initializer for the specified user-defined reduction, if any. | 
|  | 887 | virtual std::pair<llvm::Function *, llvm::Function *> | 
|  | 888 | getUserDefinedReduction(const OMPDeclareReductionDecl *D); | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 889 |  | 
| Michael Kruse | d47b943 | 2019-08-05 18:43:21 +0000 | [diff] [blame] | 890 | /// Emit the function for the user defined mapper construct. | 
|  | 891 | void emitUserDefinedMapper(const OMPDeclareMapperDecl *D, | 
|  | 892 | CodeGenFunction *CGF = nullptr); | 
|  | 893 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 894 | /// Emits outlined function for the specified OpenMP parallel directive | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 895 | /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID, | 
|  | 896 | /// kmp_int32 BoundID, struct context_vars*). | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 897 | /// \param D OpenMP directive. | 
|  | 898 | /// \param ThreadIDVar Variable for thread id in the current OpenMP region. | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 899 | /// \param InnermostKind Kind of innermost directive (for simple directives it | 
|  | 900 | /// is a directive itself, for combined - its innermost directive). | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 901 | /// \param CodeGen Code generation sequence for the \a D directive. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 902 | virtual llvm::Function *emitParallelOutlinedFunction( | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 903 | const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, | 
|  | 904 | OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen); | 
|  | 905 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 906 | /// Emits outlined function for the specified OpenMP teams directive | 
| Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 907 | /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID, | 
|  | 908 | /// kmp_int32 BoundID, struct context_vars*). | 
|  | 909 | /// \param D OpenMP directive. | 
|  | 910 | /// \param ThreadIDVar Variable for thread id in the current OpenMP region. | 
|  | 911 | /// \param InnermostKind Kind of innermost directive (for simple directives it | 
|  | 912 | /// is a directive itself, for combined - its innermost directive). | 
|  | 913 | /// \param CodeGen Code generation sequence for the \a D directive. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 914 | virtual llvm::Function *emitTeamsOutlinedFunction( | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 915 | const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, | 
|  | 916 | OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen); | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 917 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 918 | /// Emits outlined function for the OpenMP task directive \a D. This | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 919 | /// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t* | 
|  | 920 | /// TaskT). | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 921 | /// \param D OpenMP directive. | 
|  | 922 | /// \param ThreadIDVar Variable for thread id in the current OpenMP region. | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 923 | /// \param PartIDVar Variable for partition id in the current OpenMP untied | 
|  | 924 | /// task region. | 
|  | 925 | /// \param TaskTVar Variable for task_t argument. | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 926 | /// \param InnermostKind Kind of innermost directive (for simple directives it | 
|  | 927 | /// is a directive itself, for combined - its innermost directive). | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 928 | /// \param CodeGen Code generation sequence for the \a D directive. | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 929 | /// \param Tied true if task is generated for tied task, false otherwise. | 
|  | 930 | /// \param NumberOfParts Number of parts in untied task. Ignored for tied | 
|  | 931 | /// tasks. | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 932 | /// | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 933 | virtual llvm::Function *emitTaskOutlinedFunction( | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 934 | const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, | 
| Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 935 | const VarDecl *PartIDVar, const VarDecl *TaskTVar, | 
|  | 936 | OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, | 
|  | 937 | bool Tied, unsigned &NumberOfParts); | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 938 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 939 | /// Cleans up references to the objects in finished function. | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 940 | /// | 
| Gheorghe-Teodor Bercea | d3dcf2f | 2018-03-14 14:17:45 +0000 | [diff] [blame] | 941 | virtual void functionFinished(CodeGenFunction &CGF); | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 942 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 943 | /// Emits code for parallel or serial call of the \a OutlinedFn with | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 944 | /// variables captured in a record which address is stored in \a | 
|  | 945 | /// CapturedStruct. | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 946 | /// \param OutlinedFn Outlined function to be run in parallel threads. Type of | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 947 | /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*). | 
| NAKAMURA Takumi | 62f0eb5 | 2015-09-11 08:13:32 +0000 | [diff] [blame] | 948 | /// \param CapturedVars A pointer to the record with the references to | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 949 | /// variables used in \a OutlinedFn function. | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 950 | /// \param IfCond Condition in the associated 'if' clause, if it was | 
|  | 951 | /// specified, nullptr otherwise. | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 952 | /// | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 953 | virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 954 | llvm::Function *OutlinedFn, | 
| Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 955 | ArrayRef<llvm::Value *> CapturedVars, | 
|  | 956 | const Expr *IfCond); | 
| Alexey Bataev | d74d060 | 2014-10-13 06:02:40 +0000 | [diff] [blame] | 957 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 958 | /// Emits a critical region. | 
| Alexey Bataev | 1809571 | 2014-10-10 12:19:54 +0000 | [diff] [blame] | 959 | /// \param CriticalName Name of the critical region. | 
| Alexey Bataev | 75ddfab | 2014-12-01 11:32:38 +0000 | [diff] [blame] | 960 | /// \param CriticalOpGen Generator for the statement associated with the given | 
|  | 961 | /// critical region. | 
| Alexey Bataev | fc57d16 | 2015-12-15 10:55:09 +0000 | [diff] [blame] | 962 | /// \param Hint Value of the 'hint' clause (optional). | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 963 | virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 964 | const RegionCodeGenTy &CriticalOpGen, | 
| Alexey Bataev | fc57d16 | 2015-12-15 10:55:09 +0000 | [diff] [blame] | 965 | SourceLocation Loc, | 
|  | 966 | const Expr *Hint = nullptr); | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 967 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 968 | /// Emits a master region. | 
| Alexey Bataev | 8d69065 | 2014-12-04 07:23:53 +0000 | [diff] [blame] | 969 | /// \param MasterOpGen Generator for the statement associated with the given | 
|  | 970 | /// master region. | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 971 | virtual void emitMasterRegion(CodeGenFunction &CGF, | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 972 | const RegionCodeGenTy &MasterOpGen, | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 973 | SourceLocation Loc); | 
| Alexey Bataev | 8d69065 | 2014-12-04 07:23:53 +0000 | [diff] [blame] | 974 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 975 | /// Emits code for a taskyield directive. | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 976 | virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc); | 
| Alexey Bataev | 9f797f3 | 2015-02-05 05:57:51 +0000 | [diff] [blame] | 977 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 978 | /// Emit a taskgroup region. | 
| Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 979 | /// \param TaskgroupOpGen Generator for the statement associated with the | 
|  | 980 | /// given taskgroup region. | 
|  | 981 | virtual void emitTaskgroupRegion(CodeGenFunction &CGF, | 
|  | 982 | const RegionCodeGenTy &TaskgroupOpGen, | 
|  | 983 | SourceLocation Loc); | 
|  | 984 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 985 | /// Emits a single region. | 
| Alexey Bataev | 6956e2e | 2015-02-05 06:35:41 +0000 | [diff] [blame] | 986 | /// \param SingleOpGen Generator for the statement associated with the given | 
|  | 987 | /// single region. | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 988 | virtual void emitSingleRegion(CodeGenFunction &CGF, | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 989 | const RegionCodeGenTy &SingleOpGen, | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 990 | SourceLocation Loc, | 
|  | 991 | ArrayRef<const Expr *> CopyprivateVars, | 
| Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 992 | ArrayRef<const Expr *> DestExprs, | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 993 | ArrayRef<const Expr *> SrcExprs, | 
| Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 994 | ArrayRef<const Expr *> AssignmentOps); | 
| Alexey Bataev | 6956e2e | 2015-02-05 06:35:41 +0000 | [diff] [blame] | 995 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 996 | /// Emit an ordered region. | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 997 | /// \param OrderedOpGen Generator for the statement associated with the given | 
| Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 998 | /// ordered region. | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 999 | virtual void emitOrderedRegion(CodeGenFunction &CGF, | 
|  | 1000 | const RegionCodeGenTy &OrderedOpGen, | 
| Alexey Bataev | 5f600d6 | 2015-09-29 03:48:57 +0000 | [diff] [blame] | 1001 | SourceLocation Loc, bool IsThreads); | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 1002 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1003 | /// Emit an implicit/explicit barrier for OpenMP threads. | 
| Alexey Bataev | f268568 | 2015-03-30 04:30:22 +0000 | [diff] [blame] | 1004 | /// \param Kind Directive for which this implicit barrier call must be | 
|  | 1005 | /// generated. Must be OMPD_barrier for explicit barrier generation. | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 1006 | /// \param EmitChecks true if need to emit checks for cancellation barriers. | 
|  | 1007 | /// \param ForceSimpleCall true simple barrier call must be emitted, false if | 
|  | 1008 | /// runtime class decides which one to emit (simple or with cancellation | 
|  | 1009 | /// checks). | 
| Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 1010 | /// | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 1011 | virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 1012 | OpenMPDirectiveKind Kind, | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 1013 | bool EmitChecks = true, | 
|  | 1014 | bool ForceSimpleCall = false); | 
| Alexey Bataev | b205978 | 2014-10-13 08:23:51 +0000 | [diff] [blame] | 1015 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1016 | /// Check if the specified \a ScheduleKind is static non-chunked. | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1017 | /// This kind of worksharing directive is emitted without outer loop. | 
|  | 1018 | /// \param ScheduleKind Schedule kind specified in the 'schedule' clause. | 
|  | 1019 | /// \param Chunked True if chunk is specified in the clause. | 
|  | 1020 | /// | 
|  | 1021 | virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind, | 
|  | 1022 | bool Chunked) const; | 
|  | 1023 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1024 | /// Check if the specified \a ScheduleKind is static non-chunked. | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 1025 | /// This kind of distribute directive is emitted without outer loop. | 
|  | 1026 | /// \param ScheduleKind Schedule kind specified in the 'dist_schedule' clause. | 
|  | 1027 | /// \param Chunked True if chunk is specified in the clause. | 
|  | 1028 | /// | 
|  | 1029 | virtual bool isStaticNonchunked(OpenMPDistScheduleClauseKind ScheduleKind, | 
|  | 1030 | bool Chunked) const; | 
|  | 1031 |  | 
| Gheorghe-Teodor Bercea | e925676 | 2018-10-29 15:45:47 +0000 | [diff] [blame] | 1032 | /// Check if the specified \a ScheduleKind is static chunked. | 
|  | 1033 | /// \param ScheduleKind Schedule kind specified in the 'schedule' clause. | 
|  | 1034 | /// \param Chunked True if chunk is specified in the clause. | 
|  | 1035 | /// | 
|  | 1036 | virtual bool isStaticChunked(OpenMPScheduleClauseKind ScheduleKind, | 
|  | 1037 | bool Chunked) const; | 
|  | 1038 |  | 
|  | 1039 | /// Check if the specified \a ScheduleKind is static non-chunked. | 
|  | 1040 | /// \param ScheduleKind Schedule kind specified in the 'dist_schedule' clause. | 
|  | 1041 | /// \param Chunked True if chunk is specified in the clause. | 
|  | 1042 | /// | 
|  | 1043 | virtual bool isStaticChunked(OpenMPDistScheduleClauseKind ScheduleKind, | 
|  | 1044 | bool Chunked) const; | 
|  | 1045 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1046 | /// Check if the specified \a ScheduleKind is dynamic. | 
| Alexander Musman | df7a8e2 | 2015-01-22 08:49:35 +0000 | [diff] [blame] | 1047 | /// This kind of worksharing directive is emitted without outer loop. | 
|  | 1048 | /// \param ScheduleKind Schedule Kind specified in the 'schedule' clause. | 
|  | 1049 | /// | 
|  | 1050 | virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const; | 
|  | 1051 |  | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 1052 | /// struct with the values to be passed to the dispatch runtime function | 
|  | 1053 | struct DispatchRTInput { | 
|  | 1054 | /// Loop lower bound | 
|  | 1055 | llvm::Value *LB = nullptr; | 
|  | 1056 | /// Loop upper bound | 
|  | 1057 | llvm::Value *UB = nullptr; | 
|  | 1058 | /// Chunk size specified using 'schedule' clause (nullptr if chunk | 
|  | 1059 | /// was not specified) | 
|  | 1060 | llvm::Value *Chunk = nullptr; | 
|  | 1061 | DispatchRTInput() = default; | 
|  | 1062 | DispatchRTInput(llvm::Value *LB, llvm::Value *UB, llvm::Value *Chunk) | 
|  | 1063 | : LB(LB), UB(UB), Chunk(Chunk) {} | 
|  | 1064 | }; | 
|  | 1065 |  | 
|  | 1066 | /// Call the appropriate runtime routine to initialize it before start | 
|  | 1067 | /// of loop. | 
|  | 1068 |  | 
|  | 1069 | /// This is used for non static scheduled types and when the ordered | 
|  | 1070 | /// clause is present on the loop construct. | 
|  | 1071 | /// Depending on the loop schedule, it is necessary to call some runtime | 
|  | 1072 | /// routine before start of the OpenMP loop to get the loop upper / lower | 
|  | 1073 | /// bounds \a LB and \a UB and stride \a ST. | 
|  | 1074 | /// | 
|  | 1075 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1076 | /// \param Loc Clang source location. | 
|  | 1077 | /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause. | 
|  | 1078 | /// \param IVSize Size of the iteration variable in bits. | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 1079 | /// \param IVSigned Sign of the iteration variable. | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 1080 | /// \param Ordered true if loop is ordered, false otherwise. | 
|  | 1081 | /// \param DispatchValues struct containing llvm values for lower bound, upper | 
|  | 1082 | /// bound, and chunk expression. | 
|  | 1083 | /// For the default (nullptr) value, the chunk 1 will be used. | 
|  | 1084 | /// | 
| NAKAMURA Takumi | ff7a925 | 2015-09-08 09:42:41 +0000 | [diff] [blame] | 1085 | virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 1086 | const OpenMPScheduleTy &ScheduleKind, | 
|  | 1087 | unsigned IVSize, bool IVSigned, bool Ordered, | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 1088 | const DispatchRTInput &DispatchValues); | 
| NAKAMURA Takumi | ff7a925 | 2015-09-08 09:42:41 +0000 | [diff] [blame] | 1089 |  | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1090 | /// Struct with the values to be passed to the static runtime function | 
|  | 1091 | struct StaticRTInput { | 
|  | 1092 | /// Size of the iteration variable in bits. | 
|  | 1093 | unsigned IVSize = 0; | 
|  | 1094 | /// Sign of the iteration variable. | 
|  | 1095 | bool IVSigned = false; | 
|  | 1096 | /// true if loop is ordered, false otherwise. | 
|  | 1097 | bool Ordered = false; | 
|  | 1098 | /// Address of the output variable in which the flag of the last iteration | 
|  | 1099 | /// is returned. | 
|  | 1100 | Address IL = Address::invalid(); | 
|  | 1101 | /// Address of the output variable in which the lower iteration number is | 
|  | 1102 | /// returned. | 
|  | 1103 | Address LB = Address::invalid(); | 
|  | 1104 | /// Address of the output variable in which the upper iteration number is | 
|  | 1105 | /// returned. | 
|  | 1106 | Address UB = Address::invalid(); | 
|  | 1107 | /// Address of the output variable in which the stride value is returned | 
|  | 1108 | /// necessary to generated the static_chunked scheduled loop. | 
|  | 1109 | Address ST = Address::invalid(); | 
|  | 1110 | /// Value of the chunk for the static_chunked scheduled loop. For the | 
|  | 1111 | /// default (nullptr) value, the chunk 1 will be used. | 
|  | 1112 | llvm::Value *Chunk = nullptr; | 
|  | 1113 | StaticRTInput(unsigned IVSize, bool IVSigned, bool Ordered, Address IL, | 
|  | 1114 | Address LB, Address UB, Address ST, | 
|  | 1115 | llvm::Value *Chunk = nullptr) | 
|  | 1116 | : IVSize(IVSize), IVSigned(IVSigned), Ordered(Ordered), IL(IL), LB(LB), | 
|  | 1117 | UB(UB), ST(ST), Chunk(Chunk) {} | 
|  | 1118 | }; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1119 | /// Call the appropriate runtime routine to initialize it before start | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1120 | /// of loop. | 
|  | 1121 | /// | 
| Carlo Bertolli | b0ff0a6 | 2017-04-25 17:52:12 +0000 | [diff] [blame] | 1122 | /// This is used only in case of static schedule, when the user did not | 
|  | 1123 | /// specify a ordered clause on the loop construct. | 
|  | 1124 | /// Depending on the loop schedule, it is necessary to call some runtime | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1125 | /// routine before start of the OpenMP loop to get the loop upper / lower | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1126 | /// bounds LB and UB and stride ST. | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1127 | /// | 
|  | 1128 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1129 | /// \param Loc Clang source location. | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1130 | /// \param DKind Kind of the directive. | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 1131 | /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause. | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1132 | /// \param Values Input arguments for the construct. | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1133 | /// | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 1134 | virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1135 | OpenMPDirectiveKind DKind, | 
| Alexey Bataev | 9ebd742 | 2016-05-10 09:57:36 +0000 | [diff] [blame] | 1136 | const OpenMPScheduleTy &ScheduleKind, | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1137 | const StaticRTInput &Values); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1138 |  | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 1139 | /// | 
|  | 1140 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1141 | /// \param Loc Clang source location. | 
|  | 1142 | /// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause. | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1143 | /// \param Values Input arguments for the construct. | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 1144 | /// | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1145 | virtual void emitDistributeStaticInit(CodeGenFunction &CGF, | 
|  | 1146 | SourceLocation Loc, | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 1147 | OpenMPDistScheduleClauseKind SchedKind, | 
| Alexey Bataev | 0f87dbe | 2017-08-14 17:56:13 +0000 | [diff] [blame] | 1148 | const StaticRTInput &Values); | 
| Carlo Bertolli | fc35ad2 | 2016-03-07 16:04:49 +0000 | [diff] [blame] | 1149 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1150 | /// Call the appropriate runtime routine to notify that we finished | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 1151 | /// iteration of the ordered loop with the dynamic scheduling. | 
|  | 1152 | /// | 
|  | 1153 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1154 | /// \param Loc Clang source location. | 
|  | 1155 | /// \param IVSize Size of the iteration variable in bits. | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 1156 | /// \param IVSigned Sign of the iteration variable. | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 1157 | /// | 
| Alexey Bataev | d7589ffe | 2015-05-20 13:12:48 +0000 | [diff] [blame] | 1158 | virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF, | 
|  | 1159 | SourceLocation Loc, unsigned IVSize, | 
|  | 1160 | bool IVSigned); | 
| Alexey Bataev | 98eb6e3 | 2015-04-22 11:15:40 +0000 | [diff] [blame] | 1161 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1162 | /// Call the appropriate runtime routine to notify that we finished | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1163 | /// all the work with current loop. | 
|  | 1164 | /// | 
|  | 1165 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1166 | /// \param Loc Clang source location. | 
| Alexey Bataev | f43f714 | 2017-09-06 16:17:35 +0000 | [diff] [blame] | 1167 | /// \param DKind Kind of the directive for which the static finish is emitted. | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1168 | /// | 
| Alexey Bataev | f43f714 | 2017-09-06 16:17:35 +0000 | [diff] [blame] | 1169 | virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1170 | OpenMPDirectiveKind DKind); | 
| Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 1171 |  | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 1172 | /// Call __kmpc_dispatch_next( | 
|  | 1173 | ///          ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, | 
|  | 1174 | ///          kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper, | 
|  | 1175 | ///          kmp_int[32|64] *p_stride); | 
|  | 1176 | /// \param IVSize Size of the iteration variable in bits. | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 1177 | /// \param IVSigned Sign of the iteration variable. | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 1178 | /// \param IL Address of the output variable in which the flag of the | 
|  | 1179 | /// last iteration is returned. | 
|  | 1180 | /// \param LB Address of the output variable in which the lower iteration | 
|  | 1181 | /// number is returned. | 
|  | 1182 | /// \param UB Address of the output variable in which the upper iteration | 
|  | 1183 | /// number is returned. | 
|  | 1184 | /// \param ST Address of the output variable in which the stride value is | 
|  | 1185 | /// returned. | 
|  | 1186 | virtual llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1187 | unsigned IVSize, bool IVSigned, | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 1188 | Address IL, Address LB, | 
|  | 1189 | Address UB, Address ST); | 
| Alexander Musman | 92bdaab | 2015-03-12 13:37:50 +0000 | [diff] [blame] | 1190 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1191 | /// Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 | 
| Alexey Bataev | b205978 | 2014-10-13 08:23:51 +0000 | [diff] [blame] | 1192 | /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads' | 
|  | 1193 | /// clause. | 
|  | 1194 | /// \param NumThreads An integer value of threads. | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 1195 | virtual void emitNumThreadsClause(CodeGenFunction &CGF, | 
|  | 1196 | llvm::Value *NumThreads, | 
|  | 1197 | SourceLocation Loc); | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 1198 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1199 | /// Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 | 
| Alexey Bataev | 7f210c6 | 2015-06-18 13:40:03 +0000 | [diff] [blame] | 1200 | /// global_tid, int proc_bind) to generate code for 'proc_bind' clause. | 
|  | 1201 | virtual void emitProcBindClause(CodeGenFunction &CGF, | 
| Johannes Doerfert | 6c5d1f40 | 2019-12-25 18:15:36 -0600 | [diff] [blame] | 1202 | llvm::omp::ProcBindKind ProcBind, | 
| Alexey Bataev | 7f210c6 | 2015-06-18 13:40:03 +0000 | [diff] [blame] | 1203 | SourceLocation Loc); | 
|  | 1204 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1205 | /// Returns address of the threadprivate variable for the current | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 1206 | /// thread. | 
| NAKAMURA Takumi | cdcbfba | 2014-11-11 07:58:06 +0000 | [diff] [blame] | 1207 | /// \param VD Threadprivate variable. | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 1208 | /// \param VDAddr Address of the global variable \a VD. | 
|  | 1209 | /// \param Loc Location of the reference to threadprivate var. | 
|  | 1210 | /// \return Address of the threadprivate variable for the current thread. | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 1211 | virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF, | 
|  | 1212 | const VarDecl *VD, | 
|  | 1213 | Address VDAddr, | 
|  | 1214 | SourceLocation Loc); | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 1215 |  | 
| Alexey Bataev | 92327c5 | 2018-03-26 16:40:55 +0000 | [diff] [blame] | 1216 | /// Returns the address of the variable marked as declare target with link | 
| Gheorghe-Teodor Bercea | 0034e84 | 2019-06-20 18:04:47 +0000 | [diff] [blame] | 1217 | /// clause OR as declare target with to clause and unified memory. | 
|  | 1218 | virtual Address getAddrOfDeclareTargetVar(const VarDecl *VD); | 
| Alexey Bataev | 92327c5 | 2018-03-26 16:40:55 +0000 | [diff] [blame] | 1219 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1220 | /// Emit a code for initialization of threadprivate variable. It emits | 
| Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 1221 | /// a call to runtime library which adds initial value to the newly created | 
|  | 1222 | /// threadprivate variable (if it is not constant) and registers destructor | 
|  | 1223 | /// for the variable (if any). | 
|  | 1224 | /// \param VD Threadprivate variable. | 
|  | 1225 | /// \param VDAddr Address of the global variable \a VD. | 
|  | 1226 | /// \param Loc Location of threadprivate declaration. | 
|  | 1227 | /// \param PerformInit true if initialization expression is not constant. | 
|  | 1228 | virtual llvm::Function * | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 1229 | emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 1230 | SourceLocation Loc, bool PerformInit, | 
|  | 1231 | CodeGenFunction *CGF = nullptr); | 
| Alexey Bataev | cc37cc1 | 2014-11-20 04:34:54 +0000 | [diff] [blame] | 1232 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1233 | /// Emit a code for initialization of declare target variable. | 
| Alexey Bataev | 34f8a70 | 2018-03-28 14:28:54 +0000 | [diff] [blame] | 1234 | /// \param VD Declare target variable. | 
|  | 1235 | /// \param Addr Address of the global variable \a VD. | 
|  | 1236 | /// \param PerformInit true if initialization expression is not constant. | 
|  | 1237 | virtual bool emitDeclareTargetVarDefinition(const VarDecl *VD, | 
|  | 1238 | llvm::GlobalVariable *Addr, | 
|  | 1239 | bool PerformInit); | 
|  | 1240 |  | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 1241 | /// Creates artificial threadprivate variable with name \p Name and type \p | 
|  | 1242 | /// VarType. | 
|  | 1243 | /// \param VarType Type of the artificial threadprivate variable. | 
|  | 1244 | /// \param Name Name of the artificial threadprivate variable. | 
|  | 1245 | virtual Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF, | 
|  | 1246 | QualType VarType, | 
|  | 1247 | StringRef Name); | 
|  | 1248 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1249 | /// Emit flush of the variables specified in 'omp flush' directive. | 
| Alexey Bataev | cc37cc1 | 2014-11-20 04:34:54 +0000 | [diff] [blame] | 1250 | /// \param Vars List of variables to flush. | 
| Alexey Bataev | 3eff5f4 | 2015-02-25 08:32:46 +0000 | [diff] [blame] | 1251 | virtual void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars, | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 1252 | SourceLocation Loc, llvm::AtomicOrdering AO); | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 1253 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1254 | /// Emit task region for the task directive. The task region is | 
| Nico Weber | 20b0ce3 | 2015-04-28 18:19:18 +0000 | [diff] [blame] | 1255 | /// emitted in several steps: | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 1256 | /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 | 
|  | 1257 | /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, | 
|  | 1258 | /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the | 
|  | 1259 | /// function: | 
|  | 1260 | /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) { | 
|  | 1261 | ///   TaskFunction(gtid, tt->part_id, tt->shareds); | 
|  | 1262 | ///   return 0; | 
|  | 1263 | /// } | 
|  | 1264 | /// 2. Copy a list of shared variables to field shareds of the resulting | 
|  | 1265 | /// structure kmp_task_t returned by the previous call (if any). | 
|  | 1266 | /// 3. Copy a pointer to destructions function to field destructions of the | 
|  | 1267 | /// resulting structure kmp_task_t. | 
|  | 1268 | /// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, | 
|  | 1269 | /// kmp_task_t *new_task), where new_task is a resulting structure from | 
|  | 1270 | /// previous items. | 
| Alexey Bataev | 36c1eb9 | 2015-04-30 06:51:57 +0000 | [diff] [blame] | 1271 | /// \param D Current task directive. | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 1272 | /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32 | 
|  | 1273 | /// /*part_id*/, captured_struct */*__context*/); | 
|  | 1274 | /// \param SharedsTy A type which contains references the shared variables. | 
| Alexey Bataev | 1d2353d | 2015-06-24 11:01:36 +0000 | [diff] [blame] | 1275 | /// \param Shareds Context with the list of shared variables from the \p | 
| Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 1276 | /// TaskFunction. | 
| Alexey Bataev | 1d67713 | 2015-04-22 13:57:31 +0000 | [diff] [blame] | 1277 | /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr | 
|  | 1278 | /// otherwise. | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 1279 | /// \param Data Additional data for task generation like tiednsee, final | 
|  | 1280 | /// state, list of privates etc. | 
|  | 1281 | virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1282 | const OMPExecutableDirective &D, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1283 | llvm::Function *TaskFunction, QualType SharedsTy, | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 1284 | Address Shareds, const Expr *IfCond, | 
|  | 1285 | const OMPTaskDataTy &Data); | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1286 |  | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 1287 | /// Emit task region for the taskloop directive. The taskloop region is | 
|  | 1288 | /// emitted in several steps: | 
|  | 1289 | /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 | 
|  | 1290 | /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, | 
|  | 1291 | /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the | 
|  | 1292 | /// function: | 
|  | 1293 | /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) { | 
|  | 1294 | ///   TaskFunction(gtid, tt->part_id, tt->shareds); | 
|  | 1295 | ///   return 0; | 
|  | 1296 | /// } | 
|  | 1297 | /// 2. Copy a list of shared variables to field shareds of the resulting | 
|  | 1298 | /// structure kmp_task_t returned by the previous call (if any). | 
|  | 1299 | /// 3. Copy a pointer to destructions function to field destructions of the | 
|  | 1300 | /// resulting structure kmp_task_t. | 
|  | 1301 | /// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t | 
|  | 1302 | /// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int | 
|  | 1303 | /// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task | 
|  | 1304 | /// is a resulting structure from | 
|  | 1305 | /// previous items. | 
|  | 1306 | /// \param D Current task directive. | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 1307 | /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32 | 
|  | 1308 | /// /*part_id*/, captured_struct */*__context*/); | 
|  | 1309 | /// \param SharedsTy A type which contains references the shared variables. | 
|  | 1310 | /// \param Shareds Context with the list of shared variables from the \p | 
|  | 1311 | /// TaskFunction. | 
|  | 1312 | /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr | 
|  | 1313 | /// otherwise. | 
| Alexey Bataev | 24b5bae | 2016-04-28 09:23:51 +0000 | [diff] [blame] | 1314 | /// \param Data Additional data for task generation like tiednsee, final | 
|  | 1315 | /// state, list of privates etc. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1316 | virtual void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1317 | const OMPLoopDirective &D, | 
|  | 1318 | llvm::Function *TaskFunction, | 
|  | 1319 | QualType SharedsTy, Address Shareds, | 
|  | 1320 | const Expr *IfCond, const OMPTaskDataTy &Data); | 
| Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 1321 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1322 | /// Emit code for the directive that does not require outlining. | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1323 | /// | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 1324 | /// \param InnermostKind Kind of innermost directive (for simple directives it | 
|  | 1325 | /// is a directive itself, for combined - its innermost directive). | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1326 | /// \param CodeGen Code generation sequence for the \a D directive. | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 1327 | /// \param HasCancel true if region has inner cancel directive, false | 
|  | 1328 | /// otherwise. | 
| Alexey Bataev | 6f1ffc0 | 2015-04-10 04:50:10 +0000 | [diff] [blame] | 1329 | virtual void emitInlinedDirective(CodeGenFunction &CGF, | 
| Alexey Bataev | 81c7ea0 | 2015-07-03 09:56:58 +0000 | [diff] [blame] | 1330 | OpenMPDirectiveKind InnermostKind, | 
| Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 1331 | const RegionCodeGenTy &CodeGen, | 
|  | 1332 | bool HasCancel = false); | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 1333 |  | 
|  | 1334 | /// Emits reduction function. | 
|  | 1335 | /// \param ArgsType Array type containing pointers to reduction variables. | 
|  | 1336 | /// \param Privates List of private copies for original reduction arguments. | 
|  | 1337 | /// \param LHSExprs List of LHS in \a ReductionOps reduction operations. | 
|  | 1338 | /// \param RHSExprs List of RHS in \a ReductionOps reduction operations. | 
|  | 1339 | /// \param ReductionOps List of reduction operations in form 'LHS binop RHS' | 
|  | 1340 | /// or 'operator binop(LHS, RHS)'. | 
| Alexey Bataev | 982a35e | 2019-03-19 17:09:52 +0000 | [diff] [blame] | 1341 | llvm::Function *emitReductionFunction(SourceLocation Loc, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1342 | llvm::Type *ArgsType, | 
|  | 1343 | ArrayRef<const Expr *> Privates, | 
|  | 1344 | ArrayRef<const Expr *> LHSExprs, | 
|  | 1345 | ArrayRef<const Expr *> RHSExprs, | 
|  | 1346 | ArrayRef<const Expr *> ReductionOps); | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 1347 |  | 
|  | 1348 | /// Emits single reduction combiner | 
|  | 1349 | void emitSingleReductionCombiner(CodeGenFunction &CGF, | 
|  | 1350 | const Expr *ReductionOp, | 
|  | 1351 | const Expr *PrivateRef, | 
|  | 1352 | const DeclRefExpr *LHS, | 
|  | 1353 | const DeclRefExpr *RHS); | 
|  | 1354 |  | 
|  | 1355 | struct ReductionOptionsTy { | 
|  | 1356 | bool WithNowait; | 
|  | 1357 | bool SimpleReduction; | 
|  | 1358 | OpenMPDirectiveKind ReductionKind; | 
|  | 1359 | }; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1360 | /// Emit a code for reduction clause. Next code should be emitted for | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1361 | /// reduction: | 
|  | 1362 | /// \code | 
|  | 1363 | /// | 
|  | 1364 | /// static kmp_critical_name lock = { 0 }; | 
|  | 1365 | /// | 
|  | 1366 | /// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { | 
|  | 1367 | ///  ... | 
|  | 1368 | ///  *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]); | 
|  | 1369 | ///  ... | 
|  | 1370 | /// } | 
|  | 1371 | /// | 
|  | 1372 | /// ... | 
|  | 1373 | /// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]}; | 
|  | 1374 | /// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), | 
|  | 1375 | /// RedList, reduce_func, &<lock>)) { | 
|  | 1376 | /// case 1: | 
|  | 1377 | ///  ... | 
|  | 1378 | ///  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]); | 
|  | 1379 | ///  ... | 
|  | 1380 | /// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>); | 
|  | 1381 | /// break; | 
|  | 1382 | /// case 2: | 
|  | 1383 | ///  ... | 
|  | 1384 | ///  Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i])); | 
|  | 1385 | ///  ... | 
|  | 1386 | /// break; | 
|  | 1387 | /// default:; | 
|  | 1388 | /// } | 
|  | 1389 | /// \endcode | 
|  | 1390 | /// | 
| Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 1391 | /// \param Privates List of private copies for original reduction arguments. | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1392 | /// \param LHSExprs List of LHS in \a ReductionOps reduction operations. | 
|  | 1393 | /// \param RHSExprs List of RHS in \a ReductionOps reduction operations. | 
|  | 1394 | /// \param ReductionOps List of reduction operations in form 'LHS binop RHS' | 
|  | 1395 | /// or 'operator binop(LHS, RHS)'. | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 1396 | /// \param Options List of options for reduction codegen: | 
|  | 1397 | ///     WithNowait true if parent directive has also nowait clause, false | 
|  | 1398 | ///     otherwise. | 
|  | 1399 | ///     SimpleReduction Emit reduction operation only. Used for omp simd | 
|  | 1400 | ///     directive on the host. | 
|  | 1401 | ///     ReductionKind The kind of reduction to perform. | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1402 | virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, | 
| Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 1403 | ArrayRef<const Expr *> Privates, | 
| Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 1404 | ArrayRef<const Expr *> LHSExprs, | 
|  | 1405 | ArrayRef<const Expr *> RHSExprs, | 
|  | 1406 | ArrayRef<const Expr *> ReductionOps, | 
| Arpith Chacko Jacob | 101e8fb | 2017-02-16 16:20:16 +0000 | [diff] [blame] | 1407 | ReductionOptionsTy Options); | 
| Alexey Bataev | 8b8e202 | 2015-04-27 05:22:09 +0000 | [diff] [blame] | 1408 |  | 
| Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 1409 | /// Emit a code for initialization of task reduction clause. Next code | 
|  | 1410 | /// should be emitted for reduction: | 
|  | 1411 | /// \code | 
|  | 1412 | /// | 
|  | 1413 | /// _task_red_item_t red_data[n]; | 
|  | 1414 | /// ... | 
|  | 1415 | /// red_data[i].shar = &origs[i]; | 
|  | 1416 | /// red_data[i].size = sizeof(origs[i]); | 
|  | 1417 | /// red_data[i].f_init = (void*)RedInit<i>; | 
|  | 1418 | /// red_data[i].f_fini = (void*)RedDest<i>; | 
|  | 1419 | /// red_data[i].f_comb = (void*)RedOp<i>; | 
|  | 1420 | /// red_data[i].flags = <Flag_i>; | 
|  | 1421 | /// ... | 
|  | 1422 | /// void* tg1 = __kmpc_task_reduction_init(gtid, n, red_data); | 
|  | 1423 | /// \endcode | 
|  | 1424 | /// | 
|  | 1425 | /// \param LHSExprs List of LHS in \a Data.ReductionOps reduction operations. | 
|  | 1426 | /// \param RHSExprs List of RHS in \a Data.ReductionOps reduction operations. | 
|  | 1427 | /// \param Data Additional data for task generation like tiedness, final | 
|  | 1428 | /// state, list of privates, reductions etc. | 
|  | 1429 | virtual llvm::Value *emitTaskReductionInit(CodeGenFunction &CGF, | 
|  | 1430 | SourceLocation Loc, | 
|  | 1431 | ArrayRef<const Expr *> LHSExprs, | 
|  | 1432 | ArrayRef<const Expr *> RHSExprs, | 
|  | 1433 | const OMPTaskDataTy &Data); | 
|  | 1434 |  | 
|  | 1435 | /// Required to resolve existing problems in the runtime. Emits threadprivate | 
|  | 1436 | /// variables to store the size of the VLAs/array sections for | 
|  | 1437 | /// initializer/combiner/finalizer functions + emits threadprivate variable to | 
|  | 1438 | /// store the pointer to the original reduction item for the custom | 
|  | 1439 | /// initializer defined by declare reduction construct. | 
|  | 1440 | /// \param RCG Allows to reuse an existing data for the reductions. | 
|  | 1441 | /// \param N Reduction item for which fixups must be emitted. | 
|  | 1442 | virtual void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1443 | ReductionCodeGen &RCG, unsigned N); | 
|  | 1444 |  | 
|  | 1445 | /// Get the address of `void *` type of the privatue copy of the reduction | 
|  | 1446 | /// item specified by the \p SharedLVal. | 
|  | 1447 | /// \param ReductionsPtr Pointer to the reduction data returned by the | 
|  | 1448 | /// emitTaskReductionInit function. | 
|  | 1449 | /// \param SharedLVal Address of the original reduction item. | 
|  | 1450 | virtual Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1451 | llvm::Value *ReductionsPtr, | 
|  | 1452 | LValue SharedLVal); | 
|  | 1453 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1454 | /// Emit code for 'taskwait' directive. | 
| Alexey Bataev | 8b8e202 | 2015-04-27 05:22:09 +0000 | [diff] [blame] | 1455 | virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc); | 
| Alexey Bataev | 0f34da1 | 2015-07-02 04:17:07 +0000 | [diff] [blame] | 1456 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1457 | /// Emit code for 'cancellation point' construct. | 
| Alexey Bataev | 0f34da1 | 2015-07-02 04:17:07 +0000 | [diff] [blame] | 1458 | /// \param CancelRegion Region kind for which the cancellation point must be | 
|  | 1459 | /// emitted. | 
|  | 1460 | /// | 
|  | 1461 | virtual void emitCancellationPointCall(CodeGenFunction &CGF, | 
|  | 1462 | SourceLocation Loc, | 
|  | 1463 | OpenMPDirectiveKind CancelRegion); | 
| Alexey Bataev | 7d5d33e | 2015-07-06 05:50:32 +0000 | [diff] [blame] | 1464 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1465 | /// Emit code for 'cancel' construct. | 
| Alexey Bataev | 87933c7 | 2015-09-18 08:07:34 +0000 | [diff] [blame] | 1466 | /// \param IfCond Condition in the associated 'if' clause, if it was | 
|  | 1467 | /// specified, nullptr otherwise. | 
| Alexey Bataev | 7d5d33e | 2015-07-06 05:50:32 +0000 | [diff] [blame] | 1468 | /// \param CancelRegion Region kind for which the cancel must be emitted. | 
|  | 1469 | /// | 
|  | 1470 | virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, | 
| Alexey Bataev | 87933c7 | 2015-09-18 08:07:34 +0000 | [diff] [blame] | 1471 | const Expr *IfCond, | 
| Alexey Bataev | 7d5d33e | 2015-07-06 05:50:32 +0000 | [diff] [blame] | 1472 | OpenMPDirectiveKind CancelRegion); | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 1473 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1474 | /// Emit outilined function for 'target' directive. | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 1475 | /// \param D Directive to emit. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 1476 | /// \param ParentName Name of the function that encloses the target region. | 
|  | 1477 | /// \param OutlinedFn Outlined function value to be defined by this call. | 
|  | 1478 | /// \param OutlinedFnID Outlined function ID value to be defined by this call. | 
|  | 1479 | /// \param IsOffloadEntry True if the outlined function is an offload entry. | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 1480 | /// \param CodeGen Code generation sequence for the \a D directive. | 
| Simon Pilgrim | 6c0eeff | 2017-07-13 17:34:44 +0000 | [diff] [blame] | 1481 | /// An outlined function may not be an entry if, e.g. the if clause always | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 1482 | /// evaluates to false. | 
|  | 1483 | virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D, | 
|  | 1484 | StringRef ParentName, | 
|  | 1485 | llvm::Function *&OutlinedFn, | 
|  | 1486 | llvm::Constant *&OutlinedFnID, | 
| Alexey Bataev | 14fa1c6 | 2016-03-29 05:34:15 +0000 | [diff] [blame] | 1487 | bool IsOffloadEntry, | 
|  | 1488 | const RegionCodeGenTy &CodeGen); | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 1489 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1490 | /// Emit the target offloading code associated with \a D. The emitted | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 1491 | /// code attempts offloading the execution to the device, an the event of | 
|  | 1492 | /// a failure it executes the host version outlined in \a OutlinedFn. | 
|  | 1493 | /// \param D Directive to emit. | 
|  | 1494 | /// \param OutlinedFn Host version of the code to be offloaded. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 1495 | /// \param OutlinedFnID ID of host version of the code to be offloaded. | 
| Samuel Antao | bed3c46 | 2015-10-02 16:14:20 +0000 | [diff] [blame] | 1496 | /// \param IfCond Expression evaluated in if clause associated with the target | 
|  | 1497 | /// directive, or null if no if clause is used. | 
|  | 1498 | /// \param Device Expression evaluated in device clause associated with the | 
|  | 1499 | /// target directive, or null if no device clause is used. | 
| Alexey Bataev | ec7946e | 2019-09-23 14:06:51 +0000 | [diff] [blame] | 1500 | /// \param SizeEmitter Callback to emit number of iterations for loop-based | 
|  | 1501 | /// directives. | 
|  | 1502 | virtual void | 
|  | 1503 | emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, | 
|  | 1504 | llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID, | 
|  | 1505 | const Expr *IfCond, const Expr *Device, | 
|  | 1506 | llvm::function_ref<llvm::Value *(CodeGenFunction &CGF, | 
|  | 1507 | const OMPLoopDirective &D)> | 
|  | 1508 | SizeEmitter); | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 1509 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1510 | /// Emit the target regions enclosed in \a GD function definition or | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 1511 | /// the function itself in case it is a valid device function. Returns true if | 
|  | 1512 | /// \a GD was dealt with successfully. | 
| Nico Weber | a2abe8c | 2016-01-06 19:13:49 +0000 | [diff] [blame] | 1513 | /// \param GD Function to scan. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 1514 | virtual bool emitTargetFunctions(GlobalDecl GD); | 
|  | 1515 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1516 | /// Emit the global variable if it is a valid device global variable. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 1517 | /// Returns true if \a GD was dealt with successfully. | 
|  | 1518 | /// \param GD Variable declaration to emit. | 
|  | 1519 | virtual bool emitTargetGlobalVariable(GlobalDecl GD); | 
|  | 1520 |  | 
| Alexey Bataev | 03f270c | 2018-03-30 18:31:07 +0000 | [diff] [blame] | 1521 | /// Checks if the provided global decl \a GD is a declare target variable and | 
|  | 1522 | /// registers it when emitting code for the host. | 
|  | 1523 | virtual void registerTargetGlobalVariable(const VarDecl *VD, | 
|  | 1524 | llvm::Constant *Addr); | 
|  | 1525 |  | 
| Alexey Bataev | 1af5bd5 | 2019-03-05 17:47:18 +0000 | [diff] [blame] | 1526 | /// Registers provided target firstprivate variable as global on the | 
|  | 1527 | /// target. | 
|  | 1528 | llvm::Constant *registerTargetFirstprivateCopy(CodeGenFunction &CGF, | 
|  | 1529 | const VarDecl *VD); | 
|  | 1530 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1531 | /// Emit the global \a GD if it is meaningful for the target. Returns | 
| Simon Pilgrim | 2c51880 | 2017-03-30 14:13:19 +0000 | [diff] [blame] | 1532 | /// if it was emitted successfully. | 
| Samuel Antao | ee8fb30 | 2016-01-06 13:42:12 +0000 | [diff] [blame] | 1533 | /// \param GD Global to scan. | 
|  | 1534 | virtual bool emitTargetGlobal(GlobalDecl GD); | 
|  | 1535 |  | 
| Gheorghe-Teodor Bercea | 66cdbb47 | 2019-05-21 19:42:01 +0000 | [diff] [blame] | 1536 | /// Creates and returns a registration function for when at least one | 
|  | 1537 | /// requires directives was used in the current module. | 
|  | 1538 | llvm::Function *emitRequiresDirectiveRegFun(); | 
|  | 1539 |  | 
| Sergey Dmitriev | 5836c35 | 2019-10-15 18:42:47 +0000 | [diff] [blame] | 1540 | /// Creates all the offload entries in the current compilation unit | 
|  | 1541 | /// along with the associated metadata. | 
|  | 1542 | void createOffloadEntriesAndInfoMetadata(); | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 1543 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1544 | /// Emits code for teams call of the \a OutlinedFn with | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 1545 | /// variables captured in a record which address is stored in \a | 
|  | 1546 | /// CapturedStruct. | 
|  | 1547 | /// \param OutlinedFn Outlined function to be run by team masters. Type of | 
|  | 1548 | /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*). | 
|  | 1549 | /// \param CapturedVars A pointer to the record with the references to | 
|  | 1550 | /// variables used in \a OutlinedFn function. | 
|  | 1551 | /// | 
|  | 1552 | virtual void emitTeamsCall(CodeGenFunction &CGF, | 
|  | 1553 | const OMPExecutableDirective &D, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1554 | SourceLocation Loc, llvm::Function *OutlinedFn, | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 1555 | ArrayRef<llvm::Value *> CapturedVars); | 
|  | 1556 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1557 | /// Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 | 
| Carlo Bertolli | 430d8ec | 2016-03-03 20:34:23 +0000 | [diff] [blame] | 1558 | /// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code | 
|  | 1559 | /// for num_teams clause. | 
| Carlo Bertolli | c687225 | 2016-04-04 15:55:02 +0000 | [diff] [blame] | 1560 | /// \param NumTeams An integer expression of teams. | 
|  | 1561 | /// \param ThreadLimit An integer expression of threads. | 
|  | 1562 | virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams, | 
|  | 1563 | const Expr *ThreadLimit, SourceLocation Loc); | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 1564 |  | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 1565 | /// Struct that keeps all the relevant information that should be kept | 
|  | 1566 | /// throughout a 'target data' region. | 
|  | 1567 | class TargetDataInfo { | 
|  | 1568 | /// Set to true if device pointer information have to be obtained. | 
|  | 1569 | bool RequiresDevicePointerInfo = false; | 
|  | 1570 |  | 
|  | 1571 | public: | 
|  | 1572 | /// The array of base pointer passed to the runtime library. | 
|  | 1573 | llvm::Value *BasePointersArray = nullptr; | 
|  | 1574 | /// The array of section pointers passed to the runtime library. | 
|  | 1575 | llvm::Value *PointersArray = nullptr; | 
|  | 1576 | /// The array of sizes passed to the runtime library. | 
|  | 1577 | llvm::Value *SizesArray = nullptr; | 
|  | 1578 | /// The array of map types passed to the runtime library. | 
|  | 1579 | llvm::Value *MapTypesArray = nullptr; | 
|  | 1580 | /// The total number of pointers passed to the runtime library. | 
|  | 1581 | unsigned NumberOfPtrs = 0u; | 
|  | 1582 | /// Map between the a declaration of a capture and the corresponding base | 
|  | 1583 | /// pointer address where the runtime returns the device pointers. | 
|  | 1584 | llvm::DenseMap<const ValueDecl *, Address> CaptureDeviceAddrMap; | 
|  | 1585 |  | 
|  | 1586 | explicit TargetDataInfo() {} | 
|  | 1587 | explicit TargetDataInfo(bool RequiresDevicePointerInfo) | 
|  | 1588 | : RequiresDevicePointerInfo(RequiresDevicePointerInfo) {} | 
|  | 1589 | /// Clear information about the data arrays. | 
|  | 1590 | void clearArrayInfo() { | 
|  | 1591 | BasePointersArray = nullptr; | 
|  | 1592 | PointersArray = nullptr; | 
|  | 1593 | SizesArray = nullptr; | 
|  | 1594 | MapTypesArray = nullptr; | 
|  | 1595 | NumberOfPtrs = 0u; | 
|  | 1596 | } | 
|  | 1597 | /// Return true if the current target data information has valid arrays. | 
|  | 1598 | bool isValid() { | 
|  | 1599 | return BasePointersArray && PointersArray && SizesArray && | 
|  | 1600 | MapTypesArray && NumberOfPtrs; | 
|  | 1601 | } | 
|  | 1602 | bool requiresDevicePointerInfo() { return RequiresDevicePointerInfo; } | 
|  | 1603 | }; | 
|  | 1604 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1605 | /// Emit the target data mapping code associated with \a D. | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 1606 | /// \param D Directive to emit. | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 1607 | /// \param IfCond Expression evaluated in if clause associated with the | 
|  | 1608 | /// target directive, or null if no device clause is used. | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 1609 | /// \param Device Expression evaluated in device clause associated with the | 
|  | 1610 | /// target directive, or null if no device clause is used. | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 1611 | /// \param Info A record used to store information that needs to be preserved | 
|  | 1612 | /// until the region is closed. | 
| Samuel Antao | df158d5 | 2016-04-27 22:58:19 +0000 | [diff] [blame] | 1613 | virtual void emitTargetDataCalls(CodeGenFunction &CGF, | 
|  | 1614 | const OMPExecutableDirective &D, | 
|  | 1615 | const Expr *IfCond, const Expr *Device, | 
| Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 1616 | const RegionCodeGenTy &CodeGen, | 
|  | 1617 | TargetDataInfo &Info); | 
| Samuel Antao | bd0ae2e | 2016-04-27 23:07:29 +0000 | [diff] [blame] | 1618 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1619 | /// Emit the data mapping/movement code associated with the directive | 
| Samuel Antao | 8d2d730 | 2016-05-26 18:30:22 +0000 | [diff] [blame] | 1620 | /// \a D that should be of the form 'target [{enter|exit} data | update]'. | 
| Samuel Antao | bd0ae2e | 2016-04-27 23:07:29 +0000 | [diff] [blame] | 1621 | /// \param D Directive to emit. | 
|  | 1622 | /// \param IfCond Expression evaluated in if clause associated with the target | 
|  | 1623 | /// directive, or null if no if clause is used. | 
|  | 1624 | /// \param Device Expression evaluated in device clause associated with the | 
|  | 1625 | /// target directive, or null if no device clause is used. | 
| Samuel Antao | 8d2d730 | 2016-05-26 18:30:22 +0000 | [diff] [blame] | 1626 | virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF, | 
|  | 1627 | const OMPExecutableDirective &D, | 
|  | 1628 | const Expr *IfCond, | 
|  | 1629 | const Expr *Device); | 
| Alexey Bataev | c7a82b4 | 2016-05-06 09:40:08 +0000 | [diff] [blame] | 1630 |  | 
|  | 1631 | /// Marks function \a Fn with properly mangled versions of vector functions. | 
|  | 1632 | /// \param FD Function marked as 'declare simd'. | 
|  | 1633 | /// \param Fn LLVM function that must be marked with 'declare simd' | 
|  | 1634 | /// attributes. | 
|  | 1635 | virtual void emitDeclareSimdFunction(const FunctionDecl *FD, | 
|  | 1636 | llvm::Function *Fn); | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 1637 |  | 
|  | 1638 | /// Emit initialization for doacross loop nesting support. | 
|  | 1639 | /// \param D Loop-based construct used in doacross nesting construct. | 
| Alexey Bataev | f138fda | 2018-08-13 19:04:24 +0000 | [diff] [blame] | 1640 | virtual void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, | 
|  | 1641 | ArrayRef<Expr *> NumIterations); | 
| Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 1642 |  | 
|  | 1643 | /// Emit code for doacross ordered directive with 'depend' clause. | 
|  | 1644 | /// \param C 'depend' clause with 'sink|source' dependency kind. | 
|  | 1645 | virtual void emitDoacrossOrdered(CodeGenFunction &CGF, | 
|  | 1646 | const OMPDependClause *C); | 
| Alexey Bataev | 2c7eee5 | 2017-08-04 19:10:54 +0000 | [diff] [blame] | 1647 |  | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 1648 | /// Translates the native parameter of outlined function if this is required | 
|  | 1649 | /// for target. | 
| Alexander Kornienko | 2a8c18d | 2018-04-06 15:14:32 +0000 | [diff] [blame] | 1650 | /// \param FD Field decl from captured record for the parameter. | 
| Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 1651 | /// \param NativeParam Parameter itself. | 
|  | 1652 | virtual const VarDecl *translateParameter(const FieldDecl *FD, | 
|  | 1653 | const VarDecl *NativeParam) const { | 
|  | 1654 | return NativeParam; | 
|  | 1655 | } | 
|  | 1656 |  | 
|  | 1657 | /// Gets the address of the native argument basing on the address of the | 
|  | 1658 | /// target-specific parameter. | 
|  | 1659 | /// \param NativeParam Parameter itself. | 
|  | 1660 | /// \param TargetParam Corresponding target-specific parameter. | 
|  | 1661 | virtual Address getParameterAddress(CodeGenFunction &CGF, | 
|  | 1662 | const VarDecl *NativeParam, | 
|  | 1663 | const VarDecl *TargetParam) const; | 
|  | 1664 |  | 
| Gheorghe-Teodor Bercea | 02650d4 | 2018-09-27 19:22:56 +0000 | [diff] [blame] | 1665 | /// Choose default schedule type and chunk value for the | 
|  | 1666 | /// dist_schedule clause. | 
|  | 1667 | virtual void getDefaultDistScheduleAndChunk(CodeGenFunction &CGF, | 
|  | 1668 | const OMPLoopDirective &S, OpenMPDistScheduleClauseKind &ScheduleKind, | 
|  | 1669 | llvm::Value *&Chunk) const {} | 
|  | 1670 |  | 
| Gheorghe-Teodor Bercea | 8233af9 | 2018-09-27 20:29:00 +0000 | [diff] [blame] | 1671 | /// Choose default schedule type and chunk value for the | 
|  | 1672 | /// schedule clause. | 
|  | 1673 | virtual void getDefaultScheduleAndChunk(CodeGenFunction &CGF, | 
|  | 1674 | const OMPLoopDirective &S, OpenMPScheduleClauseKind &ScheduleKind, | 
| Alexey Bataev | f6a53d6 | 2019-03-18 18:40:00 +0000 | [diff] [blame] | 1675 | const Expr *&ChunkExpr) const; | 
| Gheorghe-Teodor Bercea | 8233af9 | 2018-09-27 20:29:00 +0000 | [diff] [blame] | 1676 |  | 
| Alexey Bataev | 2c7eee5 | 2017-08-04 19:10:54 +0000 | [diff] [blame] | 1677 | /// Emits call of the outlined function with the provided arguments, | 
|  | 1678 | /// translating these arguments to correct target-specific arguments. | 
|  | 1679 | virtual void | 
| Alexey Bataev | 3c595a6 | 2017-08-14 15:01:03 +0000 | [diff] [blame] | 1680 | emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1681 | llvm::FunctionCallee OutlinedFn, | 
| Alexey Bataev | 2c7eee5 | 2017-08-04 19:10:54 +0000 | [diff] [blame] | 1682 | ArrayRef<llvm::Value *> Args = llvm::None) const; | 
| Gheorghe-Teodor Bercea | d3dcf2f | 2018-03-14 14:17:45 +0000 | [diff] [blame] | 1683 |  | 
|  | 1684 | /// Emits OpenMP-specific function prolog. | 
|  | 1685 | /// Required for device constructs. | 
| Gheorghe-Teodor Bercea | 66cdbb47 | 2019-05-21 19:42:01 +0000 | [diff] [blame] | 1686 | virtual void emitFunctionProlog(CodeGenFunction &CGF, const Decl *D); | 
| Gheorghe-Teodor Bercea | d3dcf2f | 2018-03-14 14:17:45 +0000 | [diff] [blame] | 1687 |  | 
|  | 1688 | /// Gets the OpenMP-specific address of the local variable. | 
|  | 1689 | virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF, | 
|  | 1690 | const VarDecl *VD); | 
| Alexey Bataev | 4f4bf7c | 2018-03-15 15:47:20 +0000 | [diff] [blame] | 1691 |  | 
| Raphael Isemann | b23ccec | 2018-12-10 12:37:46 +0000 | [diff] [blame] | 1692 | /// Marks the declaration as already emitted for the device code and returns | 
| Alexey Bataev | 4f4bf7c | 2018-03-15 15:47:20 +0000 | [diff] [blame] | 1693 | /// true, if it was marked already, and false, otherwise. | 
| Alexey Bataev | 6d94410 | 2018-05-02 15:45:28 +0000 | [diff] [blame] | 1694 | bool markAsGlobalTarget(GlobalDecl GD); | 
| Alexey Bataev | 4f4bf7c | 2018-03-15 15:47:20 +0000 | [diff] [blame] | 1695 |  | 
| Alexey Bataev | bf8fe71 | 2018-08-07 16:14:36 +0000 | [diff] [blame] | 1696 | /// Emit deferred declare target variables marked for deferred emission. | 
|  | 1697 | void emitDeferredTargetDecls() const; | 
| Alexey Bataev | 6070542 | 2018-10-30 15:50:12 +0000 | [diff] [blame] | 1698 |  | 
|  | 1699 | /// Adjust some parameters for the target-based directives, like addresses of | 
|  | 1700 | /// the variables captured by reference in lambdas. | 
|  | 1701 | virtual void | 
|  | 1702 | adjustTargetSpecificDataForLambdas(CodeGenFunction &CGF, | 
|  | 1703 | const OMPExecutableDirective &D) const; | 
| Patrick Lyster | 8f7f586 | 2018-11-19 15:09:33 +0000 | [diff] [blame] | 1704 |  | 
|  | 1705 | /// Perform check on requires decl to ensure that target architecture | 
|  | 1706 | /// supports unified addressing | 
| Alexey Bataev | 2d4f80f | 2020-02-11 15:15:21 -0500 | [diff] [blame^] | 1707 | virtual void processRequiresDirective(const OMPRequiresDecl *D); | 
|  | 1708 |  | 
|  | 1709 | /// Gets default memory ordering as specified in requires directive. | 
|  | 1710 | llvm::AtomicOrdering getDefaultMemoryOrdering() const; | 
| Alexey Bataev | c568725 | 2019-03-21 19:35:27 +0000 | [diff] [blame] | 1711 |  | 
|  | 1712 | /// Checks if the variable has associated OMPAllocateDeclAttr attribute with | 
|  | 1713 | /// the predefined allocator and translates it into the corresponding address | 
|  | 1714 | /// space. | 
|  | 1715 | virtual bool hasAllocateAttributeForGlobalVar(const VarDecl *VD, LangAS &AS); | 
| Gheorghe-Teodor Bercea | 5254f0a | 2019-06-14 17:58:26 +0000 | [diff] [blame] | 1716 |  | 
|  | 1717 | /// Return whether the unified_shared_memory has been specified. | 
|  | 1718 | bool hasRequiresUnifiedSharedMemory() const; | 
| Alexey Bataev | 2df5f12 | 2019-10-01 20:18:32 +0000 | [diff] [blame] | 1719 |  | 
|  | 1720 | /// Emits the definition of the declare variant function. | 
|  | 1721 | virtual bool emitDeclareVariant(GlobalDecl GD, bool IsForDefinition); | 
| Alexey Bataev | 0860db9 | 2019-12-19 10:01:10 -0500 | [diff] [blame] | 1722 |  | 
|  | 1723 | /// Checks if the \p VD variable is marked as nontemporal declaration in | 
|  | 1724 | /// current context. | 
|  | 1725 | bool isNontemporalDecl(const ValueDecl *VD) const; | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 1726 |  | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 1727 | /// Create specialized alloca to handle lastprivate conditionals. | 
|  | 1728 | Address emitLastprivateConditionalInit(CodeGenFunction &CGF, | 
|  | 1729 | const VarDecl *VD); | 
|  | 1730 |  | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 1731 | /// Checks if the provided \p LVal is lastprivate conditional and emits the | 
|  | 1732 | /// code to update the value of the original variable. | 
|  | 1733 | /// \code | 
|  | 1734 | /// lastprivate(conditional: a) | 
|  | 1735 | /// ... | 
|  | 1736 | /// <type> a; | 
|  | 1737 | /// lp_a = ...; | 
|  | 1738 | /// #pragma omp critical(a) | 
|  | 1739 | /// if (last_iv_a <= iv) { | 
|  | 1740 | ///   last_iv_a = iv; | 
|  | 1741 | ///   global_a = lp_a; | 
|  | 1742 | /// } | 
|  | 1743 | /// \endcode | 
|  | 1744 | virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, | 
|  | 1745 | const Expr *LHS); | 
|  | 1746 |  | 
| Alexey Bataev | 4697874 | 2020-01-30 10:46:11 -0500 | [diff] [blame] | 1747 | /// Checks if the lastprivate conditional was updated in inner region and | 
|  | 1748 | /// writes the value. | 
|  | 1749 | /// \code | 
|  | 1750 | /// lastprivate(conditional: a) | 
|  | 1751 | /// ... | 
|  | 1752 | /// <type> a;bool Fired = false; | 
|  | 1753 | /// #pragma omp ... shared(a) | 
|  | 1754 | /// { | 
|  | 1755 | ///   lp_a = ...; | 
|  | 1756 | ///   Fired = true; | 
|  | 1757 | /// } | 
|  | 1758 | /// if (Fired) { | 
|  | 1759 | ///   #pragma omp critical(a) | 
|  | 1760 | ///   if (last_iv_a <= iv) { | 
|  | 1761 | ///     last_iv_a = iv; | 
|  | 1762 | ///     global_a = lp_a; | 
|  | 1763 | ///   } | 
|  | 1764 | ///   Fired = false; | 
|  | 1765 | /// } | 
|  | 1766 | /// \endcode | 
|  | 1767 | virtual void checkAndEmitSharedLastprivateConditional( | 
|  | 1768 | CodeGenFunction &CGF, const OMPExecutableDirective &D, | 
|  | 1769 | const llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> &IgnoredDecls); | 
|  | 1770 |  | 
| Alexey Bataev | a58da1a | 2019-12-27 09:44:43 -0500 | [diff] [blame] | 1771 | /// Gets the address of the global copy used for lastprivate conditional | 
|  | 1772 | /// update, if any. | 
|  | 1773 | /// \param PrivLVal LValue for the private copy. | 
|  | 1774 | /// \param VD Original lastprivate declaration. | 
|  | 1775 | virtual void emitLastprivateConditionalFinalUpdate(CodeGenFunction &CGF, | 
|  | 1776 | LValue PrivLVal, | 
|  | 1777 | const VarDecl *VD, | 
|  | 1778 | SourceLocation Loc); | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 1779 | }; | 
| Alexey Bataev | 8cbe0a6 | 2015-02-26 10:27:34 +0000 | [diff] [blame] | 1780 |  | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1781 | /// Class supports emissionof SIMD-only code. | 
|  | 1782 | class CGOpenMPSIMDRuntime final : public CGOpenMPRuntime { | 
|  | 1783 | public: | 
|  | 1784 | explicit CGOpenMPSIMDRuntime(CodeGenModule &CGM) : CGOpenMPRuntime(CGM) {} | 
|  | 1785 | ~CGOpenMPSIMDRuntime() override {} | 
|  | 1786 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1787 | /// Emits outlined function for the specified OpenMP parallel directive | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1788 | /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID, | 
|  | 1789 | /// kmp_int32 BoundID, struct context_vars*). | 
|  | 1790 | /// \param D OpenMP directive. | 
|  | 1791 | /// \param ThreadIDVar Variable for thread id in the current OpenMP region. | 
|  | 1792 | /// \param InnermostKind Kind of innermost directive (for simple directives it | 
|  | 1793 | /// is a directive itself, for combined - its innermost directive). | 
|  | 1794 | /// \param CodeGen Code generation sequence for the \a D directive. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1795 | llvm::Function * | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1796 | emitParallelOutlinedFunction(const OMPExecutableDirective &D, | 
|  | 1797 | const VarDecl *ThreadIDVar, | 
|  | 1798 | OpenMPDirectiveKind InnermostKind, | 
|  | 1799 | const RegionCodeGenTy &CodeGen) override; | 
|  | 1800 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1801 | /// Emits outlined function for the specified OpenMP teams directive | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1802 | /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID, | 
|  | 1803 | /// kmp_int32 BoundID, struct context_vars*). | 
|  | 1804 | /// \param D OpenMP directive. | 
|  | 1805 | /// \param ThreadIDVar Variable for thread id in the current OpenMP region. | 
|  | 1806 | /// \param InnermostKind Kind of innermost directive (for simple directives it | 
|  | 1807 | /// is a directive itself, for combined - its innermost directive). | 
|  | 1808 | /// \param CodeGen Code generation sequence for the \a D directive. | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1809 | llvm::Function * | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1810 | emitTeamsOutlinedFunction(const OMPExecutableDirective &D, | 
|  | 1811 | const VarDecl *ThreadIDVar, | 
|  | 1812 | OpenMPDirectiveKind InnermostKind, | 
|  | 1813 | const RegionCodeGenTy &CodeGen) override; | 
|  | 1814 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1815 | /// Emits outlined function for the OpenMP task directive \a D. This | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1816 | /// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t* | 
|  | 1817 | /// TaskT). | 
|  | 1818 | /// \param D OpenMP directive. | 
|  | 1819 | /// \param ThreadIDVar Variable for thread id in the current OpenMP region. | 
|  | 1820 | /// \param PartIDVar Variable for partition id in the current OpenMP untied | 
|  | 1821 | /// task region. | 
|  | 1822 | /// \param TaskTVar Variable for task_t argument. | 
|  | 1823 | /// \param InnermostKind Kind of innermost directive (for simple directives it | 
|  | 1824 | /// is a directive itself, for combined - its innermost directive). | 
|  | 1825 | /// \param CodeGen Code generation sequence for the \a D directive. | 
|  | 1826 | /// \param Tied true if task is generated for tied task, false otherwise. | 
|  | 1827 | /// \param NumberOfParts Number of parts in untied task. Ignored for tied | 
|  | 1828 | /// tasks. | 
|  | 1829 | /// | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1830 | llvm::Function *emitTaskOutlinedFunction( | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1831 | const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, | 
|  | 1832 | const VarDecl *PartIDVar, const VarDecl *TaskTVar, | 
|  | 1833 | OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, | 
|  | 1834 | bool Tied, unsigned &NumberOfParts) override; | 
|  | 1835 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1836 | /// Emits code for parallel or serial call of the \a OutlinedFn with | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1837 | /// variables captured in a record which address is stored in \a | 
|  | 1838 | /// CapturedStruct. | 
|  | 1839 | /// \param OutlinedFn Outlined function to be run in parallel threads. Type of | 
|  | 1840 | /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*). | 
|  | 1841 | /// \param CapturedVars A pointer to the record with the references to | 
|  | 1842 | /// variables used in \a OutlinedFn function. | 
|  | 1843 | /// \param IfCond Condition in the associated 'if' clause, if it was | 
|  | 1844 | /// specified, nullptr otherwise. | 
|  | 1845 | /// | 
|  | 1846 | void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 1847 | llvm::Function *OutlinedFn, | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1848 | ArrayRef<llvm::Value *> CapturedVars, | 
|  | 1849 | const Expr *IfCond) override; | 
|  | 1850 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1851 | /// Emits a critical region. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1852 | /// \param CriticalName Name of the critical region. | 
|  | 1853 | /// \param CriticalOpGen Generator for the statement associated with the given | 
|  | 1854 | /// critical region. | 
|  | 1855 | /// \param Hint Value of the 'hint' clause (optional). | 
|  | 1856 | void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, | 
|  | 1857 | const RegionCodeGenTy &CriticalOpGen, | 
|  | 1858 | SourceLocation Loc, | 
|  | 1859 | const Expr *Hint = nullptr) override; | 
|  | 1860 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1861 | /// Emits a master region. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1862 | /// \param MasterOpGen Generator for the statement associated with the given | 
|  | 1863 | /// master region. | 
|  | 1864 | void emitMasterRegion(CodeGenFunction &CGF, | 
|  | 1865 | const RegionCodeGenTy &MasterOpGen, | 
|  | 1866 | SourceLocation Loc) override; | 
|  | 1867 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1868 | /// Emits code for a taskyield directive. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1869 | void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc) override; | 
|  | 1870 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1871 | /// Emit a taskgroup region. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1872 | /// \param TaskgroupOpGen Generator for the statement associated with the | 
|  | 1873 | /// given taskgroup region. | 
|  | 1874 | void emitTaskgroupRegion(CodeGenFunction &CGF, | 
|  | 1875 | const RegionCodeGenTy &TaskgroupOpGen, | 
|  | 1876 | SourceLocation Loc) override; | 
|  | 1877 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1878 | /// Emits a single region. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1879 | /// \param SingleOpGen Generator for the statement associated with the given | 
|  | 1880 | /// single region. | 
|  | 1881 | void emitSingleRegion(CodeGenFunction &CGF, | 
|  | 1882 | const RegionCodeGenTy &SingleOpGen, SourceLocation Loc, | 
|  | 1883 | ArrayRef<const Expr *> CopyprivateVars, | 
|  | 1884 | ArrayRef<const Expr *> DestExprs, | 
|  | 1885 | ArrayRef<const Expr *> SrcExprs, | 
|  | 1886 | ArrayRef<const Expr *> AssignmentOps) override; | 
|  | 1887 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1888 | /// Emit an ordered region. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1889 | /// \param OrderedOpGen Generator for the statement associated with the given | 
|  | 1890 | /// ordered region. | 
|  | 1891 | void emitOrderedRegion(CodeGenFunction &CGF, | 
|  | 1892 | const RegionCodeGenTy &OrderedOpGen, | 
|  | 1893 | SourceLocation Loc, bool IsThreads) override; | 
|  | 1894 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1895 | /// Emit an implicit/explicit barrier for OpenMP threads. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1896 | /// \param Kind Directive for which this implicit barrier call must be | 
|  | 1897 | /// generated. Must be OMPD_barrier for explicit barrier generation. | 
|  | 1898 | /// \param EmitChecks true if need to emit checks for cancellation barriers. | 
|  | 1899 | /// \param ForceSimpleCall true simple barrier call must be emitted, false if | 
|  | 1900 | /// runtime class decides which one to emit (simple or with cancellation | 
|  | 1901 | /// checks). | 
|  | 1902 | /// | 
|  | 1903 | void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1904 | OpenMPDirectiveKind Kind, bool EmitChecks = true, | 
|  | 1905 | bool ForceSimpleCall = false) override; | 
|  | 1906 |  | 
|  | 1907 | /// This is used for non static scheduled types and when the ordered | 
|  | 1908 | /// clause is present on the loop construct. | 
|  | 1909 | /// Depending on the loop schedule, it is necessary to call some runtime | 
|  | 1910 | /// routine before start of the OpenMP loop to get the loop upper / lower | 
|  | 1911 | /// bounds \a LB and \a UB and stride \a ST. | 
|  | 1912 | /// | 
|  | 1913 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1914 | /// \param Loc Clang source location. | 
|  | 1915 | /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause. | 
|  | 1916 | /// \param IVSize Size of the iteration variable in bits. | 
|  | 1917 | /// \param IVSigned Sign of the iteration variable. | 
|  | 1918 | /// \param Ordered true if loop is ordered, false otherwise. | 
|  | 1919 | /// \param DispatchValues struct containing llvm values for lower bound, upper | 
|  | 1920 | /// bound, and chunk expression. | 
|  | 1921 | /// For the default (nullptr) value, the chunk 1 will be used. | 
|  | 1922 | /// | 
|  | 1923 | void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1924 | const OpenMPScheduleTy &ScheduleKind, | 
|  | 1925 | unsigned IVSize, bool IVSigned, bool Ordered, | 
|  | 1926 | const DispatchRTInput &DispatchValues) override; | 
|  | 1927 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1928 | /// Call the appropriate runtime routine to initialize it before start | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1929 | /// of loop. | 
|  | 1930 | /// | 
|  | 1931 | /// This is used only in case of static schedule, when the user did not | 
|  | 1932 | /// specify a ordered clause on the loop construct. | 
|  | 1933 | /// Depending on the loop schedule, it is necessary to call some runtime | 
|  | 1934 | /// routine before start of the OpenMP loop to get the loop upper / lower | 
|  | 1935 | /// bounds LB and UB and stride ST. | 
|  | 1936 | /// | 
|  | 1937 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1938 | /// \param Loc Clang source location. | 
|  | 1939 | /// \param DKind Kind of the directive. | 
|  | 1940 | /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause. | 
|  | 1941 | /// \param Values Input arguments for the construct. | 
|  | 1942 | /// | 
|  | 1943 | void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1944 | OpenMPDirectiveKind DKind, | 
|  | 1945 | const OpenMPScheduleTy &ScheduleKind, | 
|  | 1946 | const StaticRTInput &Values) override; | 
|  | 1947 |  | 
|  | 1948 | /// | 
|  | 1949 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1950 | /// \param Loc Clang source location. | 
|  | 1951 | /// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause. | 
|  | 1952 | /// \param Values Input arguments for the construct. | 
|  | 1953 | /// | 
|  | 1954 | void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1955 | OpenMPDistScheduleClauseKind SchedKind, | 
|  | 1956 | const StaticRTInput &Values) override; | 
|  | 1957 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1958 | /// Call the appropriate runtime routine to notify that we finished | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1959 | /// iteration of the ordered loop with the dynamic scheduling. | 
|  | 1960 | /// | 
|  | 1961 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1962 | /// \param Loc Clang source location. | 
|  | 1963 | /// \param IVSize Size of the iteration variable in bits. | 
|  | 1964 | /// \param IVSigned Sign of the iteration variable. | 
|  | 1965 | /// | 
|  | 1966 | void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1967 | unsigned IVSize, bool IVSigned) override; | 
|  | 1968 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1969 | /// Call the appropriate runtime routine to notify that we finished | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1970 | /// all the work with current loop. | 
|  | 1971 | /// | 
|  | 1972 | /// \param CGF Reference to current CodeGenFunction. | 
|  | 1973 | /// \param Loc Clang source location. | 
|  | 1974 | /// \param DKind Kind of the directive for which the static finish is emitted. | 
|  | 1975 | /// | 
|  | 1976 | void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1977 | OpenMPDirectiveKind DKind) override; | 
|  | 1978 |  | 
|  | 1979 | /// Call __kmpc_dispatch_next( | 
|  | 1980 | ///          ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, | 
|  | 1981 | ///          kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper, | 
|  | 1982 | ///          kmp_int[32|64] *p_stride); | 
|  | 1983 | /// \param IVSize Size of the iteration variable in bits. | 
|  | 1984 | /// \param IVSigned Sign of the iteration variable. | 
|  | 1985 | /// \param IL Address of the output variable in which the flag of the | 
|  | 1986 | /// last iteration is returned. | 
|  | 1987 | /// \param LB Address of the output variable in which the lower iteration | 
|  | 1988 | /// number is returned. | 
|  | 1989 | /// \param UB Address of the output variable in which the upper iteration | 
|  | 1990 | /// number is returned. | 
|  | 1991 | /// \param ST Address of the output variable in which the stride value is | 
|  | 1992 | /// returned. | 
|  | 1993 | llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 1994 | unsigned IVSize, bool IVSigned, Address IL, | 
|  | 1995 | Address LB, Address UB, Address ST) override; | 
|  | 1996 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1997 | /// Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 1998 | /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads' | 
|  | 1999 | /// clause. | 
|  | 2000 | /// \param NumThreads An integer value of threads. | 
|  | 2001 | void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads, | 
|  | 2002 | SourceLocation Loc) override; | 
|  | 2003 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2004 | /// Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2005 | /// global_tid, int proc_bind) to generate code for 'proc_bind' clause. | 
|  | 2006 | void emitProcBindClause(CodeGenFunction &CGF, | 
| Johannes Doerfert | 6c5d1f40 | 2019-12-25 18:15:36 -0600 | [diff] [blame] | 2007 | llvm::omp::ProcBindKind ProcBind, | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2008 | SourceLocation Loc) override; | 
|  | 2009 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2010 | /// Returns address of the threadprivate variable for the current | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2011 | /// thread. | 
|  | 2012 | /// \param VD Threadprivate variable. | 
|  | 2013 | /// \param VDAddr Address of the global variable \a VD. | 
|  | 2014 | /// \param Loc Location of the reference to threadprivate var. | 
|  | 2015 | /// \return Address of the threadprivate variable for the current thread. | 
|  | 2016 | Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, | 
|  | 2017 | Address VDAddr, SourceLocation Loc) override; | 
|  | 2018 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2019 | /// Emit a code for initialization of threadprivate variable. It emits | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2020 | /// a call to runtime library which adds initial value to the newly created | 
|  | 2021 | /// threadprivate variable (if it is not constant) and registers destructor | 
|  | 2022 | /// for the variable (if any). | 
|  | 2023 | /// \param VD Threadprivate variable. | 
|  | 2024 | /// \param VDAddr Address of the global variable \a VD. | 
|  | 2025 | /// \param Loc Location of threadprivate declaration. | 
|  | 2026 | /// \param PerformInit true if initialization expression is not constant. | 
|  | 2027 | llvm::Function * | 
|  | 2028 | emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, | 
|  | 2029 | SourceLocation Loc, bool PerformInit, | 
|  | 2030 | CodeGenFunction *CGF = nullptr) override; | 
|  | 2031 |  | 
|  | 2032 | /// Creates artificial threadprivate variable with name \p Name and type \p | 
|  | 2033 | /// VarType. | 
|  | 2034 | /// \param VarType Type of the artificial threadprivate variable. | 
|  | 2035 | /// \param Name Name of the artificial threadprivate variable. | 
|  | 2036 | Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF, | 
|  | 2037 | QualType VarType, | 
|  | 2038 | StringRef Name) override; | 
|  | 2039 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2040 | /// Emit flush of the variables specified in 'omp flush' directive. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2041 | /// \param Vars List of variables to flush. | 
|  | 2042 | void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars, | 
| Alexey Bataev | e8e05de | 2020-02-07 12:22:23 -0500 | [diff] [blame] | 2043 | SourceLocation Loc, llvm::AtomicOrdering AO) override; | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2044 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2045 | /// Emit task region for the task directive. The task region is | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2046 | /// emitted in several steps: | 
|  | 2047 | /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 | 
|  | 2048 | /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, | 
|  | 2049 | /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the | 
|  | 2050 | /// function: | 
|  | 2051 | /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) { | 
|  | 2052 | ///   TaskFunction(gtid, tt->part_id, tt->shareds); | 
|  | 2053 | ///   return 0; | 
|  | 2054 | /// } | 
|  | 2055 | /// 2. Copy a list of shared variables to field shareds of the resulting | 
|  | 2056 | /// structure kmp_task_t returned by the previous call (if any). | 
|  | 2057 | /// 3. Copy a pointer to destructions function to field destructions of the | 
|  | 2058 | /// resulting structure kmp_task_t. | 
|  | 2059 | /// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, | 
|  | 2060 | /// kmp_task_t *new_task), where new_task is a resulting structure from | 
|  | 2061 | /// previous items. | 
|  | 2062 | /// \param D Current task directive. | 
|  | 2063 | /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32 | 
|  | 2064 | /// /*part_id*/, captured_struct */*__context*/); | 
|  | 2065 | /// \param SharedsTy A type which contains references the shared variables. | 
|  | 2066 | /// \param Shareds Context with the list of shared variables from the \p | 
|  | 2067 | /// TaskFunction. | 
|  | 2068 | /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr | 
|  | 2069 | /// otherwise. | 
|  | 2070 | /// \param Data Additional data for task generation like tiednsee, final | 
|  | 2071 | /// state, list of privates etc. | 
|  | 2072 | void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 2073 | const OMPExecutableDirective &D, | 
|  | 2074 | llvm::Function *TaskFunction, QualType SharedsTy, | 
|  | 2075 | Address Shareds, const Expr *IfCond, | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2076 | const OMPTaskDataTy &Data) override; | 
|  | 2077 |  | 
|  | 2078 | /// Emit task region for the taskloop directive. The taskloop region is | 
|  | 2079 | /// emitted in several steps: | 
|  | 2080 | /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 | 
|  | 2081 | /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, | 
|  | 2082 | /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the | 
|  | 2083 | /// function: | 
|  | 2084 | /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) { | 
|  | 2085 | ///   TaskFunction(gtid, tt->part_id, tt->shareds); | 
|  | 2086 | ///   return 0; | 
|  | 2087 | /// } | 
|  | 2088 | /// 2. Copy a list of shared variables to field shareds of the resulting | 
|  | 2089 | /// structure kmp_task_t returned by the previous call (if any). | 
|  | 2090 | /// 3. Copy a pointer to destructions function to field destructions of the | 
|  | 2091 | /// resulting structure kmp_task_t. | 
|  | 2092 | /// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t | 
|  | 2093 | /// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int | 
|  | 2094 | /// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task | 
|  | 2095 | /// is a resulting structure from | 
|  | 2096 | /// previous items. | 
|  | 2097 | /// \param D Current task directive. | 
|  | 2098 | /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32 | 
|  | 2099 | /// /*part_id*/, captured_struct */*__context*/); | 
|  | 2100 | /// \param SharedsTy A type which contains references the shared variables. | 
|  | 2101 | /// \param Shareds Context with the list of shared variables from the \p | 
|  | 2102 | /// TaskFunction. | 
|  | 2103 | /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr | 
|  | 2104 | /// otherwise. | 
|  | 2105 | /// \param Data Additional data for task generation like tiednsee, final | 
|  | 2106 | /// state, list of privates etc. | 
|  | 2107 | void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 2108 | const OMPLoopDirective &D, llvm::Function *TaskFunction, | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2109 | QualType SharedsTy, Address Shareds, const Expr *IfCond, | 
|  | 2110 | const OMPTaskDataTy &Data) override; | 
|  | 2111 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2112 | /// Emit a code for reduction clause. Next code should be emitted for | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2113 | /// reduction: | 
|  | 2114 | /// \code | 
|  | 2115 | /// | 
|  | 2116 | /// static kmp_critical_name lock = { 0 }; | 
|  | 2117 | /// | 
|  | 2118 | /// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { | 
|  | 2119 | ///  ... | 
|  | 2120 | ///  *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]); | 
|  | 2121 | ///  ... | 
|  | 2122 | /// } | 
|  | 2123 | /// | 
|  | 2124 | /// ... | 
|  | 2125 | /// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]}; | 
|  | 2126 | /// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), | 
|  | 2127 | /// RedList, reduce_func, &<lock>)) { | 
|  | 2128 | /// case 1: | 
|  | 2129 | ///  ... | 
|  | 2130 | ///  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]); | 
|  | 2131 | ///  ... | 
|  | 2132 | /// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>); | 
|  | 2133 | /// break; | 
|  | 2134 | /// case 2: | 
|  | 2135 | ///  ... | 
|  | 2136 | ///  Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i])); | 
|  | 2137 | ///  ... | 
|  | 2138 | /// break; | 
|  | 2139 | /// default:; | 
|  | 2140 | /// } | 
|  | 2141 | /// \endcode | 
|  | 2142 | /// | 
|  | 2143 | /// \param Privates List of private copies for original reduction arguments. | 
|  | 2144 | /// \param LHSExprs List of LHS in \a ReductionOps reduction operations. | 
|  | 2145 | /// \param RHSExprs List of RHS in \a ReductionOps reduction operations. | 
|  | 2146 | /// \param ReductionOps List of reduction operations in form 'LHS binop RHS' | 
|  | 2147 | /// or 'operator binop(LHS, RHS)'. | 
|  | 2148 | /// \param Options List of options for reduction codegen: | 
|  | 2149 | ///     WithNowait true if parent directive has also nowait clause, false | 
|  | 2150 | ///     otherwise. | 
|  | 2151 | ///     SimpleReduction Emit reduction operation only. Used for omp simd | 
|  | 2152 | ///     directive on the host. | 
|  | 2153 | ///     ReductionKind The kind of reduction to perform. | 
|  | 2154 | void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 2155 | ArrayRef<const Expr *> Privates, | 
|  | 2156 | ArrayRef<const Expr *> LHSExprs, | 
|  | 2157 | ArrayRef<const Expr *> RHSExprs, | 
|  | 2158 | ArrayRef<const Expr *> ReductionOps, | 
|  | 2159 | ReductionOptionsTy Options) override; | 
|  | 2160 |  | 
|  | 2161 | /// Emit a code for initialization of task reduction clause. Next code | 
|  | 2162 | /// should be emitted for reduction: | 
|  | 2163 | /// \code | 
|  | 2164 | /// | 
|  | 2165 | /// _task_red_item_t red_data[n]; | 
|  | 2166 | /// ... | 
|  | 2167 | /// red_data[i].shar = &origs[i]; | 
|  | 2168 | /// red_data[i].size = sizeof(origs[i]); | 
|  | 2169 | /// red_data[i].f_init = (void*)RedInit<i>; | 
|  | 2170 | /// red_data[i].f_fini = (void*)RedDest<i>; | 
|  | 2171 | /// red_data[i].f_comb = (void*)RedOp<i>; | 
|  | 2172 | /// red_data[i].flags = <Flag_i>; | 
|  | 2173 | /// ... | 
|  | 2174 | /// void* tg1 = __kmpc_task_reduction_init(gtid, n, red_data); | 
|  | 2175 | /// \endcode | 
|  | 2176 | /// | 
|  | 2177 | /// \param LHSExprs List of LHS in \a Data.ReductionOps reduction operations. | 
|  | 2178 | /// \param RHSExprs List of RHS in \a Data.ReductionOps reduction operations. | 
|  | 2179 | /// \param Data Additional data for task generation like tiedness, final | 
|  | 2180 | /// state, list of privates, reductions etc. | 
|  | 2181 | llvm::Value *emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 2182 | ArrayRef<const Expr *> LHSExprs, | 
|  | 2183 | ArrayRef<const Expr *> RHSExprs, | 
|  | 2184 | const OMPTaskDataTy &Data) override; | 
|  | 2185 |  | 
|  | 2186 | /// Required to resolve existing problems in the runtime. Emits threadprivate | 
|  | 2187 | /// variables to store the size of the VLAs/array sections for | 
|  | 2188 | /// initializer/combiner/finalizer functions + emits threadprivate variable to | 
|  | 2189 | /// store the pointer to the original reduction item for the custom | 
|  | 2190 | /// initializer defined by declare reduction construct. | 
|  | 2191 | /// \param RCG Allows to reuse an existing data for the reductions. | 
|  | 2192 | /// \param N Reduction item for which fixups must be emitted. | 
|  | 2193 | void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 2194 | ReductionCodeGen &RCG, unsigned N) override; | 
|  | 2195 |  | 
|  | 2196 | /// Get the address of `void *` type of the privatue copy of the reduction | 
|  | 2197 | /// item specified by the \p SharedLVal. | 
|  | 2198 | /// \param ReductionsPtr Pointer to the reduction data returned by the | 
|  | 2199 | /// emitTaskReductionInit function. | 
|  | 2200 | /// \param SharedLVal Address of the original reduction item. | 
|  | 2201 | Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 2202 | llvm::Value *ReductionsPtr, | 
|  | 2203 | LValue SharedLVal) override; | 
|  | 2204 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2205 | /// Emit code for 'taskwait' directive. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2206 | void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc) override; | 
|  | 2207 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2208 | /// Emit code for 'cancellation point' construct. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2209 | /// \param CancelRegion Region kind for which the cancellation point must be | 
|  | 2210 | /// emitted. | 
|  | 2211 | /// | 
|  | 2212 | void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 2213 | OpenMPDirectiveKind CancelRegion) override; | 
|  | 2214 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2215 | /// Emit code for 'cancel' construct. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2216 | /// \param IfCond Condition in the associated 'if' clause, if it was | 
|  | 2217 | /// specified, nullptr otherwise. | 
|  | 2218 | /// \param CancelRegion Region kind for which the cancel must be emitted. | 
|  | 2219 | /// | 
|  | 2220 | void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, | 
|  | 2221 | const Expr *IfCond, | 
|  | 2222 | OpenMPDirectiveKind CancelRegion) override; | 
|  | 2223 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2224 | /// Emit outilined function for 'target' directive. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2225 | /// \param D Directive to emit. | 
|  | 2226 | /// \param ParentName Name of the function that encloses the target region. | 
|  | 2227 | /// \param OutlinedFn Outlined function value to be defined by this call. | 
|  | 2228 | /// \param OutlinedFnID Outlined function ID value to be defined by this call. | 
|  | 2229 | /// \param IsOffloadEntry True if the outlined function is an offload entry. | 
|  | 2230 | /// \param CodeGen Code generation sequence for the \a D directive. | 
|  | 2231 | /// An outlined function may not be an entry if, e.g. the if clause always | 
|  | 2232 | /// evaluates to false. | 
|  | 2233 | void emitTargetOutlinedFunction(const OMPExecutableDirective &D, | 
|  | 2234 | StringRef ParentName, | 
|  | 2235 | llvm::Function *&OutlinedFn, | 
|  | 2236 | llvm::Constant *&OutlinedFnID, | 
|  | 2237 | bool IsOffloadEntry, | 
|  | 2238 | const RegionCodeGenTy &CodeGen) override; | 
|  | 2239 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2240 | /// Emit the target offloading code associated with \a D. The emitted | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2241 | /// code attempts offloading the execution to the device, an the event of | 
|  | 2242 | /// a failure it executes the host version outlined in \a OutlinedFn. | 
|  | 2243 | /// \param D Directive to emit. | 
|  | 2244 | /// \param OutlinedFn Host version of the code to be offloaded. | 
|  | 2245 | /// \param OutlinedFnID ID of host version of the code to be offloaded. | 
|  | 2246 | /// \param IfCond Expression evaluated in if clause associated with the target | 
|  | 2247 | /// directive, or null if no if clause is used. | 
|  | 2248 | /// \param Device Expression evaluated in device clause associated with the | 
|  | 2249 | /// target directive, or null if no device clause is used. | 
| Alexey Bataev | ec7946e | 2019-09-23 14:06:51 +0000 | [diff] [blame] | 2250 | void | 
|  | 2251 | emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, | 
|  | 2252 | llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID, | 
|  | 2253 | const Expr *IfCond, const Expr *Device, | 
|  | 2254 | llvm::function_ref<llvm::Value *(CodeGenFunction &CGF, | 
|  | 2255 | const OMPLoopDirective &D)> | 
|  | 2256 | SizeEmitter) override; | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2257 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2258 | /// Emit the target regions enclosed in \a GD function definition or | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2259 | /// the function itself in case it is a valid device function. Returns true if | 
|  | 2260 | /// \a GD was dealt with successfully. | 
|  | 2261 | /// \param GD Function to scan. | 
|  | 2262 | bool emitTargetFunctions(GlobalDecl GD) override; | 
|  | 2263 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2264 | /// Emit the global variable if it is a valid device global variable. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2265 | /// Returns true if \a GD was dealt with successfully. | 
|  | 2266 | /// \param GD Variable declaration to emit. | 
|  | 2267 | bool emitTargetGlobalVariable(GlobalDecl GD) override; | 
|  | 2268 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2269 | /// Emit the global \a GD if it is meaningful for the target. Returns | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2270 | /// if it was emitted successfully. | 
|  | 2271 | /// \param GD Global to scan. | 
|  | 2272 | bool emitTargetGlobal(GlobalDecl GD) override; | 
|  | 2273 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2274 | /// Emits code for teams call of the \a OutlinedFn with | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2275 | /// variables captured in a record which address is stored in \a | 
|  | 2276 | /// CapturedStruct. | 
|  | 2277 | /// \param OutlinedFn Outlined function to be run by team masters. Type of | 
|  | 2278 | /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*). | 
|  | 2279 | /// \param CapturedVars A pointer to the record with the references to | 
|  | 2280 | /// variables used in \a OutlinedFn function. | 
|  | 2281 | /// | 
|  | 2282 | void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, | 
| James Y Knight | 9871db0 | 2019-02-05 16:42:33 +0000 | [diff] [blame] | 2283 | SourceLocation Loc, llvm::Function *OutlinedFn, | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2284 | ArrayRef<llvm::Value *> CapturedVars) override; | 
|  | 2285 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2286 | /// Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2287 | /// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code | 
|  | 2288 | /// for num_teams clause. | 
|  | 2289 | /// \param NumTeams An integer expression of teams. | 
|  | 2290 | /// \param ThreadLimit An integer expression of threads. | 
|  | 2291 | void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams, | 
|  | 2292 | const Expr *ThreadLimit, SourceLocation Loc) override; | 
|  | 2293 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2294 | /// Emit the target data mapping code associated with \a D. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2295 | /// \param D Directive to emit. | 
|  | 2296 | /// \param IfCond Expression evaluated in if clause associated with the | 
|  | 2297 | /// target directive, or null if no device clause is used. | 
|  | 2298 | /// \param Device Expression evaluated in device clause associated with the | 
|  | 2299 | /// target directive, or null if no device clause is used. | 
|  | 2300 | /// \param Info A record used to store information that needs to be preserved | 
|  | 2301 | /// until the region is closed. | 
|  | 2302 | void emitTargetDataCalls(CodeGenFunction &CGF, | 
|  | 2303 | const OMPExecutableDirective &D, const Expr *IfCond, | 
|  | 2304 | const Expr *Device, const RegionCodeGenTy &CodeGen, | 
|  | 2305 | TargetDataInfo &Info) override; | 
|  | 2306 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2307 | /// Emit the data mapping/movement code associated with the directive | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2308 | /// \a D that should be of the form 'target [{enter|exit} data | update]'. | 
|  | 2309 | /// \param D Directive to emit. | 
|  | 2310 | /// \param IfCond Expression evaluated in if clause associated with the target | 
|  | 2311 | /// directive, or null if no if clause is used. | 
|  | 2312 | /// \param Device Expression evaluated in device clause associated with the | 
|  | 2313 | /// target directive, or null if no device clause is used. | 
|  | 2314 | void emitTargetDataStandAloneCall(CodeGenFunction &CGF, | 
|  | 2315 | const OMPExecutableDirective &D, | 
|  | 2316 | const Expr *IfCond, | 
|  | 2317 | const Expr *Device) override; | 
|  | 2318 |  | 
|  | 2319 | /// Emit initialization for doacross loop nesting support. | 
|  | 2320 | /// \param D Loop-based construct used in doacross nesting construct. | 
| Alexey Bataev | f138fda | 2018-08-13 19:04:24 +0000 | [diff] [blame] | 2321 | void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, | 
|  | 2322 | ArrayRef<Expr *> NumIterations) override; | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2323 |  | 
|  | 2324 | /// Emit code for doacross ordered directive with 'depend' clause. | 
|  | 2325 | /// \param C 'depend' clause with 'sink|source' dependency kind. | 
|  | 2326 | void emitDoacrossOrdered(CodeGenFunction &CGF, | 
|  | 2327 | const OMPDependClause *C) override; | 
|  | 2328 |  | 
|  | 2329 | /// Translates the native parameter of outlined function if this is required | 
|  | 2330 | /// for target. | 
| Alexander Kornienko | 2a8c18d | 2018-04-06 15:14:32 +0000 | [diff] [blame] | 2331 | /// \param FD Field decl from captured record for the parameter. | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2332 | /// \param NativeParam Parameter itself. | 
|  | 2333 | const VarDecl *translateParameter(const FieldDecl *FD, | 
|  | 2334 | const VarDecl *NativeParam) const override; | 
|  | 2335 |  | 
|  | 2336 | /// Gets the address of the native argument basing on the address of the | 
|  | 2337 | /// target-specific parameter. | 
|  | 2338 | /// \param NativeParam Parameter itself. | 
|  | 2339 | /// \param TargetParam Corresponding target-specific parameter. | 
|  | 2340 | Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam, | 
|  | 2341 | const VarDecl *TargetParam) const override; | 
| Alexey Bataev | 4f680db | 2019-03-19 16:41:16 +0000 | [diff] [blame] | 2342 |  | 
|  | 2343 | /// Gets the OpenMP-specific address of the local variable. | 
|  | 2344 | Address getAddressOfLocalVariable(CodeGenFunction &CGF, | 
|  | 2345 | const VarDecl *VD) override { | 
|  | 2346 | return Address::invalid(); | 
|  | 2347 | } | 
| Alexey Bataev | a8a9153a | 2017-12-29 18:07:07 +0000 | [diff] [blame] | 2348 | }; | 
|  | 2349 |  | 
| Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 2350 | } // namespace CodeGen | 
|  | 2351 | } // namespace clang | 
| Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 2352 |  | 
|  | 2353 | #endif |