blob: 51c3305f817066daf37161134b009b31be983641 [file] [log] [blame]
Alexey Bataev9959db52014-05-06 10:08:46 +00001//===----- CGOpenMPRuntime.h - Interface to OpenMP Runtimes -----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This provides a class for OpenMP runtime code generation.
11//
12//===----------------------------------------------------------------------===//
13
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +000014#ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
15#define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
Alexey Bataev9959db52014-05-06 10:08:46 +000016
Alexey Bataev7292c292016-04-25 12:22:29 +000017#include "CGValue.h"
Alexey Bataev62b63b12015-03-10 07:28:44 +000018#include "clang/AST/Type.h"
Alexander Musmanc6388682014-12-15 07:07:06 +000019#include "clang/Basic/OpenMPKinds.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000020#include "clang/Basic/SourceLocation.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000021#include "llvm/ADT/DenseMap.h"
Benjamin Kramer8fdba912016-02-02 14:24:21 +000022#include "llvm/ADT/SmallPtrSet.h"
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +000023#include "llvm/ADT/StringMap.h"
Benjamin Kramer8fdba912016-02-02 14:24:21 +000024#include "llvm/IR/Function.h"
Alexey Bataev97720002014-11-11 04:05:39 +000025#include "llvm/IR/ValueHandle.h"
Alexey Bataev18095712014-10-10 12:19:54 +000026
27namespace llvm {
28class ArrayType;
29class Constant;
Alexey Bataev18095712014-10-10 12:19:54 +000030class FunctionType;
Alexey Bataev97720002014-11-11 04:05:39 +000031class GlobalVariable;
Alexey Bataev18095712014-10-10 12:19:54 +000032class StructType;
33class Type;
34class Value;
35} // namespace llvm
Alexey Bataev9959db52014-05-06 10:08:46 +000036
Alexey Bataev9959db52014-05-06 10:08:46 +000037namespace clang {
Alexey Bataevcc37cc12014-11-20 04:34:54 +000038class Expr;
Samuel Antaoee8fb302016-01-06 13:42:12 +000039class GlobalDecl;
Alexey Bataev8b427062016-05-25 12:36:08 +000040class OMPDependClause;
Alexey Bataev18095712014-10-10 12:19:54 +000041class OMPExecutableDirective;
Alexey Bataev7292c292016-04-25 12:22:29 +000042class OMPLoopDirective;
Alexey Bataev18095712014-10-10 12:19:54 +000043class VarDecl;
Alexey Bataevc5b1d322016-03-04 09:22:22 +000044class OMPDeclareReductionDecl;
45class IdentifierInfo;
Alexey Bataev18095712014-10-10 12:19:54 +000046
Alexey Bataev9959db52014-05-06 10:08:46 +000047namespace CodeGen {
John McCall7f416cc2015-09-08 08:05:57 +000048class Address;
Alexey Bataev18095712014-10-10 12:19:54 +000049class CodeGenFunction;
50class CodeGenModule;
Alexey Bataev9959db52014-05-06 10:08:46 +000051
Alexey Bataev14fa1c62016-03-29 05:34:15 +000052/// A basic class for pre|post-action for advanced codegen sequence for OpenMP
53/// region.
54class PrePostActionTy {
55public:
56 explicit PrePostActionTy() {}
57 virtual void Enter(CodeGenFunction &CGF) {}
58 virtual void Exit(CodeGenFunction &CGF) {}
59 virtual ~PrePostActionTy() {}
60};
61
62/// Class provides a way to call simple version of codegen for OpenMP region, or
63/// an advanced with possible pre|post-actions in codegen.
64class RegionCodeGenTy final {
65 intptr_t CodeGen;
66 typedef void (*CodeGenTy)(intptr_t, CodeGenFunction &, PrePostActionTy &);
67 CodeGenTy Callback;
68 mutable PrePostActionTy *PrePostAction;
69 RegionCodeGenTy() = delete;
70 RegionCodeGenTy &operator=(const RegionCodeGenTy &) = delete;
71 template <typename Callable>
72 static void CallbackFn(intptr_t CodeGen, CodeGenFunction &CGF,
73 PrePostActionTy &Action) {
74 return (*reinterpret_cast<Callable *>(CodeGen))(CGF, Action);
75 }
76
77public:
78 template <typename Callable>
79 RegionCodeGenTy(
80 Callable &&CodeGen,
81 typename std::enable_if<
82 !std::is_same<typename std::remove_reference<Callable>::type,
83 RegionCodeGenTy>::value>::type * = nullptr)
84 : CodeGen(reinterpret_cast<intptr_t>(&CodeGen)),
85 Callback(CallbackFn<typename std::remove_reference<Callable>::type>),
86 PrePostAction(nullptr) {}
87 void setAction(PrePostActionTy &Action) const { PrePostAction = &Action; }
88 void operator()(CodeGenFunction &CGF) const;
89};
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000090
Alexey Bataev24b5bae2016-04-28 09:23:51 +000091struct OMPTaskDataTy final {
92 SmallVector<const Expr *, 4> PrivateVars;
93 SmallVector<const Expr *, 4> PrivateCopies;
94 SmallVector<const Expr *, 4> FirstprivateVars;
95 SmallVector<const Expr *, 4> FirstprivateCopies;
96 SmallVector<const Expr *, 4> FirstprivateInits;
Alexey Bataevf93095a2016-05-05 08:46:22 +000097 SmallVector<const Expr *, 4> LastprivateVars;
98 SmallVector<const Expr *, 4> LastprivateCopies;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +000099 SmallVector<const Expr *, 4> ReductionVars;
100 SmallVector<const Expr *, 4> ReductionCopies;
101 SmallVector<const Expr *, 4> ReductionOps;
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000102 SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 4> Dependences;
103 llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
104 llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule;
Alexey Bataev1e1e2862016-05-10 12:21:02 +0000105 llvm::PointerIntPair<llvm::Value *, 1, bool> Priority;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000106 llvm::Value *Reductions = nullptr;
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000107 unsigned NumberOfParts = 0;
108 bool Tied = true;
109 bool Nogroup = false;
110};
111
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000112/// Class intended to support codegen of all kind of the reduction clauses.
113class ReductionCodeGen {
114private:
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000115 /// Data required for codegen of reduction clauses.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000116 struct ReductionData {
117 /// Reference to the original shared item.
118 const Expr *Ref = nullptr;
119 /// Helper expression for generation of private copy.
120 const Expr *Private = nullptr;
121 /// Helper expression for generation reduction operation.
122 const Expr *ReductionOp = nullptr;
123 ReductionData(const Expr *Ref, const Expr *Private, const Expr *ReductionOp)
124 : Ref(Ref), Private(Private), ReductionOp(ReductionOp) {}
125 };
126 /// List of reduction-based clauses.
127 SmallVector<ReductionData, 4> ClausesData;
128
129 /// List of addresses of original shared variables/expressions.
130 SmallVector<std::pair<LValue, LValue>, 4> SharedAddresses;
131 /// Sizes of the reduction items in chars.
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000132 SmallVector<std::pair<llvm::Value *, llvm::Value *>, 4> Sizes;
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000133 /// Base declarations for the reduction items.
134 SmallVector<const VarDecl *, 4> BaseDecls;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000135
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000136 /// Emits lvalue for shared expresion.
137 LValue emitSharedLValue(CodeGenFunction &CGF, const Expr *E);
138 /// Emits upper bound for shared expression (if array section).
139 LValue emitSharedLValueUB(CodeGenFunction &CGF, const Expr *E);
140 /// Performs aggregate initialization.
141 /// \param N Number of reduction item in the common list.
142 /// \param PrivateAddr Address of the corresponding private item.
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000143 /// \param SharedLVal Address of the original shared variable.
144 /// \param DRD Declare reduction construct used for reduction item.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000145 void emitAggregateInitialization(CodeGenFunction &CGF, unsigned N,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000146 Address PrivateAddr, LValue SharedLVal,
147 const OMPDeclareReductionDecl *DRD);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000148
149public:
150 ReductionCodeGen(ArrayRef<const Expr *> Shareds,
151 ArrayRef<const Expr *> Privates,
152 ArrayRef<const Expr *> ReductionOps);
153 /// Emits lvalue for a reduction item.
154 /// \param N Number of the reduction item.
155 void emitSharedLValue(CodeGenFunction &CGF, unsigned N);
156 /// Emits the code for the variable-modified type, if required.
157 /// \param N Number of the reduction item.
158 void emitAggregateType(CodeGenFunction &CGF, unsigned N);
159 /// Emits the code for the variable-modified type, if required.
160 /// \param N Number of the reduction item.
161 /// \param Size Size of the type in chars.
162 void emitAggregateType(CodeGenFunction &CGF, unsigned N, llvm::Value *Size);
163 /// Performs initialization of the private copy for the reduction item.
164 /// \param N Number of the reduction item.
165 /// \param PrivateAddr Address of the corresponding private item.
166 /// \param DefaultInit Default initialization sequence that should be
167 /// performed if no reduction specific initialization is found.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000168 /// \param SharedLVal Address of the original shared variable.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000169 void
170 emitInitialization(CodeGenFunction &CGF, unsigned N, Address PrivateAddr,
171 LValue SharedLVal,
172 llvm::function_ref<bool(CodeGenFunction &)> DefaultInit);
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000173 /// Returns true if the private copy requires cleanups.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000174 bool needCleanups(unsigned N);
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000175 /// Emits cleanup code for the reduction item.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000176 /// \param N Number of the reduction item.
177 /// \param PrivateAddr Address of the corresponding private item.
178 void emitCleanups(CodeGenFunction &CGF, unsigned N, Address PrivateAddr);
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000179 /// Adjusts \p PrivatedAddr for using instead of the original variable
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000180 /// address in normal operations.
181 /// \param N Number of the reduction item.
182 /// \param PrivateAddr Address of the corresponding private item.
183 Address adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
184 Address PrivateAddr);
185 /// Returns LValue for the reduction item.
186 LValue getSharedLValue(unsigned N) const { return SharedAddresses[N].first; }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000187 /// Returns the size of the reduction item (in chars and total number of
188 /// elements in the item), or nullptr, if the size is a constant.
189 std::pair<llvm::Value *, llvm::Value *> getSizes(unsigned N) const {
190 return Sizes[N];
191 }
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000192 /// Returns the base declaration of the reduction item.
193 const VarDecl *getBaseDecl(unsigned N) const { return BaseDecls[N]; }
Alexey Bataev1c44e152018-03-06 18:59:43 +0000194 /// Returns the base declaration of the reduction item.
195 const Expr *getRefExpr(unsigned N) const { return ClausesData[N].Ref; }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000196 /// Returns true if the initialization of the reduction item uses initializer
197 /// from declare reduction construct.
198 bool usesReductionInitializer(unsigned N) const;
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000199};
200
Alexey Bataev9959db52014-05-06 10:08:46 +0000201class CGOpenMPRuntime {
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +0000202public:
203 /// Allows to disable automatic handling of functions used in target regions
204 /// as those marked as `omp declare target`.
205 class DisableAutoDeclareTargetRAII {
206 CodeGenModule &CGM;
207 bool SavedShouldMarkAsGlobal;
208
209 public:
210 DisableAutoDeclareTargetRAII(CodeGenModule &CGM);
211 ~DisableAutoDeclareTargetRAII();
212 };
213
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000214protected:
Alexey Bataev9959db52014-05-06 10:08:46 +0000215 CodeGenModule &CGM;
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000216
217 /// \brief Creates offloading entry for the provided entry ID \a ID,
Samuel Antaof83efdb2017-01-05 16:02:49 +0000218 /// address \a Addr, size \a Size, and flags \a Flags.
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000219 virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000220 uint64_t Size, int32_t Flags,
221 llvm::GlobalValue::LinkageTypes Linkage);
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000222
223 /// \brief Helper to emit outlined function for 'target' directive.
224 /// \param D Directive to emit.
225 /// \param ParentName Name of the function that encloses the target region.
226 /// \param OutlinedFn Outlined function value to be defined by this call.
227 /// \param OutlinedFnID Outlined function ID value to be defined by this call.
228 /// \param IsOffloadEntry True if the outlined function is an offload entry.
229 /// \param CodeGen Lambda codegen specific to an accelerator device.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000230 /// An outlined function may not be an entry if, e.g. the if clause always
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000231 /// evaluates to false.
232 virtual void emitTargetOutlinedFunctionHelper(const OMPExecutableDirective &D,
233 StringRef ParentName,
234 llvm::Function *&OutlinedFn,
235 llvm::Constant *&OutlinedFnID,
236 bool IsOffloadEntry,
237 const RegionCodeGenTy &CodeGen);
238
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000239 /// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
240 /// function. Here is the logic:
241 /// if (Cond) {
242 /// ThenGen();
243 /// } else {
244 /// ElseGen();
245 /// }
246 void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
247 const RegionCodeGenTy &ThenGen,
248 const RegionCodeGenTy &ElseGen);
249
250 /// \brief Emits object of ident_t type with info for source location.
251 /// \param Flags Flags for OpenMP location.
252 ///
253 llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
254 unsigned Flags = 0);
255
256 /// \brief Returns pointer to ident_t type.
257 llvm::Type *getIdentTyPointerTy();
258
259 /// \brief Gets thread id value for the current thread.
260 ///
261 llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc);
262
263 /// \brief Get the function name of an outlined region.
264 // The name can be customized depending on the target.
265 //
266 virtual StringRef getOutlinedHelperName() const { return ".omp_outlined."; }
267
Alexey Bataev3c595a62017-08-14 15:01:03 +0000268 /// Emits \p Callee function call with arguments \p Args with location \p Loc.
Alexey Bataev7ef47a62018-02-22 18:33:31 +0000269 void emitCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *Callee,
270 ArrayRef<llvm::Value *> Args = llvm::None) const;
Alexey Bataev3c595a62017-08-14 15:01:03 +0000271
Alexey Bataevb7f3cba2018-03-19 17:04:07 +0000272 /// \brief Emits address of the word in a memory where current thread id is
273 /// stored.
274 virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc);
275
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000276private:
Alexey Bataev9959db52014-05-06 10:08:46 +0000277 /// \brief Default const ident_t object used for initialization of all other
278 /// ident_t objects.
Alexey Bataevc5b1d322016-03-04 09:22:22 +0000279 llvm::Constant *DefaultOpenMPPSource = nullptr;
Alexey Bataev18095712014-10-10 12:19:54 +0000280 /// \brief Map of flags and corresponding default locations.
Alexey Bataev15007ba2014-05-07 06:18:01 +0000281 typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDefaultLocMapTy;
282 OpenMPDefaultLocMapTy OpenMPDefaultLocMap;
Alexey Bataev50b3c952016-02-19 10:38:26 +0000283 Address getOrCreateDefaultLocation(unsigned Flags);
John McCall7f416cc2015-09-08 08:05:57 +0000284
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000285 llvm::StructType *IdentTy = nullptr;
Alexey Bataev18095712014-10-10 12:19:54 +0000286 /// \brief Map for SourceLocation and OpenMP runtime library debug locations.
Alexey Bataevf002aca2014-05-30 05:48:40 +0000287 typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy;
288 OpenMPDebugLocMapTy OpenMPDebugLocMap;
Alexey Bataev9959db52014-05-06 10:08:46 +0000289 /// \brief The type for a microtask which gets passed to __kmpc_fork_call().
290 /// Original representation is:
291 /// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...);
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000292 llvm::FunctionType *Kmpc_MicroTy = nullptr;
Alexey Bataev18095712014-10-10 12:19:54 +0000293 /// \brief Stores debug location and ThreadID for the function.
294 struct DebugLocThreadIdTy {
295 llvm::Value *DebugLoc;
296 llvm::Value *ThreadID;
297 };
298 /// \brief Map of local debug location, ThreadId and functions.
299 typedef llvm::DenseMap<llvm::Function *, DebugLocThreadIdTy>
300 OpenMPLocThreadIDMapTy;
301 OpenMPLocThreadIDMapTy OpenMPLocThreadIDMap;
Alexey Bataevc5b1d322016-03-04 09:22:22 +0000302 /// Map of UDRs and corresponding combiner/initializer.
303 typedef llvm::DenseMap<const OMPDeclareReductionDecl *,
304 std::pair<llvm::Function *, llvm::Function *>>
305 UDRMapTy;
306 UDRMapTy UDRMap;
307 /// Map of functions and locally defined UDRs.
308 typedef llvm::DenseMap<llvm::Function *,
309 SmallVector<const OMPDeclareReductionDecl *, 4>>
310 FunctionUDRMapTy;
311 FunctionUDRMapTy FunctionUDRMap;
312 IdentifierInfo *In = nullptr;
313 IdentifierInfo *Out = nullptr;
314 IdentifierInfo *Priv = nullptr;
315 IdentifierInfo *Orig = nullptr;
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000316 /// \brief Type kmp_critical_name, originally defined as typedef kmp_int32
317 /// kmp_critical_name[8];
318 llvm::ArrayType *KmpCriticalNameTy;
Alexey Bataev97720002014-11-11 04:05:39 +0000319 /// \brief An ordered map of auto-generated variables to their unique names.
320 /// It stores variables with the following names: 1) ".gomp_critical_user_" +
321 /// <critical_section_name> + ".var" for "omp critical" directives; 2)
322 /// <mangled_name_for_global_var> + ".cache." for cache for threadprivate
323 /// variables.
324 llvm::StringMap<llvm::AssertingVH<llvm::Constant>, llvm::BumpPtrAllocator>
325 InternalVars;
Alexey Bataev62b63b12015-03-10 07:28:44 +0000326 /// \brief Type typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *);
Alexey Bataevc5b1d322016-03-04 09:22:22 +0000327 llvm::Type *KmpRoutineEntryPtrTy = nullptr;
Alexey Bataev62b63b12015-03-10 07:28:44 +0000328 QualType KmpRoutineEntryPtrQTy;
Alexey Bataev8fc69dc2015-05-18 07:54:53 +0000329 /// \brief Type typedef struct kmp_task {
330 /// void * shareds; /**< pointer to block of pointers to
331 /// shared vars */
332 /// kmp_routine_entry_t routine; /**< pointer to routine to call for
333 /// executing task */
334 /// kmp_int32 part_id; /**< part id for the task */
335 /// kmp_routine_entry_t destructors; /* pointer to function to invoke
336 /// deconstructors of firstprivate C++ objects */
337 /// } kmp_task_t;
338 QualType KmpTaskTQTy;
Alexey Bataeve213f3e2017-10-11 15:29:40 +0000339 /// Saved kmp_task_t for task directive.
340 QualType SavedKmpTaskTQTy;
341 /// Saved kmp_task_t for taskloop-based directive.
342 QualType SavedKmpTaskloopTQTy;
Alexey Bataev1d2353d2015-06-24 11:01:36 +0000343 /// \brief Type typedef struct kmp_depend_info {
344 /// kmp_intptr_t base_addr;
345 /// size_t len;
346 /// struct {
347 /// bool in:1;
348 /// bool out:1;
349 /// } flags;
350 /// } kmp_depend_info_t;
351 QualType KmpDependInfoTy;
Alexey Bataev8b427062016-05-25 12:36:08 +0000352 /// struct kmp_dim { // loop bounds info casted to kmp_int64
353 /// kmp_int64 lo; // lower
354 /// kmp_int64 up; // upper
355 /// kmp_int64 st; // stride
356 /// };
357 QualType KmpDimTy;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000358 /// \brief Type struct __tgt_offload_entry{
359 /// void *addr; // Pointer to the offload entry info.
360 /// // (function or global)
361 /// char *name; // Name of the function or global.
362 /// size_t size; // Size of the entry info (0 if it a function).
363 /// };
364 QualType TgtOffloadEntryQTy;
365 /// struct __tgt_device_image{
366 /// void *ImageStart; // Pointer to the target code start.
367 /// void *ImageEnd; // Pointer to the target code end.
368 /// // We also add the host entries to the device image, as it may be useful
369 /// // for the target runtime to have access to that information.
370 /// __tgt_offload_entry *EntriesBegin; // Begin of the table with all
371 /// // the entries.
372 /// __tgt_offload_entry *EntriesEnd; // End of the table with all the
373 /// // entries (non inclusive).
374 /// };
375 QualType TgtDeviceImageQTy;
376 /// struct __tgt_bin_desc{
377 /// int32_t NumDevices; // Number of devices supported.
378 /// __tgt_device_image *DeviceImages; // Arrays of device images
379 /// // (one per device).
380 /// __tgt_offload_entry *EntriesBegin; // Begin of the table with all the
381 /// // entries.
382 /// __tgt_offload_entry *EntriesEnd; // End of the table with all the
383 /// // entries (non inclusive).
384 /// };
385 QualType TgtBinaryDescriptorQTy;
386 /// \brief Entity that registers the offloading constants that were emitted so
387 /// far.
388 class OffloadEntriesInfoManagerTy {
389 CodeGenModule &CGM;
Alexey Bataev1d2353d2015-06-24 11:01:36 +0000390
Samuel Antaoee8fb302016-01-06 13:42:12 +0000391 /// \brief Number of entries registered so far.
Alexey Bataev03f270c2018-03-30 18:31:07 +0000392 unsigned OffloadingEntriesNum = 0;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000393
394 public:
Samuel Antaof83efdb2017-01-05 16:02:49 +0000395 /// Base class of the entries info.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000396 class OffloadEntryInfo {
397 public:
Alexey Bataev34f8a702018-03-28 14:28:54 +0000398 /// Kind of a given entry.
Reid Klecknerdc78f952016-01-11 20:55:16 +0000399 enum OffloadingEntryInfoKinds : unsigned {
Alexey Bataev34f8a702018-03-28 14:28:54 +0000400 /// Entry is a target region.
401 OffloadingEntryInfoTargetRegion = 0,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000402 /// Entry is a declare target variable.
403 OffloadingEntryInfoDeviceGlobalVar = 1,
Alexey Bataev34f8a702018-03-28 14:28:54 +0000404 /// Invalid entry info.
405 OffloadingEntryInfoInvalid = ~0u
Samuel Antaoee8fb302016-01-06 13:42:12 +0000406 };
407
Alexey Bataev03f270c2018-03-30 18:31:07 +0000408 protected:
409 OffloadEntryInfo() = delete;
410 explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind) : Kind(Kind) {}
Samuel Antaof83efdb2017-01-05 16:02:49 +0000411 explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000412 uint32_t Flags)
Samuel Antaof83efdb2017-01-05 16:02:49 +0000413 : Flags(Flags), Order(Order), Kind(Kind) {}
Alexey Bataev03f270c2018-03-30 18:31:07 +0000414 ~OffloadEntryInfo() = default;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000415
Alexey Bataev03f270c2018-03-30 18:31:07 +0000416 public:
Samuel Antaoee8fb302016-01-06 13:42:12 +0000417 bool isValid() const { return Order != ~0u; }
418 unsigned getOrder() const { return Order; }
419 OffloadingEntryInfoKinds getKind() const { return Kind; }
Alexey Bataev03f270c2018-03-30 18:31:07 +0000420 uint32_t getFlags() const { return Flags; }
421 void setFlags(uint32_t NewFlags) { Flags = NewFlags; }
422 llvm::Constant *getAddress() const {
423 return cast_or_null<llvm::Constant>(Addr);
424 }
425 void setAddress(llvm::Constant *V) {
426 assert(!Addr.pointsToAliveValue() && "Address has been set before!");
427 Addr = V;
428 }
Samuel Antaoee8fb302016-01-06 13:42:12 +0000429 static bool classof(const OffloadEntryInfo *Info) { return true; }
430
Samuel Antaof83efdb2017-01-05 16:02:49 +0000431 private:
Alexey Bataev03f270c2018-03-30 18:31:07 +0000432 /// Address of the entity that has to be mapped for offloading.
433 llvm::WeakTrackingVH Addr;
434
Samuel Antaof83efdb2017-01-05 16:02:49 +0000435 /// Flags associated with the device global.
Alexey Bataev03f270c2018-03-30 18:31:07 +0000436 uint32_t Flags = 0u;
Samuel Antaof83efdb2017-01-05 16:02:49 +0000437
438 /// Order this entry was emitted.
Alexey Bataev03f270c2018-03-30 18:31:07 +0000439 unsigned Order = ~0u;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000440
Alexey Bataev03f270c2018-03-30 18:31:07 +0000441 OffloadingEntryInfoKinds Kind = OffloadingEntryInfoInvalid;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000442 };
443
Alexey Bataev03f270c2018-03-30 18:31:07 +0000444 /// Return true if a there are no entries defined.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000445 bool empty() const;
Alexey Bataev03f270c2018-03-30 18:31:07 +0000446 /// Return number of entries defined so far.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000447 unsigned size() const { return OffloadingEntriesNum; }
Alexey Bataev03f270c2018-03-30 18:31:07 +0000448 OffloadEntriesInfoManagerTy(CodeGenModule &CGM) : CGM(CGM) {}
Samuel Antaoee8fb302016-01-06 13:42:12 +0000449
Alexey Bataev03f270c2018-03-30 18:31:07 +0000450 //
451 // Target region entries related.
452 //
453
454 /// Kind of the target registry entry.
455 enum OMPTargetRegionEntryKind : uint32_t {
456 /// Mark the entry as target region.
457 OMPTargetRegionEntryTargetRegion = 0x0,
458 /// Mark the entry as a global constructor.
459 OMPTargetRegionEntryCtor = 0x02,
460 /// Mark the entry as a global destructor.
461 OMPTargetRegionEntryDtor = 0x04,
462 };
463
464 /// Target region entries info.
465 class OffloadEntryInfoTargetRegion final : public OffloadEntryInfo {
466 /// Address that can be used as the ID of the entry.
467 llvm::Constant *ID = nullptr;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000468
469 public:
470 OffloadEntryInfoTargetRegion()
Alexey Bataev03f270c2018-03-30 18:31:07 +0000471 : OffloadEntryInfo(OffloadingEntryInfoTargetRegion) {}
Samuel Antaoee8fb302016-01-06 13:42:12 +0000472 explicit OffloadEntryInfoTargetRegion(unsigned Order,
473 llvm::Constant *Addr,
Alexey Bataev34f8a702018-03-28 14:28:54 +0000474 llvm::Constant *ID,
475 OMPTargetRegionEntryKind Flags)
476 : OffloadEntryInfo(OffloadingEntryInfoTargetRegion, Order, Flags),
Alexey Bataev03f270c2018-03-30 18:31:07 +0000477 ID(ID) {
478 setAddress(Addr);
Samuel Antaoee8fb302016-01-06 13:42:12 +0000479 }
Alexey Bataev03f270c2018-03-30 18:31:07 +0000480
481 llvm::Constant *getID() const { return ID; }
Samuel Antaoee8fb302016-01-06 13:42:12 +0000482 void setID(llvm::Constant *V) {
Alexey Bataev34f8a702018-03-28 14:28:54 +0000483 assert(!ID && "ID has been set before!");
Samuel Antaoee8fb302016-01-06 13:42:12 +0000484 ID = V;
485 }
486 static bool classof(const OffloadEntryInfo *Info) {
Alexey Bataev34f8a702018-03-28 14:28:54 +0000487 return Info->getKind() == OffloadingEntryInfoTargetRegion;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000488 }
489 };
Alexey Bataev03f270c2018-03-30 18:31:07 +0000490
491 /// Initialize target region entry.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000492 void initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
493 StringRef ParentName, unsigned LineNum,
Samuel Antao2de62b02016-02-13 23:35:10 +0000494 unsigned Order);
Alexey Bataev03f270c2018-03-30 18:31:07 +0000495 /// Register target region entry.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000496 void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
497 StringRef ParentName, unsigned LineNum,
Samuel Antaof83efdb2017-01-05 16:02:49 +0000498 llvm::Constant *Addr, llvm::Constant *ID,
Alexey Bataev34f8a702018-03-28 14:28:54 +0000499 OMPTargetRegionEntryKind Flags);
Alexey Bataev03f270c2018-03-30 18:31:07 +0000500 /// Return true if a target region entry with the provided information
501 /// exists.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000502 bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
Samuel Antao2de62b02016-02-13 23:35:10 +0000503 StringRef ParentName, unsigned LineNum) const;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000504 /// brief Applies action \a Action on all registered entries.
505 typedef llvm::function_ref<void(unsigned, unsigned, StringRef, unsigned,
Alexey Bataev03f270c2018-03-30 18:31:07 +0000506 const OffloadEntryInfoTargetRegion &)>
Samuel Antaoee8fb302016-01-06 13:42:12 +0000507 OffloadTargetRegionEntryInfoActTy;
508 void actOnTargetRegionEntriesInfo(
509 const OffloadTargetRegionEntryInfoActTy &Action);
510
Alexey Bataev03f270c2018-03-30 18:31:07 +0000511 //
512 // Device global variable entries related.
513 //
514
515 /// Kind of the global variable entry..
516 enum OMPTargetGlobalVarEntryKind : uint32_t {
517 /// Mark the entry as a to declare target.
518 OMPTargetGlobalVarEntryTo = 0x0,
519 };
520
521 /// Device global variable entries info.
522 class OffloadEntryInfoDeviceGlobalVar final : public OffloadEntryInfo {
523 /// Type of the global variable.
524 CharUnits VarSize;
525 llvm::GlobalValue::LinkageTypes Linkage;
526
527 public:
528 OffloadEntryInfoDeviceGlobalVar()
529 : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar) {}
530 explicit OffloadEntryInfoDeviceGlobalVar(unsigned Order,
531 OMPTargetGlobalVarEntryKind Flags)
532 : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags) {}
533 explicit OffloadEntryInfoDeviceGlobalVar(
534 unsigned Order, llvm::Constant *Addr, CharUnits VarSize,
535 OMPTargetGlobalVarEntryKind Flags,
536 llvm::GlobalValue::LinkageTypes Linkage)
537 : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags),
538 VarSize(VarSize), Linkage(Linkage) {
539 setAddress(Addr);
540 }
541
542 CharUnits getVarSize() const { return VarSize; }
543 void setVarSize(CharUnits Size) { VarSize = Size; }
544 llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
545 void setLinkage(llvm::GlobalValue::LinkageTypes LT) { Linkage = LT; }
546 static bool classof(const OffloadEntryInfo *Info) {
547 return Info->getKind() == OffloadingEntryInfoDeviceGlobalVar;
548 }
549 };
550
551 /// Initialize device global variable entry.
552 void initializeDeviceGlobalVarEntryInfo(StringRef Name,
553 OMPTargetGlobalVarEntryKind Flags,
554 unsigned Order);
555
556 /// Register device global variable entry.
557 void
558 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
559 CharUnits VarSize,
560 OMPTargetGlobalVarEntryKind Flags,
561 llvm::GlobalValue::LinkageTypes Linkage);
562 /// Checks if the variable with the given name has been registered already.
563 bool hasDeviceGlobalVarEntryInfo(StringRef VarName) const {
564 return OffloadEntriesDeviceGlobalVar.count(VarName) > 0;
565 }
566 /// Applies action \a Action on all registered entries.
567 typedef llvm::function_ref<void(StringRef,
568 const OffloadEntryInfoDeviceGlobalVar &)>
569 OffloadDeviceGlobalVarEntryInfoActTy;
570 void actOnDeviceGlobalVarEntriesInfo(
571 const OffloadDeviceGlobalVarEntryInfoActTy &Action);
572
Samuel Antaoee8fb302016-01-06 13:42:12 +0000573 private:
574 // Storage for target region entries kind. The storage is to be indexed by
Samuel Antao2de62b02016-02-13 23:35:10 +0000575 // file ID, device ID, parent function name and line number.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000576 typedef llvm::DenseMap<unsigned, OffloadEntryInfoTargetRegion>
Samuel Antaoee8fb302016-01-06 13:42:12 +0000577 OffloadEntriesTargetRegionPerLine;
578 typedef llvm::StringMap<OffloadEntriesTargetRegionPerLine>
579 OffloadEntriesTargetRegionPerParentName;
580 typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerParentName>
581 OffloadEntriesTargetRegionPerFile;
582 typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerFile>
583 OffloadEntriesTargetRegionPerDevice;
584 typedef OffloadEntriesTargetRegionPerDevice OffloadEntriesTargetRegionTy;
585 OffloadEntriesTargetRegionTy OffloadEntriesTargetRegion;
Alexey Bataev03f270c2018-03-30 18:31:07 +0000586 /// Storage for device global variable entries kind. The storage is to be
587 /// indexed by mangled name.
588 typedef llvm::StringMap<OffloadEntryInfoDeviceGlobalVar>
589 OffloadEntriesDeviceGlobalVarTy;
590 OffloadEntriesDeviceGlobalVarTy OffloadEntriesDeviceGlobalVar;
Samuel Antaoee8fb302016-01-06 13:42:12 +0000591 };
592 OffloadEntriesInfoManagerTy OffloadEntriesInfoManager;
593
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +0000594 bool ShouldMarkAsGlobal = true;
595 llvm::SmallDenseSet<const FunctionDecl *> AlreadyEmittedTargetFunctions;
596
Samuel Antaoee8fb302016-01-06 13:42:12 +0000597 /// \brief Creates and registers offloading binary descriptor for the current
598 /// compilation unit. The function that does the registration is returned.
599 llvm::Function *createOffloadingBinaryDescriptorRegistration();
600
Samuel Antaoee8fb302016-01-06 13:42:12 +0000601 /// \brief Creates all the offload entries in the current compilation unit
602 /// along with the associated metadata.
603 void createOffloadEntriesAndInfoMetadata();
604
605 /// \brief Loads all the offload entries information from the host IR
606 /// metadata.
607 void loadOffloadInfoMetadata();
608
609 /// \brief Returns __tgt_offload_entry type.
610 QualType getTgtOffloadEntryQTy();
611
612 /// \brief Returns __tgt_device_image type.
613 QualType getTgtDeviceImageQTy();
614
615 /// \brief Returns __tgt_bin_desc type.
616 QualType getTgtBinaryDescriptorQTy();
617
618 /// \brief Start scanning from statement \a S and and emit all target regions
619 /// found along the way.
620 /// \param S Starting statement.
621 /// \param ParentName Name of the function declaration that is being scanned.
622 void scanForTargetRegionsFunctions(const Stmt *S, StringRef ParentName);
Alexey Bataev62b63b12015-03-10 07:28:44 +0000623
624 /// \brief Build type kmp_routine_entry_t (if not built yet).
625 void emitKmpRoutineEntryT(QualType KmpInt32Ty);
Alexey Bataev9959db52014-05-06 10:08:46 +0000626
Alexey Bataevd74d0602014-10-13 06:02:40 +0000627 /// \brief Returns pointer to kmpc_micro type.
Alexey Bataev9959db52014-05-06 10:08:46 +0000628 llvm::Type *getKmpc_MicroPointerTy();
629
630 /// \brief Returns specified OpenMP runtime function.
631 /// \param Function OpenMP runtime function.
632 /// \return Specified function.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000633 llvm::Constant *createRuntimeFunction(unsigned Function);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000634
Alexander Musman21212e42015-03-13 10:38:23 +0000635 /// \brief Returns __kmpc_for_static_init_* runtime function for the specified
636 /// size \a IVSize and sign \a IVSigned.
637 llvm::Constant *createForStaticInitFunction(unsigned IVSize, bool IVSigned);
638
Alexander Musman92bdaab2015-03-12 13:37:50 +0000639 /// \brief Returns __kmpc_dispatch_init_* runtime function for the specified
640 /// size \a IVSize and sign \a IVSigned.
641 llvm::Constant *createDispatchInitFunction(unsigned IVSize, bool IVSigned);
642
643 /// \brief Returns __kmpc_dispatch_next_* runtime function for the specified
644 /// size \a IVSize and sign \a IVSigned.
645 llvm::Constant *createDispatchNextFunction(unsigned IVSize, bool IVSigned);
646
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000647 /// \brief Returns __kmpc_dispatch_fini_* runtime function for the specified
648 /// size \a IVSize and sign \a IVSigned.
649 llvm::Constant *createDispatchFiniFunction(unsigned IVSize, bool IVSigned);
650
Alexey Bataev97720002014-11-11 04:05:39 +0000651 /// \brief If the specified mangled name is not in the module, create and
652 /// return threadprivate cache object. This object is a pointer's worth of
653 /// storage that's reserved for use by the OpenMP runtime.
NAKAMURA Takumicdcbfba2014-11-11 07:58:06 +0000654 /// \param VD Threadprivate variable.
Alexey Bataev97720002014-11-11 04:05:39 +0000655 /// \return Cache variable for the specified threadprivate.
656 llvm::Constant *getOrCreateThreadPrivateCache(const VarDecl *VD);
657
Alexey Bataev97720002014-11-11 04:05:39 +0000658 /// \brief Gets (if variable with the given name already exist) or creates
659 /// internal global variable with the specified Name. The created variable has
660 /// linkage CommonLinkage by default and is initialized by null value.
661 /// \param Ty Type of the global variable. If it is exist already the type
662 /// must be the same.
663 /// \param Name Name of the variable.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000664 llvm::Constant *getOrCreateInternalVariable(llvm::Type *Ty,
Alexey Bataev97720002014-11-11 04:05:39 +0000665 const llvm::Twine &Name);
666
667 /// \brief Set of threadprivate variables with the generated initializer.
Benjamin Kramer8fdba912016-02-02 14:24:21 +0000668 llvm::SmallPtrSet<const VarDecl *, 4> ThreadPrivateWithDefinition;
Alexey Bataev97720002014-11-11 04:05:39 +0000669
Alexey Bataev34f8a702018-03-28 14:28:54 +0000670 /// Set of declare target variables with the generated initializer.
671 llvm::SmallPtrSet<const VarDecl *, 4> DeclareTargetWithDefinition;
672
Alexey Bataev97720002014-11-11 04:05:39 +0000673 /// \brief Emits initialization code for the threadprivate variables.
674 /// \param VDAddr Address of the global variable \a VD.
675 /// \param Ctor Pointer to a global init function for \a VD.
676 /// \param CopyCtor Pointer to a global copy function for \a VD.
677 /// \param Dtor Pointer to a global destructor function for \a VD.
678 /// \param Loc Location of threadprivate declaration.
John McCall7f416cc2015-09-08 08:05:57 +0000679 void emitThreadPrivateVarInit(CodeGenFunction &CGF, Address VDAddr,
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000680 llvm::Value *Ctor, llvm::Value *CopyCtor,
681 llvm::Value *Dtor, SourceLocation Loc);
Alexey Bataev97720002014-11-11 04:05:39 +0000682
Alexey Bataev75ddfab2014-12-01 11:32:38 +0000683 /// \brief Returns corresponding lock object for the specified critical region
684 /// name. If the lock object does not exist it is created, otherwise the
685 /// reference to the existing copy is returned.
686 /// \param CriticalName Name of the critical region.
687 ///
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000688 llvm::Value *getCriticalRegionLock(StringRef CriticalName);
Alexey Bataev75ddfab2014-12-01 11:32:38 +0000689
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000690 struct TaskResultTy {
691 llvm::Value *NewTask = nullptr;
692 llvm::Value *TaskEntry = nullptr;
693 llvm::Value *NewTaskNewTaskTTy = nullptr;
Alexey Bataev7292c292016-04-25 12:22:29 +0000694 LValue TDBase;
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000695 RecordDecl *KmpTaskTQTyRD = nullptr;
Alexey Bataevf93095a2016-05-05 08:46:22 +0000696 llvm::Value *TaskDupFn = nullptr;
Alexey Bataev7292c292016-04-25 12:22:29 +0000697 };
698 /// Emit task region for the task directive. The task region is emitted in
699 /// several steps:
700 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
701 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
702 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
703 /// function:
704 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
705 /// TaskFunction(gtid, tt->part_id, tt->shareds);
706 /// return 0;
707 /// }
708 /// 2. Copy a list of shared variables to field shareds of the resulting
709 /// structure kmp_task_t returned by the previous call (if any).
710 /// 3. Copy a pointer to destructions function to field destructions of the
711 /// resulting structure kmp_task_t.
712 /// \param D Current task directive.
Alexey Bataev7292c292016-04-25 12:22:29 +0000713 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
714 /// /*part_id*/, captured_struct */*__context*/);
715 /// \param SharedsTy A type which contains references the shared variables.
716 /// \param Shareds Context with the list of shared variables from the \p
717 /// TaskFunction.
Alexey Bataev24b5bae2016-04-28 09:23:51 +0000718 /// \param Data Additional data for task generation like tiednsee, final
719 /// state, list of privates etc.
720 TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
721 const OMPExecutableDirective &D,
722 llvm::Value *TaskFunction, QualType SharedsTy,
723 Address Shareds, const OMPTaskDataTy &Data);
Alexey Bataev7292c292016-04-25 12:22:29 +0000724
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000725public:
726 explicit CGOpenMPRuntime(CodeGenModule &CGM);
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +0000727 virtual ~CGOpenMPRuntime() {}
Alexey Bataev91797552015-03-18 04:13:55 +0000728 virtual void clear();
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000729
Alexey Bataevc5b1d322016-03-04 09:22:22 +0000730 /// Emit code for the specified user defined reduction construct.
731 virtual void emitUserDefinedReduction(CodeGenFunction *CGF,
732 const OMPDeclareReductionDecl *D);
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000733 /// Get combiner/initializer for the specified user-defined reduction, if any.
734 virtual std::pair<llvm::Function *, llvm::Function *>
735 getUserDefinedReduction(const OMPDeclareReductionDecl *D);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000736
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000737 /// \brief Emits outlined function for the specified OpenMP parallel directive
738 /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
739 /// kmp_int32 BoundID, struct context_vars*).
Alexey Bataev18095712014-10-10 12:19:54 +0000740 /// \param D OpenMP directive.
741 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000742 /// \param InnermostKind Kind of innermost directive (for simple directives it
743 /// is a directive itself, for combined - its innermost directive).
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000744 /// \param CodeGen Code generation sequence for the \a D directive.
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000745 virtual llvm::Value *emitParallelOutlinedFunction(
746 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
747 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
748
749 /// \brief Emits outlined function for the specified OpenMP teams directive
750 /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
751 /// kmp_int32 BoundID, struct context_vars*).
752 /// \param D OpenMP directive.
753 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
754 /// \param InnermostKind Kind of innermost directive (for simple directives it
755 /// is a directive itself, for combined - its innermost directive).
756 /// \param CodeGen Code generation sequence for the \a D directive.
757 virtual llvm::Value *emitTeamsOutlinedFunction(
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000758 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
759 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
Alexey Bataev18095712014-10-10 12:19:54 +0000760
Alexey Bataev62b63b12015-03-10 07:28:44 +0000761 /// \brief Emits outlined function for the OpenMP task directive \a D. This
Alexey Bataev48591dd2016-04-20 04:01:36 +0000762 /// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t*
763 /// TaskT).
Alexey Bataev62b63b12015-03-10 07:28:44 +0000764 /// \param D OpenMP directive.
765 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000766 /// \param PartIDVar Variable for partition id in the current OpenMP untied
767 /// task region.
768 /// \param TaskTVar Variable for task_t argument.
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000769 /// \param InnermostKind Kind of innermost directive (for simple directives it
770 /// is a directive itself, for combined - its innermost directive).
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000771 /// \param CodeGen Code generation sequence for the \a D directive.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000772 /// \param Tied true if task is generated for tied task, false otherwise.
773 /// \param NumberOfParts Number of parts in untied task. Ignored for tied
774 /// tasks.
Alexey Bataev62b63b12015-03-10 07:28:44 +0000775 ///
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000776 virtual llvm::Value *emitTaskOutlinedFunction(
777 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
Alexey Bataev48591dd2016-04-20 04:01:36 +0000778 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
779 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
780 bool Tied, unsigned &NumberOfParts);
Alexey Bataev62b63b12015-03-10 07:28:44 +0000781
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000782 /// \brief Cleans up references to the objects in finished function.
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000783 ///
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +0000784 virtual void functionFinished(CodeGenFunction &CGF);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000785
Alexey Bataev1d677132015-04-22 13:57:31 +0000786 /// \brief Emits code for parallel or serial call of the \a OutlinedFn with
787 /// variables captured in a record which address is stored in \a
788 /// CapturedStruct.
Alexey Bataev18095712014-10-10 12:19:54 +0000789 /// \param OutlinedFn Outlined function to be run in parallel threads. Type of
Alexey Bataev62b63b12015-03-10 07:28:44 +0000790 /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
NAKAMURA Takumi62f0eb52015-09-11 08:13:32 +0000791 /// \param CapturedVars A pointer to the record with the references to
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000792 /// variables used in \a OutlinedFn function.
Alexey Bataev1d677132015-04-22 13:57:31 +0000793 /// \param IfCond Condition in the associated 'if' clause, if it was
794 /// specified, nullptr otherwise.
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000795 ///
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000796 virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
797 llvm::Value *OutlinedFn,
Alexey Bataev2377fe92015-09-10 08:12:02 +0000798 ArrayRef<llvm::Value *> CapturedVars,
799 const Expr *IfCond);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000800
Alexey Bataev75ddfab2014-12-01 11:32:38 +0000801 /// \brief Emits a critical region.
Alexey Bataev18095712014-10-10 12:19:54 +0000802 /// \param CriticalName Name of the critical region.
Alexey Bataev75ddfab2014-12-01 11:32:38 +0000803 /// \param CriticalOpGen Generator for the statement associated with the given
804 /// critical region.
Alexey Bataevfc57d162015-12-15 10:55:09 +0000805 /// \param Hint Value of the 'hint' clause (optional).
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000806 virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000807 const RegionCodeGenTy &CriticalOpGen,
Alexey Bataevfc57d162015-12-15 10:55:09 +0000808 SourceLocation Loc,
809 const Expr *Hint = nullptr);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000810
Alexey Bataev8d690652014-12-04 07:23:53 +0000811 /// \brief Emits a master region.
812 /// \param MasterOpGen Generator for the statement associated with the given
813 /// master region.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000814 virtual void emitMasterRegion(CodeGenFunction &CGF,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000815 const RegionCodeGenTy &MasterOpGen,
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000816 SourceLocation Loc);
Alexey Bataev8d690652014-12-04 07:23:53 +0000817
Alexey Bataev9f797f32015-02-05 05:57:51 +0000818 /// \brief Emits code for a taskyield directive.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000819 virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc);
Alexey Bataev9f797f32015-02-05 05:57:51 +0000820
Alexey Bataevc30dd2d2015-06-18 12:14:09 +0000821 /// \brief Emit a taskgroup region.
822 /// \param TaskgroupOpGen Generator for the statement associated with the
823 /// given taskgroup region.
824 virtual void emitTaskgroupRegion(CodeGenFunction &CGF,
825 const RegionCodeGenTy &TaskgroupOpGen,
826 SourceLocation Loc);
827
Alexey Bataev6956e2e2015-02-05 06:35:41 +0000828 /// \brief Emits a single region.
829 /// \param SingleOpGen Generator for the statement associated with the given
830 /// single region.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000831 virtual void emitSingleRegion(CodeGenFunction &CGF,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000832 const RegionCodeGenTy &SingleOpGen,
Alexey Bataeva63048e2015-03-23 06:18:07 +0000833 SourceLocation Loc,
834 ArrayRef<const Expr *> CopyprivateVars,
Alexey Bataev420d45b2015-04-14 05:11:24 +0000835 ArrayRef<const Expr *> DestExprs,
Alexey Bataeva63048e2015-03-23 06:18:07 +0000836 ArrayRef<const Expr *> SrcExprs,
Alexey Bataeva63048e2015-03-23 06:18:07 +0000837 ArrayRef<const Expr *> AssignmentOps);
Alexey Bataev6956e2e2015-02-05 06:35:41 +0000838
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000839 /// \brief Emit an ordered region.
840 /// \param OrderedOpGen Generator for the statement associated with the given
Alexey Bataevc30dd2d2015-06-18 12:14:09 +0000841 /// ordered region.
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000842 virtual void emitOrderedRegion(CodeGenFunction &CGF,
843 const RegionCodeGenTy &OrderedOpGen,
Alexey Bataev5f600d62015-09-29 03:48:57 +0000844 SourceLocation Loc, bool IsThreads);
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000845
Alexey Bataevf2685682015-03-30 04:30:22 +0000846 /// \brief Emit an implicit/explicit barrier for OpenMP threads.
847 /// \param Kind Directive for which this implicit barrier call must be
848 /// generated. Must be OMPD_barrier for explicit barrier generation.
Alexey Bataev25e5b442015-09-15 12:52:43 +0000849 /// \param EmitChecks true if need to emit checks for cancellation barriers.
850 /// \param ForceSimpleCall true simple barrier call must be emitted, false if
851 /// runtime class decides which one to emit (simple or with cancellation
852 /// checks).
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000853 ///
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000854 virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000855 OpenMPDirectiveKind Kind,
Alexey Bataev25e5b442015-09-15 12:52:43 +0000856 bool EmitChecks = true,
857 bool ForceSimpleCall = false);
Alexey Bataevb2059782014-10-13 08:23:51 +0000858
Alexander Musmanc6388682014-12-15 07:07:06 +0000859 /// \brief Check if the specified \a ScheduleKind is static non-chunked.
860 /// This kind of worksharing directive is emitted without outer loop.
861 /// \param ScheduleKind Schedule kind specified in the 'schedule' clause.
862 /// \param Chunked True if chunk is specified in the clause.
863 ///
864 virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
865 bool Chunked) const;
866
Carlo Bertollifc35ad22016-03-07 16:04:49 +0000867 /// \brief Check if the specified \a ScheduleKind is static non-chunked.
868 /// This kind of distribute directive is emitted without outer loop.
869 /// \param ScheduleKind Schedule kind specified in the 'dist_schedule' clause.
870 /// \param Chunked True if chunk is specified in the clause.
871 ///
872 virtual bool isStaticNonchunked(OpenMPDistScheduleClauseKind ScheduleKind,
873 bool Chunked) const;
874
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000875 /// \brief Check if the specified \a ScheduleKind is dynamic.
876 /// This kind of worksharing directive is emitted without outer loop.
877 /// \param ScheduleKind Schedule Kind specified in the 'schedule' clause.
878 ///
879 virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const;
880
Carlo Bertollib0ff0a62017-04-25 17:52:12 +0000881 /// struct with the values to be passed to the dispatch runtime function
882 struct DispatchRTInput {
883 /// Loop lower bound
884 llvm::Value *LB = nullptr;
885 /// Loop upper bound
886 llvm::Value *UB = nullptr;
887 /// Chunk size specified using 'schedule' clause (nullptr if chunk
888 /// was not specified)
889 llvm::Value *Chunk = nullptr;
890 DispatchRTInput() = default;
891 DispatchRTInput(llvm::Value *LB, llvm::Value *UB, llvm::Value *Chunk)
892 : LB(LB), UB(UB), Chunk(Chunk) {}
893 };
894
895 /// Call the appropriate runtime routine to initialize it before start
896 /// of loop.
897
898 /// This is used for non static scheduled types and when the ordered
899 /// clause is present on the loop construct.
900 /// Depending on the loop schedule, it is necessary to call some runtime
901 /// routine before start of the OpenMP loop to get the loop upper / lower
902 /// bounds \a LB and \a UB and stride \a ST.
903 ///
904 /// \param CGF Reference to current CodeGenFunction.
905 /// \param Loc Clang source location.
906 /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
907 /// \param IVSize Size of the iteration variable in bits.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000908 /// \param IVSigned Sign of the iteration variable.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +0000909 /// \param Ordered true if loop is ordered, false otherwise.
910 /// \param DispatchValues struct containing llvm values for lower bound, upper
911 /// bound, and chunk expression.
912 /// For the default (nullptr) value, the chunk 1 will be used.
913 ///
NAKAMURA Takumiff7a9252015-09-08 09:42:41 +0000914 virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev9ebd7422016-05-10 09:57:36 +0000915 const OpenMPScheduleTy &ScheduleKind,
916 unsigned IVSize, bool IVSigned, bool Ordered,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +0000917 const DispatchRTInput &DispatchValues);
NAKAMURA Takumiff7a9252015-09-08 09:42:41 +0000918
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000919 /// Struct with the values to be passed to the static runtime function
920 struct StaticRTInput {
921 /// Size of the iteration variable in bits.
922 unsigned IVSize = 0;
923 /// Sign of the iteration variable.
924 bool IVSigned = false;
925 /// true if loop is ordered, false otherwise.
926 bool Ordered = false;
927 /// Address of the output variable in which the flag of the last iteration
928 /// is returned.
929 Address IL = Address::invalid();
930 /// Address of the output variable in which the lower iteration number is
931 /// returned.
932 Address LB = Address::invalid();
933 /// Address of the output variable in which the upper iteration number is
934 /// returned.
935 Address UB = Address::invalid();
936 /// Address of the output variable in which the stride value is returned
937 /// necessary to generated the static_chunked scheduled loop.
938 Address ST = Address::invalid();
939 /// Value of the chunk for the static_chunked scheduled loop. For the
940 /// default (nullptr) value, the chunk 1 will be used.
941 llvm::Value *Chunk = nullptr;
942 StaticRTInput(unsigned IVSize, bool IVSigned, bool Ordered, Address IL,
943 Address LB, Address UB, Address ST,
944 llvm::Value *Chunk = nullptr)
945 : IVSize(IVSize), IVSigned(IVSigned), Ordered(Ordered), IL(IL), LB(LB),
946 UB(UB), ST(ST), Chunk(Chunk) {}
947 };
Alexander Musmanc6388682014-12-15 07:07:06 +0000948 /// \brief Call the appropriate runtime routine to initialize it before start
949 /// of loop.
950 ///
Carlo Bertollib0ff0a62017-04-25 17:52:12 +0000951 /// This is used only in case of static schedule, when the user did not
952 /// specify a ordered clause on the loop construct.
953 /// Depending on the loop schedule, it is necessary to call some runtime
Alexander Musmanc6388682014-12-15 07:07:06 +0000954 /// routine before start of the OpenMP loop to get the loop upper / lower
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000955 /// bounds LB and UB and stride ST.
Alexander Musmanc6388682014-12-15 07:07:06 +0000956 ///
957 /// \param CGF Reference to current CodeGenFunction.
958 /// \param Loc Clang source location.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000959 /// \param DKind Kind of the directive.
Alexey Bataev9ebd7422016-05-10 09:57:36 +0000960 /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000961 /// \param Values Input arguments for the construct.
Alexander Musmanc6388682014-12-15 07:07:06 +0000962 ///
John McCall7f416cc2015-09-08 08:05:57 +0000963 virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000964 OpenMPDirectiveKind DKind,
Alexey Bataev9ebd7422016-05-10 09:57:36 +0000965 const OpenMPScheduleTy &ScheduleKind,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000966 const StaticRTInput &Values);
Alexander Musmanc6388682014-12-15 07:07:06 +0000967
Carlo Bertollifc35ad22016-03-07 16:04:49 +0000968 ///
969 /// \param CGF Reference to current CodeGenFunction.
970 /// \param Loc Clang source location.
971 /// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000972 /// \param Values Input arguments for the construct.
Carlo Bertollifc35ad22016-03-07 16:04:49 +0000973 ///
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000974 virtual void emitDistributeStaticInit(CodeGenFunction &CGF,
975 SourceLocation Loc,
Carlo Bertollifc35ad22016-03-07 16:04:49 +0000976 OpenMPDistScheduleClauseKind SchedKind,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000977 const StaticRTInput &Values);
Carlo Bertollifc35ad22016-03-07 16:04:49 +0000978
Alexander Musmanc6388682014-12-15 07:07:06 +0000979 /// \brief Call the appropriate runtime routine to notify that we finished
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000980 /// iteration of the ordered loop with the dynamic scheduling.
981 ///
982 /// \param CGF Reference to current CodeGenFunction.
983 /// \param Loc Clang source location.
984 /// \param IVSize Size of the iteration variable in bits.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +0000985 /// \param IVSigned Sign of the iteration variable.
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000986 ///
Alexey Bataevd7589ffe2015-05-20 13:12:48 +0000987 virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF,
988 SourceLocation Loc, unsigned IVSize,
989 bool IVSigned);
Alexey Bataev98eb6e32015-04-22 11:15:40 +0000990
991 /// \brief Call the appropriate runtime routine to notify that we finished
Alexander Musmanc6388682014-12-15 07:07:06 +0000992 /// all the work with current loop.
993 ///
994 /// \param CGF Reference to current CodeGenFunction.
995 /// \param Loc Clang source location.
Alexey Bataevf43f7142017-09-06 16:17:35 +0000996 /// \param DKind Kind of the directive for which the static finish is emitted.
Alexander Musmanc6388682014-12-15 07:07:06 +0000997 ///
Alexey Bataevf43f7142017-09-06 16:17:35 +0000998 virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc,
999 OpenMPDirectiveKind DKind);
Alexander Musmanc6388682014-12-15 07:07:06 +00001000
Alexander Musman92bdaab2015-03-12 13:37:50 +00001001 /// Call __kmpc_dispatch_next(
1002 /// ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
1003 /// kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
1004 /// kmp_int[32|64] *p_stride);
1005 /// \param IVSize Size of the iteration variable in bits.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +00001006 /// \param IVSigned Sign of the iteration variable.
Alexander Musman92bdaab2015-03-12 13:37:50 +00001007 /// \param IL Address of the output variable in which the flag of the
1008 /// last iteration is returned.
1009 /// \param LB Address of the output variable in which the lower iteration
1010 /// number is returned.
1011 /// \param UB Address of the output variable in which the upper iteration
1012 /// number is returned.
1013 /// \param ST Address of the output variable in which the stride value is
1014 /// returned.
1015 virtual llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc,
1016 unsigned IVSize, bool IVSigned,
John McCall7f416cc2015-09-08 08:05:57 +00001017 Address IL, Address LB,
1018 Address UB, Address ST);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001019
Alexey Bataevb2059782014-10-13 08:23:51 +00001020 /// \brief Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
1021 /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
1022 /// clause.
1023 /// \param NumThreads An integer value of threads.
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001024 virtual void emitNumThreadsClause(CodeGenFunction &CGF,
1025 llvm::Value *NumThreads,
1026 SourceLocation Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00001027
Alexey Bataev7f210c62015-06-18 13:40:03 +00001028 /// \brief Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32
1029 /// global_tid, int proc_bind) to generate code for 'proc_bind' clause.
1030 virtual void emitProcBindClause(CodeGenFunction &CGF,
1031 OpenMPProcBindClauseKind ProcBind,
1032 SourceLocation Loc);
1033
Alexey Bataev97720002014-11-11 04:05:39 +00001034 /// \brief Returns address of the threadprivate variable for the current
1035 /// thread.
NAKAMURA Takumicdcbfba2014-11-11 07:58:06 +00001036 /// \param VD Threadprivate variable.
Alexey Bataev97720002014-11-11 04:05:39 +00001037 /// \param VDAddr Address of the global variable \a VD.
1038 /// \param Loc Location of the reference to threadprivate var.
1039 /// \return Address of the threadprivate variable for the current thread.
John McCall7f416cc2015-09-08 08:05:57 +00001040 virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF,
1041 const VarDecl *VD,
1042 Address VDAddr,
1043 SourceLocation Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00001044
Alexey Bataev92327c52018-03-26 16:40:55 +00001045 /// Returns the address of the variable marked as declare target with link
1046 /// clause.
Alexey Bataev03f270c2018-03-30 18:31:07 +00001047 virtual Address getAddrOfDeclareTargetLink(const VarDecl *VD);
Alexey Bataev92327c52018-03-26 16:40:55 +00001048
Alexey Bataev97720002014-11-11 04:05:39 +00001049 /// \brief Emit a code for initialization of threadprivate variable. It emits
1050 /// a call to runtime library which adds initial value to the newly created
1051 /// threadprivate variable (if it is not constant) and registers destructor
1052 /// for the variable (if any).
1053 /// \param VD Threadprivate variable.
1054 /// \param VDAddr Address of the global variable \a VD.
1055 /// \param Loc Location of threadprivate declaration.
1056 /// \param PerformInit true if initialization expression is not constant.
1057 virtual llvm::Function *
John McCall7f416cc2015-09-08 08:05:57 +00001058 emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr,
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001059 SourceLocation Loc, bool PerformInit,
1060 CodeGenFunction *CGF = nullptr);
Alexey Bataevcc37cc12014-11-20 04:34:54 +00001061
Alexey Bataev34f8a702018-03-28 14:28:54 +00001062 /// \brief Emit a code for initialization of declare target variable.
1063 /// \param VD Declare target variable.
1064 /// \param Addr Address of the global variable \a VD.
1065 /// \param PerformInit true if initialization expression is not constant.
1066 virtual bool emitDeclareTargetVarDefinition(const VarDecl *VD,
1067 llvm::GlobalVariable *Addr,
1068 bool PerformInit);
1069
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001070 /// Creates artificial threadprivate variable with name \p Name and type \p
1071 /// VarType.
1072 /// \param VarType Type of the artificial threadprivate variable.
1073 /// \param Name Name of the artificial threadprivate variable.
1074 virtual Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
1075 QualType VarType,
1076 StringRef Name);
1077
Alexey Bataevcc37cc12014-11-20 04:34:54 +00001078 /// \brief Emit flush of the variables specified in 'omp flush' directive.
1079 /// \param Vars List of variables to flush.
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001080 virtual void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars,
1081 SourceLocation Loc);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001082
1083 /// \brief Emit task region for the task directive. The task region is
Nico Weber20b0ce32015-04-28 18:19:18 +00001084 /// emitted in several steps:
Alexey Bataev62b63b12015-03-10 07:28:44 +00001085 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
1086 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1087 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
1088 /// function:
1089 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
1090 /// TaskFunction(gtid, tt->part_id, tt->shareds);
1091 /// return 0;
1092 /// }
1093 /// 2. Copy a list of shared variables to field shareds of the resulting
1094 /// structure kmp_task_t returned by the previous call (if any).
1095 /// 3. Copy a pointer to destructions function to field destructions of the
1096 /// resulting structure kmp_task_t.
1097 /// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid,
1098 /// kmp_task_t *new_task), where new_task is a resulting structure from
1099 /// previous items.
Alexey Bataev36c1eb92015-04-30 06:51:57 +00001100 /// \param D Current task directive.
Alexey Bataev62b63b12015-03-10 07:28:44 +00001101 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
1102 /// /*part_id*/, captured_struct */*__context*/);
1103 /// \param SharedsTy A type which contains references the shared variables.
Alexey Bataev1d2353d2015-06-24 11:01:36 +00001104 /// \param Shareds Context with the list of shared variables from the \p
Alexey Bataev62b63b12015-03-10 07:28:44 +00001105 /// TaskFunction.
Alexey Bataev1d677132015-04-22 13:57:31 +00001106 /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
1107 /// otherwise.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00001108 /// \param Data Additional data for task generation like tiednsee, final
1109 /// state, list of privates etc.
1110 virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
1111 const OMPExecutableDirective &D,
1112 llvm::Value *TaskFunction, QualType SharedsTy,
1113 Address Shareds, const Expr *IfCond,
1114 const OMPTaskDataTy &Data);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001115
Alexey Bataev7292c292016-04-25 12:22:29 +00001116 /// Emit task region for the taskloop directive. The taskloop region is
1117 /// emitted in several steps:
1118 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
1119 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1120 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
1121 /// function:
1122 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
1123 /// TaskFunction(gtid, tt->part_id, tt->shareds);
1124 /// return 0;
1125 /// }
1126 /// 2. Copy a list of shared variables to field shareds of the resulting
1127 /// structure kmp_task_t returned by the previous call (if any).
1128 /// 3. Copy a pointer to destructions function to field destructions of the
1129 /// resulting structure kmp_task_t.
1130 /// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t
1131 /// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int
1132 /// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task
1133 /// is a resulting structure from
1134 /// previous items.
1135 /// \param D Current task directive.
Alexey Bataev7292c292016-04-25 12:22:29 +00001136 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
1137 /// /*part_id*/, captured_struct */*__context*/);
1138 /// \param SharedsTy A type which contains references the shared variables.
1139 /// \param Shareds Context with the list of shared variables from the \p
1140 /// TaskFunction.
1141 /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
1142 /// otherwise.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00001143 /// \param Data Additional data for task generation like tiednsee, final
1144 /// state, list of privates etc.
Alexey Bataev7292c292016-04-25 12:22:29 +00001145 virtual void emitTaskLoopCall(
1146 CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00001147 llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds,
1148 const Expr *IfCond, const OMPTaskDataTy &Data);
Alexey Bataev7292c292016-04-25 12:22:29 +00001149
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001150 /// \brief Emit code for the directive that does not require outlining.
1151 ///
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001152 /// \param InnermostKind Kind of innermost directive (for simple directives it
1153 /// is a directive itself, for combined - its innermost directive).
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001154 /// \param CodeGen Code generation sequence for the \a D directive.
Alexey Bataev25e5b442015-09-15 12:52:43 +00001155 /// \param HasCancel true if region has inner cancel directive, false
1156 /// otherwise.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001157 virtual void emitInlinedDirective(CodeGenFunction &CGF,
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001158 OpenMPDirectiveKind InnermostKind,
Alexey Bataev25e5b442015-09-15 12:52:43 +00001159 const RegionCodeGenTy &CodeGen,
1160 bool HasCancel = false);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001161
1162 /// Emits reduction function.
1163 /// \param ArgsType Array type containing pointers to reduction variables.
1164 /// \param Privates List of private copies for original reduction arguments.
1165 /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
1166 /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
1167 /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
1168 /// or 'operator binop(LHS, RHS)'.
Alexey Bataev7cae94e2018-01-04 19:45:16 +00001169 llvm::Value *emitReductionFunction(CodeGenModule &CGM, SourceLocation Loc,
1170 llvm::Type *ArgsType,
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001171 ArrayRef<const Expr *> Privates,
1172 ArrayRef<const Expr *> LHSExprs,
1173 ArrayRef<const Expr *> RHSExprs,
1174 ArrayRef<const Expr *> ReductionOps);
1175
1176 /// Emits single reduction combiner
1177 void emitSingleReductionCombiner(CodeGenFunction &CGF,
1178 const Expr *ReductionOp,
1179 const Expr *PrivateRef,
1180 const DeclRefExpr *LHS,
1181 const DeclRefExpr *RHS);
1182
1183 struct ReductionOptionsTy {
1184 bool WithNowait;
1185 bool SimpleReduction;
1186 OpenMPDirectiveKind ReductionKind;
1187 };
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001188 /// \brief Emit a code for reduction clause. Next code should be emitted for
1189 /// reduction:
1190 /// \code
1191 ///
1192 /// static kmp_critical_name lock = { 0 };
1193 ///
1194 /// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
1195 /// ...
1196 /// *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
1197 /// ...
1198 /// }
1199 ///
1200 /// ...
1201 /// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
1202 /// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
1203 /// RedList, reduce_func, &<lock>)) {
1204 /// case 1:
1205 /// ...
1206 /// <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
1207 /// ...
1208 /// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
1209 /// break;
1210 /// case 2:
1211 /// ...
1212 /// Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
1213 /// ...
1214 /// break;
1215 /// default:;
1216 /// }
1217 /// \endcode
1218 ///
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001219 /// \param Privates List of private copies for original reduction arguments.
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001220 /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
1221 /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
1222 /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
1223 /// or 'operator binop(LHS, RHS)'.
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001224 /// \param Options List of options for reduction codegen:
1225 /// WithNowait true if parent directive has also nowait clause, false
1226 /// otherwise.
1227 /// SimpleReduction Emit reduction operation only. Used for omp simd
1228 /// directive on the host.
1229 /// ReductionKind The kind of reduction to perform.
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001230 virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001231 ArrayRef<const Expr *> Privates,
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001232 ArrayRef<const Expr *> LHSExprs,
1233 ArrayRef<const Expr *> RHSExprs,
1234 ArrayRef<const Expr *> ReductionOps,
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001235 ReductionOptionsTy Options);
Alexey Bataev8b8e2022015-04-27 05:22:09 +00001236
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001237 /// Emit a code for initialization of task reduction clause. Next code
1238 /// should be emitted for reduction:
1239 /// \code
1240 ///
1241 /// _task_red_item_t red_data[n];
1242 /// ...
1243 /// red_data[i].shar = &origs[i];
1244 /// red_data[i].size = sizeof(origs[i]);
1245 /// red_data[i].f_init = (void*)RedInit<i>;
1246 /// red_data[i].f_fini = (void*)RedDest<i>;
1247 /// red_data[i].f_comb = (void*)RedOp<i>;
1248 /// red_data[i].flags = <Flag_i>;
1249 /// ...
1250 /// void* tg1 = __kmpc_task_reduction_init(gtid, n, red_data);
1251 /// \endcode
1252 ///
1253 /// \param LHSExprs List of LHS in \a Data.ReductionOps reduction operations.
1254 /// \param RHSExprs List of RHS in \a Data.ReductionOps reduction operations.
1255 /// \param Data Additional data for task generation like tiedness, final
1256 /// state, list of privates, reductions etc.
1257 virtual llvm::Value *emitTaskReductionInit(CodeGenFunction &CGF,
1258 SourceLocation Loc,
1259 ArrayRef<const Expr *> LHSExprs,
1260 ArrayRef<const Expr *> RHSExprs,
1261 const OMPTaskDataTy &Data);
1262
1263 /// Required to resolve existing problems in the runtime. Emits threadprivate
1264 /// variables to store the size of the VLAs/array sections for
1265 /// initializer/combiner/finalizer functions + emits threadprivate variable to
1266 /// store the pointer to the original reduction item for the custom
1267 /// initializer defined by declare reduction construct.
1268 /// \param RCG Allows to reuse an existing data for the reductions.
1269 /// \param N Reduction item for which fixups must be emitted.
1270 virtual void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc,
1271 ReductionCodeGen &RCG, unsigned N);
1272
1273 /// Get the address of `void *` type of the privatue copy of the reduction
1274 /// item specified by the \p SharedLVal.
1275 /// \param ReductionsPtr Pointer to the reduction data returned by the
1276 /// emitTaskReductionInit function.
1277 /// \param SharedLVal Address of the original reduction item.
1278 virtual Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc,
1279 llvm::Value *ReductionsPtr,
1280 LValue SharedLVal);
1281
Alexey Bataev8b8e2022015-04-27 05:22:09 +00001282 /// \brief Emit code for 'taskwait' directive.
1283 virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc);
Alexey Bataev0f34da12015-07-02 04:17:07 +00001284
1285 /// \brief Emit code for 'cancellation point' construct.
1286 /// \param CancelRegion Region kind for which the cancellation point must be
1287 /// emitted.
1288 ///
1289 virtual void emitCancellationPointCall(CodeGenFunction &CGF,
1290 SourceLocation Loc,
1291 OpenMPDirectiveKind CancelRegion);
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00001292
1293 /// \brief Emit code for 'cancel' construct.
Alexey Bataev87933c72015-09-18 08:07:34 +00001294 /// \param IfCond Condition in the associated 'if' clause, if it was
1295 /// specified, nullptr otherwise.
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00001296 /// \param CancelRegion Region kind for which the cancel must be emitted.
1297 ///
1298 virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev87933c72015-09-18 08:07:34 +00001299 const Expr *IfCond,
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00001300 OpenMPDirectiveKind CancelRegion);
Samuel Antaobed3c462015-10-02 16:14:20 +00001301
1302 /// \brief Emit outilined function for 'target' directive.
1303 /// \param D Directive to emit.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001304 /// \param ParentName Name of the function that encloses the target region.
1305 /// \param OutlinedFn Outlined function value to be defined by this call.
1306 /// \param OutlinedFnID Outlined function ID value to be defined by this call.
1307 /// \param IsOffloadEntry True if the outlined function is an offload entry.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001308 /// \param CodeGen Code generation sequence for the \a D directive.
Simon Pilgrim6c0eeff2017-07-13 17:34:44 +00001309 /// An outlined function may not be an entry if, e.g. the if clause always
Samuel Antaoee8fb302016-01-06 13:42:12 +00001310 /// evaluates to false.
1311 virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
1312 StringRef ParentName,
1313 llvm::Function *&OutlinedFn,
1314 llvm::Constant *&OutlinedFnID,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001315 bool IsOffloadEntry,
1316 const RegionCodeGenTy &CodeGen);
Samuel Antaobed3c462015-10-02 16:14:20 +00001317
1318 /// \brief Emit the target offloading code associated with \a D. The emitted
1319 /// code attempts offloading the execution to the device, an the event of
1320 /// a failure it executes the host version outlined in \a OutlinedFn.
1321 /// \param D Directive to emit.
1322 /// \param OutlinedFn Host version of the code to be offloaded.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001323 /// \param OutlinedFnID ID of host version of the code to be offloaded.
Samuel Antaobed3c462015-10-02 16:14:20 +00001324 /// \param IfCond Expression evaluated in if clause associated with the target
1325 /// directive, or null if no if clause is used.
1326 /// \param Device Expression evaluated in device clause associated with the
1327 /// target directive, or null if no device clause is used.
Samuel Antaobed3c462015-10-02 16:14:20 +00001328 virtual void emitTargetCall(CodeGenFunction &CGF,
1329 const OMPExecutableDirective &D,
Samuel Antaoee8fb302016-01-06 13:42:12 +00001330 llvm::Value *OutlinedFn,
1331 llvm::Value *OutlinedFnID, const Expr *IfCond,
Alexey Bataev8451efa2018-01-15 19:06:12 +00001332 const Expr *Device);
Samuel Antaoee8fb302016-01-06 13:42:12 +00001333
1334 /// \brief Emit the target regions enclosed in \a GD function definition or
1335 /// the function itself in case it is a valid device function. Returns true if
1336 /// \a GD was dealt with successfully.
Nico Webera2abe8c2016-01-06 19:13:49 +00001337 /// \param GD Function to scan.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001338 virtual bool emitTargetFunctions(GlobalDecl GD);
1339
1340 /// \brief Emit the global variable if it is a valid device global variable.
1341 /// Returns true if \a GD was dealt with successfully.
1342 /// \param GD Variable declaration to emit.
1343 virtual bool emitTargetGlobalVariable(GlobalDecl GD);
1344
Alexey Bataev03f270c2018-03-30 18:31:07 +00001345 /// Checks if the provided global decl \a GD is a declare target variable and
1346 /// registers it when emitting code for the host.
1347 virtual void registerTargetGlobalVariable(const VarDecl *VD,
1348 llvm::Constant *Addr);
1349
Samuel Antaoee8fb302016-01-06 13:42:12 +00001350 /// \brief Emit the global \a GD if it is meaningful for the target. Returns
Simon Pilgrim2c518802017-03-30 14:13:19 +00001351 /// if it was emitted successfully.
Samuel Antaoee8fb302016-01-06 13:42:12 +00001352 /// \param GD Global to scan.
1353 virtual bool emitTargetGlobal(GlobalDecl GD);
1354
1355 /// \brief Creates the offloading descriptor in the event any target region
1356 /// was emitted in the current module and return the function that registers
1357 /// it.
1358 virtual llvm::Function *emitRegistrationFunction();
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00001359
1360 /// \brief Emits code for teams call of the \a OutlinedFn with
1361 /// variables captured in a record which address is stored in \a
1362 /// CapturedStruct.
1363 /// \param OutlinedFn Outlined function to be run by team masters. Type of
1364 /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
1365 /// \param CapturedVars A pointer to the record with the references to
1366 /// variables used in \a OutlinedFn function.
1367 ///
1368 virtual void emitTeamsCall(CodeGenFunction &CGF,
1369 const OMPExecutableDirective &D,
1370 SourceLocation Loc, llvm::Value *OutlinedFn,
1371 ArrayRef<llvm::Value *> CapturedVars);
1372
1373 /// \brief Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
1374 /// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code
1375 /// for num_teams clause.
Carlo Bertollic6872252016-04-04 15:55:02 +00001376 /// \param NumTeams An integer expression of teams.
1377 /// \param ThreadLimit An integer expression of threads.
1378 virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams,
1379 const Expr *ThreadLimit, SourceLocation Loc);
Samuel Antaodf158d52016-04-27 22:58:19 +00001380
Samuel Antaocc10b852016-07-28 14:23:26 +00001381 /// Struct that keeps all the relevant information that should be kept
1382 /// throughout a 'target data' region.
1383 class TargetDataInfo {
1384 /// Set to true if device pointer information have to be obtained.
1385 bool RequiresDevicePointerInfo = false;
1386
1387 public:
1388 /// The array of base pointer passed to the runtime library.
1389 llvm::Value *BasePointersArray = nullptr;
1390 /// The array of section pointers passed to the runtime library.
1391 llvm::Value *PointersArray = nullptr;
1392 /// The array of sizes passed to the runtime library.
1393 llvm::Value *SizesArray = nullptr;
1394 /// The array of map types passed to the runtime library.
1395 llvm::Value *MapTypesArray = nullptr;
1396 /// The total number of pointers passed to the runtime library.
1397 unsigned NumberOfPtrs = 0u;
1398 /// Map between the a declaration of a capture and the corresponding base
1399 /// pointer address where the runtime returns the device pointers.
1400 llvm::DenseMap<const ValueDecl *, Address> CaptureDeviceAddrMap;
1401
1402 explicit TargetDataInfo() {}
1403 explicit TargetDataInfo(bool RequiresDevicePointerInfo)
1404 : RequiresDevicePointerInfo(RequiresDevicePointerInfo) {}
1405 /// Clear information about the data arrays.
1406 void clearArrayInfo() {
1407 BasePointersArray = nullptr;
1408 PointersArray = nullptr;
1409 SizesArray = nullptr;
1410 MapTypesArray = nullptr;
1411 NumberOfPtrs = 0u;
1412 }
1413 /// Return true if the current target data information has valid arrays.
1414 bool isValid() {
1415 return BasePointersArray && PointersArray && SizesArray &&
1416 MapTypesArray && NumberOfPtrs;
1417 }
1418 bool requiresDevicePointerInfo() { return RequiresDevicePointerInfo; }
1419 };
1420
Samuel Antaodf158d52016-04-27 22:58:19 +00001421 /// \brief Emit the target data mapping code associated with \a D.
1422 /// \param D Directive to emit.
Samuel Antaocc10b852016-07-28 14:23:26 +00001423 /// \param IfCond Expression evaluated in if clause associated with the
1424 /// target directive, or null if no device clause is used.
Samuel Antaodf158d52016-04-27 22:58:19 +00001425 /// \param Device Expression evaluated in device clause associated with the
1426 /// target directive, or null if no device clause is used.
Samuel Antaocc10b852016-07-28 14:23:26 +00001427 /// \param Info A record used to store information that needs to be preserved
1428 /// until the region is closed.
Samuel Antaodf158d52016-04-27 22:58:19 +00001429 virtual void emitTargetDataCalls(CodeGenFunction &CGF,
1430 const OMPExecutableDirective &D,
1431 const Expr *IfCond, const Expr *Device,
Samuel Antaocc10b852016-07-28 14:23:26 +00001432 const RegionCodeGenTy &CodeGen,
1433 TargetDataInfo &Info);
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00001434
Samuel Antao8d2d7302016-05-26 18:30:22 +00001435 /// \brief Emit the data mapping/movement code associated with the directive
1436 /// \a D that should be of the form 'target [{enter|exit} data | update]'.
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00001437 /// \param D Directive to emit.
1438 /// \param IfCond Expression evaluated in if clause associated with the target
1439 /// directive, or null if no if clause is used.
1440 /// \param Device Expression evaluated in device clause associated with the
1441 /// target directive, or null if no device clause is used.
Samuel Antao8d2d7302016-05-26 18:30:22 +00001442 virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF,
1443 const OMPExecutableDirective &D,
1444 const Expr *IfCond,
1445 const Expr *Device);
Alexey Bataevc7a82b42016-05-06 09:40:08 +00001446
1447 /// Marks function \a Fn with properly mangled versions of vector functions.
1448 /// \param FD Function marked as 'declare simd'.
1449 /// \param Fn LLVM function that must be marked with 'declare simd'
1450 /// attributes.
1451 virtual void emitDeclareSimdFunction(const FunctionDecl *FD,
1452 llvm::Function *Fn);
Alexey Bataev8b427062016-05-25 12:36:08 +00001453
1454 /// Emit initialization for doacross loop nesting support.
1455 /// \param D Loop-based construct used in doacross nesting construct.
1456 virtual void emitDoacrossInit(CodeGenFunction &CGF,
1457 const OMPLoopDirective &D);
1458
1459 /// Emit code for doacross ordered directive with 'depend' clause.
1460 /// \param C 'depend' clause with 'sink|source' dependency kind.
1461 virtual void emitDoacrossOrdered(CodeGenFunction &CGF,
1462 const OMPDependClause *C);
Alexey Bataev2c7eee52017-08-04 19:10:54 +00001463
Alexey Bataev3b8d5582017-08-08 18:04:06 +00001464 /// Translates the native parameter of outlined function if this is required
1465 /// for target.
1466 /// \param FD Field decl from captured record for the paramater.
1467 /// \param NativeParam Parameter itself.
1468 virtual const VarDecl *translateParameter(const FieldDecl *FD,
1469 const VarDecl *NativeParam) const {
1470 return NativeParam;
1471 }
1472
1473 /// Gets the address of the native argument basing on the address of the
1474 /// target-specific parameter.
1475 /// \param NativeParam Parameter itself.
1476 /// \param TargetParam Corresponding target-specific parameter.
1477 virtual Address getParameterAddress(CodeGenFunction &CGF,
1478 const VarDecl *NativeParam,
1479 const VarDecl *TargetParam) const;
1480
Alexey Bataev2c7eee52017-08-04 19:10:54 +00001481 /// Emits call of the outlined function with the provided arguments,
1482 /// translating these arguments to correct target-specific arguments.
1483 virtual void
Alexey Bataev3c595a62017-08-14 15:01:03 +00001484 emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc,
1485 llvm::Value *OutlinedFn,
Alexey Bataev2c7eee52017-08-04 19:10:54 +00001486 ArrayRef<llvm::Value *> Args = llvm::None) const;
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +00001487
1488 /// Emits OpenMP-specific function prolog.
1489 /// Required for device constructs.
1490 virtual void emitFunctionProlog(CodeGenFunction &CGF, const Decl *D) {}
1491
1492 /// Gets the OpenMP-specific address of the local variable.
1493 virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF,
1494 const VarDecl *VD);
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001495
1496 /// Marks the declaration as alread emitted for the device code and returns
1497 /// true, if it was marked already, and false, otherwise.
1498 bool markAsGlobalTarget(const FunctionDecl *D);
1499
Alexey Bataev9959db52014-05-06 10:08:46 +00001500};
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00001501
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001502/// Class supports emissionof SIMD-only code.
1503class CGOpenMPSIMDRuntime final : public CGOpenMPRuntime {
1504public:
1505 explicit CGOpenMPSIMDRuntime(CodeGenModule &CGM) : CGOpenMPRuntime(CGM) {}
1506 ~CGOpenMPSIMDRuntime() override {}
1507
1508 /// \brief Emits outlined function for the specified OpenMP parallel directive
1509 /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
1510 /// kmp_int32 BoundID, struct context_vars*).
1511 /// \param D OpenMP directive.
1512 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
1513 /// \param InnermostKind Kind of innermost directive (for simple directives it
1514 /// is a directive itself, for combined - its innermost directive).
1515 /// \param CodeGen Code generation sequence for the \a D directive.
1516 llvm::Value *
1517 emitParallelOutlinedFunction(const OMPExecutableDirective &D,
1518 const VarDecl *ThreadIDVar,
1519 OpenMPDirectiveKind InnermostKind,
1520 const RegionCodeGenTy &CodeGen) override;
1521
1522 /// \brief Emits outlined function for the specified OpenMP teams directive
1523 /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
1524 /// kmp_int32 BoundID, struct context_vars*).
1525 /// \param D OpenMP directive.
1526 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
1527 /// \param InnermostKind Kind of innermost directive (for simple directives it
1528 /// is a directive itself, for combined - its innermost directive).
1529 /// \param CodeGen Code generation sequence for the \a D directive.
1530 llvm::Value *
1531 emitTeamsOutlinedFunction(const OMPExecutableDirective &D,
1532 const VarDecl *ThreadIDVar,
1533 OpenMPDirectiveKind InnermostKind,
1534 const RegionCodeGenTy &CodeGen) override;
1535
1536 /// \brief Emits outlined function for the OpenMP task directive \a D. This
1537 /// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t*
1538 /// TaskT).
1539 /// \param D OpenMP directive.
1540 /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
1541 /// \param PartIDVar Variable for partition id in the current OpenMP untied
1542 /// task region.
1543 /// \param TaskTVar Variable for task_t argument.
1544 /// \param InnermostKind Kind of innermost directive (for simple directives it
1545 /// is a directive itself, for combined - its innermost directive).
1546 /// \param CodeGen Code generation sequence for the \a D directive.
1547 /// \param Tied true if task is generated for tied task, false otherwise.
1548 /// \param NumberOfParts Number of parts in untied task. Ignored for tied
1549 /// tasks.
1550 ///
1551 llvm::Value *emitTaskOutlinedFunction(
1552 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1553 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
1554 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1555 bool Tied, unsigned &NumberOfParts) override;
1556
1557 /// \brief Emits code for parallel or serial call of the \a OutlinedFn with
1558 /// variables captured in a record which address is stored in \a
1559 /// CapturedStruct.
1560 /// \param OutlinedFn Outlined function to be run in parallel threads. Type of
1561 /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
1562 /// \param CapturedVars A pointer to the record with the references to
1563 /// variables used in \a OutlinedFn function.
1564 /// \param IfCond Condition in the associated 'if' clause, if it was
1565 /// specified, nullptr otherwise.
1566 ///
1567 void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
1568 llvm::Value *OutlinedFn,
1569 ArrayRef<llvm::Value *> CapturedVars,
1570 const Expr *IfCond) override;
1571
1572 /// \brief Emits a critical region.
1573 /// \param CriticalName Name of the critical region.
1574 /// \param CriticalOpGen Generator for the statement associated with the given
1575 /// critical region.
1576 /// \param Hint Value of the 'hint' clause (optional).
1577 void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName,
1578 const RegionCodeGenTy &CriticalOpGen,
1579 SourceLocation Loc,
1580 const Expr *Hint = nullptr) override;
1581
1582 /// \brief Emits a master region.
1583 /// \param MasterOpGen Generator for the statement associated with the given
1584 /// master region.
1585 void emitMasterRegion(CodeGenFunction &CGF,
1586 const RegionCodeGenTy &MasterOpGen,
1587 SourceLocation Loc) override;
1588
1589 /// \brief Emits code for a taskyield directive.
1590 void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc) override;
1591
1592 /// \brief Emit a taskgroup region.
1593 /// \param TaskgroupOpGen Generator for the statement associated with the
1594 /// given taskgroup region.
1595 void emitTaskgroupRegion(CodeGenFunction &CGF,
1596 const RegionCodeGenTy &TaskgroupOpGen,
1597 SourceLocation Loc) override;
1598
1599 /// \brief Emits a single region.
1600 /// \param SingleOpGen Generator for the statement associated with the given
1601 /// single region.
1602 void emitSingleRegion(CodeGenFunction &CGF,
1603 const RegionCodeGenTy &SingleOpGen, SourceLocation Loc,
1604 ArrayRef<const Expr *> CopyprivateVars,
1605 ArrayRef<const Expr *> DestExprs,
1606 ArrayRef<const Expr *> SrcExprs,
1607 ArrayRef<const Expr *> AssignmentOps) override;
1608
1609 /// \brief Emit an ordered region.
1610 /// \param OrderedOpGen Generator for the statement associated with the given
1611 /// ordered region.
1612 void emitOrderedRegion(CodeGenFunction &CGF,
1613 const RegionCodeGenTy &OrderedOpGen,
1614 SourceLocation Loc, bool IsThreads) override;
1615
1616 /// \brief Emit an implicit/explicit barrier for OpenMP threads.
1617 /// \param Kind Directive for which this implicit barrier call must be
1618 /// generated. Must be OMPD_barrier for explicit barrier generation.
1619 /// \param EmitChecks true if need to emit checks for cancellation barriers.
1620 /// \param ForceSimpleCall true simple barrier call must be emitted, false if
1621 /// runtime class decides which one to emit (simple or with cancellation
1622 /// checks).
1623 ///
1624 void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
1625 OpenMPDirectiveKind Kind, bool EmitChecks = true,
1626 bool ForceSimpleCall = false) override;
1627
1628 /// This is used for non static scheduled types and when the ordered
1629 /// clause is present on the loop construct.
1630 /// Depending on the loop schedule, it is necessary to call some runtime
1631 /// routine before start of the OpenMP loop to get the loop upper / lower
1632 /// bounds \a LB and \a UB and stride \a ST.
1633 ///
1634 /// \param CGF Reference to current CodeGenFunction.
1635 /// \param Loc Clang source location.
1636 /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
1637 /// \param IVSize Size of the iteration variable in bits.
1638 /// \param IVSigned Sign of the iteration variable.
1639 /// \param Ordered true if loop is ordered, false otherwise.
1640 /// \param DispatchValues struct containing llvm values for lower bound, upper
1641 /// bound, and chunk expression.
1642 /// For the default (nullptr) value, the chunk 1 will be used.
1643 ///
1644 void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc,
1645 const OpenMPScheduleTy &ScheduleKind,
1646 unsigned IVSize, bool IVSigned, bool Ordered,
1647 const DispatchRTInput &DispatchValues) override;
1648
1649 /// \brief Call the appropriate runtime routine to initialize it before start
1650 /// of loop.
1651 ///
1652 /// This is used only in case of static schedule, when the user did not
1653 /// specify a ordered clause on the loop construct.
1654 /// Depending on the loop schedule, it is necessary to call some runtime
1655 /// routine before start of the OpenMP loop to get the loop upper / lower
1656 /// bounds LB and UB and stride ST.
1657 ///
1658 /// \param CGF Reference to current CodeGenFunction.
1659 /// \param Loc Clang source location.
1660 /// \param DKind Kind of the directive.
1661 /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
1662 /// \param Values Input arguments for the construct.
1663 ///
1664 void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
1665 OpenMPDirectiveKind DKind,
1666 const OpenMPScheduleTy &ScheduleKind,
1667 const StaticRTInput &Values) override;
1668
1669 ///
1670 /// \param CGF Reference to current CodeGenFunction.
1671 /// \param Loc Clang source location.
1672 /// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause.
1673 /// \param Values Input arguments for the construct.
1674 ///
1675 void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
1676 OpenMPDistScheduleClauseKind SchedKind,
1677 const StaticRTInput &Values) override;
1678
1679 /// \brief Call the appropriate runtime routine to notify that we finished
1680 /// iteration of the ordered loop with the dynamic scheduling.
1681 ///
1682 /// \param CGF Reference to current CodeGenFunction.
1683 /// \param Loc Clang source location.
1684 /// \param IVSize Size of the iteration variable in bits.
1685 /// \param IVSigned Sign of the iteration variable.
1686 ///
1687 void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc,
1688 unsigned IVSize, bool IVSigned) override;
1689
1690 /// \brief Call the appropriate runtime routine to notify that we finished
1691 /// all the work with current loop.
1692 ///
1693 /// \param CGF Reference to current CodeGenFunction.
1694 /// \param Loc Clang source location.
1695 /// \param DKind Kind of the directive for which the static finish is emitted.
1696 ///
1697 void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc,
1698 OpenMPDirectiveKind DKind) override;
1699
1700 /// Call __kmpc_dispatch_next(
1701 /// ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
1702 /// kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
1703 /// kmp_int[32|64] *p_stride);
1704 /// \param IVSize Size of the iteration variable in bits.
1705 /// \param IVSigned Sign of the iteration variable.
1706 /// \param IL Address of the output variable in which the flag of the
1707 /// last iteration is returned.
1708 /// \param LB Address of the output variable in which the lower iteration
1709 /// number is returned.
1710 /// \param UB Address of the output variable in which the upper iteration
1711 /// number is returned.
1712 /// \param ST Address of the output variable in which the stride value is
1713 /// returned.
1714 llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc,
1715 unsigned IVSize, bool IVSigned, Address IL,
1716 Address LB, Address UB, Address ST) override;
1717
1718 /// \brief Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
1719 /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
1720 /// clause.
1721 /// \param NumThreads An integer value of threads.
1722 void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads,
1723 SourceLocation Loc) override;
1724
1725 /// \brief Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32
1726 /// global_tid, int proc_bind) to generate code for 'proc_bind' clause.
1727 void emitProcBindClause(CodeGenFunction &CGF,
1728 OpenMPProcBindClauseKind ProcBind,
1729 SourceLocation Loc) override;
1730
1731 /// \brief Returns address of the threadprivate variable for the current
1732 /// thread.
1733 /// \param VD Threadprivate variable.
1734 /// \param VDAddr Address of the global variable \a VD.
1735 /// \param Loc Location of the reference to threadprivate var.
1736 /// \return Address of the threadprivate variable for the current thread.
1737 Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD,
1738 Address VDAddr, SourceLocation Loc) override;
1739
1740 /// \brief Emit a code for initialization of threadprivate variable. It emits
1741 /// a call to runtime library which adds initial value to the newly created
1742 /// threadprivate variable (if it is not constant) and registers destructor
1743 /// for the variable (if any).
1744 /// \param VD Threadprivate variable.
1745 /// \param VDAddr Address of the global variable \a VD.
1746 /// \param Loc Location of threadprivate declaration.
1747 /// \param PerformInit true if initialization expression is not constant.
1748 llvm::Function *
1749 emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr,
1750 SourceLocation Loc, bool PerformInit,
1751 CodeGenFunction *CGF = nullptr) override;
1752
1753 /// Creates artificial threadprivate variable with name \p Name and type \p
1754 /// VarType.
1755 /// \param VarType Type of the artificial threadprivate variable.
1756 /// \param Name Name of the artificial threadprivate variable.
1757 Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
1758 QualType VarType,
1759 StringRef Name) override;
1760
1761 /// \brief Emit flush of the variables specified in 'omp flush' directive.
1762 /// \param Vars List of variables to flush.
1763 void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars,
1764 SourceLocation Loc) override;
1765
1766 /// \brief Emit task region for the task directive. The task region is
1767 /// emitted in several steps:
1768 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
1769 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1770 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
1771 /// function:
1772 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
1773 /// TaskFunction(gtid, tt->part_id, tt->shareds);
1774 /// return 0;
1775 /// }
1776 /// 2. Copy a list of shared variables to field shareds of the resulting
1777 /// structure kmp_task_t returned by the previous call (if any).
1778 /// 3. Copy a pointer to destructions function to field destructions of the
1779 /// resulting structure kmp_task_t.
1780 /// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid,
1781 /// kmp_task_t *new_task), where new_task is a resulting structure from
1782 /// previous items.
1783 /// \param D Current task directive.
1784 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
1785 /// /*part_id*/, captured_struct */*__context*/);
1786 /// \param SharedsTy A type which contains references the shared variables.
1787 /// \param Shareds Context with the list of shared variables from the \p
1788 /// TaskFunction.
1789 /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
1790 /// otherwise.
1791 /// \param Data Additional data for task generation like tiednsee, final
1792 /// state, list of privates etc.
1793 void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
1794 const OMPExecutableDirective &D, llvm::Value *TaskFunction,
1795 QualType SharedsTy, Address Shareds, const Expr *IfCond,
1796 const OMPTaskDataTy &Data) override;
1797
1798 /// Emit task region for the taskloop directive. The taskloop region is
1799 /// emitted in several steps:
1800 /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
1801 /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1802 /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
1803 /// function:
1804 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
1805 /// TaskFunction(gtid, tt->part_id, tt->shareds);
1806 /// return 0;
1807 /// }
1808 /// 2. Copy a list of shared variables to field shareds of the resulting
1809 /// structure kmp_task_t returned by the previous call (if any).
1810 /// 3. Copy a pointer to destructions function to field destructions of the
1811 /// resulting structure kmp_task_t.
1812 /// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t
1813 /// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int
1814 /// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task
1815 /// is a resulting structure from
1816 /// previous items.
1817 /// \param D Current task directive.
1818 /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
1819 /// /*part_id*/, captured_struct */*__context*/);
1820 /// \param SharedsTy A type which contains references the shared variables.
1821 /// \param Shareds Context with the list of shared variables from the \p
1822 /// TaskFunction.
1823 /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
1824 /// otherwise.
1825 /// \param Data Additional data for task generation like tiednsee, final
1826 /// state, list of privates etc.
1827 void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
1828 const OMPLoopDirective &D, llvm::Value *TaskFunction,
1829 QualType SharedsTy, Address Shareds, const Expr *IfCond,
1830 const OMPTaskDataTy &Data) override;
1831
1832 /// \brief Emit a code for reduction clause. Next code should be emitted for
1833 /// reduction:
1834 /// \code
1835 ///
1836 /// static kmp_critical_name lock = { 0 };
1837 ///
1838 /// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
1839 /// ...
1840 /// *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
1841 /// ...
1842 /// }
1843 ///
1844 /// ...
1845 /// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
1846 /// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
1847 /// RedList, reduce_func, &<lock>)) {
1848 /// case 1:
1849 /// ...
1850 /// <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
1851 /// ...
1852 /// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
1853 /// break;
1854 /// case 2:
1855 /// ...
1856 /// Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
1857 /// ...
1858 /// break;
1859 /// default:;
1860 /// }
1861 /// \endcode
1862 ///
1863 /// \param Privates List of private copies for original reduction arguments.
1864 /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
1865 /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
1866 /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
1867 /// or 'operator binop(LHS, RHS)'.
1868 /// \param Options List of options for reduction codegen:
1869 /// WithNowait true if parent directive has also nowait clause, false
1870 /// otherwise.
1871 /// SimpleReduction Emit reduction operation only. Used for omp simd
1872 /// directive on the host.
1873 /// ReductionKind The kind of reduction to perform.
1874 void emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
1875 ArrayRef<const Expr *> Privates,
1876 ArrayRef<const Expr *> LHSExprs,
1877 ArrayRef<const Expr *> RHSExprs,
1878 ArrayRef<const Expr *> ReductionOps,
1879 ReductionOptionsTy Options) override;
1880
1881 /// Emit a code for initialization of task reduction clause. Next code
1882 /// should be emitted for reduction:
1883 /// \code
1884 ///
1885 /// _task_red_item_t red_data[n];
1886 /// ...
1887 /// red_data[i].shar = &origs[i];
1888 /// red_data[i].size = sizeof(origs[i]);
1889 /// red_data[i].f_init = (void*)RedInit<i>;
1890 /// red_data[i].f_fini = (void*)RedDest<i>;
1891 /// red_data[i].f_comb = (void*)RedOp<i>;
1892 /// red_data[i].flags = <Flag_i>;
1893 /// ...
1894 /// void* tg1 = __kmpc_task_reduction_init(gtid, n, red_data);
1895 /// \endcode
1896 ///
1897 /// \param LHSExprs List of LHS in \a Data.ReductionOps reduction operations.
1898 /// \param RHSExprs List of RHS in \a Data.ReductionOps reduction operations.
1899 /// \param Data Additional data for task generation like tiedness, final
1900 /// state, list of privates, reductions etc.
1901 llvm::Value *emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc,
1902 ArrayRef<const Expr *> LHSExprs,
1903 ArrayRef<const Expr *> RHSExprs,
1904 const OMPTaskDataTy &Data) override;
1905
1906 /// Required to resolve existing problems in the runtime. Emits threadprivate
1907 /// variables to store the size of the VLAs/array sections for
1908 /// initializer/combiner/finalizer functions + emits threadprivate variable to
1909 /// store the pointer to the original reduction item for the custom
1910 /// initializer defined by declare reduction construct.
1911 /// \param RCG Allows to reuse an existing data for the reductions.
1912 /// \param N Reduction item for which fixups must be emitted.
1913 void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc,
1914 ReductionCodeGen &RCG, unsigned N) override;
1915
1916 /// Get the address of `void *` type of the privatue copy of the reduction
1917 /// item specified by the \p SharedLVal.
1918 /// \param ReductionsPtr Pointer to the reduction data returned by the
1919 /// emitTaskReductionInit function.
1920 /// \param SharedLVal Address of the original reduction item.
1921 Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc,
1922 llvm::Value *ReductionsPtr,
1923 LValue SharedLVal) override;
1924
1925 /// \brief Emit code for 'taskwait' directive.
1926 void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc) override;
1927
1928 /// \brief Emit code for 'cancellation point' construct.
1929 /// \param CancelRegion Region kind for which the cancellation point must be
1930 /// emitted.
1931 ///
1932 void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc,
1933 OpenMPDirectiveKind CancelRegion) override;
1934
1935 /// \brief Emit code for 'cancel' construct.
1936 /// \param IfCond Condition in the associated 'if' clause, if it was
1937 /// specified, nullptr otherwise.
1938 /// \param CancelRegion Region kind for which the cancel must be emitted.
1939 ///
1940 void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
1941 const Expr *IfCond,
1942 OpenMPDirectiveKind CancelRegion) override;
1943
1944 /// \brief Emit outilined function for 'target' directive.
1945 /// \param D Directive to emit.
1946 /// \param ParentName Name of the function that encloses the target region.
1947 /// \param OutlinedFn Outlined function value to be defined by this call.
1948 /// \param OutlinedFnID Outlined function ID value to be defined by this call.
1949 /// \param IsOffloadEntry True if the outlined function is an offload entry.
1950 /// \param CodeGen Code generation sequence for the \a D directive.
1951 /// An outlined function may not be an entry if, e.g. the if clause always
1952 /// evaluates to false.
1953 void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
1954 StringRef ParentName,
1955 llvm::Function *&OutlinedFn,
1956 llvm::Constant *&OutlinedFnID,
1957 bool IsOffloadEntry,
1958 const RegionCodeGenTy &CodeGen) override;
1959
1960 /// \brief Emit the target offloading code associated with \a D. The emitted
1961 /// code attempts offloading the execution to the device, an the event of
1962 /// a failure it executes the host version outlined in \a OutlinedFn.
1963 /// \param D Directive to emit.
1964 /// \param OutlinedFn Host version of the code to be offloaded.
1965 /// \param OutlinedFnID ID of host version of the code to be offloaded.
1966 /// \param IfCond Expression evaluated in if clause associated with the target
1967 /// directive, or null if no if clause is used.
1968 /// \param Device Expression evaluated in device clause associated with the
1969 /// target directive, or null if no device clause is used.
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001970 void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
1971 llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID,
Alexey Bataev8451efa2018-01-15 19:06:12 +00001972 const Expr *IfCond, const Expr *Device) override;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001973
1974 /// \brief Emit the target regions enclosed in \a GD function definition or
1975 /// the function itself in case it is a valid device function. Returns true if
1976 /// \a GD was dealt with successfully.
1977 /// \param GD Function to scan.
1978 bool emitTargetFunctions(GlobalDecl GD) override;
1979
1980 /// \brief Emit the global variable if it is a valid device global variable.
1981 /// Returns true if \a GD was dealt with successfully.
1982 /// \param GD Variable declaration to emit.
1983 bool emitTargetGlobalVariable(GlobalDecl GD) override;
1984
1985 /// \brief Emit the global \a GD if it is meaningful for the target. Returns
1986 /// if it was emitted successfully.
1987 /// \param GD Global to scan.
1988 bool emitTargetGlobal(GlobalDecl GD) override;
1989
1990 /// \brief Creates the offloading descriptor in the event any target region
1991 /// was emitted in the current module and return the function that registers
1992 /// it.
1993 llvm::Function *emitRegistrationFunction() override;
1994
1995 /// \brief Emits code for teams call of the \a OutlinedFn with
1996 /// variables captured in a record which address is stored in \a
1997 /// CapturedStruct.
1998 /// \param OutlinedFn Outlined function to be run by team masters. Type of
1999 /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
2000 /// \param CapturedVars A pointer to the record with the references to
2001 /// variables used in \a OutlinedFn function.
2002 ///
2003 void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
2004 SourceLocation Loc, llvm::Value *OutlinedFn,
2005 ArrayRef<llvm::Value *> CapturedVars) override;
2006
2007 /// \brief Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
2008 /// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code
2009 /// for num_teams clause.
2010 /// \param NumTeams An integer expression of teams.
2011 /// \param ThreadLimit An integer expression of threads.
2012 void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams,
2013 const Expr *ThreadLimit, SourceLocation Loc) override;
2014
2015 /// \brief Emit the target data mapping code associated with \a D.
2016 /// \param D Directive to emit.
2017 /// \param IfCond Expression evaluated in if clause associated with the
2018 /// target directive, or null if no device clause is used.
2019 /// \param Device Expression evaluated in device clause associated with the
2020 /// target directive, or null if no device clause is used.
2021 /// \param Info A record used to store information that needs to be preserved
2022 /// until the region is closed.
2023 void emitTargetDataCalls(CodeGenFunction &CGF,
2024 const OMPExecutableDirective &D, const Expr *IfCond,
2025 const Expr *Device, const RegionCodeGenTy &CodeGen,
2026 TargetDataInfo &Info) override;
2027
2028 /// \brief Emit the data mapping/movement code associated with the directive
2029 /// \a D that should be of the form 'target [{enter|exit} data | update]'.
2030 /// \param D Directive to emit.
2031 /// \param IfCond Expression evaluated in if clause associated with the target
2032 /// directive, or null if no if clause is used.
2033 /// \param Device Expression evaluated in device clause associated with the
2034 /// target directive, or null if no device clause is used.
2035 void emitTargetDataStandAloneCall(CodeGenFunction &CGF,
2036 const OMPExecutableDirective &D,
2037 const Expr *IfCond,
2038 const Expr *Device) override;
2039
2040 /// Emit initialization for doacross loop nesting support.
2041 /// \param D Loop-based construct used in doacross nesting construct.
2042 void emitDoacrossInit(CodeGenFunction &CGF,
2043 const OMPLoopDirective &D) override;
2044
2045 /// Emit code for doacross ordered directive with 'depend' clause.
2046 /// \param C 'depend' clause with 'sink|source' dependency kind.
2047 void emitDoacrossOrdered(CodeGenFunction &CGF,
2048 const OMPDependClause *C) override;
2049
2050 /// Translates the native parameter of outlined function if this is required
2051 /// for target.
2052 /// \param FD Field decl from captured record for the paramater.
2053 /// \param NativeParam Parameter itself.
2054 const VarDecl *translateParameter(const FieldDecl *FD,
2055 const VarDecl *NativeParam) const override;
2056
2057 /// Gets the address of the native argument basing on the address of the
2058 /// target-specific parameter.
2059 /// \param NativeParam Parameter itself.
2060 /// \param TargetParam Corresponding target-specific parameter.
2061 Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam,
2062 const VarDecl *TargetParam) const override;
2063};
2064
Alexey Bataev23b69422014-06-18 07:08:49 +00002065} // namespace CodeGen
2066} // namespace clang
Alexey Bataev9959db52014-05-06 10:08:46 +00002067
2068#endif