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