1 //===----- 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 
14 #ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
15 #define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
16 
17 #include "CGValue.h"
18 #include "clang/AST/Type.h"
19 #include "clang/Basic/OpenMPKinds.h"
20 #include "clang/Basic/SourceLocation.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/StringMap.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/ValueHandle.h"
26 
27 namespace llvm {
28 class ArrayType;
29 class Constant;
30 class FunctionType;
31 class GlobalVariable;
32 class StructType;
33 class Type;
34 class Value;
35 } // namespace llvm
36 
37 namespace clang {
38 class Expr;
39 class GlobalDecl;
40 class OMPDependClause;
41 class OMPExecutableDirective;
42 class OMPLoopDirective;
43 class VarDecl;
44 class OMPDeclareReductionDecl;
45 class IdentifierInfo;
46 
47 namespace CodeGen {
48 class Address;
49 class CodeGenFunction;
50 class CodeGenModule;
51 
52 /// A basic class for pre|post-action for advanced codegen sequence for OpenMP
53 /// region.
54 class PrePostActionTy {
55 public:
56   explicit PrePostActionTy() {}
57   virtual void Enter(CodeGenFunction &CGF) {}
58   virtual void Exit(CodeGenFunction &CGF) {}
59   virtual ~PrePostActionTy() {}
60 };
61 
62 /// Class provides a way to call simple version of codegen for OpenMP region, or
63 /// an advanced with possible pre|post-actions in codegen.
64 class RegionCodeGenTy final {
65   intptr_t CodeGen;
66   typedef void (*CodeGenTy)(intptr_t, CodeGenFunction &, PrePostActionTy &);
67   CodeGenTy Callback;
68   mutable PrePostActionTy *PrePostAction;
69   RegionCodeGenTy() = delete;
70   RegionCodeGenTy &operator=(const RegionCodeGenTy &) = delete;
71   template <typename Callable>
72   static void CallbackFn(intptr_t CodeGen, CodeGenFunction &CGF,
73                          PrePostActionTy &Action) {
74     return (*reinterpret_cast<Callable *>(CodeGen))(CGF, Action);
75   }
76 
77 public:
78   template <typename Callable>
79   RegionCodeGenTy(
80       Callable &&CodeGen,
81       typename std::enable_if<
82           !std::is_same<typename std::remove_reference<Callable>::type,
83                         RegionCodeGenTy>::value>::type * = nullptr)
84       : CodeGen(reinterpret_cast<intptr_t>(&CodeGen)),
85         Callback(CallbackFn<typename std::remove_reference<Callable>::type>),
86         PrePostAction(nullptr) {}
87   void setAction(PrePostActionTy &Action) const { PrePostAction = &Action; }
88   void operator()(CodeGenFunction &CGF) const;
89 };
90 
91 struct OMPTaskDataTy final {
92   SmallVector<const Expr *, 4> PrivateVars;
93   SmallVector<const Expr *, 4> PrivateCopies;
94   SmallVector<const Expr *, 4> FirstprivateVars;
95   SmallVector<const Expr *, 4> FirstprivateCopies;
96   SmallVector<const Expr *, 4> FirstprivateInits;
97   SmallVector<const Expr *, 4> LastprivateVars;
98   SmallVector<const Expr *, 4> LastprivateCopies;
99   SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 4> Dependences;
100   llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
101   llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule;
102   llvm::PointerIntPair<llvm::Value *, 1, bool> Priority;
103   unsigned NumberOfParts = 0;
104   bool Tied = true;
105   bool Nogroup = false;
106 };
107 
108 class CGOpenMPRuntime {
109 protected:
110   CodeGenModule &CGM;
111 
112   /// \brief Creates offloading entry for the provided entry ID \a ID,
113   /// address \a Addr, size \a Size, and flags \a Flags.
114   virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr,
115                                   uint64_t Size, int32_t Flags = 0);
116 
117   /// \brief Helper to emit outlined function for 'target' directive.
118   /// \param D Directive to emit.
119   /// \param ParentName Name of the function that encloses the target region.
120   /// \param OutlinedFn Outlined function value to be defined by this call.
121   /// \param OutlinedFnID Outlined function ID value to be defined by this call.
122   /// \param IsOffloadEntry True if the outlined function is an offload entry.
123   /// \param CodeGen Lambda codegen specific to an accelerator device.
124   /// An oulined function may not be an entry if, e.g. the if clause always
125   /// evaluates to false.
126   virtual void emitTargetOutlinedFunctionHelper(const OMPExecutableDirective &D,
127                                                 StringRef ParentName,
128                                                 llvm::Function *&OutlinedFn,
129                                                 llvm::Constant *&OutlinedFnID,
130                                                 bool IsOffloadEntry,
131                                                 const RegionCodeGenTy &CodeGen);
132 
133   /// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
134   /// function. Here is the logic:
135   /// if (Cond) {
136   ///   ThenGen();
137   /// } else {
138   ///   ElseGen();
139   /// }
140   void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
141                        const RegionCodeGenTy &ThenGen,
142                        const RegionCodeGenTy &ElseGen);
143 
144   /// \brief Emits object of ident_t type with info for source location.
145   /// \param Flags Flags for OpenMP location.
146   ///
147   llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
148                                   unsigned Flags = 0);
149 
150   /// \brief Returns pointer to ident_t type.
151   llvm::Type *getIdentTyPointerTy();
152 
153   /// \brief Gets thread id value for the current thread.
154   ///
155   llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc);
156 
157   /// \brief Get the function name of an outlined region.
158   //  The name can be customized depending on the target.
159   //
160   virtual StringRef getOutlinedHelperName() const { return ".omp_outlined."; }
161 
162 private:
163   /// \brief Default const ident_t object used for initialization of all other
164   /// ident_t objects.
165   llvm::Constant *DefaultOpenMPPSource = nullptr;
166   /// \brief Map of flags and corresponding default locations.
167   typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDefaultLocMapTy;
168   OpenMPDefaultLocMapTy OpenMPDefaultLocMap;
169   Address getOrCreateDefaultLocation(unsigned Flags);
170 
171   llvm::StructType *IdentTy = nullptr;
172   /// \brief Map for SourceLocation and OpenMP runtime library debug locations.
173   typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy;
174   OpenMPDebugLocMapTy OpenMPDebugLocMap;
175   /// \brief The type for a microtask which gets passed to __kmpc_fork_call().
176   /// Original representation is:
177   /// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...);
178   llvm::FunctionType *Kmpc_MicroTy = nullptr;
179   /// \brief Stores debug location and ThreadID for the function.
180   struct DebugLocThreadIdTy {
181     llvm::Value *DebugLoc;
182     llvm::Value *ThreadID;
183   };
184   /// \brief Map of local debug location, ThreadId and functions.
185   typedef llvm::DenseMap<llvm::Function *, DebugLocThreadIdTy>
186       OpenMPLocThreadIDMapTy;
187   OpenMPLocThreadIDMapTy OpenMPLocThreadIDMap;
188   /// Map of UDRs and corresponding combiner/initializer.
189   typedef llvm::DenseMap<const OMPDeclareReductionDecl *,
190                          std::pair<llvm::Function *, llvm::Function *>>
191       UDRMapTy;
192   UDRMapTy UDRMap;
193   /// Map of functions and locally defined UDRs.
194   typedef llvm::DenseMap<llvm::Function *,
195                          SmallVector<const OMPDeclareReductionDecl *, 4>>
196       FunctionUDRMapTy;
197   FunctionUDRMapTy FunctionUDRMap;
198   IdentifierInfo *In = nullptr;
199   IdentifierInfo *Out = nullptr;
200   IdentifierInfo *Priv = nullptr;
201   IdentifierInfo *Orig = nullptr;
202   /// \brief Type kmp_critical_name, originally defined as typedef kmp_int32
203   /// kmp_critical_name[8];
204   llvm::ArrayType *KmpCriticalNameTy;
205   /// \brief An ordered map of auto-generated variables to their unique names.
206   /// It stores variables with the following names: 1) ".gomp_critical_user_" +
207   /// <critical_section_name> + ".var" for "omp critical" directives; 2)
208   /// <mangled_name_for_global_var> + ".cache." for cache for threadprivate
209   /// variables.
210   llvm::StringMap<llvm::AssertingVH<llvm::Constant>, llvm::BumpPtrAllocator>
211       InternalVars;
212   /// \brief Type typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *);
213   llvm::Type *KmpRoutineEntryPtrTy = nullptr;
214   QualType KmpRoutineEntryPtrQTy;
215   /// \brief Type typedef struct kmp_task {
216   ///    void *              shareds; /**< pointer to block of pointers to
217   ///    shared vars   */
218   ///    kmp_routine_entry_t routine; /**< pointer to routine to call for
219   ///    executing task */
220   ///    kmp_int32           part_id; /**< part id for the task */
221   ///    kmp_routine_entry_t destructors; /* pointer to function to invoke
222   ///    deconstructors of firstprivate C++ objects */
223   /// } kmp_task_t;
224   QualType KmpTaskTQTy;
225   /// \brief Type typedef struct kmp_depend_info {
226   ///    kmp_intptr_t               base_addr;
227   ///    size_t                     len;
228   ///    struct {
229   ///             bool                   in:1;
230   ///             bool                   out:1;
231   ///    } flags;
232   /// } kmp_depend_info_t;
233   QualType KmpDependInfoTy;
234   /// struct kmp_dim {  // loop bounds info casted to kmp_int64
235   ///  kmp_int64 lo; // lower
236   ///  kmp_int64 up; // upper
237   ///  kmp_int64 st; // stride
238   /// };
239   QualType KmpDimTy;
240   /// \brief Type struct __tgt_offload_entry{
241   ///   void      *addr;       // Pointer to the offload entry info.
242   ///                          // (function or global)
243   ///   char      *name;       // Name of the function or global.
244   ///   size_t     size;       // Size of the entry info (0 if it a function).
245   /// };
246   QualType TgtOffloadEntryQTy;
247   /// struct __tgt_device_image{
248   /// void   *ImageStart;       // Pointer to the target code start.
249   /// void   *ImageEnd;         // Pointer to the target code end.
250   /// // We also add the host entries to the device image, as it may be useful
251   /// // for the target runtime to have access to that information.
252   /// __tgt_offload_entry  *EntriesBegin;   // Begin of the table with all
253   ///                                       // the entries.
254   /// __tgt_offload_entry  *EntriesEnd;     // End of the table with all the
255   ///                                       // entries (non inclusive).
256   /// };
257   QualType TgtDeviceImageQTy;
258   /// struct __tgt_bin_desc{
259   ///   int32_t              NumDevices;      // Number of devices supported.
260   ///   __tgt_device_image   *DeviceImages;   // Arrays of device images
261   ///                                         // (one per device).
262   ///   __tgt_offload_entry  *EntriesBegin;   // Begin of the table with all the
263   ///                                         // entries.
264   ///   __tgt_offload_entry  *EntriesEnd;     // End of the table with all the
265   ///                                         // entries (non inclusive).
266   /// };
267   QualType TgtBinaryDescriptorQTy;
268   /// \brief Entity that registers the offloading constants that were emitted so
269   /// far.
270   class OffloadEntriesInfoManagerTy {
271     CodeGenModule &CGM;
272 
273     /// \brief Number of entries registered so far.
274     unsigned OffloadingEntriesNum;
275 
276   public:
277     /// Base class of the entries info.
278     class OffloadEntryInfo {
279     public:
280       /// Kind of a given entry. Currently, only target regions are
281       /// supported.
282       enum OffloadingEntryInfoKinds : unsigned {
283         // Entry is a target region.
284         OFFLOAD_ENTRY_INFO_TARGET_REGION = 0,
285         // Invalid entry info.
286         OFFLOAD_ENTRY_INFO_INVALID = ~0u
287       };
288 
289       OffloadEntryInfo()
290           : Flags(0), Order(~0u), Kind(OFFLOAD_ENTRY_INFO_INVALID) {}
291       explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order,
292                                 int32_t Flags)
293           : Flags(Flags), Order(Order), Kind(Kind) {}
294 
295       bool isValid() const { return Order != ~0u; }
296       unsigned getOrder() const { return Order; }
297       OffloadingEntryInfoKinds getKind() const { return Kind; }
298       int32_t getFlags() const { return Flags; }
299       void setFlags(int32_t NewFlags) { Flags = NewFlags; }
300       static bool classof(const OffloadEntryInfo *Info) { return true; }
301 
302     private:
303       /// Flags associated with the device global.
304       int32_t Flags;
305 
306       /// Order this entry was emitted.
307       unsigned Order;
308 
309       OffloadingEntryInfoKinds Kind;
310     };
311 
312     /// \brief Return true if a there are no entries defined.
313     bool empty() const;
314     /// \brief Return number of entries defined so far.
315     unsigned size() const { return OffloadingEntriesNum; }
316     OffloadEntriesInfoManagerTy(CodeGenModule &CGM)
317         : CGM(CGM), OffloadingEntriesNum(0) {}
318 
319     ///
320     /// Target region entries related.
321     ///
322     /// \brief Target region entries info.
323     class OffloadEntryInfoTargetRegion : public OffloadEntryInfo {
324       // \brief Address of the entity that has to be mapped for offloading.
325       llvm::Constant *Addr;
326       // \brief Address that can be used as the ID of the entry.
327       llvm::Constant *ID;
328 
329     public:
330       OffloadEntryInfoTargetRegion()
331           : OffloadEntryInfo(OFFLOAD_ENTRY_INFO_TARGET_REGION, ~0u,
332                              /*Flags=*/0),
333             Addr(nullptr), ID(nullptr) {}
334       explicit OffloadEntryInfoTargetRegion(unsigned Order,
335                                             llvm::Constant *Addr,
336                                             llvm::Constant *ID, int32_t Flags)
337           : OffloadEntryInfo(OFFLOAD_ENTRY_INFO_TARGET_REGION, Order, Flags),
338             Addr(Addr), ID(ID) {}
339 
340       llvm::Constant *getAddress() const { return Addr; }
341       llvm::Constant *getID() const { return ID; }
342       void setAddress(llvm::Constant *V) {
343         assert(!Addr && "Address as been set before!");
344         Addr = V;
345       }
346       void setID(llvm::Constant *V) {
347         assert(!ID && "ID as been set before!");
348         ID = V;
349       }
350       static bool classof(const OffloadEntryInfo *Info) {
351         return Info->getKind() == OFFLOAD_ENTRY_INFO_TARGET_REGION;
352       }
353     };
354     /// \brief Initialize target region entry.
355     void initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
356                                          StringRef ParentName, unsigned LineNum,
357                                          unsigned Order);
358     /// \brief Register target region entry.
359     void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
360                                        StringRef ParentName, unsigned LineNum,
361                                        llvm::Constant *Addr, llvm::Constant *ID,
362                                        int32_t Flags);
363     /// \brief Return true if a target region entry with the provided
364     /// information exists.
365     bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
366                                   StringRef ParentName, unsigned LineNum) const;
367     /// brief Applies action \a Action on all registered entries.
368     typedef llvm::function_ref<void(unsigned, unsigned, StringRef, unsigned,
369                                     OffloadEntryInfoTargetRegion &)>
370         OffloadTargetRegionEntryInfoActTy;
371     void actOnTargetRegionEntriesInfo(
372         const OffloadTargetRegionEntryInfoActTy &Action);
373 
374   private:
375     // Storage for target region entries kind. The storage is to be indexed by
376     // file ID, device ID, parent function name and line number.
377     typedef llvm::DenseMap<unsigned, OffloadEntryInfoTargetRegion>
378         OffloadEntriesTargetRegionPerLine;
379     typedef llvm::StringMap<OffloadEntriesTargetRegionPerLine>
380         OffloadEntriesTargetRegionPerParentName;
381     typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerParentName>
382         OffloadEntriesTargetRegionPerFile;
383     typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerFile>
384         OffloadEntriesTargetRegionPerDevice;
385     typedef OffloadEntriesTargetRegionPerDevice OffloadEntriesTargetRegionTy;
386     OffloadEntriesTargetRegionTy OffloadEntriesTargetRegion;
387   };
388   OffloadEntriesInfoManagerTy OffloadEntriesInfoManager;
389 
390   /// \brief Creates and registers offloading binary descriptor for the current
391   /// compilation unit. The function that does the registration is returned.
392   llvm::Function *createOffloadingBinaryDescriptorRegistration();
393 
394   /// \brief Creates all the offload entries in the current compilation unit
395   /// along with the associated metadata.
396   void createOffloadEntriesAndInfoMetadata();
397 
398   /// \brief Loads all the offload entries information from the host IR
399   /// metadata.
400   void loadOffloadInfoMetadata();
401 
402   /// \brief Returns __tgt_offload_entry type.
403   QualType getTgtOffloadEntryQTy();
404 
405   /// \brief Returns __tgt_device_image type.
406   QualType getTgtDeviceImageQTy();
407 
408   /// \brief Returns __tgt_bin_desc type.
409   QualType getTgtBinaryDescriptorQTy();
410 
411   /// \brief Start scanning from statement \a S and and emit all target regions
412   /// found along the way.
413   /// \param S Starting statement.
414   /// \param ParentName Name of the function declaration that is being scanned.
415   void scanForTargetRegionsFunctions(const Stmt *S, StringRef ParentName);
416 
417   /// \brief Build type kmp_routine_entry_t (if not built yet).
418   void emitKmpRoutineEntryT(QualType KmpInt32Ty);
419 
420   /// \brief Returns pointer to kmpc_micro type.
421   llvm::Type *getKmpc_MicroPointerTy();
422 
423   /// \brief Returns specified OpenMP runtime function.
424   /// \param Function OpenMP runtime function.
425   /// \return Specified function.
426   llvm::Constant *createRuntimeFunction(unsigned Function);
427 
428   /// \brief Returns __kmpc_for_static_init_* runtime function for the specified
429   /// size \a IVSize and sign \a IVSigned.
430   llvm::Constant *createForStaticInitFunction(unsigned IVSize, bool IVSigned);
431 
432   /// \brief Returns __kmpc_dispatch_init_* runtime function for the specified
433   /// size \a IVSize and sign \a IVSigned.
434   llvm::Constant *createDispatchInitFunction(unsigned IVSize, bool IVSigned);
435 
436   /// \brief Returns __kmpc_dispatch_next_* runtime function for the specified
437   /// size \a IVSize and sign \a IVSigned.
438   llvm::Constant *createDispatchNextFunction(unsigned IVSize, bool IVSigned);
439 
440   /// \brief Returns __kmpc_dispatch_fini_* runtime function for the specified
441   /// size \a IVSize and sign \a IVSigned.
442   llvm::Constant *createDispatchFiniFunction(unsigned IVSize, bool IVSigned);
443 
444   /// \brief If the specified mangled name is not in the module, create and
445   /// return threadprivate cache object. This object is a pointer's worth of
446   /// storage that's reserved for use by the OpenMP runtime.
447   /// \param VD Threadprivate variable.
448   /// \return Cache variable for the specified threadprivate.
449   llvm::Constant *getOrCreateThreadPrivateCache(const VarDecl *VD);
450 
451   /// \brief Emits address of the word in a memory where current thread id is
452   /// stored.
453   virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc);
454 
455   /// \brief Gets (if variable with the given name already exist) or creates
456   /// internal global variable with the specified Name. The created variable has
457   /// linkage CommonLinkage by default and is initialized by null value.
458   /// \param Ty Type of the global variable. If it is exist already the type
459   /// must be the same.
460   /// \param Name Name of the variable.
461   llvm::Constant *getOrCreateInternalVariable(llvm::Type *Ty,
462                                               const llvm::Twine &Name);
463 
464   /// \brief Set of threadprivate variables with the generated initializer.
465   llvm::SmallPtrSet<const VarDecl *, 4> ThreadPrivateWithDefinition;
466 
467   /// \brief Emits initialization code for the threadprivate variables.
468   /// \param VDAddr Address of the global variable \a VD.
469   /// \param Ctor Pointer to a global init function for \a VD.
470   /// \param CopyCtor Pointer to a global copy function for \a VD.
471   /// \param Dtor Pointer to a global destructor function for \a VD.
472   /// \param Loc Location of threadprivate declaration.
473   void emitThreadPrivateVarInit(CodeGenFunction &CGF, Address VDAddr,
474                                 llvm::Value *Ctor, llvm::Value *CopyCtor,
475                                 llvm::Value *Dtor, SourceLocation Loc);
476 
477   /// \brief Returns corresponding lock object for the specified critical region
478   /// name. If the lock object does not exist it is created, otherwise the
479   /// reference to the existing copy is returned.
480   /// \param CriticalName Name of the critical region.
481   ///
482   llvm::Value *getCriticalRegionLock(StringRef CriticalName);
483 
484   struct TaskResultTy {
485     llvm::Value *NewTask = nullptr;
486     llvm::Value *TaskEntry = nullptr;
487     llvm::Value *NewTaskNewTaskTTy = nullptr;
488     LValue TDBase;
489     RecordDecl *KmpTaskTQTyRD = nullptr;
490     llvm::Value *TaskDupFn = nullptr;
491   };
492   /// Emit task region for the task directive. The task region is emitted in
493   /// several steps:
494   /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
495   /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
496   /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
497   /// function:
498   /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
499   ///   TaskFunction(gtid, tt->part_id, tt->shareds);
500   ///   return 0;
501   /// }
502   /// 2. Copy a list of shared variables to field shareds of the resulting
503   /// structure kmp_task_t returned by the previous call (if any).
504   /// 3. Copy a pointer to destructions function to field destructions of the
505   /// resulting structure kmp_task_t.
506   /// \param D Current task directive.
507   /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
508   /// /*part_id*/, captured_struct */*__context*/);
509   /// \param SharedsTy A type which contains references the shared variables.
510   /// \param Shareds Context with the list of shared variables from the \p
511   /// TaskFunction.
512   /// \param Data Additional data for task generation like tiednsee, final
513   /// state, list of privates etc.
514   TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
515                             const OMPExecutableDirective &D,
516                             llvm::Value *TaskFunction, QualType SharedsTy,
517                             Address Shareds, const OMPTaskDataTy &Data);
518 
519 public:
520   explicit CGOpenMPRuntime(CodeGenModule &CGM);
521   virtual ~CGOpenMPRuntime() {}
522   virtual void clear();
523 
524   /// Emit code for the specified user defined reduction construct.
525   virtual void emitUserDefinedReduction(CodeGenFunction *CGF,
526                                         const OMPDeclareReductionDecl *D);
527   /// Get combiner/initializer for the specified user-defined reduction, if any.
528   virtual std::pair<llvm::Function *, llvm::Function *>
529   getUserDefinedReduction(const OMPDeclareReductionDecl *D);
530 
531   /// \brief Emits outlined function for the specified OpenMP parallel directive
532   /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
533   /// kmp_int32 BoundID, struct context_vars*).
534   /// \param D OpenMP directive.
535   /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
536   /// \param InnermostKind Kind of innermost directive (for simple directives it
537   /// is a directive itself, for combined - its innermost directive).
538   /// \param CodeGen Code generation sequence for the \a D directive.
539   virtual llvm::Value *emitParallelOutlinedFunction(
540       const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
541       OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
542 
543   /// \brief Emits outlined function for the specified OpenMP teams directive
544   /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
545   /// kmp_int32 BoundID, struct context_vars*).
546   /// \param D OpenMP directive.
547   /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
548   /// \param InnermostKind Kind of innermost directive (for simple directives it
549   /// is a directive itself, for combined - its innermost directive).
550   /// \param CodeGen Code generation sequence for the \a D directive.
551   virtual llvm::Value *emitTeamsOutlinedFunction(
552       const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
553       OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
554 
555   /// \brief Emits outlined function for the OpenMP task directive \a D. This
556   /// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t*
557   /// TaskT).
558   /// \param D OpenMP directive.
559   /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
560   /// \param PartIDVar Variable for partition id in the current OpenMP untied
561   /// task region.
562   /// \param TaskTVar Variable for task_t argument.
563   /// \param InnermostKind Kind of innermost directive (for simple directives it
564   /// is a directive itself, for combined - its innermost directive).
565   /// \param CodeGen Code generation sequence for the \a D directive.
566   /// \param Tied true if task is generated for tied task, false otherwise.
567   /// \param NumberOfParts Number of parts in untied task. Ignored for tied
568   /// tasks.
569   ///
570   virtual llvm::Value *emitTaskOutlinedFunction(
571       const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
572       const VarDecl *PartIDVar, const VarDecl *TaskTVar,
573       OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
574       bool Tied, unsigned &NumberOfParts);
575 
576   /// \brief Cleans up references to the objects in finished function.
577   ///
578   void functionFinished(CodeGenFunction &CGF);
579 
580   /// \brief Emits code for parallel or serial call of the \a OutlinedFn with
581   /// variables captured in a record which address is stored in \a
582   /// CapturedStruct.
583   /// \param OutlinedFn Outlined function to be run in parallel threads. Type of
584   /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
585   /// \param CapturedVars A pointer to the record with the references to
586   /// variables used in \a OutlinedFn function.
587   /// \param IfCond Condition in the associated 'if' clause, if it was
588   /// specified, nullptr otherwise.
589   ///
590   virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
591                                 llvm::Value *OutlinedFn,
592                                 ArrayRef<llvm::Value *> CapturedVars,
593                                 const Expr *IfCond);
594 
595   /// \brief Emits a critical region.
596   /// \param CriticalName Name of the critical region.
597   /// \param CriticalOpGen Generator for the statement associated with the given
598   /// critical region.
599   /// \param Hint Value of the 'hint' clause (optional).
600   virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName,
601                                   const RegionCodeGenTy &CriticalOpGen,
602                                   SourceLocation Loc,
603                                   const Expr *Hint = nullptr);
604 
605   /// \brief Emits a master region.
606   /// \param MasterOpGen Generator for the statement associated with the given
607   /// master region.
608   virtual void emitMasterRegion(CodeGenFunction &CGF,
609                                 const RegionCodeGenTy &MasterOpGen,
610                                 SourceLocation Loc);
611 
612   /// \brief Emits code for a taskyield directive.
613   virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc);
614 
615   /// \brief Emit a taskgroup region.
616   /// \param TaskgroupOpGen Generator for the statement associated with the
617   /// given taskgroup region.
618   virtual void emitTaskgroupRegion(CodeGenFunction &CGF,
619                                    const RegionCodeGenTy &TaskgroupOpGen,
620                                    SourceLocation Loc);
621 
622   /// \brief Emits a single region.
623   /// \param SingleOpGen Generator for the statement associated with the given
624   /// single region.
625   virtual void emitSingleRegion(CodeGenFunction &CGF,
626                                 const RegionCodeGenTy &SingleOpGen,
627                                 SourceLocation Loc,
628                                 ArrayRef<const Expr *> CopyprivateVars,
629                                 ArrayRef<const Expr *> DestExprs,
630                                 ArrayRef<const Expr *> SrcExprs,
631                                 ArrayRef<const Expr *> AssignmentOps);
632 
633   /// \brief Emit an ordered region.
634   /// \param OrderedOpGen Generator for the statement associated with the given
635   /// ordered region.
636   virtual void emitOrderedRegion(CodeGenFunction &CGF,
637                                  const RegionCodeGenTy &OrderedOpGen,
638                                  SourceLocation Loc, bool IsThreads);
639 
640   /// \brief Emit an implicit/explicit barrier for OpenMP threads.
641   /// \param Kind Directive for which this implicit barrier call must be
642   /// generated. Must be OMPD_barrier for explicit barrier generation.
643   /// \param EmitChecks true if need to emit checks for cancellation barriers.
644   /// \param ForceSimpleCall true simple barrier call must be emitted, false if
645   /// runtime class decides which one to emit (simple or with cancellation
646   /// checks).
647   ///
648   virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
649                                OpenMPDirectiveKind Kind,
650                                bool EmitChecks = true,
651                                bool ForceSimpleCall = false);
652 
653   /// \brief Check if the specified \a ScheduleKind is static non-chunked.
654   /// This kind of worksharing directive is emitted without outer loop.
655   /// \param ScheduleKind Schedule kind specified in the 'schedule' clause.
656   /// \param Chunked True if chunk is specified in the clause.
657   ///
658   virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
659                                   bool Chunked) const;
660 
661   /// \brief Check if the specified \a ScheduleKind is static non-chunked.
662   /// This kind of distribute directive is emitted without outer loop.
663   /// \param ScheduleKind Schedule kind specified in the 'dist_schedule' clause.
664   /// \param Chunked True if chunk is specified in the clause.
665   ///
666   virtual bool isStaticNonchunked(OpenMPDistScheduleClauseKind ScheduleKind,
667                                   bool Chunked) const;
668 
669   /// \brief Check if the specified \a ScheduleKind is dynamic.
670   /// This kind of worksharing directive is emitted without outer loop.
671   /// \param ScheduleKind Schedule Kind specified in the 'schedule' clause.
672   ///
673   virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const;
674 
675   /// struct with the values to be passed to the dispatch runtime function
676   struct DispatchRTInput {
677     /// Loop lower bound
678     llvm::Value *LB = nullptr;
679     /// Loop upper bound
680     llvm::Value *UB = nullptr;
681     /// Chunk size specified using 'schedule' clause (nullptr if chunk
682     /// was not specified)
683     llvm::Value *Chunk = nullptr;
684     DispatchRTInput() = default;
685     DispatchRTInput(llvm::Value *LB, llvm::Value *UB, llvm::Value *Chunk)
686         : LB(LB), UB(UB), Chunk(Chunk) {}
687   };
688 
689   /// Call the appropriate runtime routine to initialize it before start
690   /// of loop.
691 
692   /// This is used for non static scheduled types and when the ordered
693   /// clause is present on the loop construct.
694   /// Depending on the loop schedule, it is necessary to call some runtime
695   /// routine before start of the OpenMP loop to get the loop upper / lower
696   /// bounds \a LB and \a UB and stride \a ST.
697   ///
698   /// \param CGF Reference to current CodeGenFunction.
699   /// \param Loc Clang source location.
700   /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
701   /// \param IVSize Size of the iteration variable in bits.
702   /// \param IVSigned Sign of the interation variable.
703   /// \param Ordered true if loop is ordered, false otherwise.
704   /// \param DispatchValues struct containing llvm values for lower bound, upper
705   /// bound, and chunk expression.
706   /// For the default (nullptr) value, the chunk 1 will be used.
707   ///
708   virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc,
709                                    const OpenMPScheduleTy &ScheduleKind,
710                                    unsigned IVSize, bool IVSigned, bool Ordered,
711                                    const DispatchRTInput &DispatchValues);
712 
713   /// \brief Call the appropriate runtime routine to initialize it before start
714   /// of loop.
715   ///
716   /// This is used only in case of static schedule, when the user did not
717   /// specify a ordered clause on the loop construct.
718   /// Depending on the loop schedule, it is necessary to call some runtime
719   /// routine before start of the OpenMP loop to get the loop upper / lower
720   /// bounds \a LB and \a UB and stride \a ST.
721   ///
722   /// \param CGF Reference to current CodeGenFunction.
723   /// \param Loc Clang source location.
724   /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
725   /// \param IVSize Size of the iteration variable in bits.
726   /// \param IVSigned Sign of the interation variable.
727   /// \param Ordered true if loop is ordered, false otherwise.
728   /// \param IL Address of the output variable in which the flag of the
729   /// last iteration is returned.
730   /// \param LB Address of the output variable in which the lower iteration
731   /// number is returned.
732   /// \param UB Address of the output variable in which the upper iteration
733   /// number is returned.
734   /// \param ST Address of the output variable in which the stride value is
735   /// returned nesessary to generated the static_chunked scheduled loop.
736   /// \param Chunk Value of the chunk for the static_chunked scheduled loop.
737   /// For the default (nullptr) value, the chunk 1 will be used.
738   ///
739   virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
740                                  const OpenMPScheduleTy &ScheduleKind,
741                                  unsigned IVSize, bool IVSigned, bool Ordered,
742                                  Address IL, Address LB, Address UB, Address ST,
743                                  llvm::Value *Chunk = nullptr);
744 
745   ///
746   /// \param CGF Reference to current CodeGenFunction.
747   /// \param Loc Clang source location.
748   /// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause.
749   /// \param IVSize Size of the iteration variable in bits.
750   /// \param IVSigned Sign of the interation variable.
751   /// \param Ordered true if loop is ordered, false otherwise.
752   /// \param IL Address of the output variable in which the flag of the
753   /// last iteration is returned.
754   /// \param LB Address of the output variable in which the lower iteration
755   /// number is returned.
756   /// \param UB Address of the output variable in which the upper iteration
757   /// number is returned.
758   /// \param ST Address of the output variable in which the stride value is
759   /// returned nesessary to generated the static_chunked scheduled loop.
760   /// \param Chunk Value of the chunk for the static_chunked scheduled loop.
761   /// For the default (nullptr) value, the chunk 1 will be used.
762   ///
763   virtual void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
764                                         OpenMPDistScheduleClauseKind SchedKind,
765                                         unsigned IVSize, bool IVSigned,
766                                         bool Ordered, Address IL, Address LB,
767                                         Address UB, Address ST,
768                                         llvm::Value *Chunk = nullptr);
769 
770   /// \brief Call the appropriate runtime routine to notify that we finished
771   /// iteration of the ordered loop with the dynamic scheduling.
772   ///
773   /// \param CGF Reference to current CodeGenFunction.
774   /// \param Loc Clang source location.
775   /// \param IVSize Size of the iteration variable in bits.
776   /// \param IVSigned Sign of the interation variable.
777   ///
778   virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF,
779                                           SourceLocation Loc, unsigned IVSize,
780                                           bool IVSigned);
781 
782   /// \brief Call the appropriate runtime routine to notify that we finished
783   /// all the work with current loop.
784   ///
785   /// \param CGF Reference to current CodeGenFunction.
786   /// \param Loc Clang source location.
787   ///
788   virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc);
789 
790   /// Call __kmpc_dispatch_next(
791   ///          ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
792   ///          kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
793   ///          kmp_int[32|64] *p_stride);
794   /// \param IVSize Size of the iteration variable in bits.
795   /// \param IVSigned Sign of the interation variable.
796   /// \param IL Address of the output variable in which the flag of the
797   /// last iteration is returned.
798   /// \param LB Address of the output variable in which the lower iteration
799   /// number is returned.
800   /// \param UB Address of the output variable in which the upper iteration
801   /// number is returned.
802   /// \param ST Address of the output variable in which the stride value is
803   /// returned.
804   virtual llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc,
805                                    unsigned IVSize, bool IVSigned,
806                                    Address IL, Address LB,
807                                    Address UB, Address ST);
808 
809   /// \brief Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
810   /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
811   /// clause.
812   /// \param NumThreads An integer value of threads.
813   virtual void emitNumThreadsClause(CodeGenFunction &CGF,
814                                     llvm::Value *NumThreads,
815                                     SourceLocation Loc);
816 
817   /// \brief Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32
818   /// global_tid, int proc_bind) to generate code for 'proc_bind' clause.
819   virtual void emitProcBindClause(CodeGenFunction &CGF,
820                                   OpenMPProcBindClauseKind ProcBind,
821                                   SourceLocation Loc);
822 
823   /// \brief Returns address of the threadprivate variable for the current
824   /// thread.
825   /// \param VD Threadprivate variable.
826   /// \param VDAddr Address of the global variable \a VD.
827   /// \param Loc Location of the reference to threadprivate var.
828   /// \return Address of the threadprivate variable for the current thread.
829   virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF,
830                                          const VarDecl *VD,
831                                          Address VDAddr,
832                                          SourceLocation Loc);
833 
834   /// \brief Emit a code for initialization of threadprivate variable. It emits
835   /// a call to runtime library which adds initial value to the newly created
836   /// threadprivate variable (if it is not constant) and registers destructor
837   /// for the variable (if any).
838   /// \param VD Threadprivate variable.
839   /// \param VDAddr Address of the global variable \a VD.
840   /// \param Loc Location of threadprivate declaration.
841   /// \param PerformInit true if initialization expression is not constant.
842   virtual llvm::Function *
843   emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr,
844                                  SourceLocation Loc, bool PerformInit,
845                                  CodeGenFunction *CGF = nullptr);
846 
847   /// \brief Emit flush of the variables specified in 'omp flush' directive.
848   /// \param Vars List of variables to flush.
849   virtual void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars,
850                          SourceLocation Loc);
851 
852   /// \brief Emit task region for the task directive. The task region is
853   /// emitted in several steps:
854   /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
855   /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
856   /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
857   /// function:
858   /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
859   ///   TaskFunction(gtid, tt->part_id, tt->shareds);
860   ///   return 0;
861   /// }
862   /// 2. Copy a list of shared variables to field shareds of the resulting
863   /// structure kmp_task_t returned by the previous call (if any).
864   /// 3. Copy a pointer to destructions function to field destructions of the
865   /// resulting structure kmp_task_t.
866   /// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid,
867   /// kmp_task_t *new_task), where new_task is a resulting structure from
868   /// previous items.
869   /// \param D Current task directive.
870   /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
871   /// /*part_id*/, captured_struct */*__context*/);
872   /// \param SharedsTy A type which contains references the shared variables.
873   /// \param Shareds Context with the list of shared variables from the \p
874   /// TaskFunction.
875   /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
876   /// otherwise.
877   /// \param Data Additional data for task generation like tiednsee, final
878   /// state, list of privates etc.
879   virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
880                             const OMPExecutableDirective &D,
881                             llvm::Value *TaskFunction, QualType SharedsTy,
882                             Address Shareds, const Expr *IfCond,
883                             const OMPTaskDataTy &Data);
884 
885   /// Emit task region for the taskloop directive. The taskloop region is
886   /// emitted in several steps:
887   /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
888   /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
889   /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
890   /// function:
891   /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
892   ///   TaskFunction(gtid, tt->part_id, tt->shareds);
893   ///   return 0;
894   /// }
895   /// 2. Copy a list of shared variables to field shareds of the resulting
896   /// structure kmp_task_t returned by the previous call (if any).
897   /// 3. Copy a pointer to destructions function to field destructions of the
898   /// resulting structure kmp_task_t.
899   /// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t
900   /// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int
901   /// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task
902   /// is a resulting structure from
903   /// previous items.
904   /// \param D Current task directive.
905   /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
906   /// /*part_id*/, captured_struct */*__context*/);
907   /// \param SharedsTy A type which contains references the shared variables.
908   /// \param Shareds Context with the list of shared variables from the \p
909   /// TaskFunction.
910   /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
911   /// otherwise.
912   /// \param Data Additional data for task generation like tiednsee, final
913   /// state, list of privates etc.
914   virtual void emitTaskLoopCall(
915       CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
916       llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds,
917       const Expr *IfCond, const OMPTaskDataTy &Data);
918 
919   /// \brief Emit code for the directive that does not require outlining.
920   ///
921   /// \param InnermostKind Kind of innermost directive (for simple directives it
922   /// is a directive itself, for combined - its innermost directive).
923   /// \param CodeGen Code generation sequence for the \a D directive.
924   /// \param HasCancel true if region has inner cancel directive, false
925   /// otherwise.
926   virtual void emitInlinedDirective(CodeGenFunction &CGF,
927                                     OpenMPDirectiveKind InnermostKind,
928                                     const RegionCodeGenTy &CodeGen,
929                                     bool HasCancel = false);
930 
931   /// Emits reduction function.
932   /// \param ArgsType Array type containing pointers to reduction variables.
933   /// \param Privates List of private copies for original reduction arguments.
934   /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
935   /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
936   /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
937   /// or 'operator binop(LHS, RHS)'.
938   llvm::Value *emitReductionFunction(CodeGenModule &CGM, llvm::Type *ArgsType,
939                                      ArrayRef<const Expr *> Privates,
940                                      ArrayRef<const Expr *> LHSExprs,
941                                      ArrayRef<const Expr *> RHSExprs,
942                                      ArrayRef<const Expr *> ReductionOps);
943 
944   /// Emits single reduction combiner
945   void emitSingleReductionCombiner(CodeGenFunction &CGF,
946                                    const Expr *ReductionOp,
947                                    const Expr *PrivateRef,
948                                    const DeclRefExpr *LHS,
949                                    const DeclRefExpr *RHS);
950 
951   struct ReductionOptionsTy {
952     bool WithNowait;
953     bool SimpleReduction;
954     OpenMPDirectiveKind ReductionKind;
955   };
956   /// \brief Emit a code for reduction clause. Next code should be emitted for
957   /// reduction:
958   /// \code
959   ///
960   /// static kmp_critical_name lock = { 0 };
961   ///
962   /// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
963   ///  ...
964   ///  *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
965   ///  ...
966   /// }
967   ///
968   /// ...
969   /// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
970   /// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
971   /// RedList, reduce_func, &<lock>)) {
972   /// case 1:
973   ///  ...
974   ///  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
975   ///  ...
976   /// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
977   /// break;
978   /// case 2:
979   ///  ...
980   ///  Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
981   ///  ...
982   /// break;
983   /// default:;
984   /// }
985   /// \endcode
986   ///
987   /// \param Privates List of private copies for original reduction arguments.
988   /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
989   /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
990   /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
991   /// or 'operator binop(LHS, RHS)'.
992   /// \param Options List of options for reduction codegen:
993   ///     WithNowait true if parent directive has also nowait clause, false
994   ///     otherwise.
995   ///     SimpleReduction Emit reduction operation only. Used for omp simd
996   ///     directive on the host.
997   ///     ReductionKind The kind of reduction to perform.
998   virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
999                              ArrayRef<const Expr *> Privates,
1000                              ArrayRef<const Expr *> LHSExprs,
1001                              ArrayRef<const Expr *> RHSExprs,
1002                              ArrayRef<const Expr *> ReductionOps,
1003                              ReductionOptionsTy Options);
1004 
1005   /// \brief Emit code for 'taskwait' directive.
1006   virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc);
1007 
1008   /// \brief Emit code for 'cancellation point' construct.
1009   /// \param CancelRegion Region kind for which the cancellation point must be
1010   /// emitted.
1011   ///
1012   virtual void emitCancellationPointCall(CodeGenFunction &CGF,
1013                                          SourceLocation Loc,
1014                                          OpenMPDirectiveKind CancelRegion);
1015 
1016   /// \brief Emit code for 'cancel' construct.
1017   /// \param IfCond Condition in the associated 'if' clause, if it was
1018   /// specified, nullptr otherwise.
1019   /// \param CancelRegion Region kind for which the cancel must be emitted.
1020   ///
1021   virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
1022                               const Expr *IfCond,
1023                               OpenMPDirectiveKind CancelRegion);
1024 
1025   /// \brief Emit outilined function for 'target' directive.
1026   /// \param D Directive to emit.
1027   /// \param ParentName Name of the function that encloses the target region.
1028   /// \param OutlinedFn Outlined function value to be defined by this call.
1029   /// \param OutlinedFnID Outlined function ID value to be defined by this call.
1030   /// \param IsOffloadEntry True if the outlined function is an offload entry.
1031   /// \param CodeGen Code generation sequence for the \a D directive.
1032   /// An oulined function may not be an entry if, e.g. the if clause always
1033   /// evaluates to false.
1034   virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
1035                                           StringRef ParentName,
1036                                           llvm::Function *&OutlinedFn,
1037                                           llvm::Constant *&OutlinedFnID,
1038                                           bool IsOffloadEntry,
1039                                           const RegionCodeGenTy &CodeGen);
1040 
1041   /// \brief Emit the target offloading code associated with \a D. The emitted
1042   /// code attempts offloading the execution to the device, an the event of
1043   /// a failure it executes the host version outlined in \a OutlinedFn.
1044   /// \param D Directive to emit.
1045   /// \param OutlinedFn Host version of the code to be offloaded.
1046   /// \param OutlinedFnID ID of host version of the code to be offloaded.
1047   /// \param IfCond Expression evaluated in if clause associated with the target
1048   /// directive, or null if no if clause is used.
1049   /// \param Device Expression evaluated in device clause associated with the
1050   /// target directive, or null if no device clause is used.
1051   /// \param CapturedVars Values captured in the current region.
1052   virtual void emitTargetCall(CodeGenFunction &CGF,
1053                               const OMPExecutableDirective &D,
1054                               llvm::Value *OutlinedFn,
1055                               llvm::Value *OutlinedFnID, const Expr *IfCond,
1056                               const Expr *Device,
1057                               ArrayRef<llvm::Value *> CapturedVars);
1058 
1059   /// \brief Emit the target regions enclosed in \a GD function definition or
1060   /// the function itself in case it is a valid device function. Returns true if
1061   /// \a GD was dealt with successfully.
1062   /// \param GD Function to scan.
1063   virtual bool emitTargetFunctions(GlobalDecl GD);
1064 
1065   /// \brief Emit the global variable if it is a valid device global variable.
1066   /// Returns true if \a GD was dealt with successfully.
1067   /// \param GD Variable declaration to emit.
1068   virtual bool emitTargetGlobalVariable(GlobalDecl GD);
1069 
1070   /// \brief Emit the global \a GD if it is meaningful for the target. Returns
1071   /// if it was emitted successfully.
1072   /// \param GD Global to scan.
1073   virtual bool emitTargetGlobal(GlobalDecl GD);
1074 
1075   /// \brief Creates the offloading descriptor in the event any target region
1076   /// was emitted in the current module and return the function that registers
1077   /// it.
1078   virtual llvm::Function *emitRegistrationFunction();
1079 
1080   /// \brief Emits code for teams call of the \a OutlinedFn with
1081   /// variables captured in a record which address is stored in \a
1082   /// CapturedStruct.
1083   /// \param OutlinedFn Outlined function to be run by team masters. Type of
1084   /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
1085   /// \param CapturedVars A pointer to the record with the references to
1086   /// variables used in \a OutlinedFn function.
1087   ///
1088   virtual void emitTeamsCall(CodeGenFunction &CGF,
1089                              const OMPExecutableDirective &D,
1090                              SourceLocation Loc, llvm::Value *OutlinedFn,
1091                              ArrayRef<llvm::Value *> CapturedVars);
1092 
1093   /// \brief Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
1094   /// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code
1095   /// for num_teams clause.
1096   /// \param NumTeams An integer expression of teams.
1097   /// \param ThreadLimit An integer expression of threads.
1098   virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams,
1099                                   const Expr *ThreadLimit, SourceLocation Loc);
1100 
1101   /// Struct that keeps all the relevant information that should be kept
1102   /// throughout a 'target data' region.
1103   class TargetDataInfo {
1104     /// Set to true if device pointer information have to be obtained.
1105     bool RequiresDevicePointerInfo = false;
1106 
1107   public:
1108     /// The array of base pointer passed to the runtime library.
1109     llvm::Value *BasePointersArray = nullptr;
1110     /// The array of section pointers passed to the runtime library.
1111     llvm::Value *PointersArray = nullptr;
1112     /// The array of sizes passed to the runtime library.
1113     llvm::Value *SizesArray = nullptr;
1114     /// The array of map types passed to the runtime library.
1115     llvm::Value *MapTypesArray = nullptr;
1116     /// The total number of pointers passed to the runtime library.
1117     unsigned NumberOfPtrs = 0u;
1118     /// Map between the a declaration of a capture and the corresponding base
1119     /// pointer address where the runtime returns the device pointers.
1120     llvm::DenseMap<const ValueDecl *, Address> CaptureDeviceAddrMap;
1121 
1122     explicit TargetDataInfo() {}
1123     explicit TargetDataInfo(bool RequiresDevicePointerInfo)
1124         : RequiresDevicePointerInfo(RequiresDevicePointerInfo) {}
1125     /// Clear information about the data arrays.
1126     void clearArrayInfo() {
1127       BasePointersArray = nullptr;
1128       PointersArray = nullptr;
1129       SizesArray = nullptr;
1130       MapTypesArray = nullptr;
1131       NumberOfPtrs = 0u;
1132     }
1133     /// Return true if the current target data information has valid arrays.
1134     bool isValid() {
1135       return BasePointersArray && PointersArray && SizesArray &&
1136              MapTypesArray && NumberOfPtrs;
1137     }
1138     bool requiresDevicePointerInfo() { return RequiresDevicePointerInfo; }
1139   };
1140 
1141   /// \brief Emit the target data mapping code associated with \a D.
1142   /// \param D Directive to emit.
1143   /// \param IfCond Expression evaluated in if clause associated with the
1144   /// target directive, or null if no device clause is used.
1145   /// \param Device Expression evaluated in device clause associated with the
1146   /// target directive, or null if no device clause is used.
1147   /// \param Info A record used to store information that needs to be preserved
1148   /// until the region is closed.
1149   virtual void emitTargetDataCalls(CodeGenFunction &CGF,
1150                                    const OMPExecutableDirective &D,
1151                                    const Expr *IfCond, const Expr *Device,
1152                                    const RegionCodeGenTy &CodeGen,
1153                                    TargetDataInfo &Info);
1154 
1155   /// \brief Emit the data mapping/movement code associated with the directive
1156   /// \a D that should be of the form 'target [{enter|exit} data | update]'.
1157   /// \param D Directive to emit.
1158   /// \param IfCond Expression evaluated in if clause associated with the target
1159   /// directive, or null if no if clause is used.
1160   /// \param Device Expression evaluated in device clause associated with the
1161   /// target directive, or null if no device clause is used.
1162   virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF,
1163                                             const OMPExecutableDirective &D,
1164                                             const Expr *IfCond,
1165                                             const Expr *Device);
1166 
1167   /// Marks function \a Fn with properly mangled versions of vector functions.
1168   /// \param FD Function marked as 'declare simd'.
1169   /// \param Fn LLVM function that must be marked with 'declare simd'
1170   /// attributes.
1171   virtual void emitDeclareSimdFunction(const FunctionDecl *FD,
1172                                        llvm::Function *Fn);
1173 
1174   /// Emit initialization for doacross loop nesting support.
1175   /// \param D Loop-based construct used in doacross nesting construct.
1176   virtual void emitDoacrossInit(CodeGenFunction &CGF,
1177                                 const OMPLoopDirective &D);
1178 
1179   /// Emit code for doacross ordered directive with 'depend' clause.
1180   /// \param C 'depend' clause with 'sink|source' dependency kind.
1181   virtual void emitDoacrossOrdered(CodeGenFunction &CGF,
1182                                    const OMPDependClause *C);
1183 };
1184 
1185 } // namespace CodeGen
1186 } // namespace clang
1187 
1188 #endif
1189