blob: f176af69b1d0a51e26e620ff5835515e6e8e1dde [file] [log] [blame]
Alexey Bataev9959db52014-05-06 10:08:46 +00001//===----- CGOpenMPRuntime.h - Interface to OpenMP Runtimes -----*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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 Bataev9959db52014-05-06 10:08:46 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This provides a class for OpenMP runtime code generation.
10//
11//===----------------------------------------------------------------------===//
12
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +000013#ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
14#define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
Alexey Bataev9959db52014-05-06 10:08:46 +000015
Alexey Bataev7292c292016-04-25 12:22:29 +000016#include "CGValue.h"
Richard Trieuf8b8b392019-01-11 01:32:35 +000017#include "clang/AST/DeclOpenMP.h"
Jordan Rupprecht52690912019-10-01 22:30:10 +000018#include "clang/AST/GlobalDecl.h"
Alexey Bataev62b63b12015-03-10 07:28:44 +000019#include "clang/AST/Type.h"
Alexander Musmanc6388682014-12-15 07:07:06 +000020#include "clang/Basic/OpenMPKinds.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000021#include "clang/Basic/SourceLocation.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000022#include "llvm/ADT/DenseMap.h"
Alexey Bataev45588422020-01-07 14:11:45 -050023#include "llvm/ADT/SmallPtrSet.h"
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +000024#include "llvm/ADT/StringMap.h"
Alexey Bataev2a6f3f52018-11-07 19:11:14 +000025#include "llvm/ADT/StringSet.h"
Johannes Doerfert6c5d1f402019-12-25 18:15:36 -060026#include "llvm/Frontend/OpenMP/OMPConstants.h"
Benjamin Kramer8fdba912016-02-02 14:24:21 +000027#include "llvm/IR/Function.h"
Alexey Bataev97720002014-11-11 04:05:39 +000028#include "llvm/IR/ValueHandle.h"
Alexey Bataev2d4f80f2020-02-11 15:15:21 -050029#include "llvm/Support/AtomicOrdering.h"
Alexey Bataev18095712014-10-10 12:19:54 +000030
31namespace llvm {
32class ArrayType;
33class Constant;
Alexey Bataev18095712014-10-10 12:19:54 +000034class FunctionType;
Alexey Bataev97720002014-11-11 04:05:39 +000035class GlobalVariable;
Alexey Bataev18095712014-10-10 12:19:54 +000036class StructType;
37class Type;
38class Value;
39} // namespace llvm
Alexey Bataev9959db52014-05-06 10:08:46 +000040
Alexey Bataev9959db52014-05-06 10:08:46 +000041namespace clang {
Alexey Bataevcc37cc12014-11-20 04:34:54 +000042class Expr;
Alexey Bataev8b427062016-05-25 12:36:08 +000043class OMPDependClause;
Alexey Bataev18095712014-10-10 12:19:54 +000044class OMPExecutableDirective;
Alexey Bataev7292c292016-04-25 12:22:29 +000045class OMPLoopDirective;
Alexey Bataev18095712014-10-10 12:19:54 +000046class VarDecl;
Alexey Bataevc5b1d322016-03-04 09:22:22 +000047class OMPDeclareReductionDecl;
48class IdentifierInfo;
Alexey Bataev18095712014-10-10 12:19:54 +000049
Alexey Bataev9959db52014-05-06 10:08:46 +000050namespace CodeGen {
John McCall7f416cc2015-09-08 08:05:57 +000051class Address;
Alexey Bataev18095712014-10-10 12:19:54 +000052class CodeGenFunction;
53class CodeGenModule;
Alexey Bataev9959db52014-05-06 10:08:46 +000054
Alexey Bataev14fa1c62016-03-29 05:34:15 +000055/// A basic class for pre|post-action for advanced codegen sequence for OpenMP
56/// region.
57class PrePostActionTy {
58public:
59 explicit PrePostActionTy() {}
60 virtual void Enter(CodeGenFunction &CGF) {}
61 virtual void Exit(CodeGenFunction &CGF) {}
62 virtual ~PrePostActionTy() {}
63};
64
65/// Class provides a way to call simple version of codegen for OpenMP region, or
66/// an advanced with possible pre|post-actions in codegen.
67class RegionCodeGenTy final {
68 intptr_t CodeGen;
69 typedef void (*CodeGenTy)(intptr_t, CodeGenFunction &, PrePostActionTy &);
70 CodeGenTy Callback;
71 mutable PrePostActionTy *PrePostAction;
72 RegionCodeGenTy() = delete;
73 RegionCodeGenTy &operator=(const RegionCodeGenTy &) = delete;
74 template <typename Callable>
75 static void CallbackFn(intptr_t CodeGen, CodeGenFunction &CGF,
76 PrePostActionTy &Action) {
77 return (*reinterpret_cast<Callable *>(CodeGen))(CGF, Action);
78 }
79
80public:
81 template <typename Callable>
82 RegionCodeGenTy(
83 Callable &&CodeGen,
Justin Lebar027eb712020-02-10 23:23:44 -080084 std::enable_if_t<!std::is_same<std::remove_reference_t<Callable>,
85 RegionCodeGenTy>::value> * = nullptr)
Alexey Bataev14fa1c62016-03-29 05:34:15 +000086 : CodeGen(reinterpret_cast<intptr_t>(&CodeGen)),
Justin Lebar027eb712020-02-10 23:23:44 -080087 Callback(CallbackFn<std::remove_reference_t<Callable>>),
Alexey Bataev14fa1c62016-03-29 05:34:15 +000088 PrePostAction(nullptr) {}
89 void setAction(PrePostActionTy &Action) const { PrePostAction = &Action; }
90 void operator()(CodeGenFunction &CGF) const;
91};
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000092
Alexey Bataev24b5bae2016-04-28 09:23:51 +000093struct OMPTaskDataTy final {
94 SmallVector<const Expr *, 4> PrivateVars;
95 SmallVector<const Expr *, 4> PrivateCopies;
96 SmallVector<const Expr *, 4> FirstprivateVars;
97 SmallVector<const Expr *, 4> FirstprivateCopies;
98 SmallVector<const Expr *, 4> FirstprivateInits;
Alexey Bataevf93095a2016-05-05 08:46:22 +000099 SmallVector<const Expr *, 4> LastprivateVars;
100 SmallVector<const Expr *, 4> LastprivateCopies;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000101 SmallVector<const Expr *, 4> ReductionVars;
102 SmallVector<const Expr *, 4> ReductionCopies;
103 SmallVector<const Expr *, 4> ReductionOps;
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000104 SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 4> Dependences;
105 llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
106 llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule;
Alexey Bataev1e1e2862016-05-10 12:21:02 +0000107 llvm::PointerIntPair<llvm::Value *, 1, bool> Priority;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000108 llvm::Value *Reductions = nullptr;
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000109 unsigned NumberOfParts = 0;
110 bool Tied = true;
111 bool Nogroup = false;
112};
113
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000114/// Class intended to support codegen of all kind of the reduction clauses.
115class ReductionCodeGen {
116private:
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000117 /// Data required for codegen of reduction clauses.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000118 struct ReductionData {
119 /// Reference to the original shared item.
120 const Expr *Ref = nullptr;
121 /// Helper expression for generation of private copy.
122 const Expr *Private = nullptr;
123 /// Helper expression for generation reduction operation.
124 const Expr *ReductionOp = nullptr;
125 ReductionData(const Expr *Ref, const Expr *Private, const Expr *ReductionOp)
126 : Ref(Ref), Private(Private), ReductionOp(ReductionOp) {}
127 };
128 /// List of reduction-based clauses.
129 SmallVector<ReductionData, 4> ClausesData;
130
131 /// List of addresses of original shared variables/expressions.
132 SmallVector<std::pair<LValue, LValue>, 4> SharedAddresses;
133 /// Sizes of the reduction items in chars.
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000134 SmallVector<std::pair<llvm::Value *, llvm::Value *>, 4> Sizes;
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000135 /// Base declarations for the reduction items.
136 SmallVector<const VarDecl *, 4> BaseDecls;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000137
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +0000138 /// Emits lvalue for shared expression.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000139 LValue emitSharedLValue(CodeGenFunction &CGF, const Expr *E);
140 /// Emits upper bound for shared expression (if array section).
141 LValue emitSharedLValueUB(CodeGenFunction &CGF, const Expr *E);
142 /// Performs aggregate initialization.
143 /// \param N Number of reduction item in the common list.
144 /// \param PrivateAddr Address of the corresponding private item.
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000145 /// \param SharedLVal Address of the original shared variable.
146 /// \param DRD Declare reduction construct used for reduction item.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000147 void emitAggregateInitialization(CodeGenFunction &CGF, unsigned N,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000148 Address PrivateAddr, LValue SharedLVal,
149 const OMPDeclareReductionDecl *DRD);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000150
151public:
152 ReductionCodeGen(ArrayRef<const Expr *> Shareds,
153 ArrayRef<const Expr *> Privates,
154 ArrayRef<const Expr *> ReductionOps);
155 /// Emits lvalue for a reduction item.
156 /// \param N Number of the reduction item.
157 void emitSharedLValue(CodeGenFunction &CGF, unsigned N);
158 /// Emits the code for the variable-modified type, if required.
159 /// \param N Number of the reduction item.
160 void emitAggregateType(CodeGenFunction &CGF, unsigned N);
161 /// Emits the code for the variable-modified type, if required.
162 /// \param N Number of the reduction item.
163 /// \param Size Size of the type in chars.
164 void emitAggregateType(CodeGenFunction &CGF, unsigned N, llvm::Value *Size);
165 /// Performs initialization of the private copy for the reduction item.
166 /// \param N Number of the reduction item.
167 /// \param PrivateAddr Address of the corresponding private item.
168 /// \param DefaultInit Default initialization sequence that should be
169 /// performed if no reduction specific initialization is found.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000170 /// \param SharedLVal Address of the original shared variable.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000171 void
172 emitInitialization(CodeGenFunction &CGF, unsigned N, Address PrivateAddr,
173 LValue SharedLVal,
174 llvm::function_ref<bool(CodeGenFunction &)> DefaultInit);
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000175 /// Returns true if the private copy requires cleanups.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000176 bool needCleanups(unsigned N);
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000177 /// Emits cleanup code for the reduction item.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000178 /// \param N Number of the reduction item.
179 /// \param PrivateAddr Address of the corresponding private item.
180 void emitCleanups(CodeGenFunction &CGF, unsigned N, Address PrivateAddr);
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000181 /// Adjusts \p PrivatedAddr for using instead of the original variable
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000182 /// address in normal operations.
183 /// \param N Number of the reduction item.
184 /// \param PrivateAddr Address of the corresponding private item.
185 Address adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
186 Address PrivateAddr);
187 /// Returns LValue for the reduction item.
188 LValue getSharedLValue(unsigned N) const { return SharedAddresses[N].first; }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000189 /// Returns the size of the reduction item (in chars and total number of
190 /// elements in the item), or nullptr, if the size is a constant.
191 std::pair<llvm::Value *, llvm::Value *> getSizes(unsigned N) const {
192 return Sizes[N];
193 }
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000194 /// Returns the base declaration of the reduction item.
195 const VarDecl *getBaseDecl(unsigned N) const { return BaseDecls[N]; }
Alexey Bataev1c44e152018-03-06 18:59:43 +0000196 /// Returns the base declaration of the reduction item.
197 const Expr *getRefExpr(unsigned N) const { return ClausesData[N].Ref; }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000198 /// Returns true if the initialization of the reduction item uses initializer
199 /// from declare reduction construct.
200 bool usesReductionInitializer(unsigned N) const;
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000201};
202
Alexey Bataev9959db52014-05-06 10:08:46 +0000203class CGOpenMPRuntime {
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +0000204public:
205 /// Allows to disable automatic handling of functions used in target regions
206 /// as those marked as `omp declare target`.
207 class DisableAutoDeclareTargetRAII {
208 CodeGenModule &CGM;
209 bool SavedShouldMarkAsGlobal;
210
211 public:
212 DisableAutoDeclareTargetRAII(CodeGenModule &CGM);
213 ~DisableAutoDeclareTargetRAII();
214 };
215
Alexey Bataev0860db92019-12-19 10:01:10 -0500216 /// Manages list of nontemporal decls for the specified directive.
217 class NontemporalDeclsRAII {
218 CodeGenModule &CGM;
219 const bool NeedToPush;
220
221 public:
222 NontemporalDeclsRAII(CodeGenModule &CGM, const OMPLoopDirective &S);
223 ~NontemporalDeclsRAII();
224 };
225
Alexey Bataeva58da1a2019-12-27 09:44:43 -0500226 /// Maps the expression for the lastprivate variable to the global copy used
227 /// to store new value because original variables are not mapped in inner
228 /// parallel regions. Only private copies are captured but we need also to
229 /// store private copy in shared address.
230 /// Also, stores the expression for the private loop counter and it
231 /// threaprivate name.
232 struct LastprivateConditionalData {
Alexey Bataev46978742020-01-30 10:46:11 -0500233 llvm::MapVector<CanonicalDeclPtr<const Decl>, SmallString<16>>
234 DeclToUniqueName;
Alexey Bataeva58da1a2019-12-27 09:44:43 -0500235 LValue IVLVal;
Alexey Bataev46978742020-01-30 10:46:11 -0500236 llvm::Function *Fn = nullptr;
237 bool Disabled = false;
Alexey Bataeva58da1a2019-12-27 09:44:43 -0500238 };
239 /// Manages list of lastprivate conditional decls for the specified directive.
240 class LastprivateConditionalRAII {
Alexey Bataev46978742020-01-30 10:46:11 -0500241 enum class ActionToDo {
242 DoNotPush,
243 PushAsLastprivateConditional,
244 DisableLastprivateConditional,
245 };
Alexey Bataeva58da1a2019-12-27 09:44:43 -0500246 CodeGenModule &CGM;
Alexey Bataev46978742020-01-30 10:46:11 -0500247 ActionToDo Action = ActionToDo::DoNotPush;
248
249 /// Check and try to disable analysis of inner regions for changes in
250 /// lastprivate conditional.
251 void tryToDisableInnerAnalysis(const OMPExecutableDirective &S,
252 llvm::DenseSet<CanonicalDeclPtr<const Decl>>
253 &NeedToAddForLPCsAsDisabled) const;
254
255 LastprivateConditionalRAII(CodeGenFunction &CGF,
256 const OMPExecutableDirective &S);
Alexey Bataeva58da1a2019-12-27 09:44:43 -0500257
258 public:
Alexey Bataev46978742020-01-30 10:46:11 -0500259 explicit LastprivateConditionalRAII(CodeGenFunction &CGF,
260 const OMPExecutableDirective &S,
261 LValue IVLVal);
262 static LastprivateConditionalRAII disable(CodeGenFunction &CGF,
263 const OMPExecutableDirective &S);
Alexey Bataeva58da1a2019-12-27 09:44:43 -0500264 ~LastprivateConditionalRAII();
265 };
266
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000267protected:
Alexey Bataev9959db52014-05-06 10:08:46 +0000268 CodeGenModule &CGM;
Alexey Bataev18fa2322018-05-02 14:20:50 +0000269 StringRef FirstSeparator, Separator;
270
271 /// Constructor allowing to redefine the name separator for the variables.
272 explicit CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator,
273 StringRef Separator);
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000274
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000275 /// Creates offloading entry for the provided entry ID \a ID,
Samuel Antaof83efdb2017-01-05 16:02:49 +0000276 /// address \a Addr, size \a Size, and flags \a Flags.
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000277 virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000278 uint64_t Size, int32_t Flags,
279 llvm::GlobalValue::LinkageTypes Linkage);
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000280
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000281 /// Helper to emit outlined function for 'target' directive.
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000282 /// \param D Directive to emit.
283 /// \param ParentName Name of the function that encloses the target region.
284 /// \param OutlinedFn Outlined function value to be defined by this call.
285 /// \param OutlinedFnID Outlined function ID value to be defined by this call.
286 /// \param IsOffloadEntry True if the outlined function is an offload entry.
287 /// \param CodeGen Lambda codegen specific to an accelerator device.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000288 /// An outlined function may not be an entry if, e.g. the if clause always
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000289 /// evaluates to false.
290 virtual void emitTargetOutlinedFunctionHelper(const OMPExecutableDirective &D,
291 StringRef ParentName,
292 llvm::Function *&OutlinedFn,
293 llvm::Constant *&OutlinedFnID,
294 bool IsOffloadEntry,
295 const RegionCodeGenTy &CodeGen);
296
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000297 /// Emits object of ident_t type with info for source location.
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000298 /// \param Flags Flags for OpenMP location.
299 ///
300 llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
301 unsigned Flags = 0);
302
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000303 /// Returns pointer to ident_t type.
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000304 llvm::Type *getIdentTyPointerTy();
305
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000306 /// Gets thread id value for the current thread.
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000307 ///
308 llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc);
309
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000310 /// Get the function name of an outlined region.
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000311 // The name can be customized depending on the target.
312 //
313 virtual StringRef getOutlinedHelperName() const { return ".omp_outlined."; }
314
Alexey Bataev3c595a62017-08-14 15:01:03 +0000315 /// Emits \p Callee function call with arguments \p Args with location \p Loc.
James Y Knight9871db02019-02-05 16:42:33 +0000316 void emitCall(CodeGenFunction &CGF, SourceLocation Loc,
317 llvm::FunctionCallee Callee,
Alexey Bataev7ef47a62018-02-22 18:33:31 +0000318 ArrayRef<llvm::Value *> Args = llvm::None) const;
Alexey Bataev3c595a62017-08-14 15:01:03 +0000319
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000320 /// Emits address of the word in a memory where current thread id is
Alexey Bataevb7f3cba2018-03-19 17:04:07 +0000321 /// stored.
322 virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc);
323
Alexey Bataevfd006c42018-10-05 15:08:53 +0000324 void setLocThreadIdInsertPt(CodeGenFunction &CGF,
325 bool AtCurrentPoint = false);
326 void clearLocThreadIdInsertPt(CodeGenFunction &CGF);
327
Alexey Bataevceeaa482018-11-21 21:04:34 +0000328 /// Check if the default location must be constant.
329 /// Default is false to support OMPT/OMPD.
330 virtual bool isDefaultLocationConstant() const { return false; }
331
332 /// Returns additional flags that can be stored in reserved_2 field of the
333 /// default location.
334 virtual unsigned getDefaultLocationReserved2Flags() const { return 0; }
335
Alexey Bataevc2cd2d42019-10-10 17:28:10 +0000336 /// Tries to emit declare variant function for \p OldGD from \p NewGD.
337 /// \param OrigAddr LLVM IR value for \p OldGD.
338 /// \param IsForDefinition true, if requested emission for the definition of
339 /// \p OldGD.
340 /// \returns true, was able to emit a definition function for \p OldGD, which
341 /// points to \p NewGD.
342 virtual bool tryEmitDeclareVariant(const GlobalDecl &NewGD,
343 const GlobalDecl &OldGD,
344 llvm::GlobalValue *OrigAddr,
345 bool IsForDefinition);
346
Alexey Bataevc3028ca2018-12-04 15:03:25 +0000347 /// Returns default flags for the barriers depending on the directive, for
348 /// which this barier is going to be emitted.
349 static unsigned getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind);
350
Alexey Bataeva1166022018-11-27 21:24:54 +0000351 /// Get the LLVM type for the critical name.
352 llvm::ArrayType *getKmpCriticalNameTy() const {return KmpCriticalNameTy;}
353
354 /// Returns corresponding lock object for the specified critical region
355 /// name. If the lock object does not exist it is created, otherwise the
356 /// reference to the existing copy is returned.
357 /// \param CriticalName Name of the critical region.
358 ///
359 llvm::Value *getCriticalRegionLock(StringRef CriticalName);
360
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000361private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000362 /// Default const ident_t object used for initialization of all other
Alexey Bataev9959db52014-05-06 10:08:46 +0000363 /// ident_t objects.
Alexey Bataevc5b1d322016-03-04 09:22:22 +0000364 llvm::Constant *DefaultOpenMPPSource = nullptr;
Alexey Bataevceeaa482018-11-21 21:04:34 +0000365 using FlagsTy = std::pair<unsigned, unsigned>;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000366 /// Map of flags and corresponding default locations.
Alexey Bataevceeaa482018-11-21 21:04:34 +0000367 using OpenMPDefaultLocMapTy = llvm::DenseMap<FlagsTy, llvm::Value *>;
Alexey Bataev15007ba2014-05-07 06:18:01 +0000368 OpenMPDefaultLocMapTy OpenMPDefaultLocMap;
Alexey Bataev50b3c952016-02-19 10:38:26 +0000369 Address getOrCreateDefaultLocation(unsigned Flags);
John McCall7f416cc2015-09-08 08:05:57 +0000370
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000371 QualType IdentQTy;
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000372 llvm::StructType *IdentTy = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000373 /// Map for SourceLocation and OpenMP runtime library debug locations.
Alexey Bataevf002aca2014-05-30 05:48:40 +0000374 typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy;
375 OpenMPDebugLocMapTy OpenMPDebugLocMap;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000376 /// The type for a microtask which gets passed to __kmpc_fork_call().
Alexey Bataev9959db52014-05-06 10:08:46 +0000377 /// Original representation is:
378 /// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...);
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000379 llvm::FunctionType *Kmpc_MicroTy = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000380 /// Stores debug location and ThreadID for the function.
Alexey Bataev18095712014-10-10 12:19:54 +0000381 struct DebugLocThreadIdTy {
382 llvm::Value *DebugLoc;
383 llvm::Value *ThreadID;
Alexey Bataevfd006c42018-10-05 15:08:53 +0000384 /// Insert point for the service instructions.
385 llvm::AssertingVH<llvm::Instruction> ServiceInsertPt = nullptr;
Alexey Bataev18095712014-10-10 12:19:54 +0000386 };
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000387 /// Map of local debug location, ThreadId and functions.
Alexey Bataev18095712014-10-10 12:19:54 +0000388 typedef llvm::DenseMap<llvm::Function *, DebugLocThreadIdTy>
389 OpenMPLocThreadIDMapTy;
390 OpenMPLocThreadIDMapTy OpenMPLocThreadIDMap;
Alexey Bataevc5b1d322016-03-04 09:22:22 +0000391 /// Map of UDRs and corresponding combiner/initializer.
392 typedef llvm::DenseMap<const OMPDeclareReductionDecl *,
393 std::pair<llvm::Function *, llvm::Function *>>
394 UDRMapTy;
395 UDRMapTy UDRMap;
396 /// Map of functions and locally defined UDRs.
397 typedef llvm::DenseMap<llvm::Function *,
398 SmallVector<const OMPDeclareReductionDecl *, 4>>
399 FunctionUDRMapTy;
400 FunctionUDRMapTy FunctionUDRMap;
Michael Krused47b9432019-08-05 18:43:21 +0000401 /// Map from the user-defined mapper declaration to its corresponding
402 /// functions.
403 llvm::DenseMap<const OMPDeclareMapperDecl *, llvm::Function *> UDMMap;
404 /// Map of functions and their local user-defined mappers.
405 using FunctionUDMMapTy =
406 llvm::DenseMap<llvm::Function *,
407 SmallVector<const OMPDeclareMapperDecl *, 4>>;
408 FunctionUDMMapTy FunctionUDMMap;
Alexey Bataev46978742020-01-30 10:46:11 -0500409 /// Maps local variables marked as lastprivate conditional to their internal
410 /// types.
411 llvm::DenseMap<llvm::Function *,
412 llvm::DenseMap<CanonicalDeclPtr<const Decl>,
413 std::tuple<QualType, const FieldDecl *,
414 const FieldDecl *, LValue>>>
415 LastprivateConditionalToTypes;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000416 /// Type kmp_critical_name, originally defined as typedef kmp_int32
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000417 /// kmp_critical_name[8];
418 llvm::ArrayType *KmpCriticalNameTy;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000419 /// An ordered map of auto-generated variables to their unique names.
Alexey Bataev97720002014-11-11 04:05:39 +0000420 /// It stores variables with the following names: 1) ".gomp_critical_user_" +
421 /// <critical_section_name> + ".var" for "omp critical" directives; 2)
422 /// <mangled_name_for_global_var> + ".cache." for cache for threadprivate
423 /// variables.
424 llvm::StringMap<llvm::AssertingVH<llvm::Constant>, llvm::BumpPtrAllocator>
425 InternalVars;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000426 /// Type typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *);
Alexey Bataevc5b1d322016-03-04 09:22:22 +0000427 llvm::Type *KmpRoutineEntryPtrTy = nullptr;
Alexey Bataev62b63b12015-03-10 07:28:44 +0000428 QualType KmpRoutineEntryPtrQTy;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000429 /// Type typedef struct kmp_task {
Alexey Bataev8fc69dc2015-05-18 07:54:53 +0000430 /// void * shareds; /**< pointer to block of pointers to
431 /// shared vars */
432 /// kmp_routine_entry_t routine; /**< pointer to routine to call for
433 /// executing task */
434 /// kmp_int32 part_id; /**< part id for the task */
435 /// kmp_routine_entry_t destructors; /* pointer to function to invoke
436 /// deconstructors of firstprivate C++ objects */
437 /// } kmp_task_t;
438 QualType KmpTaskTQTy;
Alexey Bataeve213f3e2017-10-11 15:29:40 +0000439 /// Saved kmp_task_t for task directive.
440 QualType SavedKmpTaskTQTy;
441 /// Saved kmp_task_t for taskloop-based directive.
442 QualType SavedKmpTaskloopTQTy;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000443 /// Type typedef struct kmp_depend_info {
Alexey Bataev1d2353d2015-06-24 11:01:36 +0000444 /// kmp_intptr_t base_addr;
445 /// size_t len;
446 /// struct {
447 /// bool in:1;
448 /// bool out:1;
449 /// } flags;
450 /// } kmp_depend_info_t;
451 QualType KmpDependInfoTy;
Alexey Bataev8b427062016-05-25 12:36:08 +0000452 /// struct kmp_dim { // loop bounds info casted to kmp_int64
453 /// kmp_int64 lo; // lower
454 /// kmp_int64 up; // upper
455 /// kmp_int64 st; // stride
456 /// };
457 QualType KmpDimTy;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000458 /// Type struct __tgt_offload_entry{
Samuel Antaoee8fb302016-01-06 13:42:12 +0000459 /// void *addr; // Pointer to the offload entry info.
460 /// // (function or global)
461 /// char *name; // Name of the function or global.
462 /// size_t size; // Size of the entry info (0 if it a function).
Alexey Bataev4c117032020-01-09 09:28:59 -0500463 /// int32_t flags;
464 /// int32_t reserved;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000465 /// };
466 QualType TgtOffloadEntryQTy;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000467 /// Entity that registers the offloading constants that were emitted so
Samuel Antaoee8fb302016-01-06 13:42:12 +0000468 /// far.
469 class OffloadEntriesInfoManagerTy {
470 CodeGenModule &CGM;
Alexey Bataev1d2353d2015-06-24 11:01:36 +0000471
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000472 /// Number of entries registered so far.
Alexey Bataev03f270c2018-03-30 18:31:07 +0000473 unsigned OffloadingEntriesNum = 0;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000474
475 public:
Samuel Antaof83efdb2017-01-05 16:02:49 +0000476 /// Base class of the entries info.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000477 class OffloadEntryInfo {
478 public:
Alexey Bataev34f8a702018-03-28 14:28:54 +0000479 /// Kind of a given entry.
Reid Klecknerdc78f952016-01-11 20:55:16 +0000480 enum OffloadingEntryInfoKinds : unsigned {
Alexey Bataev34f8a702018-03-28 14:28:54 +0000481 /// Entry is a target region.
482 OffloadingEntryInfoTargetRegion = 0,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000483 /// Entry is a declare target variable.
484 OffloadingEntryInfoDeviceGlobalVar = 1,
Alexey Bataev34f8a702018-03-28 14:28:54 +0000485 /// Invalid entry info.
486 OffloadingEntryInfoInvalid = ~0u
Samuel Antaoee8fb302016-01-06 13:42:12 +0000487 };
488
Alexey Bataev03f270c2018-03-30 18:31:07 +0000489 protected:
490 OffloadEntryInfo() = delete;
491 explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind) : Kind(Kind) {}
Samuel Antaof83efdb2017-01-05 16:02:49 +0000492 explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000493 uint32_t Flags)
Samuel Antaof83efdb2017-01-05 16:02:49 +0000494 : Flags(Flags), Order(Order), Kind(Kind) {}
Alexey Bataev03f270c2018-03-30 18:31:07 +0000495 ~OffloadEntryInfo() = default;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000496
Alexey Bataev03f270c2018-03-30 18:31:07 +0000497 public:
Samuel Antaoee8fb302016-01-06 13:42:12 +0000498 bool isValid() const { return Order != ~0u; }
499 unsigned getOrder() const { return Order; }
500 OffloadingEntryInfoKinds getKind() const { return Kind; }
Alexey Bataev03f270c2018-03-30 18:31:07 +0000501 uint32_t getFlags() const { return Flags; }
502 void setFlags(uint32_t NewFlags) { Flags = NewFlags; }
503 llvm::Constant *getAddress() const {
504 return cast_or_null<llvm::Constant>(Addr);
505 }
506 void setAddress(llvm::Constant *V) {
507 assert(!Addr.pointsToAliveValue() && "Address has been set before!");
508 Addr = V;
509 }
Samuel Antaoee8fb302016-01-06 13:42:12 +0000510 static bool classof(const OffloadEntryInfo *Info) { return true; }
511
Samuel Antaof83efdb2017-01-05 16:02:49 +0000512 private:
Alexey Bataev03f270c2018-03-30 18:31:07 +0000513 /// Address of the entity that has to be mapped for offloading.
514 llvm::WeakTrackingVH Addr;
515
Samuel Antaof83efdb2017-01-05 16:02:49 +0000516 /// Flags associated with the device global.
Alexey Bataev03f270c2018-03-30 18:31:07 +0000517 uint32_t Flags = 0u;
Samuel Antaof83efdb2017-01-05 16:02:49 +0000518
519 /// Order this entry was emitted.
Alexey Bataev03f270c2018-03-30 18:31:07 +0000520 unsigned Order = ~0u;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000521
Alexey Bataev03f270c2018-03-30 18:31:07 +0000522 OffloadingEntryInfoKinds Kind = OffloadingEntryInfoInvalid;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000523 };
524
Alexey Bataev03f270c2018-03-30 18:31:07 +0000525 /// Return true if a there are no entries defined.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000526 bool empty() const;
Alexey Bataev03f270c2018-03-30 18:31:07 +0000527 /// Return number of entries defined so far.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000528 unsigned size() const { return OffloadingEntriesNum; }
Alexey Bataev03f270c2018-03-30 18:31:07 +0000529 OffloadEntriesInfoManagerTy(CodeGenModule &CGM) : CGM(CGM) {}
Samuel Antaoee8fb302016-01-06 13:42:12 +0000530
Alexey Bataev03f270c2018-03-30 18:31:07 +0000531 //
532 // Target region entries related.
533 //
534
535 /// Kind of the target registry entry.
536 enum OMPTargetRegionEntryKind : uint32_t {
537 /// Mark the entry as target region.
538 OMPTargetRegionEntryTargetRegion = 0x0,
539 /// Mark the entry as a global constructor.
540 OMPTargetRegionEntryCtor = 0x02,
541 /// Mark the entry as a global destructor.
542 OMPTargetRegionEntryDtor = 0x04,
543 };
544
545 /// Target region entries info.
546 class OffloadEntryInfoTargetRegion final : public OffloadEntryInfo {
547 /// Address that can be used as the ID of the entry.
548 llvm::Constant *ID = nullptr;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000549
550 public:
551 OffloadEntryInfoTargetRegion()
Alexey Bataev03f270c2018-03-30 18:31:07 +0000552 : OffloadEntryInfo(OffloadingEntryInfoTargetRegion) {}
Samuel Antaoee8fb302016-01-06 13:42:12 +0000553 explicit OffloadEntryInfoTargetRegion(unsigned Order,
554 llvm::Constant *Addr,
Alexey Bataev34f8a702018-03-28 14:28:54 +0000555 llvm::Constant *ID,
556 OMPTargetRegionEntryKind Flags)
557 : OffloadEntryInfo(OffloadingEntryInfoTargetRegion, Order, Flags),
Alexey Bataev03f270c2018-03-30 18:31:07 +0000558 ID(ID) {
559 setAddress(Addr);
Samuel Antaoee8fb302016-01-06 13:42:12 +0000560 }
Alexey Bataev03f270c2018-03-30 18:31:07 +0000561
562 llvm::Constant *getID() const { return ID; }
Samuel Antaoee8fb302016-01-06 13:42:12 +0000563 void setID(llvm::Constant *V) {
Alexey Bataev34f8a702018-03-28 14:28:54 +0000564 assert(!ID && "ID has been set before!");
Samuel Antaoee8fb302016-01-06 13:42:12 +0000565 ID = V;
566 }
567 static bool classof(const OffloadEntryInfo *Info) {
Alexey Bataev34f8a702018-03-28 14:28:54 +0000568 return Info->getKind() == OffloadingEntryInfoTargetRegion;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000569 }
570 };
Alexey Bataev03f270c2018-03-30 18:31:07 +0000571
572 /// Initialize target region entry.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000573 void initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
574 StringRef ParentName, unsigned LineNum,
Samuel Antao2de62b02016-02-13 23:35:10 +0000575 unsigned Order);
Alexey Bataev03f270c2018-03-30 18:31:07 +0000576 /// Register target region entry.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000577 void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
578 StringRef ParentName, unsigned LineNum,
Samuel Antaof83efdb2017-01-05 16:02:49 +0000579 llvm::Constant *Addr, llvm::Constant *ID,
Alexey Bataev34f8a702018-03-28 14:28:54 +0000580 OMPTargetRegionEntryKind Flags);
Alexey Bataev03f270c2018-03-30 18:31:07 +0000581 /// Return true if a target region entry with the provided information
582 /// exists.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000583 bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
Samuel Antao2de62b02016-02-13 23:35:10 +0000584 StringRef ParentName, unsigned LineNum) const;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000585 /// brief Applies action \a Action on all registered entries.
586 typedef llvm::function_ref<void(unsigned, unsigned, StringRef, unsigned,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000587 const OffloadEntryInfoTargetRegion &)>
Samuel Antaoee8fb302016-01-06 13:42:12 +0000588 OffloadTargetRegionEntryInfoActTy;
589 void actOnTargetRegionEntriesInfo(
590 const OffloadTargetRegionEntryInfoActTy &Action);
591
Alexey Bataev03f270c2018-03-30 18:31:07 +0000592 //
593 // Device global variable entries related.
594 //
595
596 /// Kind of the global variable entry..
597 enum OMPTargetGlobalVarEntryKind : uint32_t {
598 /// Mark the entry as a to declare target.
599 OMPTargetGlobalVarEntryTo = 0x0,
Alexey Bataevc52f01d2018-07-16 20:05:25 +0000600 /// Mark the entry as a to declare target link.
601 OMPTargetGlobalVarEntryLink = 0x1,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000602 };
603
604 /// Device global variable entries info.
605 class OffloadEntryInfoDeviceGlobalVar final : public OffloadEntryInfo {
606 /// Type of the global variable.
607 CharUnits VarSize;
608 llvm::GlobalValue::LinkageTypes Linkage;
609
610 public:
611 OffloadEntryInfoDeviceGlobalVar()
612 : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar) {}
613 explicit OffloadEntryInfoDeviceGlobalVar(unsigned Order,
614 OMPTargetGlobalVarEntryKind Flags)
615 : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags) {}
616 explicit OffloadEntryInfoDeviceGlobalVar(
617 unsigned Order, llvm::Constant *Addr, CharUnits VarSize,
618 OMPTargetGlobalVarEntryKind Flags,
619 llvm::GlobalValue::LinkageTypes Linkage)
620 : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags),
621 VarSize(VarSize), Linkage(Linkage) {
622 setAddress(Addr);
623 }
624
625 CharUnits getVarSize() const { return VarSize; }
626 void setVarSize(CharUnits Size) { VarSize = Size; }
627 llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
628 void setLinkage(llvm::GlobalValue::LinkageTypes LT) { Linkage = LT; }
629 static bool classof(const OffloadEntryInfo *Info) {
630 return Info->getKind() == OffloadingEntryInfoDeviceGlobalVar;
631 }
632 };
633
634 /// Initialize device global variable entry.
635 void initializeDeviceGlobalVarEntryInfo(StringRef Name,
636 OMPTargetGlobalVarEntryKind Flags,
637 unsigned Order);
638
639 /// Register device global variable entry.
640 void
641 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
642 CharUnits VarSize,
643 OMPTargetGlobalVarEntryKind Flags,
644 llvm::GlobalValue::LinkageTypes Linkage);
645 /// Checks if the variable with the given name has been registered already.
646 bool hasDeviceGlobalVarEntryInfo(StringRef VarName) const {
647 return OffloadEntriesDeviceGlobalVar.count(VarName) > 0;
648 }
649 /// Applies action \a Action on all registered entries.
650 typedef llvm::function_ref<void(StringRef,
651 const OffloadEntryInfoDeviceGlobalVar &)>
652 OffloadDeviceGlobalVarEntryInfoActTy;
653 void actOnDeviceGlobalVarEntriesInfo(
654 const OffloadDeviceGlobalVarEntryInfoActTy &Action);
655
Samuel Antaoee8fb302016-01-06 13:42:12 +0000656 private:
657 // Storage for target region entries kind. The storage is to be indexed by
Samuel Antao2de62b02016-02-13 23:35:10 +0000658 // file ID, device ID, parent function name and line number.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000659 typedef llvm::DenseMap<unsigned, OffloadEntryInfoTargetRegion>
Samuel Antaoee8fb302016-01-06 13:42:12 +0000660 OffloadEntriesTargetRegionPerLine;
661 typedef llvm::StringMap<OffloadEntriesTargetRegionPerLine>
662 OffloadEntriesTargetRegionPerParentName;
663 typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerParentName>
664 OffloadEntriesTargetRegionPerFile;
665 typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerFile>
666 OffloadEntriesTargetRegionPerDevice;
667 typedef OffloadEntriesTargetRegionPerDevice OffloadEntriesTargetRegionTy;
668 OffloadEntriesTargetRegionTy OffloadEntriesTargetRegion;
Alexey Bataev03f270c2018-03-30 18:31:07 +0000669 /// Storage for device global variable entries kind. The storage is to be
670 /// indexed by mangled name.
671 typedef llvm::StringMap<OffloadEntryInfoDeviceGlobalVar>
672 OffloadEntriesDeviceGlobalVarTy;
673 OffloadEntriesDeviceGlobalVarTy OffloadEntriesDeviceGlobalVar;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000674 };
675 OffloadEntriesInfoManagerTy OffloadEntriesInfoManager;
676
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +0000677 bool ShouldMarkAsGlobal = true;
Alexey Bataev45588422020-01-07 14:11:45 -0500678 /// List of the emitted declarations.
679 llvm::DenseSet<CanonicalDeclPtr<const Decl>> AlreadyEmittedTargetDecls;
Alexey Bataev2a6f3f52018-11-07 19:11:14 +0000680 /// List of the global variables with their addresses that should not be
681 /// emitted for the target.
682 llvm::StringMap<llvm::WeakTrackingVH> EmittedNonTargetVariables;
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +0000683
Alexey Bataevbf8fe712018-08-07 16:14:36 +0000684 /// List of variables that can become declare target implicitly and, thus,
685 /// must be emitted.
686 llvm::SmallDenseSet<const VarDecl *> DeferredGlobalVariables;
687
Alexey Bataev2df5f122019-10-01 20:18:32 +0000688 /// Mapping of the original functions to their variants and original global
689 /// decl.
690 llvm::MapVector<CanonicalDeclPtr<const FunctionDecl>,
691 std::pair<GlobalDecl, GlobalDecl>>
692 DeferredVariantFunction;
693
Alexey Bataev0860db92019-12-19 10:01:10 -0500694 using NontemporalDeclsSet = llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>>;
695 /// Stack for list of declarations in current context marked as nontemporal.
696 /// The set is the union of all current stack elements.
697 llvm::SmallVector<NontemporalDeclsSet, 4> NontemporalDeclsStack;
698
Alexey Bataeva58da1a2019-12-27 09:44:43 -0500699 /// Stack for list of addresses of declarations in current context marked as
700 /// lastprivate conditional. The set is the union of all current stack
701 /// elements.
702 llvm::SmallVector<LastprivateConditionalData, 4> LastprivateConditionalStack;
703
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +0000704 /// Flag for keeping track of weather a requires unified_shared_memory
705 /// directive is present.
706 bool HasRequiresUnifiedSharedMemory = false;
707
Alexey Bataev2d4f80f2020-02-11 15:15:21 -0500708 /// Atomic ordering from the omp requires directive.
709 llvm::AtomicOrdering RequiresAtomicOrdering = llvm::AtomicOrdering::Monotonic;
710
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +0000711 /// Flag for keeping track of weather a target region has been emitted.
712 bool HasEmittedTargetRegion = false;
713
714 /// Flag for keeping track of weather a device routine has been emitted.
715 /// Device routines are specific to the
716 bool HasEmittedDeclareTargetRegion = false;
717
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000718 /// Loads all the offload entries information from the host IR
Samuel Antaoee8fb302016-01-06 13:42:12 +0000719 /// metadata.
720 void loadOffloadInfoMetadata();
721
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000722 /// Returns __tgt_offload_entry type.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000723 QualType getTgtOffloadEntryQTy();
724
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000725 /// Start scanning from statement \a S and and emit all target regions
Samuel Antaoee8fb302016-01-06 13:42:12 +0000726 /// found along the way.
727 /// \param S Starting statement.
728 /// \param ParentName Name of the function declaration that is being scanned.
729 void scanForTargetRegionsFunctions(const Stmt *S, StringRef ParentName);
Alexey Bataev62b63b12015-03-10 07:28:44 +0000730
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000731 /// Build type kmp_routine_entry_t (if not built yet).
Alexey Bataev62b63b12015-03-10 07:28:44 +0000732 void emitKmpRoutineEntryT(QualType KmpInt32Ty);
Alexey Bataev9959db52014-05-06 10:08:46 +0000733
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000734 /// Returns pointer to kmpc_micro type.
Alexey Bataev9959db52014-05-06 10:08:46 +0000735 llvm::Type *getKmpc_MicroPointerTy();
736
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000737 /// Returns specified OpenMP runtime function.
Alexey Bataev9959db52014-05-06 10:08:46 +0000738 /// \param Function OpenMP runtime function.
739 /// \return Specified function.
James Y Knight9871db02019-02-05 16:42:33 +0000740 llvm::FunctionCallee createRuntimeFunction(unsigned Function);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000741
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000742 /// Returns __kmpc_for_static_init_* runtime function for the specified
Alexander Musman21212e42015-03-13 10:38:23 +0000743 /// size \a IVSize and sign \a IVSigned.
James Y Knight9871db02019-02-05 16:42:33 +0000744 llvm::FunctionCallee createForStaticInitFunction(unsigned IVSize,
745 bool IVSigned);
Alexander Musman21212e42015-03-13 10:38:23 +0000746
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000747 /// Returns __kmpc_dispatch_init_* runtime function for the specified
Alexander Musman92bdaab2015-03-12 13:37:50 +0000748 /// size \a IVSize and sign \a IVSigned.
James Y Knight9871db02019-02-05 16:42:33 +0000749 llvm::FunctionCallee createDispatchInitFunction(unsigned IVSize,
750 bool IVSigned);
Alexander Musman92bdaab2015-03-12 13:37:50 +0000751
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000752 /// Returns __kmpc_dispatch_next_* runtime function for the specified
Alexander Musman92bdaab2015-03-12 13:37:50 +0000753 /// size \a IVSize and sign \a IVSigned.
James Y Knight9871db02019-02-05 16:42:33 +0000754 llvm::FunctionCallee createDispatchNextFunction(unsigned IVSize,
755 bool IVSigned);
Alexander Musman92bdaab2015-03-12 13:37:50 +0000756
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000757 /// Returns __kmpc_dispatch_fini_* runtime function for the specified
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000758 /// size \a IVSize and sign \a IVSigned.
James Y Knight9871db02019-02-05 16:42:33 +0000759 llvm::FunctionCallee createDispatchFiniFunction(unsigned IVSize,
760 bool IVSigned);
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000761
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000762 /// If the specified mangled name is not in the module, create and
Alexey Bataev97720002014-11-11 04:05:39 +0000763 /// return threadprivate cache object. This object is a pointer's worth of
764 /// storage that's reserved for use by the OpenMP runtime.
NAKAMURA Takumicdcbfba2014-11-11 07:58:06 +0000765 /// \param VD Threadprivate variable.
Alexey Bataev97720002014-11-11 04:05:39 +0000766 /// \return Cache variable for the specified threadprivate.
767 llvm::Constant *getOrCreateThreadPrivateCache(const VarDecl *VD);
768
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000769 /// Gets (if variable with the given name already exist) or creates
Alexey Bataev97720002014-11-11 04:05:39 +0000770 /// internal global variable with the specified Name. The created variable has
771 /// linkage CommonLinkage by default and is initialized by null value.
772 /// \param Ty Type of the global variable. If it is exist already the type
773 /// must be the same.
774 /// \param Name Name of the variable.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000775 llvm::Constant *getOrCreateInternalVariable(llvm::Type *Ty,
Alexey Bataev1af5bd52019-03-05 17:47:18 +0000776 const llvm::Twine &Name,
777 unsigned AddressSpace = 0);
Alexey Bataev97720002014-11-11 04:05:39 +0000778
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000779 /// Set of threadprivate variables with the generated initializer.
Alexey Bataev2a6f3f52018-11-07 19:11:14 +0000780 llvm::StringSet<> ThreadPrivateWithDefinition;
Alexey Bataev97720002014-11-11 04:05:39 +0000781
Alexey Bataev34f8a702018-03-28 14:28:54 +0000782 /// Set of declare target variables with the generated initializer.
Alexey Bataev2a6f3f52018-11-07 19:11:14 +0000783 llvm::StringSet<> DeclareTargetWithDefinition;
Alexey Bataev34f8a702018-03-28 14:28:54 +0000784
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000785 /// Emits initialization code for the threadprivate variables.
Alexey Bataev97720002014-11-11 04:05:39 +0000786 /// \param VDAddr Address of the global variable \a VD.
787 /// \param Ctor Pointer to a global init function for \a VD.
788 /// \param CopyCtor Pointer to a global copy function for \a VD.
789 /// \param Dtor Pointer to a global destructor function for \a VD.
790 /// \param Loc Location of threadprivate declaration.
John McCall7f416cc2015-09-08 08:05:57 +0000791 void emitThreadPrivateVarInit(CodeGenFunction &CGF, Address VDAddr,
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000792 llvm::Value *Ctor, llvm::Value *CopyCtor,
793 llvm::Value *Dtor, SourceLocation Loc);
Alexey Bataev97720002014-11-11 04:05:39 +0000794
Michael Krused47b9432019-08-05 18:43:21 +0000795 /// Emit the array initialization or deletion portion for user-defined mapper
796 /// code generation.
797 void emitUDMapperArrayInitOrDel(CodeGenFunction &MapperCGF,
798 llvm::Value *Handle, llvm::Value *BasePtr,
799 llvm::Value *Ptr, llvm::Value *Size,
800 llvm::Value *MapType, CharUnits ElementSize,
801 llvm::BasicBlock *ExitBB, bool IsInit);
802
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000803 struct TaskResultTy {
804 llvm::Value *NewTask = nullptr;
James Y Knight9871db02019-02-05 16:42:33 +0000805 llvm::Function *TaskEntry = nullptr;
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000806 llvm::Value *NewTaskNewTaskTTy = nullptr;
Alexey Bataev7292c292016-04-25 12:22:29 +0000807 LValue TDBase;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000808 const RecordDecl *KmpTaskTQTyRD = nullptr;
Alexey Bataevf93095a2016-05-05 08:46:22 +0000809 llvm::Value *TaskDupFn = nullptr;
Alexey Bataev7292c292016-04-25 12:22:29 +0000810 };
811 /// Emit task region for the task directive. The task region is emitted in
812 /// several steps:
813 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
814 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
815 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
816 /// function:
817 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
818 /// TaskFunction(gtid, tt->part_id, tt->shareds);
819 /// return 0;
820 /// }
821 /// 2. Copy a list of shared variables to field shareds of the resulting
822 /// structure kmp_task_t returned by the previous call (if any).
823 /// 3. Copy a pointer to destructions function to field destructions of the
824 /// resulting structure kmp_task_t.
825 /// \param D Current task directive.
Alexey Bataev7292c292016-04-25 12:22:29 +0000826 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
827 /// /*part_id*/, captured_struct */*__context*/);
828 /// \param SharedsTy A type which contains references the shared variables.
829 /// \param Shareds Context with the list of shared variables from the \p
830 /// TaskFunction.
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000831 /// \param Data Additional data for task generation like tiednsee, final
832 /// state, list of privates etc.
833 TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
834 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +0000835 llvm::Function *TaskFunction, QualType SharedsTy,
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000836 Address Shareds, const OMPTaskDataTy &Data);
Alexey Bataev7292c292016-04-25 12:22:29 +0000837
Alexey Bataev1af5bd52019-03-05 17:47:18 +0000838 /// Returns default address space for the constant firstprivates, 0 by
839 /// default.
840 virtual unsigned getDefaultFirstprivateAddressSpace() const { return 0; }
841
Alexey Bataevec7946e2019-09-23 14:06:51 +0000842 /// Emit code that pushes the trip count of loops associated with constructs
843 /// 'target teams distribute' and 'teams distribute parallel for'.
844 /// \param SizeEmitter Emits the int64 value for the number of iterations of
845 /// the associated loop.
846 void emitTargetNumIterationsCall(
847 CodeGenFunction &CGF, const OMPExecutableDirective &D,
848 llvm::Value *DeviceID,
849 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
850 const OMPLoopDirective &D)>
851 SizeEmitter);
852
Alexey Bataev46978742020-01-30 10:46:11 -0500853 /// Emit update for lastprivate conditional data.
854 void emitLastprivateConditionalUpdate(CodeGenFunction &CGF, LValue IVLVal,
855 StringRef UniqueDeclName, LValue LVal,
856 SourceLocation Loc);
857
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000858public:
Alexey Bataev18fa2322018-05-02 14:20:50 +0000859 explicit CGOpenMPRuntime(CodeGenModule &CGM)
860 : CGOpenMPRuntime(CGM, ".", ".") {}
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +0000861 virtual ~CGOpenMPRuntime() {}
Alexey Bataev91797552015-03-18 04:13:55 +0000862 virtual void clear();
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000863
Alexey Bataevd08c0562019-11-19 12:07:54 -0500864 /// Emits code for OpenMP 'if' clause using specified \a CodeGen
865 /// function. Here is the logic:
866 /// if (Cond) {
867 /// ThenGen();
868 /// } else {
869 /// ElseGen();
870 /// }
871 void emitIfClause(CodeGenFunction &CGF, const Expr *Cond,
872 const RegionCodeGenTy &ThenGen,
873 const RegionCodeGenTy &ElseGen);
874
Alexey Bataev5c427362019-04-10 19:11:33 +0000875 /// Checks if the \p Body is the \a CompoundStmt and returns its child
876 /// statement iff there is only one that is not evaluatable at the compile
877 /// time.
878 static const Stmt *getSingleCompoundChild(ASTContext &Ctx, const Stmt *Body);
879
Alexey Bataev18fa2322018-05-02 14:20:50 +0000880 /// Get the platform-specific name separator.
881 std::string getName(ArrayRef<StringRef> Parts) const;
882
Alexey Bataevc5b1d322016-03-04 09:22:22 +0000883 /// Emit code for the specified user defined reduction construct.
884 virtual void emitUserDefinedReduction(CodeGenFunction *CGF,
885 const OMPDeclareReductionDecl *D);
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000886 /// Get combiner/initializer for the specified user-defined reduction, if any.
887 virtual std::pair<llvm::Function *, llvm::Function *>
888 getUserDefinedReduction(const OMPDeclareReductionDecl *D);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000889
Michael Krused47b9432019-08-05 18:43:21 +0000890 /// Emit the function for the user defined mapper construct.
891 void emitUserDefinedMapper(const OMPDeclareMapperDecl *D,
892 CodeGenFunction *CGF = nullptr);
893
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000894 /// Emits outlined function for the specified OpenMP parallel directive
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000895 /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
896 /// kmp_int32 BoundID, struct context_vars*).
Alexey Bataev18095712014-10-10 12:19:54 +0000897 /// \param D OpenMP directive.
898 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000899 /// \param InnermostKind Kind of innermost directive (for simple directives it
900 /// is a directive itself, for combined - its innermost directive).
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000901 /// \param CodeGen Code generation sequence for the \a D directive.
James Y Knight9871db02019-02-05 16:42:33 +0000902 virtual llvm::Function *emitParallelOutlinedFunction(
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000903 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
904 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
905
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000906 /// Emits outlined function for the specified OpenMP teams directive
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000907 /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
908 /// kmp_int32 BoundID, struct context_vars*).
909 /// \param D OpenMP directive.
910 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
911 /// \param InnermostKind Kind of innermost directive (for simple directives it
912 /// is a directive itself, for combined - its innermost directive).
913 /// \param CodeGen Code generation sequence for the \a D directive.
James Y Knight9871db02019-02-05 16:42:33 +0000914 virtual llvm::Function *emitTeamsOutlinedFunction(
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000915 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
916 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
Alexey Bataev18095712014-10-10 12:19:54 +0000917
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000918 /// Emits outlined function for the OpenMP task directive \a D. This
Alexey Bataev48591dd2016-04-20 04:01:36 +0000919 /// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t*
920 /// TaskT).
Alexey Bataev62b63b12015-03-10 07:28:44 +0000921 /// \param D OpenMP directive.
922 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000923 /// \param PartIDVar Variable for partition id in the current OpenMP untied
924 /// task region.
925 /// \param TaskTVar Variable for task_t argument.
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000926 /// \param InnermostKind Kind of innermost directive (for simple directives it
927 /// is a directive itself, for combined - its innermost directive).
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000928 /// \param CodeGen Code generation sequence for the \a D directive.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000929 /// \param Tied true if task is generated for tied task, false otherwise.
930 /// \param NumberOfParts Number of parts in untied task. Ignored for tied
931 /// tasks.
Alexey Bataev62b63b12015-03-10 07:28:44 +0000932 ///
James Y Knight9871db02019-02-05 16:42:33 +0000933 virtual llvm::Function *emitTaskOutlinedFunction(
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000934 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
Alexey Bataev48591dd2016-04-20 04:01:36 +0000935 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
936 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
937 bool Tied, unsigned &NumberOfParts);
Alexey Bataev62b63b12015-03-10 07:28:44 +0000938
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000939 /// Cleans up references to the objects in finished function.
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000940 ///
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +0000941 virtual void functionFinished(CodeGenFunction &CGF);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000942
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000943 /// Emits code for parallel or serial call of the \a OutlinedFn with
Alexey Bataev1d677132015-04-22 13:57:31 +0000944 /// variables captured in a record which address is stored in \a
945 /// CapturedStruct.
Alexey Bataev18095712014-10-10 12:19:54 +0000946 /// \param OutlinedFn Outlined function to be run in parallel threads. Type of
Alexey Bataev62b63b12015-03-10 07:28:44 +0000947 /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
NAKAMURA Takumi62f0eb52015-09-11 08:13:32 +0000948 /// \param CapturedVars A pointer to the record with the references to
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000949 /// variables used in \a OutlinedFn function.
Alexey Bataev1d677132015-04-22 13:57:31 +0000950 /// \param IfCond Condition in the associated 'if' clause, if it was
951 /// specified, nullptr otherwise.
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000952 ///
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000953 virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +0000954 llvm::Function *OutlinedFn,
Alexey Bataev2377fe92015-09-10 08:12:02 +0000955 ArrayRef<llvm::Value *> CapturedVars,
956 const Expr *IfCond);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000957
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000958 /// Emits a critical region.
Alexey Bataev18095712014-10-10 12:19:54 +0000959 /// \param CriticalName Name of the critical region.
Alexey Bataev75ddfab2014-12-01 11:32:38 +0000960 /// \param CriticalOpGen Generator for the statement associated with the given
961 /// critical region.
Alexey Bataevfc57d162015-12-15 10:55:09 +0000962 /// \param Hint Value of the 'hint' clause (optional).
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000963 virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000964 const RegionCodeGenTy &CriticalOpGen,
Alexey Bataevfc57d162015-12-15 10:55:09 +0000965 SourceLocation Loc,
966 const Expr *Hint = nullptr);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000967
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000968 /// Emits a master region.
Alexey Bataev8d690652014-12-04 07:23:53 +0000969 /// \param MasterOpGen Generator for the statement associated with the given
970 /// master region.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000971 virtual void emitMasterRegion(CodeGenFunction &CGF,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000972 const RegionCodeGenTy &MasterOpGen,
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000973 SourceLocation Loc);
Alexey Bataev8d690652014-12-04 07:23:53 +0000974
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000975 /// Emits code for a taskyield directive.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000976 virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc);
Alexey Bataev9f797f32015-02-05 05:57:51 +0000977
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000978 /// Emit a taskgroup region.
Alexey Bataevc30dd2d2015-06-18 12:14:09 +0000979 /// \param TaskgroupOpGen Generator for the statement associated with the
980 /// given taskgroup region.
981 virtual void emitTaskgroupRegion(CodeGenFunction &CGF,
982 const RegionCodeGenTy &TaskgroupOpGen,
983 SourceLocation Loc);
984
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000985 /// Emits a single region.
Alexey Bataev6956e2e2015-02-05 06:35:41 +0000986 /// \param SingleOpGen Generator for the statement associated with the given
987 /// single region.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000988 virtual void emitSingleRegion(CodeGenFunction &CGF,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000989 const RegionCodeGenTy &SingleOpGen,
Alexey Bataeva63048e2015-03-23 06:18:07 +0000990 SourceLocation Loc,
991 ArrayRef<const Expr *> CopyprivateVars,
Alexey Bataev420d45b2015-04-14 05:11:24 +0000992 ArrayRef<const Expr *> DestExprs,
Alexey Bataeva63048e2015-03-23 06:18:07 +0000993 ArrayRef<const Expr *> SrcExprs,
Alexey Bataeva63048e2015-03-23 06:18:07 +0000994 ArrayRef<const Expr *> AssignmentOps);
Alexey Bataev6956e2e2015-02-05 06:35:41 +0000995
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000996 /// Emit an ordered region.
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000997 /// \param OrderedOpGen Generator for the statement associated with the given
Alexey Bataevc30dd2d2015-06-18 12:14:09 +0000998 /// ordered region.
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000999 virtual void emitOrderedRegion(CodeGenFunction &CGF,
1000 const RegionCodeGenTy &OrderedOpGen,
Alexey Bataev5f600d62015-09-29 03:48:57 +00001001 SourceLocation Loc, bool IsThreads);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001002
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001003 /// Emit an implicit/explicit barrier for OpenMP threads.
Alexey Bataevf2685682015-03-30 04:30:22 +00001004 /// \param Kind Directive for which this implicit barrier call must be
1005 /// generated. Must be OMPD_barrier for explicit barrier generation.
Alexey Bataev25e5b442015-09-15 12:52:43 +00001006 /// \param EmitChecks true if need to emit checks for cancellation barriers.
1007 /// \param ForceSimpleCall true simple barrier call must be emitted, false if
1008 /// runtime class decides which one to emit (simple or with cancellation
1009 /// checks).
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001010 ///
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001011 virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001012 OpenMPDirectiveKind Kind,
Alexey Bataev25e5b442015-09-15 12:52:43 +00001013 bool EmitChecks = true,
1014 bool ForceSimpleCall = false);
Alexey Bataevb2059782014-10-13 08:23:51 +00001015
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001016 /// Check if the specified \a ScheduleKind is static non-chunked.
Alexander Musmanc6388682014-12-15 07:07:06 +00001017 /// This kind of worksharing directive is emitted without outer loop.
1018 /// \param ScheduleKind Schedule kind specified in the 'schedule' clause.
1019 /// \param Chunked True if chunk is specified in the clause.
1020 ///
1021 virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
1022 bool Chunked) const;
1023
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001024 /// Check if the specified \a ScheduleKind is static non-chunked.
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001025 /// This kind of distribute directive is emitted without outer loop.
1026 /// \param ScheduleKind Schedule kind specified in the 'dist_schedule' clause.
1027 /// \param Chunked True if chunk is specified in the clause.
1028 ///
1029 virtual bool isStaticNonchunked(OpenMPDistScheduleClauseKind ScheduleKind,
1030 bool Chunked) const;
1031
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00001032 /// Check if the specified \a ScheduleKind is static chunked.
1033 /// \param ScheduleKind Schedule kind specified in the 'schedule' clause.
1034 /// \param Chunked True if chunk is specified in the clause.
1035 ///
1036 virtual bool isStaticChunked(OpenMPScheduleClauseKind ScheduleKind,
1037 bool Chunked) const;
1038
1039 /// Check if the specified \a ScheduleKind is static non-chunked.
1040 /// \param ScheduleKind Schedule kind specified in the 'dist_schedule' clause.
1041 /// \param Chunked True if chunk is specified in the clause.
1042 ///
1043 virtual bool isStaticChunked(OpenMPDistScheduleClauseKind ScheduleKind,
1044 bool Chunked) const;
1045
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001046 /// Check if the specified \a ScheduleKind is dynamic.
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001047 /// This kind of worksharing directive is emitted without outer loop.
1048 /// \param ScheduleKind Schedule Kind specified in the 'schedule' clause.
1049 ///
1050 virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const;
1051
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001052 /// struct with the values to be passed to the dispatch runtime function
1053 struct DispatchRTInput {
1054 /// Loop lower bound
1055 llvm::Value *LB = nullptr;
1056 /// Loop upper bound
1057 llvm::Value *UB = nullptr;
1058 /// Chunk size specified using 'schedule' clause (nullptr if chunk
1059 /// was not specified)
1060 llvm::Value *Chunk = nullptr;
1061 DispatchRTInput() = default;
1062 DispatchRTInput(llvm::Value *LB, llvm::Value *UB, llvm::Value *Chunk)
1063 : LB(LB), UB(UB), Chunk(Chunk) {}
1064 };
1065
1066 /// Call the appropriate runtime routine to initialize it before start
1067 /// of loop.
1068
1069 /// This is used for non static scheduled types and when the ordered
1070 /// clause is present on the loop construct.
1071 /// Depending on the loop schedule, it is necessary to call some runtime
1072 /// routine before start of the OpenMP loop to get the loop upper / lower
1073 /// bounds \a LB and \a UB and stride \a ST.
1074 ///
1075 /// \param CGF Reference to current CodeGenFunction.
1076 /// \param Loc Clang source location.
1077 /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
1078 /// \param IVSize Size of the iteration variable in bits.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +00001079 /// \param IVSigned Sign of the iteration variable.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001080 /// \param Ordered true if loop is ordered, false otherwise.
1081 /// \param DispatchValues struct containing llvm values for lower bound, upper
1082 /// bound, and chunk expression.
1083 /// For the default (nullptr) value, the chunk 1 will be used.
1084 ///
NAKAMURA Takumiff7a9252015-09-08 09:42:41 +00001085 virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001086 const OpenMPScheduleTy &ScheduleKind,
1087 unsigned IVSize, bool IVSigned, bool Ordered,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001088 const DispatchRTInput &DispatchValues);
NAKAMURA Takumiff7a9252015-09-08 09:42:41 +00001089
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001090 /// Struct with the values to be passed to the static runtime function
1091 struct StaticRTInput {
1092 /// Size of the iteration variable in bits.
1093 unsigned IVSize = 0;
1094 /// Sign of the iteration variable.
1095 bool IVSigned = false;
1096 /// true if loop is ordered, false otherwise.
1097 bool Ordered = false;
1098 /// Address of the output variable in which the flag of the last iteration
1099 /// is returned.
1100 Address IL = Address::invalid();
1101 /// Address of the output variable in which the lower iteration number is
1102 /// returned.
1103 Address LB = Address::invalid();
1104 /// Address of the output variable in which the upper iteration number is
1105 /// returned.
1106 Address UB = Address::invalid();
1107 /// Address of the output variable in which the stride value is returned
1108 /// necessary to generated the static_chunked scheduled loop.
1109 Address ST = Address::invalid();
1110 /// Value of the chunk for the static_chunked scheduled loop. For the
1111 /// default (nullptr) value, the chunk 1 will be used.
1112 llvm::Value *Chunk = nullptr;
1113 StaticRTInput(unsigned IVSize, bool IVSigned, bool Ordered, Address IL,
1114 Address LB, Address UB, Address ST,
1115 llvm::Value *Chunk = nullptr)
1116 : IVSize(IVSize), IVSigned(IVSigned), Ordered(Ordered), IL(IL), LB(LB),
1117 UB(UB), ST(ST), Chunk(Chunk) {}
1118 };
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001119 /// Call the appropriate runtime routine to initialize it before start
Alexander Musmanc6388682014-12-15 07:07:06 +00001120 /// of loop.
1121 ///
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001122 /// This is used only in case of static schedule, when the user did not
1123 /// specify a ordered clause on the loop construct.
1124 /// Depending on the loop schedule, it is necessary to call some runtime
Alexander Musmanc6388682014-12-15 07:07:06 +00001125 /// routine before start of the OpenMP loop to get the loop upper / lower
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001126 /// bounds LB and UB and stride ST.
Alexander Musmanc6388682014-12-15 07:07:06 +00001127 ///
1128 /// \param CGF Reference to current CodeGenFunction.
1129 /// \param Loc Clang source location.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001130 /// \param DKind Kind of the directive.
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001131 /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001132 /// \param Values Input arguments for the construct.
Alexander Musmanc6388682014-12-15 07:07:06 +00001133 ///
John McCall7f416cc2015-09-08 08:05:57 +00001134 virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001135 OpenMPDirectiveKind DKind,
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001136 const OpenMPScheduleTy &ScheduleKind,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001137 const StaticRTInput &Values);
Alexander Musmanc6388682014-12-15 07:07:06 +00001138
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001139 ///
1140 /// \param CGF Reference to current CodeGenFunction.
1141 /// \param Loc Clang source location.
1142 /// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001143 /// \param Values Input arguments for the construct.
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001144 ///
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001145 virtual void emitDistributeStaticInit(CodeGenFunction &CGF,
1146 SourceLocation Loc,
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001147 OpenMPDistScheduleClauseKind SchedKind,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001148 const StaticRTInput &Values);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001149
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001150 /// Call the appropriate runtime routine to notify that we finished
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001151 /// iteration of the ordered loop with the dynamic scheduling.
1152 ///
1153 /// \param CGF Reference to current CodeGenFunction.
1154 /// \param Loc Clang source location.
1155 /// \param IVSize Size of the iteration variable in bits.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +00001156 /// \param IVSigned Sign of the iteration variable.
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001157 ///
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001158 virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF,
1159 SourceLocation Loc, unsigned IVSize,
1160 bool IVSigned);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001161
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001162 /// Call the appropriate runtime routine to notify that we finished
Alexander Musmanc6388682014-12-15 07:07:06 +00001163 /// all the work with current loop.
1164 ///
1165 /// \param CGF Reference to current CodeGenFunction.
1166 /// \param Loc Clang source location.
Alexey Bataevf43f7142017-09-06 16:17:35 +00001167 /// \param DKind Kind of the directive for which the static finish is emitted.
Alexander Musmanc6388682014-12-15 07:07:06 +00001168 ///
Alexey Bataevf43f7142017-09-06 16:17:35 +00001169 virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc,
1170 OpenMPDirectiveKind DKind);
Alexander Musmanc6388682014-12-15 07:07:06 +00001171
Alexander Musman92bdaab2015-03-12 13:37:50 +00001172 /// Call __kmpc_dispatch_next(
1173 /// ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
1174 /// kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
1175 /// kmp_int[32|64] *p_stride);
1176 /// \param IVSize Size of the iteration variable in bits.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +00001177 /// \param IVSigned Sign of the iteration variable.
Alexander Musman92bdaab2015-03-12 13:37:50 +00001178 /// \param IL Address of the output variable in which the flag of the
1179 /// last iteration is returned.
1180 /// \param LB Address of the output variable in which the lower iteration
1181 /// number is returned.
1182 /// \param UB Address of the output variable in which the upper iteration
1183 /// number is returned.
1184 /// \param ST Address of the output variable in which the stride value is
1185 /// returned.
1186 virtual llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc,
1187 unsigned IVSize, bool IVSigned,
John McCall7f416cc2015-09-08 08:05:57 +00001188 Address IL, Address LB,
1189 Address UB, Address ST);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001190
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001191 /// Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
Alexey Bataevb2059782014-10-13 08:23:51 +00001192 /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
1193 /// clause.
1194 /// \param NumThreads An integer value of threads.
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001195 virtual void emitNumThreadsClause(CodeGenFunction &CGF,
1196 llvm::Value *NumThreads,
1197 SourceLocation Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00001198
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001199 /// Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32
Alexey Bataev7f210c62015-06-18 13:40:03 +00001200 /// global_tid, int proc_bind) to generate code for 'proc_bind' clause.
1201 virtual void emitProcBindClause(CodeGenFunction &CGF,
Johannes Doerfert6c5d1f402019-12-25 18:15:36 -06001202 llvm::omp::ProcBindKind ProcBind,
Alexey Bataev7f210c62015-06-18 13:40:03 +00001203 SourceLocation Loc);
1204
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001205 /// Returns address of the threadprivate variable for the current
Alexey Bataev97720002014-11-11 04:05:39 +00001206 /// thread.
NAKAMURA Takumicdcbfba2014-11-11 07:58:06 +00001207 /// \param VD Threadprivate variable.
Alexey Bataev97720002014-11-11 04:05:39 +00001208 /// \param VDAddr Address of the global variable \a VD.
1209 /// \param Loc Location of the reference to threadprivate var.
1210 /// \return Address of the threadprivate variable for the current thread.
John McCall7f416cc2015-09-08 08:05:57 +00001211 virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF,
1212 const VarDecl *VD,
1213 Address VDAddr,
1214 SourceLocation Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00001215
Alexey Bataev92327c52018-03-26 16:40:55 +00001216 /// Returns the address of the variable marked as declare target with link
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00001217 /// clause OR as declare target with to clause and unified memory.
1218 virtual Address getAddrOfDeclareTargetVar(const VarDecl *VD);
Alexey Bataev92327c52018-03-26 16:40:55 +00001219
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001220 /// Emit a code for initialization of threadprivate variable. It emits
Alexey Bataev97720002014-11-11 04:05:39 +00001221 /// a call to runtime library which adds initial value to the newly created
1222 /// threadprivate variable (if it is not constant) and registers destructor
1223 /// for the variable (if any).
1224 /// \param VD Threadprivate variable.
1225 /// \param VDAddr Address of the global variable \a VD.
1226 /// \param Loc Location of threadprivate declaration.
1227 /// \param PerformInit true if initialization expression is not constant.
1228 virtual llvm::Function *
John McCall7f416cc2015-09-08 08:05:57 +00001229 emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr,
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001230 SourceLocation Loc, bool PerformInit,
1231 CodeGenFunction *CGF = nullptr);
Alexey Bataevcc37cc12014-11-20 04:34:54 +00001232
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001233 /// Emit a code for initialization of declare target variable.
Alexey Bataev34f8a702018-03-28 14:28:54 +00001234 /// \param VD Declare target variable.
1235 /// \param Addr Address of the global variable \a VD.
1236 /// \param PerformInit true if initialization expression is not constant.
1237 virtual bool emitDeclareTargetVarDefinition(const VarDecl *VD,
1238 llvm::GlobalVariable *Addr,
1239 bool PerformInit);
1240
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001241 /// Creates artificial threadprivate variable with name \p Name and type \p
1242 /// VarType.
1243 /// \param VarType Type of the artificial threadprivate variable.
1244 /// \param Name Name of the artificial threadprivate variable.
1245 virtual Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
1246 QualType VarType,
1247 StringRef Name);
1248
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001249 /// Emit flush of the variables specified in 'omp flush' directive.
Alexey Bataevcc37cc12014-11-20 04:34:54 +00001250 /// \param Vars List of variables to flush.
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001251 virtual void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars,
Alexey Bataeve8e05de2020-02-07 12:22:23 -05001252 SourceLocation Loc, llvm::AtomicOrdering AO);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001253
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001254 /// Emit task region for the task directive. The task region is
Nico Weber20b0ce32015-04-28 18:19:18 +00001255 /// emitted in several steps:
Alexey Bataev62b63b12015-03-10 07:28:44 +00001256 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
1257 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1258 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
1259 /// function:
1260 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
1261 /// TaskFunction(gtid, tt->part_id, tt->shareds);
1262 /// return 0;
1263 /// }
1264 /// 2. Copy a list of shared variables to field shareds of the resulting
1265 /// structure kmp_task_t returned by the previous call (if any).
1266 /// 3. Copy a pointer to destructions function to field destructions of the
1267 /// resulting structure kmp_task_t.
1268 /// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid,
1269 /// kmp_task_t *new_task), where new_task is a resulting structure from
1270 /// previous items.
Alexey Bataev36c1eb92015-04-30 06:51:57 +00001271 /// \param D Current task directive.
Alexey Bataev62b63b12015-03-10 07:28:44 +00001272 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
1273 /// /*part_id*/, captured_struct */*__context*/);
1274 /// \param SharedsTy A type which contains references the shared variables.
Alexey Bataev1d2353d2015-06-24 11:01:36 +00001275 /// \param Shareds Context with the list of shared variables from the \p
Alexey Bataev62b63b12015-03-10 07:28:44 +00001276 /// TaskFunction.
Alexey Bataev1d677132015-04-22 13:57:31 +00001277 /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
1278 /// otherwise.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00001279 /// \param Data Additional data for task generation like tiednsee, final
1280 /// state, list of privates etc.
1281 virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
1282 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00001283 llvm::Function *TaskFunction, QualType SharedsTy,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00001284 Address Shareds, const Expr *IfCond,
1285 const OMPTaskDataTy &Data);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001286
Alexey Bataev7292c292016-04-25 12:22:29 +00001287 /// Emit task region for the taskloop directive. The taskloop region is
1288 /// emitted in several steps:
1289 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
1290 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1291 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
1292 /// function:
1293 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
1294 /// TaskFunction(gtid, tt->part_id, tt->shareds);
1295 /// return 0;
1296 /// }
1297 /// 2. Copy a list of shared variables to field shareds of the resulting
1298 /// structure kmp_task_t returned by the previous call (if any).
1299 /// 3. Copy a pointer to destructions function to field destructions of the
1300 /// resulting structure kmp_task_t.
1301 /// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t
1302 /// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int
1303 /// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task
1304 /// is a resulting structure from
1305 /// previous items.
1306 /// \param D Current task directive.
Alexey Bataev7292c292016-04-25 12:22:29 +00001307 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
1308 /// /*part_id*/, captured_struct */*__context*/);
1309 /// \param SharedsTy A type which contains references the shared variables.
1310 /// \param Shareds Context with the list of shared variables from the \p
1311 /// TaskFunction.
1312 /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
1313 /// otherwise.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00001314 /// \param Data Additional data for task generation like tiednsee, final
1315 /// state, list of privates etc.
James Y Knight9871db02019-02-05 16:42:33 +00001316 virtual void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
1317 const OMPLoopDirective &D,
1318 llvm::Function *TaskFunction,
1319 QualType SharedsTy, Address Shareds,
1320 const Expr *IfCond, const OMPTaskDataTy &Data);
Alexey Bataev7292c292016-04-25 12:22:29 +00001321
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001322 /// Emit code for the directive that does not require outlining.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001323 ///
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001324 /// \param InnermostKind Kind of innermost directive (for simple directives it
1325 /// is a directive itself, for combined - its innermost directive).
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001326 /// \param CodeGen Code generation sequence for the \a D directive.
Alexey Bataev25e5b442015-09-15 12:52:43 +00001327 /// \param HasCancel true if region has inner cancel directive, false
1328 /// otherwise.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001329 virtual void emitInlinedDirective(CodeGenFunction &CGF,
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001330 OpenMPDirectiveKind InnermostKind,
Alexey Bataev25e5b442015-09-15 12:52:43 +00001331 const RegionCodeGenTy &CodeGen,
1332 bool HasCancel = false);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001333
1334 /// Emits reduction function.
1335 /// \param ArgsType Array type containing pointers to reduction variables.
1336 /// \param Privates List of private copies for original reduction arguments.
1337 /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
1338 /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
1339 /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
1340 /// or 'operator binop(LHS, RHS)'.
Alexey Bataev982a35e2019-03-19 17:09:52 +00001341 llvm::Function *emitReductionFunction(SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00001342 llvm::Type *ArgsType,
1343 ArrayRef<const Expr *> Privates,
1344 ArrayRef<const Expr *> LHSExprs,
1345 ArrayRef<const Expr *> RHSExprs,
1346 ArrayRef<const Expr *> ReductionOps);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001347
1348 /// Emits single reduction combiner
1349 void emitSingleReductionCombiner(CodeGenFunction &CGF,
1350 const Expr *ReductionOp,
1351 const Expr *PrivateRef,
1352 const DeclRefExpr *LHS,
1353 const DeclRefExpr *RHS);
1354
1355 struct ReductionOptionsTy {
1356 bool WithNowait;
1357 bool SimpleReduction;
1358 OpenMPDirectiveKind ReductionKind;
1359 };
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001360 /// Emit a code for reduction clause. Next code should be emitted for
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001361 /// reduction:
1362 /// \code
1363 ///
1364 /// static kmp_critical_name lock = { 0 };
1365 ///
1366 /// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
1367 /// ...
1368 /// *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
1369 /// ...
1370 /// }
1371 ///
1372 /// ...
1373 /// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
1374 /// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
1375 /// RedList, reduce_func, &<lock>)) {
1376 /// case 1:
1377 /// ...
1378 /// <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
1379 /// ...
1380 /// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
1381 /// break;
1382 /// case 2:
1383 /// ...
1384 /// Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
1385 /// ...
1386 /// break;
1387 /// default:;
1388 /// }
1389 /// \endcode
1390 ///
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001391 /// \param Privates List of private copies for original reduction arguments.
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001392 /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
1393 /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
1394 /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
1395 /// or 'operator binop(LHS, RHS)'.
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001396 /// \param Options List of options for reduction codegen:
1397 /// WithNowait true if parent directive has also nowait clause, false
1398 /// otherwise.
1399 /// SimpleReduction Emit reduction operation only. Used for omp simd
1400 /// directive on the host.
1401 /// ReductionKind The kind of reduction to perform.
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001402 virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001403 ArrayRef<const Expr *> Privates,
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001404 ArrayRef<const Expr *> LHSExprs,
1405 ArrayRef<const Expr *> RHSExprs,
1406 ArrayRef<const Expr *> ReductionOps,
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001407 ReductionOptionsTy Options);
Alexey Bataev8b8e2022015-04-27 05:22:09 +00001408
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001409 /// Emit a code for initialization of task reduction clause. Next code
1410 /// should be emitted for reduction:
1411 /// \code
1412 ///
1413 /// _task_red_item_t red_data[n];
1414 /// ...
1415 /// red_data[i].shar = &origs[i];
1416 /// red_data[i].size = sizeof(origs[i]);
1417 /// red_data[i].f_init = (void*)RedInit<i>;
1418 /// red_data[i].f_fini = (void*)RedDest<i>;
1419 /// red_data[i].f_comb = (void*)RedOp<i>;
1420 /// red_data[i].flags = <Flag_i>;
1421 /// ...
1422 /// void* tg1 = __kmpc_task_reduction_init(gtid, n, red_data);
1423 /// \endcode
1424 ///
1425 /// \param LHSExprs List of LHS in \a Data.ReductionOps reduction operations.
1426 /// \param RHSExprs List of RHS in \a Data.ReductionOps reduction operations.
1427 /// \param Data Additional data for task generation like tiedness, final
1428 /// state, list of privates, reductions etc.
1429 virtual llvm::Value *emitTaskReductionInit(CodeGenFunction &CGF,
1430 SourceLocation Loc,
1431 ArrayRef<const Expr *> LHSExprs,
1432 ArrayRef<const Expr *> RHSExprs,
1433 const OMPTaskDataTy &Data);
1434
1435 /// Required to resolve existing problems in the runtime. Emits threadprivate
1436 /// variables to store the size of the VLAs/array sections for
1437 /// initializer/combiner/finalizer functions + emits threadprivate variable to
1438 /// store the pointer to the original reduction item for the custom
1439 /// initializer defined by declare reduction construct.
1440 /// \param RCG Allows to reuse an existing data for the reductions.
1441 /// \param N Reduction item for which fixups must be emitted.
1442 virtual void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc,
1443 ReductionCodeGen &RCG, unsigned N);
1444
1445 /// Get the address of `void *` type of the privatue copy of the reduction
1446 /// item specified by the \p SharedLVal.
1447 /// \param ReductionsPtr Pointer to the reduction data returned by the
1448 /// emitTaskReductionInit function.
1449 /// \param SharedLVal Address of the original reduction item.
1450 virtual Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc,
1451 llvm::Value *ReductionsPtr,
1452 LValue SharedLVal);
1453
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001454 /// Emit code for 'taskwait' directive.
Alexey Bataev8b8e2022015-04-27 05:22:09 +00001455 virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc);
Alexey Bataev0f34da12015-07-02 04:17:07 +00001456
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001457 /// Emit code for 'cancellation point' construct.
Alexey Bataev0f34da12015-07-02 04:17:07 +00001458 /// \param CancelRegion Region kind for which the cancellation point must be
1459 /// emitted.
1460 ///
1461 virtual void emitCancellationPointCall(CodeGenFunction &CGF,
1462 SourceLocation Loc,
1463 OpenMPDirectiveKind CancelRegion);
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00001464
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001465 /// Emit code for 'cancel' construct.
Alexey Bataev87933c72015-09-18 08:07:34 +00001466 /// \param IfCond Condition in the associated 'if' clause, if it was
1467 /// specified, nullptr otherwise.
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00001468 /// \param CancelRegion Region kind for which the cancel must be emitted.
1469 ///
1470 virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev87933c72015-09-18 08:07:34 +00001471 const Expr *IfCond,
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00001472 OpenMPDirectiveKind CancelRegion);
Samuel Antaobed3c462015-10-02 16:14:20 +00001473
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001474 /// Emit outilined function for 'target' directive.
Samuel Antaobed3c462015-10-02 16:14:20 +00001475 /// \param D Directive to emit.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001476 /// \param ParentName Name of the function that encloses the target region.
1477 /// \param OutlinedFn Outlined function value to be defined by this call.
1478 /// \param OutlinedFnID Outlined function ID value to be defined by this call.
1479 /// \param IsOffloadEntry True if the outlined function is an offload entry.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001480 /// \param CodeGen Code generation sequence for the \a D directive.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +00001481 /// An outlined function may not be an entry if, e.g. the if clause always
Samuel Antaoee8fb302016-01-06 13:42:12 +00001482 /// evaluates to false.
1483 virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
1484 StringRef ParentName,
1485 llvm::Function *&OutlinedFn,
1486 llvm::Constant *&OutlinedFnID,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001487 bool IsOffloadEntry,
1488 const RegionCodeGenTy &CodeGen);
Samuel Antaobed3c462015-10-02 16:14:20 +00001489
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001490 /// Emit the target offloading code associated with \a D. The emitted
Samuel Antaobed3c462015-10-02 16:14:20 +00001491 /// code attempts offloading the execution to the device, an the event of
1492 /// a failure it executes the host version outlined in \a OutlinedFn.
1493 /// \param D Directive to emit.
1494 /// \param OutlinedFn Host version of the code to be offloaded.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001495 /// \param OutlinedFnID ID of host version of the code to be offloaded.
Samuel Antaobed3c462015-10-02 16:14:20 +00001496 /// \param IfCond Expression evaluated in if clause associated with the target
1497 /// directive, or null if no if clause is used.
1498 /// \param Device Expression evaluated in device clause associated with the
1499 /// target directive, or null if no device clause is used.
Alexey Bataevec7946e2019-09-23 14:06:51 +00001500 /// \param SizeEmitter Callback to emit number of iterations for loop-based
1501 /// directives.
1502 virtual void
1503 emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
1504 llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID,
1505 const Expr *IfCond, const Expr *Device,
1506 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
1507 const OMPLoopDirective &D)>
1508 SizeEmitter);
Samuel Antaoee8fb302016-01-06 13:42:12 +00001509
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001510 /// Emit the target regions enclosed in \a GD function definition or
Samuel Antaoee8fb302016-01-06 13:42:12 +00001511 /// the function itself in case it is a valid device function. Returns true if
1512 /// \a GD was dealt with successfully.
Nico Webera2abe8c2016-01-06 19:13:49 +00001513 /// \param GD Function to scan.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001514 virtual bool emitTargetFunctions(GlobalDecl GD);
1515
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001516 /// Emit the global variable if it is a valid device global variable.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001517 /// Returns true if \a GD was dealt with successfully.
1518 /// \param GD Variable declaration to emit.
1519 virtual bool emitTargetGlobalVariable(GlobalDecl GD);
1520
Alexey Bataev03f270c2018-03-30 18:31:07 +00001521 /// Checks if the provided global decl \a GD is a declare target variable and
1522 /// registers it when emitting code for the host.
1523 virtual void registerTargetGlobalVariable(const VarDecl *VD,
1524 llvm::Constant *Addr);
1525
Alexey Bataev1af5bd52019-03-05 17:47:18 +00001526 /// Registers provided target firstprivate variable as global on the
1527 /// target.
1528 llvm::Constant *registerTargetFirstprivateCopy(CodeGenFunction &CGF,
1529 const VarDecl *VD);
1530
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001531 /// Emit the global \a GD if it is meaningful for the target. Returns
Simon Pilgrim2c518802017-03-30 14:13:19 +00001532 /// if it was emitted successfully.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001533 /// \param GD Global to scan.
1534 virtual bool emitTargetGlobal(GlobalDecl GD);
1535
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00001536 /// Creates and returns a registration function for when at least one
1537 /// requires directives was used in the current module.
1538 llvm::Function *emitRequiresDirectiveRegFun();
1539
Sergey Dmitriev5836c352019-10-15 18:42:47 +00001540 /// Creates all the offload entries in the current compilation unit
1541 /// along with the associated metadata.
1542 void createOffloadEntriesAndInfoMetadata();
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00001543
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001544 /// Emits code for teams call of the \a OutlinedFn with
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00001545 /// variables captured in a record which address is stored in \a
1546 /// CapturedStruct.
1547 /// \param OutlinedFn Outlined function to be run by team masters. Type of
1548 /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
1549 /// \param CapturedVars A pointer to the record with the references to
1550 /// variables used in \a OutlinedFn function.
1551 ///
1552 virtual void emitTeamsCall(CodeGenFunction &CGF,
1553 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00001554 SourceLocation Loc, llvm::Function *OutlinedFn,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00001555 ArrayRef<llvm::Value *> CapturedVars);
1556
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001557 /// Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00001558 /// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code
1559 /// for num_teams clause.
Carlo Bertollic6872252016-04-04 15:55:02 +00001560 /// \param NumTeams An integer expression of teams.
1561 /// \param ThreadLimit An integer expression of threads.
1562 virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams,
1563 const Expr *ThreadLimit, SourceLocation Loc);
Samuel Antaodf158d52016-04-27 22:58:19 +00001564
Samuel Antaocc10b852016-07-28 14:23:26 +00001565 /// Struct that keeps all the relevant information that should be kept
1566 /// throughout a 'target data' region.
1567 class TargetDataInfo {
1568 /// Set to true if device pointer information have to be obtained.
1569 bool RequiresDevicePointerInfo = false;
1570
1571 public:
1572 /// The array of base pointer passed to the runtime library.
1573 llvm::Value *BasePointersArray = nullptr;
1574 /// The array of section pointers passed to the runtime library.
1575 llvm::Value *PointersArray = nullptr;
1576 /// The array of sizes passed to the runtime library.
1577 llvm::Value *SizesArray = nullptr;
1578 /// The array of map types passed to the runtime library.
1579 llvm::Value *MapTypesArray = nullptr;
1580 /// The total number of pointers passed to the runtime library.
1581 unsigned NumberOfPtrs = 0u;
1582 /// Map between the a declaration of a capture and the corresponding base
1583 /// pointer address where the runtime returns the device pointers.
1584 llvm::DenseMap<const ValueDecl *, Address> CaptureDeviceAddrMap;
1585
1586 explicit TargetDataInfo() {}
1587 explicit TargetDataInfo(bool RequiresDevicePointerInfo)
1588 : RequiresDevicePointerInfo(RequiresDevicePointerInfo) {}
1589 /// Clear information about the data arrays.
1590 void clearArrayInfo() {
1591 BasePointersArray = nullptr;
1592 PointersArray = nullptr;
1593 SizesArray = nullptr;
1594 MapTypesArray = nullptr;
1595 NumberOfPtrs = 0u;
1596 }
1597 /// Return true if the current target data information has valid arrays.
1598 bool isValid() {
1599 return BasePointersArray && PointersArray && SizesArray &&
1600 MapTypesArray && NumberOfPtrs;
1601 }
1602 bool requiresDevicePointerInfo() { return RequiresDevicePointerInfo; }
1603 };
1604
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001605 /// Emit the target data mapping code associated with \a D.
Samuel Antaodf158d52016-04-27 22:58:19 +00001606 /// \param D Directive to emit.
Samuel Antaocc10b852016-07-28 14:23:26 +00001607 /// \param IfCond Expression evaluated in if clause associated with the
1608 /// target directive, or null if no device clause is used.
Samuel Antaodf158d52016-04-27 22:58:19 +00001609 /// \param Device Expression evaluated in device clause associated with the
1610 /// target directive, or null if no device clause is used.
Samuel Antaocc10b852016-07-28 14:23:26 +00001611 /// \param Info A record used to store information that needs to be preserved
1612 /// until the region is closed.
Samuel Antaodf158d52016-04-27 22:58:19 +00001613 virtual void emitTargetDataCalls(CodeGenFunction &CGF,
1614 const OMPExecutableDirective &D,
1615 const Expr *IfCond, const Expr *Device,
Samuel Antaocc10b852016-07-28 14:23:26 +00001616 const RegionCodeGenTy &CodeGen,
1617 TargetDataInfo &Info);
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00001618
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001619 /// Emit the data mapping/movement code associated with the directive
Samuel Antao8d2d7302016-05-26 18:30:22 +00001620 /// \a D that should be of the form 'target [{enter|exit} data | update]'.
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00001621 /// \param D Directive to emit.
1622 /// \param IfCond Expression evaluated in if clause associated with the target
1623 /// directive, or null if no if clause is used.
1624 /// \param Device Expression evaluated in device clause associated with the
1625 /// target directive, or null if no device clause is used.
Samuel Antao8d2d7302016-05-26 18:30:22 +00001626 virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF,
1627 const OMPExecutableDirective &D,
1628 const Expr *IfCond,
1629 const Expr *Device);
Alexey Bataevc7a82b42016-05-06 09:40:08 +00001630
1631 /// Marks function \a Fn with properly mangled versions of vector functions.
1632 /// \param FD Function marked as 'declare simd'.
1633 /// \param Fn LLVM function that must be marked with 'declare simd'
1634 /// attributes.
1635 virtual void emitDeclareSimdFunction(const FunctionDecl *FD,
1636 llvm::Function *Fn);
Alexey Bataev8b427062016-05-25 12:36:08 +00001637
1638 /// Emit initialization for doacross loop nesting support.
1639 /// \param D Loop-based construct used in doacross nesting construct.
Alexey Bataevf138fda2018-08-13 19:04:24 +00001640 virtual void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D,
1641 ArrayRef<Expr *> NumIterations);
Alexey Bataev8b427062016-05-25 12:36:08 +00001642
1643 /// Emit code for doacross ordered directive with 'depend' clause.
1644 /// \param C 'depend' clause with 'sink|source' dependency kind.
1645 virtual void emitDoacrossOrdered(CodeGenFunction &CGF,
1646 const OMPDependClause *C);
Alexey Bataev2c7eee52017-08-04 19:10:54 +00001647
Alexey Bataev3b8d5582017-08-08 18:04:06 +00001648 /// Translates the native parameter of outlined function if this is required
1649 /// for target.
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00001650 /// \param FD Field decl from captured record for the parameter.
Alexey Bataev3b8d5582017-08-08 18:04:06 +00001651 /// \param NativeParam Parameter itself.
1652 virtual const VarDecl *translateParameter(const FieldDecl *FD,
1653 const VarDecl *NativeParam) const {
1654 return NativeParam;
1655 }
1656
1657 /// Gets the address of the native argument basing on the address of the
1658 /// target-specific parameter.
1659 /// \param NativeParam Parameter itself.
1660 /// \param TargetParam Corresponding target-specific parameter.
1661 virtual Address getParameterAddress(CodeGenFunction &CGF,
1662 const VarDecl *NativeParam,
1663 const VarDecl *TargetParam) const;
1664
Gheorghe-Teodor Bercea02650d42018-09-27 19:22:56 +00001665 /// Choose default schedule type and chunk value for the
1666 /// dist_schedule clause.
1667 virtual void getDefaultDistScheduleAndChunk(CodeGenFunction &CGF,
1668 const OMPLoopDirective &S, OpenMPDistScheduleClauseKind &ScheduleKind,
1669 llvm::Value *&Chunk) const {}
1670
Gheorghe-Teodor Bercea8233af92018-09-27 20:29:00 +00001671 /// Choose default schedule type and chunk value for the
1672 /// schedule clause.
1673 virtual void getDefaultScheduleAndChunk(CodeGenFunction &CGF,
1674 const OMPLoopDirective &S, OpenMPScheduleClauseKind &ScheduleKind,
Alexey Bataevf6a53d62019-03-18 18:40:00 +00001675 const Expr *&ChunkExpr) const;
Gheorghe-Teodor Bercea8233af92018-09-27 20:29:00 +00001676
Alexey Bataev2c7eee52017-08-04 19:10:54 +00001677 /// Emits call of the outlined function with the provided arguments,
1678 /// translating these arguments to correct target-specific arguments.
1679 virtual void
Alexey Bataev3c595a62017-08-14 15:01:03 +00001680 emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00001681 llvm::FunctionCallee OutlinedFn,
Alexey Bataev2c7eee52017-08-04 19:10:54 +00001682 ArrayRef<llvm::Value *> Args = llvm::None) const;
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +00001683
1684 /// Emits OpenMP-specific function prolog.
1685 /// Required for device constructs.
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00001686 virtual void emitFunctionProlog(CodeGenFunction &CGF, const Decl *D);
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +00001687
1688 /// Gets the OpenMP-specific address of the local variable.
1689 virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF,
1690 const VarDecl *VD);
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001691
Raphael Isemannb23ccec2018-12-10 12:37:46 +00001692 /// Marks the declaration as already emitted for the device code and returns
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001693 /// true, if it was marked already, and false, otherwise.
Alexey Bataev6d944102018-05-02 15:45:28 +00001694 bool markAsGlobalTarget(GlobalDecl GD);
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001695
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001696 /// Emit deferred declare target variables marked for deferred emission.
1697 void emitDeferredTargetDecls() const;
Alexey Bataev60705422018-10-30 15:50:12 +00001698
1699 /// Adjust some parameters for the target-based directives, like addresses of
1700 /// the variables captured by reference in lambdas.
1701 virtual void
1702 adjustTargetSpecificDataForLambdas(CodeGenFunction &CGF,
1703 const OMPExecutableDirective &D) const;
Patrick Lyster8f7f5862018-11-19 15:09:33 +00001704
1705 /// Perform check on requires decl to ensure that target architecture
1706 /// supports unified addressing
Alexey Bataev2d4f80f2020-02-11 15:15:21 -05001707 virtual void processRequiresDirective(const OMPRequiresDecl *D);
1708
1709 /// Gets default memory ordering as specified in requires directive.
1710 llvm::AtomicOrdering getDefaultMemoryOrdering() const;
Alexey Bataevc5687252019-03-21 19:35:27 +00001711
1712 /// Checks if the variable has associated OMPAllocateDeclAttr attribute with
1713 /// the predefined allocator and translates it into the corresponding address
1714 /// space.
1715 virtual bool hasAllocateAttributeForGlobalVar(const VarDecl *VD, LangAS &AS);
Gheorghe-Teodor Bercea5254f0a2019-06-14 17:58:26 +00001716
1717 /// Return whether the unified_shared_memory has been specified.
1718 bool hasRequiresUnifiedSharedMemory() const;
Alexey Bataev2df5f122019-10-01 20:18:32 +00001719
1720 /// Emits the definition of the declare variant function.
1721 virtual bool emitDeclareVariant(GlobalDecl GD, bool IsForDefinition);
Alexey Bataev0860db92019-12-19 10:01:10 -05001722
1723 /// Checks if the \p VD variable is marked as nontemporal declaration in
1724 /// current context.
1725 bool isNontemporalDecl(const ValueDecl *VD) const;
Alexey Bataeva58da1a2019-12-27 09:44:43 -05001726
Alexey Bataev46978742020-01-30 10:46:11 -05001727 /// Create specialized alloca to handle lastprivate conditionals.
1728 Address emitLastprivateConditionalInit(CodeGenFunction &CGF,
1729 const VarDecl *VD);
1730
Alexey Bataeva58da1a2019-12-27 09:44:43 -05001731 /// Checks if the provided \p LVal is lastprivate conditional and emits the
1732 /// code to update the value of the original variable.
1733 /// \code
1734 /// lastprivate(conditional: a)
1735 /// ...
1736 /// <type> a;
1737 /// lp_a = ...;
1738 /// #pragma omp critical(a)
1739 /// if (last_iv_a <= iv) {
1740 /// last_iv_a = iv;
1741 /// global_a = lp_a;
1742 /// }
1743 /// \endcode
1744 virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF,
1745 const Expr *LHS);
1746
Alexey Bataev46978742020-01-30 10:46:11 -05001747 /// Checks if the lastprivate conditional was updated in inner region and
1748 /// writes the value.
1749 /// \code
1750 /// lastprivate(conditional: a)
1751 /// ...
1752 /// <type> a;bool Fired = false;
1753 /// #pragma omp ... shared(a)
1754 /// {
1755 /// lp_a = ...;
1756 /// Fired = true;
1757 /// }
1758 /// if (Fired) {
1759 /// #pragma omp critical(a)
1760 /// if (last_iv_a <= iv) {
1761 /// last_iv_a = iv;
1762 /// global_a = lp_a;
1763 /// }
1764 /// Fired = false;
1765 /// }
1766 /// \endcode
1767 virtual void checkAndEmitSharedLastprivateConditional(
1768 CodeGenFunction &CGF, const OMPExecutableDirective &D,
1769 const llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> &IgnoredDecls);
1770
Alexey Bataeva58da1a2019-12-27 09:44:43 -05001771 /// Gets the address of the global copy used for lastprivate conditional
1772 /// update, if any.
1773 /// \param PrivLVal LValue for the private copy.
1774 /// \param VD Original lastprivate declaration.
1775 virtual void emitLastprivateConditionalFinalUpdate(CodeGenFunction &CGF,
1776 LValue PrivLVal,
1777 const VarDecl *VD,
1778 SourceLocation Loc);
Alexey Bataeve46f0fe2020-03-04 14:37:51 -05001779
1780 /// Emits list of dependecies based on the provided data (array of
1781 /// dependence/expression pairs).
1782 /// \param ForDepobj true if the memory for depencies is alloacted for depobj
1783 /// directive. In this case, the variable is allocated in dynamically.
1784 /// \returns Pointer to the first element of the array casted to VoidPtr type.
1785 Address emitDependClause(
1786 CodeGenFunction &CGF,
1787 ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependencies,
1788 bool ForDepobj, SourceLocation Loc);
Alexey Bataevb27ff4d2020-03-04 16:15:28 -05001789
1790 /// Emits the code to destroy the dependency object provided in depobj
1791 /// directive.
1792 void emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal,
1793 SourceLocation Loc);
Alexey Bataev8d7b1182020-03-05 13:45:28 -05001794
1795 /// Updates the dependency kind in the specified depobj object.
1796 /// \param DepobjLVal LValue for the main depobj object.
1797 /// \param NewDepKind New dependency kind.
1798 void emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal,
1799 OpenMPDependClauseKind NewDepKind, SourceLocation Loc);
Alexey Bataev9959db52014-05-06 10:08:46 +00001800};
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00001801
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001802/// Class supports emissionof SIMD-only code.
1803class CGOpenMPSIMDRuntime final : public CGOpenMPRuntime {
1804public:
1805 explicit CGOpenMPSIMDRuntime(CodeGenModule &CGM) : CGOpenMPRuntime(CGM) {}
1806 ~CGOpenMPSIMDRuntime() override {}
1807
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001808 /// Emits outlined function for the specified OpenMP parallel directive
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001809 /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
1810 /// kmp_int32 BoundID, struct context_vars*).
1811 /// \param D OpenMP directive.
1812 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
1813 /// \param InnermostKind Kind of innermost directive (for simple directives it
1814 /// is a directive itself, for combined - its innermost directive).
1815 /// \param CodeGen Code generation sequence for the \a D directive.
James Y Knight9871db02019-02-05 16:42:33 +00001816 llvm::Function *
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001817 emitParallelOutlinedFunction(const OMPExecutableDirective &D,
1818 const VarDecl *ThreadIDVar,
1819 OpenMPDirectiveKind InnermostKind,
1820 const RegionCodeGenTy &CodeGen) override;
1821
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001822 /// Emits outlined function for the specified OpenMP teams directive
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001823 /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
1824 /// kmp_int32 BoundID, struct context_vars*).
1825 /// \param D OpenMP directive.
1826 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
1827 /// \param InnermostKind Kind of innermost directive (for simple directives it
1828 /// is a directive itself, for combined - its innermost directive).
1829 /// \param CodeGen Code generation sequence for the \a D directive.
James Y Knight9871db02019-02-05 16:42:33 +00001830 llvm::Function *
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001831 emitTeamsOutlinedFunction(const OMPExecutableDirective &D,
1832 const VarDecl *ThreadIDVar,
1833 OpenMPDirectiveKind InnermostKind,
1834 const RegionCodeGenTy &CodeGen) override;
1835
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001836 /// Emits outlined function for the OpenMP task directive \a D. This
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001837 /// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t*
1838 /// TaskT).
1839 /// \param D OpenMP directive.
1840 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
1841 /// \param PartIDVar Variable for partition id in the current OpenMP untied
1842 /// task region.
1843 /// \param TaskTVar Variable for task_t argument.
1844 /// \param InnermostKind Kind of innermost directive (for simple directives it
1845 /// is a directive itself, for combined - its innermost directive).
1846 /// \param CodeGen Code generation sequence for the \a D directive.
1847 /// \param Tied true if task is generated for tied task, false otherwise.
1848 /// \param NumberOfParts Number of parts in untied task. Ignored for tied
1849 /// tasks.
1850 ///
James Y Knight9871db02019-02-05 16:42:33 +00001851 llvm::Function *emitTaskOutlinedFunction(
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001852 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1853 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
1854 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1855 bool Tied, unsigned &NumberOfParts) override;
1856
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001857 /// Emits code for parallel or serial call of the \a OutlinedFn with
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001858 /// variables captured in a record which address is stored in \a
1859 /// CapturedStruct.
1860 /// \param OutlinedFn Outlined function to be run in parallel threads. Type of
1861 /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
1862 /// \param CapturedVars A pointer to the record with the references to
1863 /// variables used in \a OutlinedFn function.
1864 /// \param IfCond Condition in the associated 'if' clause, if it was
1865 /// specified, nullptr otherwise.
1866 ///
1867 void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00001868 llvm::Function *OutlinedFn,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001869 ArrayRef<llvm::Value *> CapturedVars,
1870 const Expr *IfCond) override;
1871
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001872 /// Emits a critical region.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001873 /// \param CriticalName Name of the critical region.
1874 /// \param CriticalOpGen Generator for the statement associated with the given
1875 /// critical region.
1876 /// \param Hint Value of the 'hint' clause (optional).
1877 void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName,
1878 const RegionCodeGenTy &CriticalOpGen,
1879 SourceLocation Loc,
1880 const Expr *Hint = nullptr) override;
1881
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001882 /// Emits a master region.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001883 /// \param MasterOpGen Generator for the statement associated with the given
1884 /// master region.
1885 void emitMasterRegion(CodeGenFunction &CGF,
1886 const RegionCodeGenTy &MasterOpGen,
1887 SourceLocation Loc) override;
1888
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001889 /// Emits code for a taskyield directive.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001890 void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc) override;
1891
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001892 /// Emit a taskgroup region.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001893 /// \param TaskgroupOpGen Generator for the statement associated with the
1894 /// given taskgroup region.
1895 void emitTaskgroupRegion(CodeGenFunction &CGF,
1896 const RegionCodeGenTy &TaskgroupOpGen,
1897 SourceLocation Loc) override;
1898
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001899 /// Emits a single region.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001900 /// \param SingleOpGen Generator for the statement associated with the given
1901 /// single region.
1902 void emitSingleRegion(CodeGenFunction &CGF,
1903 const RegionCodeGenTy &SingleOpGen, SourceLocation Loc,
1904 ArrayRef<const Expr *> CopyprivateVars,
1905 ArrayRef<const Expr *> DestExprs,
1906 ArrayRef<const Expr *> SrcExprs,
1907 ArrayRef<const Expr *> AssignmentOps) override;
1908
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001909 /// Emit an ordered region.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001910 /// \param OrderedOpGen Generator for the statement associated with the given
1911 /// ordered region.
1912 void emitOrderedRegion(CodeGenFunction &CGF,
1913 const RegionCodeGenTy &OrderedOpGen,
1914 SourceLocation Loc, bool IsThreads) override;
1915
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001916 /// Emit an implicit/explicit barrier for OpenMP threads.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001917 /// \param Kind Directive for which this implicit barrier call must be
1918 /// generated. Must be OMPD_barrier for explicit barrier generation.
1919 /// \param EmitChecks true if need to emit checks for cancellation barriers.
1920 /// \param ForceSimpleCall true simple barrier call must be emitted, false if
1921 /// runtime class decides which one to emit (simple or with cancellation
1922 /// checks).
1923 ///
1924 void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
1925 OpenMPDirectiveKind Kind, bool EmitChecks = true,
1926 bool ForceSimpleCall = false) override;
1927
1928 /// This is used for non static scheduled types and when the ordered
1929 /// clause is present on the loop construct.
1930 /// Depending on the loop schedule, it is necessary to call some runtime
1931 /// routine before start of the OpenMP loop to get the loop upper / lower
1932 /// bounds \a LB and \a UB and stride \a ST.
1933 ///
1934 /// \param CGF Reference to current CodeGenFunction.
1935 /// \param Loc Clang source location.
1936 /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
1937 /// \param IVSize Size of the iteration variable in bits.
1938 /// \param IVSigned Sign of the iteration variable.
1939 /// \param Ordered true if loop is ordered, false otherwise.
1940 /// \param DispatchValues struct containing llvm values for lower bound, upper
1941 /// bound, and chunk expression.
1942 /// For the default (nullptr) value, the chunk 1 will be used.
1943 ///
1944 void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc,
1945 const OpenMPScheduleTy &ScheduleKind,
1946 unsigned IVSize, bool IVSigned, bool Ordered,
1947 const DispatchRTInput &DispatchValues) override;
1948
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001949 /// Call the appropriate runtime routine to initialize it before start
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001950 /// of loop.
1951 ///
1952 /// This is used only in case of static schedule, when the user did not
1953 /// specify a ordered clause on the loop construct.
1954 /// Depending on the loop schedule, it is necessary to call some runtime
1955 /// routine before start of the OpenMP loop to get the loop upper / lower
1956 /// bounds LB and UB and stride ST.
1957 ///
1958 /// \param CGF Reference to current CodeGenFunction.
1959 /// \param Loc Clang source location.
1960 /// \param DKind Kind of the directive.
1961 /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
1962 /// \param Values Input arguments for the construct.
1963 ///
1964 void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
1965 OpenMPDirectiveKind DKind,
1966 const OpenMPScheduleTy &ScheduleKind,
1967 const StaticRTInput &Values) override;
1968
1969 ///
1970 /// \param CGF Reference to current CodeGenFunction.
1971 /// \param Loc Clang source location.
1972 /// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause.
1973 /// \param Values Input arguments for the construct.
1974 ///
1975 void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
1976 OpenMPDistScheduleClauseKind SchedKind,
1977 const StaticRTInput &Values) override;
1978
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001979 /// Call the appropriate runtime routine to notify that we finished
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001980 /// iteration of the ordered loop with the dynamic scheduling.
1981 ///
1982 /// \param CGF Reference to current CodeGenFunction.
1983 /// \param Loc Clang source location.
1984 /// \param IVSize Size of the iteration variable in bits.
1985 /// \param IVSigned Sign of the iteration variable.
1986 ///
1987 void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc,
1988 unsigned IVSize, bool IVSigned) override;
1989
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001990 /// Call the appropriate runtime routine to notify that we finished
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001991 /// all the work with current loop.
1992 ///
1993 /// \param CGF Reference to current CodeGenFunction.
1994 /// \param Loc Clang source location.
1995 /// \param DKind Kind of the directive for which the static finish is emitted.
1996 ///
1997 void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc,
1998 OpenMPDirectiveKind DKind) override;
1999
2000 /// Call __kmpc_dispatch_next(
2001 /// ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
2002 /// kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
2003 /// kmp_int[32|64] *p_stride);
2004 /// \param IVSize Size of the iteration variable in bits.
2005 /// \param IVSigned Sign of the iteration variable.
2006 /// \param IL Address of the output variable in which the flag of the
2007 /// last iteration is returned.
2008 /// \param LB Address of the output variable in which the lower iteration
2009 /// number is returned.
2010 /// \param UB Address of the output variable in which the upper iteration
2011 /// number is returned.
2012 /// \param ST Address of the output variable in which the stride value is
2013 /// returned.
2014 llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc,
2015 unsigned IVSize, bool IVSigned, Address IL,
2016 Address LB, Address UB, Address ST) override;
2017
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002018 /// Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002019 /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
2020 /// clause.
2021 /// \param NumThreads An integer value of threads.
2022 void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads,
2023 SourceLocation Loc) override;
2024
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002025 /// Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002026 /// global_tid, int proc_bind) to generate code for 'proc_bind' clause.
2027 void emitProcBindClause(CodeGenFunction &CGF,
Johannes Doerfert6c5d1f402019-12-25 18:15:36 -06002028 llvm::omp::ProcBindKind ProcBind,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002029 SourceLocation Loc) override;
2030
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002031 /// Returns address of the threadprivate variable for the current
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002032 /// thread.
2033 /// \param VD Threadprivate variable.
2034 /// \param VDAddr Address of the global variable \a VD.
2035 /// \param Loc Location of the reference to threadprivate var.
2036 /// \return Address of the threadprivate variable for the current thread.
2037 Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD,
2038 Address VDAddr, SourceLocation Loc) override;
2039
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002040 /// Emit a code for initialization of threadprivate variable. It emits
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002041 /// a call to runtime library which adds initial value to the newly created
2042 /// threadprivate variable (if it is not constant) and registers destructor
2043 /// for the variable (if any).
2044 /// \param VD Threadprivate variable.
2045 /// \param VDAddr Address of the global variable \a VD.
2046 /// \param Loc Location of threadprivate declaration.
2047 /// \param PerformInit true if initialization expression is not constant.
2048 llvm::Function *
2049 emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr,
2050 SourceLocation Loc, bool PerformInit,
2051 CodeGenFunction *CGF = nullptr) override;
2052
2053 /// Creates artificial threadprivate variable with name \p Name and type \p
2054 /// VarType.
2055 /// \param VarType Type of the artificial threadprivate variable.
2056 /// \param Name Name of the artificial threadprivate variable.
2057 Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
2058 QualType VarType,
2059 StringRef Name) override;
2060
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002061 /// Emit flush of the variables specified in 'omp flush' directive.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002062 /// \param Vars List of variables to flush.
2063 void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars,
Alexey Bataeve8e05de2020-02-07 12:22:23 -05002064 SourceLocation Loc, llvm::AtomicOrdering AO) override;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002065
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002066 /// Emit task region for the task directive. The task region is
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002067 /// emitted in several steps:
2068 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
2069 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
2070 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
2071 /// function:
2072 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
2073 /// TaskFunction(gtid, tt->part_id, tt->shareds);
2074 /// return 0;
2075 /// }
2076 /// 2. Copy a list of shared variables to field shareds of the resulting
2077 /// structure kmp_task_t returned by the previous call (if any).
2078 /// 3. Copy a pointer to destructions function to field destructions of the
2079 /// resulting structure kmp_task_t.
2080 /// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid,
2081 /// kmp_task_t *new_task), where new_task is a resulting structure from
2082 /// previous items.
2083 /// \param D Current task directive.
2084 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
2085 /// /*part_id*/, captured_struct */*__context*/);
2086 /// \param SharedsTy A type which contains references the shared variables.
2087 /// \param Shareds Context with the list of shared variables from the \p
2088 /// TaskFunction.
2089 /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
2090 /// otherwise.
2091 /// \param Data Additional data for task generation like tiednsee, final
2092 /// state, list of privates etc.
2093 void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00002094 const OMPExecutableDirective &D,
2095 llvm::Function *TaskFunction, QualType SharedsTy,
2096 Address Shareds, const Expr *IfCond,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002097 const OMPTaskDataTy &Data) override;
2098
2099 /// Emit task region for the taskloop directive. The taskloop region is
2100 /// emitted in several steps:
2101 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
2102 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
2103 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
2104 /// function:
2105 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
2106 /// TaskFunction(gtid, tt->part_id, tt->shareds);
2107 /// return 0;
2108 /// }
2109 /// 2. Copy a list of shared variables to field shareds of the resulting
2110 /// structure kmp_task_t returned by the previous call (if any).
2111 /// 3. Copy a pointer to destructions function to field destructions of the
2112 /// resulting structure kmp_task_t.
2113 /// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t
2114 /// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int
2115 /// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task
2116 /// is a resulting structure from
2117 /// previous items.
2118 /// \param D Current task directive.
2119 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
2120 /// /*part_id*/, captured_struct */*__context*/);
2121 /// \param SharedsTy A type which contains references the shared variables.
2122 /// \param Shareds Context with the list of shared variables from the \p
2123 /// TaskFunction.
2124 /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
2125 /// otherwise.
2126 /// \param Data Additional data for task generation like tiednsee, final
2127 /// state, list of privates etc.
2128 void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00002129 const OMPLoopDirective &D, llvm::Function *TaskFunction,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002130 QualType SharedsTy, Address Shareds, const Expr *IfCond,
2131 const OMPTaskDataTy &Data) override;
2132
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002133 /// Emit a code for reduction clause. Next code should be emitted for
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002134 /// reduction:
2135 /// \code
2136 ///
2137 /// static kmp_critical_name lock = { 0 };
2138 ///
2139 /// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
2140 /// ...
2141 /// *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
2142 /// ...
2143 /// }
2144 ///
2145 /// ...
2146 /// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
2147 /// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
2148 /// RedList, reduce_func, &<lock>)) {
2149 /// case 1:
2150 /// ...
2151 /// <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
2152 /// ...
2153 /// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
2154 /// break;
2155 /// case 2:
2156 /// ...
2157 /// Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
2158 /// ...
2159 /// break;
2160 /// default:;
2161 /// }
2162 /// \endcode
2163 ///
2164 /// \param Privates List of private copies for original reduction arguments.
2165 /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
2166 /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
2167 /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
2168 /// or 'operator binop(LHS, RHS)'.
2169 /// \param Options List of options for reduction codegen:
2170 /// WithNowait true if parent directive has also nowait clause, false
2171 /// otherwise.
2172 /// SimpleReduction Emit reduction operation only. Used for omp simd
2173 /// directive on the host.
2174 /// ReductionKind The kind of reduction to perform.
2175 void emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
2176 ArrayRef<const Expr *> Privates,
2177 ArrayRef<const Expr *> LHSExprs,
2178 ArrayRef<const Expr *> RHSExprs,
2179 ArrayRef<const Expr *> ReductionOps,
2180 ReductionOptionsTy Options) override;
2181
2182 /// Emit a code for initialization of task reduction clause. Next code
2183 /// should be emitted for reduction:
2184 /// \code
2185 ///
2186 /// _task_red_item_t red_data[n];
2187 /// ...
2188 /// red_data[i].shar = &origs[i];
2189 /// red_data[i].size = sizeof(origs[i]);
2190 /// red_data[i].f_init = (void*)RedInit<i>;
2191 /// red_data[i].f_fini = (void*)RedDest<i>;
2192 /// red_data[i].f_comb = (void*)RedOp<i>;
2193 /// red_data[i].flags = <Flag_i>;
2194 /// ...
2195 /// void* tg1 = __kmpc_task_reduction_init(gtid, n, red_data);
2196 /// \endcode
2197 ///
2198 /// \param LHSExprs List of LHS in \a Data.ReductionOps reduction operations.
2199 /// \param RHSExprs List of RHS in \a Data.ReductionOps reduction operations.
2200 /// \param Data Additional data for task generation like tiedness, final
2201 /// state, list of privates, reductions etc.
2202 llvm::Value *emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc,
2203 ArrayRef<const Expr *> LHSExprs,
2204 ArrayRef<const Expr *> RHSExprs,
2205 const OMPTaskDataTy &Data) override;
2206
2207 /// Required to resolve existing problems in the runtime. Emits threadprivate
2208 /// variables to store the size of the VLAs/array sections for
2209 /// initializer/combiner/finalizer functions + emits threadprivate variable to
2210 /// store the pointer to the original reduction item for the custom
2211 /// initializer defined by declare reduction construct.
2212 /// \param RCG Allows to reuse an existing data for the reductions.
2213 /// \param N Reduction item for which fixups must be emitted.
2214 void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc,
2215 ReductionCodeGen &RCG, unsigned N) override;
2216
2217 /// Get the address of `void *` type of the privatue copy of the reduction
2218 /// item specified by the \p SharedLVal.
2219 /// \param ReductionsPtr Pointer to the reduction data returned by the
2220 /// emitTaskReductionInit function.
2221 /// \param SharedLVal Address of the original reduction item.
2222 Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc,
2223 llvm::Value *ReductionsPtr,
2224 LValue SharedLVal) override;
2225
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002226 /// Emit code for 'taskwait' directive.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002227 void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc) override;
2228
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002229 /// Emit code for 'cancellation point' construct.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002230 /// \param CancelRegion Region kind for which the cancellation point must be
2231 /// emitted.
2232 ///
2233 void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc,
2234 OpenMPDirectiveKind CancelRegion) override;
2235
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002236 /// Emit code for 'cancel' construct.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002237 /// \param IfCond Condition in the associated 'if' clause, if it was
2238 /// specified, nullptr otherwise.
2239 /// \param CancelRegion Region kind for which the cancel must be emitted.
2240 ///
2241 void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
2242 const Expr *IfCond,
2243 OpenMPDirectiveKind CancelRegion) override;
2244
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002245 /// Emit outilined function for 'target' directive.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002246 /// \param D Directive to emit.
2247 /// \param ParentName Name of the function that encloses the target region.
2248 /// \param OutlinedFn Outlined function value to be defined by this call.
2249 /// \param OutlinedFnID Outlined function ID value to be defined by this call.
2250 /// \param IsOffloadEntry True if the outlined function is an offload entry.
2251 /// \param CodeGen Code generation sequence for the \a D directive.
2252 /// An outlined function may not be an entry if, e.g. the if clause always
2253 /// evaluates to false.
2254 void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
2255 StringRef ParentName,
2256 llvm::Function *&OutlinedFn,
2257 llvm::Constant *&OutlinedFnID,
2258 bool IsOffloadEntry,
2259 const RegionCodeGenTy &CodeGen) override;
2260
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002261 /// Emit the target offloading code associated with \a D. The emitted
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002262 /// code attempts offloading the execution to the device, an the event of
2263 /// a failure it executes the host version outlined in \a OutlinedFn.
2264 /// \param D Directive to emit.
2265 /// \param OutlinedFn Host version of the code to be offloaded.
2266 /// \param OutlinedFnID ID of host version of the code to be offloaded.
2267 /// \param IfCond Expression evaluated in if clause associated with the target
2268 /// directive, or null if no if clause is used.
2269 /// \param Device Expression evaluated in device clause associated with the
2270 /// target directive, or null if no device clause is used.
Alexey Bataevec7946e2019-09-23 14:06:51 +00002271 void
2272 emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
2273 llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID,
2274 const Expr *IfCond, const Expr *Device,
2275 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
2276 const OMPLoopDirective &D)>
2277 SizeEmitter) override;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002278
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002279 /// Emit the target regions enclosed in \a GD function definition or
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002280 /// the function itself in case it is a valid device function. Returns true if
2281 /// \a GD was dealt with successfully.
2282 /// \param GD Function to scan.
2283 bool emitTargetFunctions(GlobalDecl GD) override;
2284
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002285 /// Emit the global variable if it is a valid device global variable.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002286 /// Returns true if \a GD was dealt with successfully.
2287 /// \param GD Variable declaration to emit.
2288 bool emitTargetGlobalVariable(GlobalDecl GD) override;
2289
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002290 /// Emit the global \a GD if it is meaningful for the target. Returns
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002291 /// if it was emitted successfully.
2292 /// \param GD Global to scan.
2293 bool emitTargetGlobal(GlobalDecl GD) override;
2294
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002295 /// Emits code for teams call of the \a OutlinedFn with
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002296 /// variables captured in a record which address is stored in \a
2297 /// CapturedStruct.
2298 /// \param OutlinedFn Outlined function to be run by team masters. Type of
2299 /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
2300 /// \param CapturedVars A pointer to the record with the references to
2301 /// variables used in \a OutlinedFn function.
2302 ///
2303 void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00002304 SourceLocation Loc, llvm::Function *OutlinedFn,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002305 ArrayRef<llvm::Value *> CapturedVars) override;
2306
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002307 /// Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002308 /// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code
2309 /// for num_teams clause.
2310 /// \param NumTeams An integer expression of teams.
2311 /// \param ThreadLimit An integer expression of threads.
2312 void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams,
2313 const Expr *ThreadLimit, SourceLocation Loc) override;
2314
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002315 /// Emit the target data mapping code associated with \a D.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002316 /// \param D Directive to emit.
2317 /// \param IfCond Expression evaluated in if clause associated with the
2318 /// target directive, or null if no device clause is used.
2319 /// \param Device Expression evaluated in device clause associated with the
2320 /// target directive, or null if no device clause is used.
2321 /// \param Info A record used to store information that needs to be preserved
2322 /// until the region is closed.
2323 void emitTargetDataCalls(CodeGenFunction &CGF,
2324 const OMPExecutableDirective &D, const Expr *IfCond,
2325 const Expr *Device, const RegionCodeGenTy &CodeGen,
2326 TargetDataInfo &Info) override;
2327
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002328 /// Emit the data mapping/movement code associated with the directive
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002329 /// \a D that should be of the form 'target [{enter|exit} data | update]'.
2330 /// \param D Directive to emit.
2331 /// \param IfCond Expression evaluated in if clause associated with the target
2332 /// directive, or null if no if clause is used.
2333 /// \param Device Expression evaluated in device clause associated with the
2334 /// target directive, or null if no device clause is used.
2335 void emitTargetDataStandAloneCall(CodeGenFunction &CGF,
2336 const OMPExecutableDirective &D,
2337 const Expr *IfCond,
2338 const Expr *Device) override;
2339
2340 /// Emit initialization for doacross loop nesting support.
2341 /// \param D Loop-based construct used in doacross nesting construct.
Alexey Bataevf138fda2018-08-13 19:04:24 +00002342 void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D,
2343 ArrayRef<Expr *> NumIterations) override;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002344
2345 /// Emit code for doacross ordered directive with 'depend' clause.
2346 /// \param C 'depend' clause with 'sink|source' dependency kind.
2347 void emitDoacrossOrdered(CodeGenFunction &CGF,
2348 const OMPDependClause *C) override;
2349
2350 /// Translates the native parameter of outlined function if this is required
2351 /// for target.
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002352 /// \param FD Field decl from captured record for the parameter.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002353 /// \param NativeParam Parameter itself.
2354 const VarDecl *translateParameter(const FieldDecl *FD,
2355 const VarDecl *NativeParam) const override;
2356
2357 /// Gets the address of the native argument basing on the address of the
2358 /// target-specific parameter.
2359 /// \param NativeParam Parameter itself.
2360 /// \param TargetParam Corresponding target-specific parameter.
2361 Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam,
2362 const VarDecl *TargetParam) const override;
Alexey Bataev4f680db2019-03-19 16:41:16 +00002363
2364 /// Gets the OpenMP-specific address of the local variable.
2365 Address getAddressOfLocalVariable(CodeGenFunction &CGF,
2366 const VarDecl *VD) override {
2367 return Address::invalid();
2368 }
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00002369};
2370
Alexey Bataev23b69422014-06-18 07:08:49 +00002371} // namespace CodeGen
2372} // namespace clang
Alexey Bataev9959db52014-05-06 10:08:46 +00002373
2374#endif