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