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