1274958Sdim//===----- CGOpenMPRuntime.h - Interface to OpenMP Runtimes -----*- C++ -*-===// 2274958Sdim// 3274958Sdim// The LLVM Compiler Infrastructure 4274958Sdim// 5274958Sdim// This file is distributed under the University of Illinois Open Source 6274958Sdim// License. See LICENSE.TXT for details. 7274958Sdim// 8274958Sdim//===----------------------------------------------------------------------===// 9274958Sdim// 10274958Sdim// This provides a class for OpenMP runtime code generation. 11274958Sdim// 12274958Sdim//===----------------------------------------------------------------------===// 13274958Sdim 14280031Sdim#ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H 15280031Sdim#define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H 16274958Sdim 17288943Sdim#include "clang/AST/Type.h" 18280031Sdim#include "clang/Basic/OpenMPKinds.h" 19280031Sdim#include "clang/Basic/SourceLocation.h" 20274958Sdim#include "llvm/ADT/DenseMap.h" 21280031Sdim#include "llvm/ADT/DenseSet.h" 22280031Sdim#include "llvm/ADT/StringMap.h" 23280031Sdim#include "llvm/IR/ValueHandle.h" 24274958Sdim 25274958Sdimnamespace llvm { 26280031Sdimclass ArrayType; 27274958Sdimclass Constant; 28274958Sdimclass Function; 29274958Sdimclass FunctionType; 30280031Sdimclass GlobalVariable; 31274958Sdimclass StructType; 32274958Sdimclass Type; 33274958Sdimclass Value; 34274958Sdim} // namespace llvm 35274958Sdim 36274958Sdimnamespace clang { 37280031Sdimclass Expr; 38296417Sdimclass GlobalDecl; 39280031Sdimclass OMPExecutableDirective; 40280031Sdimclass VarDecl; 41274958Sdim 42274958Sdimnamespace CodeGen { 43296417Sdimclass Address; 44274958Sdimclass CodeGenFunction; 45274958Sdimclass CodeGenModule; 46274958Sdim 47288943Sdimtypedef llvm::function_ref<void(CodeGenFunction &)> RegionCodeGenTy; 48288943Sdim 49274958Sdimclass CGOpenMPRuntime { 50280031Sdimprivate: 51280031Sdim enum OpenMPRTLFunction { 52280031Sdim /// \brief Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, 53280031Sdim /// kmpc_micro microtask, ...); 54280031Sdim OMPRTL__kmpc_fork_call, 55280031Sdim /// \brief Call to void *__kmpc_threadprivate_cached(ident_t *loc, 56280031Sdim /// kmp_int32 global_tid, void *data, size_t size, void ***cache); 57280031Sdim OMPRTL__kmpc_threadprivate_cached, 58280031Sdim /// \brief Call to void __kmpc_threadprivate_register( ident_t *, 59280031Sdim /// void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor); 60280031Sdim OMPRTL__kmpc_threadprivate_register, 61280031Sdim // Call to __kmpc_int32 kmpc_global_thread_num(ident_t *loc); 62280031Sdim OMPRTL__kmpc_global_thread_num, 63280031Sdim // Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid, 64280031Sdim // kmp_critical_name *crit); 65280031Sdim OMPRTL__kmpc_critical, 66296417Sdim // Call to void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 67296417Sdim // global_tid, kmp_critical_name *crit, uintptr_t hint); 68296417Sdim OMPRTL__kmpc_critical_with_hint, 69280031Sdim // Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid, 70280031Sdim // kmp_critical_name *crit); 71280031Sdim OMPRTL__kmpc_end_critical, 72280031Sdim // Call to kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32 73280031Sdim // global_tid); 74280031Sdim OMPRTL__kmpc_cancel_barrier, 75288943Sdim // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid); 76288943Sdim OMPRTL__kmpc_barrier, 77288943Sdim // Call to void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid); 78280031Sdim OMPRTL__kmpc_for_static_fini, 79280031Sdim // Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32 80280031Sdim // global_tid); 81280031Sdim OMPRTL__kmpc_serialized_parallel, 82280031Sdim // Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32 83280031Sdim // global_tid); 84280031Sdim OMPRTL__kmpc_end_serialized_parallel, 85280031Sdim // Call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, 86280031Sdim // kmp_int32 num_threads); 87280031Sdim OMPRTL__kmpc_push_num_threads, 88288943Sdim // Call to void __kmpc_flush(ident_t *loc); 89280031Sdim OMPRTL__kmpc_flush, 90280031Sdim // Call to kmp_int32 __kmpc_master(ident_t *, kmp_int32 global_tid); 91280031Sdim OMPRTL__kmpc_master, 92280031Sdim // Call to void __kmpc_end_master(ident_t *, kmp_int32 global_tid); 93280031Sdim OMPRTL__kmpc_end_master, 94288943Sdim // Call to kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid, 95288943Sdim // int end_part); 96288943Sdim OMPRTL__kmpc_omp_taskyield, 97288943Sdim // Call to kmp_int32 __kmpc_single(ident_t *, kmp_int32 global_tid); 98288943Sdim OMPRTL__kmpc_single, 99288943Sdim // Call to void __kmpc_end_single(ident_t *, kmp_int32 global_tid); 100288943Sdim OMPRTL__kmpc_end_single, 101288943Sdim // Call to kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid, 102288943Sdim // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, 103288943Sdim // kmp_routine_entry_t *task_entry); 104288943Sdim OMPRTL__kmpc_omp_task_alloc, 105288943Sdim // Call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t * 106288943Sdim // new_task); 107288943Sdim OMPRTL__kmpc_omp_task, 108288943Sdim // Call to void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid, 109288943Sdim // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *), 110288943Sdim // kmp_int32 didit); 111288943Sdim OMPRTL__kmpc_copyprivate, 112288943Sdim // Call to kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid, 113288943Sdim // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void 114288943Sdim // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck); 115288943Sdim OMPRTL__kmpc_reduce, 116288943Sdim // Call to kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32 117288943Sdim // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data, 118288943Sdim // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name 119288943Sdim // *lck); 120288943Sdim OMPRTL__kmpc_reduce_nowait, 121288943Sdim // Call to void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid, 122288943Sdim // kmp_critical_name *lck); 123288943Sdim OMPRTL__kmpc_end_reduce, 124288943Sdim // Call to void __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid, 125288943Sdim // kmp_critical_name *lck); 126288943Sdim OMPRTL__kmpc_end_reduce_nowait, 127288943Sdim // Call to void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid, 128288943Sdim // kmp_task_t * new_task); 129288943Sdim OMPRTL__kmpc_omp_task_begin_if0, 130288943Sdim // Call to void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid, 131288943Sdim // kmp_task_t * new_task); 132288943Sdim OMPRTL__kmpc_omp_task_complete_if0, 133288943Sdim // Call to void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid); 134288943Sdim OMPRTL__kmpc_ordered, 135288943Sdim // Call to void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid); 136288943Sdim OMPRTL__kmpc_end_ordered, 137288943Sdim // Call to kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 138288943Sdim // global_tid); 139288943Sdim OMPRTL__kmpc_omp_taskwait, 140288943Sdim // Call to void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid); 141288943Sdim OMPRTL__kmpc_taskgroup, 142288943Sdim // Call to void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid); 143288943Sdim OMPRTL__kmpc_end_taskgroup, 144288943Sdim // Call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid, 145288943Sdim // int proc_bind); 146288943Sdim OMPRTL__kmpc_push_proc_bind, 147288943Sdim // Call to kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32 148288943Sdim // gtid, kmp_task_t * new_task, kmp_int32 ndeps, kmp_depend_info_t 149288943Sdim // *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list); 150288943Sdim OMPRTL__kmpc_omp_task_with_deps, 151288943Sdim // Call to void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 152288943Sdim // gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 153288943Sdim // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); 154288943Sdim OMPRTL__kmpc_omp_wait_deps, 155288943Sdim // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32 156288943Sdim // global_tid, kmp_int32 cncl_kind); 157288943Sdim OMPRTL__kmpc_cancellationpoint, 158288943Sdim // Call to kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid, 159288943Sdim // kmp_int32 cncl_kind); 160288943Sdim OMPRTL__kmpc_cancel, 161296417Sdim 162296417Sdim // 163296417Sdim // Offloading related calls 164296417Sdim // 165296417Sdim // Call to int32_t __tgt_target(int32_t device_id, void *host_ptr, int32_t 166296417Sdim // arg_num, void** args_base, void **args, size_t *arg_sizes, int32_t 167296417Sdim // *arg_types); 168296417Sdim OMPRTL__tgt_target, 169296417Sdim // Call to void __tgt_register_lib(__tgt_bin_desc *desc); 170296417Sdim OMPRTL__tgt_register_lib, 171296417Sdim // Call to void __tgt_unregister_lib(__tgt_bin_desc *desc); 172296417Sdim OMPRTL__tgt_unregister_lib, 173280031Sdim }; 174280031Sdim 175274958Sdim /// \brief Values for bit flags used in the ident_t to describe the fields. 176274958Sdim /// All enumeric elements are named and described in accordance with the code 177274958Sdim /// from http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h 178274958Sdim enum OpenMPLocationFlags { 179274958Sdim /// \brief Use trampoline for internal microtask. 180274958Sdim OMP_IDENT_IMD = 0x01, 181274958Sdim /// \brief Use c-style ident structure. 182274958Sdim OMP_IDENT_KMPC = 0x02, 183274958Sdim /// \brief Atomic reduction option for kmpc_reduce. 184274958Sdim OMP_ATOMIC_REDUCE = 0x10, 185274958Sdim /// \brief Explicit 'barrier' directive. 186274958Sdim OMP_IDENT_BARRIER_EXPL = 0x20, 187274958Sdim /// \brief Implicit barrier in code. 188274958Sdim OMP_IDENT_BARRIER_IMPL = 0x40, 189274958Sdim /// \brief Implicit barrier in 'for' directive. 190274958Sdim OMP_IDENT_BARRIER_IMPL_FOR = 0x40, 191274958Sdim /// \brief Implicit barrier in 'sections' directive. 192274958Sdim OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0, 193274958Sdim /// \brief Implicit barrier in 'single' directive. 194274958Sdim OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140 195274958Sdim }; 196274958Sdim CodeGenModule &CGM; 197274958Sdim /// \brief Default const ident_t object used for initialization of all other 198274958Sdim /// ident_t objects. 199274958Sdim llvm::Constant *DefaultOpenMPPSource; 200280031Sdim /// \brief Map of flags and corresponding default locations. 201274958Sdim typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDefaultLocMapTy; 202274958Sdim OpenMPDefaultLocMapTy OpenMPDefaultLocMap; 203296417Sdim Address getOrCreateDefaultLocation(OpenMPLocationFlags Flags); 204296417Sdim 205296417Sdimpublic: 206274958Sdim /// \brief Describes ident structure that describes a source location. 207274958Sdim /// All descriptions are taken from 208274958Sdim /// http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h 209274958Sdim /// Original structure: 210274958Sdim /// typedef struct ident { 211274958Sdim /// kmp_int32 reserved_1; /**< might be used in Fortran; 212274958Sdim /// see above */ 213274958Sdim /// kmp_int32 flags; /**< also f.flags; KMP_IDENT_xxx flags; 214274958Sdim /// KMP_IDENT_KMPC identifies this union 215274958Sdim /// member */ 216274958Sdim /// kmp_int32 reserved_2; /**< not really used in Fortran any more; 217274958Sdim /// see above */ 218274958Sdim ///#if USE_ITT_BUILD 219274958Sdim /// /* but currently used for storing 220274958Sdim /// region-specific ITT */ 221274958Sdim /// /* contextual information. */ 222274958Sdim ///#endif /* USE_ITT_BUILD */ 223274958Sdim /// kmp_int32 reserved_3; /**< source[4] in Fortran, do not use for 224274958Sdim /// C++ */ 225274958Sdim /// char const *psource; /**< String describing the source location. 226274958Sdim /// The string is composed of semi-colon separated 227274958Sdim // fields which describe the source file, 228274958Sdim /// the function and a pair of line numbers that 229274958Sdim /// delimit the construct. 230274958Sdim /// */ 231274958Sdim /// } ident_t; 232274958Sdim enum IdentFieldIndex { 233274958Sdim /// \brief might be used in Fortran 234274958Sdim IdentField_Reserved_1, 235274958Sdim /// \brief OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member. 236274958Sdim IdentField_Flags, 237274958Sdim /// \brief Not really used in Fortran any more 238274958Sdim IdentField_Reserved_2, 239274958Sdim /// \brief Source[4] in Fortran, do not use for C++ 240274958Sdim IdentField_Reserved_3, 241274958Sdim /// \brief String describing the source location. The string is composed of 242274958Sdim /// semi-colon separated fields which describe the source file, the function 243274958Sdim /// and a pair of line numbers that delimit the construct. 244274958Sdim IdentField_PSource 245274958Sdim }; 246296417Sdimprivate: 247274958Sdim llvm::StructType *IdentTy; 248280031Sdim /// \brief Map for SourceLocation and OpenMP runtime library debug locations. 249274958Sdim typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy; 250274958Sdim OpenMPDebugLocMapTy OpenMPDebugLocMap; 251274958Sdim /// \brief The type for a microtask which gets passed to __kmpc_fork_call(). 252274958Sdim /// Original representation is: 253274958Sdim /// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...); 254274958Sdim llvm::FunctionType *Kmpc_MicroTy; 255280031Sdim /// \brief Stores debug location and ThreadID for the function. 256280031Sdim struct DebugLocThreadIdTy { 257280031Sdim llvm::Value *DebugLoc; 258280031Sdim llvm::Value *ThreadID; 259280031Sdim }; 260280031Sdim /// \brief Map of local debug location, ThreadId and functions. 261280031Sdim typedef llvm::DenseMap<llvm::Function *, DebugLocThreadIdTy> 262280031Sdim OpenMPLocThreadIDMapTy; 263280031Sdim OpenMPLocThreadIDMapTy OpenMPLocThreadIDMap; 264280031Sdim /// \brief Type kmp_critical_name, originally defined as typedef kmp_int32 265280031Sdim /// kmp_critical_name[8]; 266280031Sdim llvm::ArrayType *KmpCriticalNameTy; 267280031Sdim /// \brief An ordered map of auto-generated variables to their unique names. 268280031Sdim /// It stores variables with the following names: 1) ".gomp_critical_user_" + 269280031Sdim /// <critical_section_name> + ".var" for "omp critical" directives; 2) 270280031Sdim /// <mangled_name_for_global_var> + ".cache." for cache for threadprivate 271280031Sdim /// variables. 272280031Sdim llvm::StringMap<llvm::AssertingVH<llvm::Constant>, llvm::BumpPtrAllocator> 273280031Sdim InternalVars; 274288943Sdim /// \brief Type typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); 275288943Sdim llvm::Type *KmpRoutineEntryPtrTy; 276288943Sdim QualType KmpRoutineEntryPtrQTy; 277288943Sdim /// \brief Type typedef struct kmp_task { 278288943Sdim /// void * shareds; /**< pointer to block of pointers to 279288943Sdim /// shared vars */ 280288943Sdim /// kmp_routine_entry_t routine; /**< pointer to routine to call for 281288943Sdim /// executing task */ 282288943Sdim /// kmp_int32 part_id; /**< part id for the task */ 283288943Sdim /// kmp_routine_entry_t destructors; /* pointer to function to invoke 284288943Sdim /// deconstructors of firstprivate C++ objects */ 285288943Sdim /// } kmp_task_t; 286288943Sdim QualType KmpTaskTQTy; 287288943Sdim /// \brief Type typedef struct kmp_depend_info { 288288943Sdim /// kmp_intptr_t base_addr; 289288943Sdim /// size_t len; 290288943Sdim /// struct { 291288943Sdim /// bool in:1; 292288943Sdim /// bool out:1; 293288943Sdim /// } flags; 294288943Sdim /// } kmp_depend_info_t; 295288943Sdim QualType KmpDependInfoTy; 296296417Sdim /// \brief Type struct __tgt_offload_entry{ 297296417Sdim /// void *addr; // Pointer to the offload entry info. 298296417Sdim /// // (function or global) 299296417Sdim /// char *name; // Name of the function or global. 300296417Sdim /// size_t size; // Size of the entry info (0 if it a function). 301296417Sdim /// }; 302296417Sdim QualType TgtOffloadEntryQTy; 303296417Sdim /// struct __tgt_device_image{ 304296417Sdim /// void *ImageStart; // Pointer to the target code start. 305296417Sdim /// void *ImageEnd; // Pointer to the target code end. 306296417Sdim /// // We also add the host entries to the device image, as it may be useful 307296417Sdim /// // for the target runtime to have access to that information. 308296417Sdim /// __tgt_offload_entry *EntriesBegin; // Begin of the table with all 309296417Sdim /// // the entries. 310296417Sdim /// __tgt_offload_entry *EntriesEnd; // End of the table with all the 311296417Sdim /// // entries (non inclusive). 312296417Sdim /// }; 313296417Sdim QualType TgtDeviceImageQTy; 314296417Sdim /// struct __tgt_bin_desc{ 315296417Sdim /// int32_t NumDevices; // Number of devices supported. 316296417Sdim /// __tgt_device_image *DeviceImages; // Arrays of device images 317296417Sdim /// // (one per device). 318296417Sdim /// __tgt_offload_entry *EntriesBegin; // Begin of the table with all the 319296417Sdim /// // entries. 320296417Sdim /// __tgt_offload_entry *EntriesEnd; // End of the table with all the 321296417Sdim /// // entries (non inclusive). 322296417Sdim /// }; 323296417Sdim QualType TgtBinaryDescriptorQTy; 324296417Sdim /// \brief Entity that registers the offloading constants that were emitted so 325296417Sdim /// far. 326296417Sdim class OffloadEntriesInfoManagerTy { 327296417Sdim CodeGenModule &CGM; 328274958Sdim 329296417Sdim /// \brief Number of entries registered so far. 330296417Sdim unsigned OffloadingEntriesNum; 331288943Sdim 332296417Sdim public: 333296417Sdim /// \brief Base class of the entries info. 334296417Sdim class OffloadEntryInfo { 335296417Sdim public: 336296417Sdim /// \brief Kind of a given entry. Currently, only target regions are 337296417Sdim /// supported. 338296417Sdim enum OffloadingEntryInfoKinds : unsigned { 339296417Sdim // Entry is a target region. 340296417Sdim OFFLOAD_ENTRY_INFO_TARGET_REGION = 0, 341296417Sdim // Invalid entry info. 342296417Sdim OFFLOAD_ENTRY_INFO_INVALID = ~0u 343296417Sdim }; 344296417Sdim 345296417Sdim OffloadEntryInfo() : Order(~0u), Kind(OFFLOAD_ENTRY_INFO_INVALID) {} 346296417Sdim explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order) 347296417Sdim : Order(Order), Kind(Kind) {} 348296417Sdim 349296417Sdim bool isValid() const { return Order != ~0u; } 350296417Sdim unsigned getOrder() const { return Order; } 351296417Sdim OffloadingEntryInfoKinds getKind() const { return Kind; } 352296417Sdim static bool classof(const OffloadEntryInfo *Info) { return true; } 353296417Sdim 354296417Sdim protected: 355296417Sdim // \brief Order this entry was emitted. 356296417Sdim unsigned Order; 357296417Sdim 358296417Sdim OffloadingEntryInfoKinds Kind; 359296417Sdim }; 360296417Sdim 361296417Sdim /// \brief Return true if a there are no entries defined. 362296417Sdim bool empty() const; 363296417Sdim /// \brief Return number of entries defined so far. 364296417Sdim unsigned size() const { return OffloadingEntriesNum; } 365296417Sdim OffloadEntriesInfoManagerTy(CodeGenModule &CGM) 366296417Sdim : CGM(CGM), OffloadingEntriesNum(0) {} 367296417Sdim 368296417Sdim /// 369296417Sdim /// Target region entries related. 370296417Sdim /// 371296417Sdim /// \brief Target region entries info. 372296417Sdim class OffloadEntryInfoTargetRegion : public OffloadEntryInfo { 373296417Sdim // \brief Address of the entity that has to be mapped for offloading. 374296417Sdim llvm::Constant *Addr; 375296417Sdim // \brief Address that can be used as the ID of the entry. 376296417Sdim llvm::Constant *ID; 377296417Sdim 378296417Sdim public: 379296417Sdim OffloadEntryInfoTargetRegion() 380296417Sdim : OffloadEntryInfo(OFFLOAD_ENTRY_INFO_TARGET_REGION, ~0u), 381296417Sdim Addr(nullptr), ID(nullptr) {} 382296417Sdim explicit OffloadEntryInfoTargetRegion(unsigned Order, 383296417Sdim llvm::Constant *Addr, 384296417Sdim llvm::Constant *ID) 385296417Sdim : OffloadEntryInfo(OFFLOAD_ENTRY_INFO_TARGET_REGION, Order), 386296417Sdim Addr(Addr), ID(ID) {} 387296417Sdim 388296417Sdim llvm::Constant *getAddress() const { return Addr; } 389296417Sdim llvm::Constant *getID() const { return ID; } 390296417Sdim void setAddress(llvm::Constant *V) { 391296417Sdim assert(!Addr && "Address as been set before!"); 392296417Sdim Addr = V; 393296417Sdim } 394296417Sdim void setID(llvm::Constant *V) { 395296417Sdim assert(!ID && "ID as been set before!"); 396296417Sdim ID = V; 397296417Sdim } 398296417Sdim static bool classof(const OffloadEntryInfo *Info) { 399296417Sdim return Info->getKind() == OFFLOAD_ENTRY_INFO_TARGET_REGION; 400296417Sdim } 401296417Sdim }; 402296417Sdim /// \brief Initialize target region entry. 403296417Sdim void initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, 404296417Sdim StringRef ParentName, unsigned LineNum, 405296417Sdim unsigned ColNum, unsigned Order); 406296417Sdim /// \brief Register target region entry. 407296417Sdim void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, 408296417Sdim StringRef ParentName, unsigned LineNum, 409296417Sdim unsigned ColNum, llvm::Constant *Addr, 410296417Sdim llvm::Constant *ID); 411296417Sdim /// \brief Return true if a target region entry with the provided 412296417Sdim /// information exists. 413296417Sdim bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, 414296417Sdim StringRef ParentName, unsigned LineNum, 415296417Sdim unsigned ColNum) const; 416296417Sdim /// brief Applies action \a Action on all registered entries. 417296417Sdim typedef llvm::function_ref<void(unsigned, unsigned, StringRef, unsigned, 418296417Sdim unsigned, OffloadEntryInfoTargetRegion &)> 419296417Sdim OffloadTargetRegionEntryInfoActTy; 420296417Sdim void actOnTargetRegionEntriesInfo( 421296417Sdim const OffloadTargetRegionEntryInfoActTy &Action); 422296417Sdim 423296417Sdim private: 424296417Sdim // Storage for target region entries kind. The storage is to be indexed by 425296417Sdim // file ID, device ID, parent function name, lane number, and column number. 426296417Sdim typedef llvm::DenseMap<unsigned, OffloadEntryInfoTargetRegion> 427296417Sdim OffloadEntriesTargetRegionPerColumn; 428296417Sdim typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerColumn> 429296417Sdim OffloadEntriesTargetRegionPerLine; 430296417Sdim typedef llvm::StringMap<OffloadEntriesTargetRegionPerLine> 431296417Sdim OffloadEntriesTargetRegionPerParentName; 432296417Sdim typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerParentName> 433296417Sdim OffloadEntriesTargetRegionPerFile; 434296417Sdim typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerFile> 435296417Sdim OffloadEntriesTargetRegionPerDevice; 436296417Sdim typedef OffloadEntriesTargetRegionPerDevice OffloadEntriesTargetRegionTy; 437296417Sdim OffloadEntriesTargetRegionTy OffloadEntriesTargetRegion; 438296417Sdim }; 439296417Sdim OffloadEntriesInfoManagerTy OffloadEntriesInfoManager; 440296417Sdim 441296417Sdim /// \brief Creates and registers offloading binary descriptor for the current 442296417Sdim /// compilation unit. The function that does the registration is returned. 443296417Sdim llvm::Function *createOffloadingBinaryDescriptorRegistration(); 444296417Sdim 445296417Sdim /// \brief Creates offloading entry for the provided address \a Addr, 446296417Sdim /// name \a Name and size \a Size. 447296417Sdim void createOffloadEntry(llvm::Constant *Addr, StringRef Name, uint64_t Size); 448296417Sdim 449296417Sdim /// \brief Creates all the offload entries in the current compilation unit 450296417Sdim /// along with the associated metadata. 451296417Sdim void createOffloadEntriesAndInfoMetadata(); 452296417Sdim 453296417Sdim /// \brief Loads all the offload entries information from the host IR 454296417Sdim /// metadata. 455296417Sdim void loadOffloadInfoMetadata(); 456296417Sdim 457296417Sdim /// \brief Returns __tgt_offload_entry type. 458296417Sdim QualType getTgtOffloadEntryQTy(); 459296417Sdim 460296417Sdim /// \brief Returns __tgt_device_image type. 461296417Sdim QualType getTgtDeviceImageQTy(); 462296417Sdim 463296417Sdim /// \brief Returns __tgt_bin_desc type. 464296417Sdim QualType getTgtBinaryDescriptorQTy(); 465296417Sdim 466296417Sdim /// \brief Start scanning from statement \a S and and emit all target regions 467296417Sdim /// found along the way. 468296417Sdim /// \param S Starting statement. 469296417Sdim /// \param ParentName Name of the function declaration that is being scanned. 470296417Sdim void scanForTargetRegionsFunctions(const Stmt *S, StringRef ParentName); 471296417Sdim 472288943Sdim /// \brief Build type kmp_routine_entry_t (if not built yet). 473288943Sdim void emitKmpRoutineEntryT(QualType KmpInt32Ty); 474288943Sdim 475280031Sdim /// \brief Emits object of ident_t type with info for source location. 476280031Sdim /// \param Flags Flags for OpenMP location. 477280031Sdim /// 478288943Sdim llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc, 479288943Sdim OpenMPLocationFlags Flags = OMP_IDENT_KMPC); 480280031Sdim 481280031Sdim /// \brief Returns pointer to ident_t type. 482280031Sdim llvm::Type *getIdentTyPointerTy(); 483280031Sdim 484280031Sdim /// \brief Returns pointer to kmpc_micro type. 485280031Sdim llvm::Type *getKmpc_MicroPointerTy(); 486280031Sdim 487280031Sdim /// \brief Returns specified OpenMP runtime function. 488280031Sdim /// \param Function OpenMP runtime function. 489280031Sdim /// \return Specified function. 490288943Sdim llvm::Constant *createRuntimeFunction(OpenMPRTLFunction Function); 491280031Sdim 492288943Sdim /// \brief Returns __kmpc_for_static_init_* runtime function for the specified 493288943Sdim /// size \a IVSize and sign \a IVSigned. 494288943Sdim llvm::Constant *createForStaticInitFunction(unsigned IVSize, bool IVSigned); 495288943Sdim 496288943Sdim /// \brief Returns __kmpc_dispatch_init_* runtime function for the specified 497288943Sdim /// size \a IVSize and sign \a IVSigned. 498288943Sdim llvm::Constant *createDispatchInitFunction(unsigned IVSize, bool IVSigned); 499288943Sdim 500288943Sdim /// \brief Returns __kmpc_dispatch_next_* runtime function for the specified 501288943Sdim /// size \a IVSize and sign \a IVSigned. 502288943Sdim llvm::Constant *createDispatchNextFunction(unsigned IVSize, bool IVSigned); 503288943Sdim 504288943Sdim /// \brief Returns __kmpc_dispatch_fini_* runtime function for the specified 505288943Sdim /// size \a IVSize and sign \a IVSigned. 506288943Sdim llvm::Constant *createDispatchFiniFunction(unsigned IVSize, bool IVSigned); 507288943Sdim 508280031Sdim /// \brief If the specified mangled name is not in the module, create and 509280031Sdim /// return threadprivate cache object. This object is a pointer's worth of 510280031Sdim /// storage that's reserved for use by the OpenMP runtime. 511280031Sdim /// \param VD Threadprivate variable. 512280031Sdim /// \return Cache variable for the specified threadprivate. 513280031Sdim llvm::Constant *getOrCreateThreadPrivateCache(const VarDecl *VD); 514280031Sdim 515280031Sdim /// \brief Emits address of the word in a memory where current thread id is 516280031Sdim /// stored. 517296417Sdim virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc); 518280031Sdim 519280031Sdim /// \brief Gets thread id value for the current thread. 520280031Sdim /// 521288943Sdim llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc); 522280031Sdim 523280031Sdim /// \brief Gets (if variable with the given name already exist) or creates 524280031Sdim /// internal global variable with the specified Name. The created variable has 525280031Sdim /// linkage CommonLinkage by default and is initialized by null value. 526280031Sdim /// \param Ty Type of the global variable. If it is exist already the type 527280031Sdim /// must be the same. 528280031Sdim /// \param Name Name of the variable. 529288943Sdim llvm::Constant *getOrCreateInternalVariable(llvm::Type *Ty, 530280031Sdim const llvm::Twine &Name); 531280031Sdim 532280031Sdim /// \brief Set of threadprivate variables with the generated initializer. 533280031Sdim llvm::DenseSet<const VarDecl *> ThreadPrivateWithDefinition; 534280031Sdim 535280031Sdim /// \brief Emits initialization code for the threadprivate variables. 536280031Sdim /// \param VDAddr Address of the global variable \a VD. 537280031Sdim /// \param Ctor Pointer to a global init function for \a VD. 538280031Sdim /// \param CopyCtor Pointer to a global copy function for \a VD. 539280031Sdim /// \param Dtor Pointer to a global destructor function for \a VD. 540280031Sdim /// \param Loc Location of threadprivate declaration. 541296417Sdim void emitThreadPrivateVarInit(CodeGenFunction &CGF, Address VDAddr, 542288943Sdim llvm::Value *Ctor, llvm::Value *CopyCtor, 543288943Sdim llvm::Value *Dtor, SourceLocation Loc); 544280031Sdim 545280031Sdim /// \brief Returns corresponding lock object for the specified critical region 546280031Sdim /// name. If the lock object does not exist it is created, otherwise the 547280031Sdim /// reference to the existing copy is returned. 548280031Sdim /// \param CriticalName Name of the critical region. 549280031Sdim /// 550288943Sdim llvm::Value *getCriticalRegionLock(StringRef CriticalName); 551280031Sdim 552274958Sdimpublic: 553274958Sdim explicit CGOpenMPRuntime(CodeGenModule &CGM); 554280031Sdim virtual ~CGOpenMPRuntime() {} 555288943Sdim virtual void clear(); 556274958Sdim 557288943Sdim /// \brief Emits outlined function for the specified OpenMP parallel directive 558288943Sdim /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID, 559288943Sdim /// kmp_int32 BoundID, struct context_vars*). 560280031Sdim /// \param D OpenMP directive. 561280031Sdim /// \param ThreadIDVar Variable for thread id in the current OpenMP region. 562288943Sdim /// \param InnermostKind Kind of innermost directive (for simple directives it 563288943Sdim /// is a directive itself, for combined - its innermost directive). 564288943Sdim /// \param CodeGen Code generation sequence for the \a D directive. 565288943Sdim virtual llvm::Value *emitParallelOutlinedFunction( 566288943Sdim const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, 567288943Sdim OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen); 568288943Sdim 569288943Sdim /// \brief Emits outlined function for the OpenMP task directive \a D. This 570288943Sdim /// outlined function has type void(*)(kmp_int32 ThreadID, kmp_int32 571288943Sdim /// PartID, struct context_vars*). 572288943Sdim /// \param D OpenMP directive. 573288943Sdim /// \param ThreadIDVar Variable for thread id in the current OpenMP region. 574288943Sdim /// \param InnermostKind Kind of innermost directive (for simple directives it 575288943Sdim /// is a directive itself, for combined - its innermost directive). 576288943Sdim /// \param CodeGen Code generation sequence for the \a D directive. 577280031Sdim /// 578288943Sdim virtual llvm::Value *emitTaskOutlinedFunction( 579288943Sdim const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, 580288943Sdim OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen); 581280031Sdim 582274958Sdim /// \brief Cleans up references to the objects in finished function. 583274958Sdim /// 584288943Sdim void functionFinished(CodeGenFunction &CGF); 585274958Sdim 586288943Sdim /// \brief Emits code for parallel or serial call of the \a OutlinedFn with 587288943Sdim /// variables captured in a record which address is stored in \a 588288943Sdim /// CapturedStruct. 589280031Sdim /// \param OutlinedFn Outlined function to be run in parallel threads. Type of 590288943Sdim /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*). 591296417Sdim /// \param CapturedVars A pointer to the record with the references to 592280031Sdim /// variables used in \a OutlinedFn function. 593288943Sdim /// \param IfCond Condition in the associated 'if' clause, if it was 594288943Sdim /// specified, nullptr otherwise. 595280031Sdim /// 596288943Sdim virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, 597288943Sdim llvm::Value *OutlinedFn, 598296417Sdim ArrayRef<llvm::Value *> CapturedVars, 599288943Sdim const Expr *IfCond); 600280031Sdim 601280031Sdim /// \brief Emits a critical region. 602280031Sdim /// \param CriticalName Name of the critical region. 603280031Sdim /// \param CriticalOpGen Generator for the statement associated with the given 604280031Sdim /// critical region. 605296417Sdim /// \param Hint Value of the 'hint' clause (optional). 606288943Sdim virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, 607288943Sdim const RegionCodeGenTy &CriticalOpGen, 608296417Sdim SourceLocation Loc, 609296417Sdim const Expr *Hint = nullptr); 610280031Sdim 611280031Sdim /// \brief Emits a master region. 612280031Sdim /// \param MasterOpGen Generator for the statement associated with the given 613280031Sdim /// master region. 614288943Sdim virtual void emitMasterRegion(CodeGenFunction &CGF, 615288943Sdim const RegionCodeGenTy &MasterOpGen, 616288943Sdim SourceLocation Loc); 617288943Sdim 618288943Sdim /// \brief Emits code for a taskyield directive. 619288943Sdim virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc); 620288943Sdim 621288943Sdim /// \brief Emit a taskgroup region. 622288943Sdim /// \param TaskgroupOpGen Generator for the statement associated with the 623288943Sdim /// given taskgroup region. 624288943Sdim virtual void emitTaskgroupRegion(CodeGenFunction &CGF, 625288943Sdim const RegionCodeGenTy &TaskgroupOpGen, 626280031Sdim SourceLocation Loc); 627280031Sdim 628288943Sdim /// \brief Emits a single region. 629288943Sdim /// \param SingleOpGen Generator for the statement associated with the given 630288943Sdim /// single region. 631288943Sdim virtual void emitSingleRegion(CodeGenFunction &CGF, 632288943Sdim const RegionCodeGenTy &SingleOpGen, 633288943Sdim SourceLocation Loc, 634288943Sdim ArrayRef<const Expr *> CopyprivateVars, 635288943Sdim ArrayRef<const Expr *> DestExprs, 636288943Sdim ArrayRef<const Expr *> SrcExprs, 637288943Sdim ArrayRef<const Expr *> AssignmentOps); 638288943Sdim 639288943Sdim /// \brief Emit an ordered region. 640288943Sdim /// \param OrderedOpGen Generator for the statement associated with the given 641288943Sdim /// ordered region. 642288943Sdim virtual void emitOrderedRegion(CodeGenFunction &CGF, 643288943Sdim const RegionCodeGenTy &OrderedOpGen, 644296417Sdim SourceLocation Loc, bool IsThreads); 645288943Sdim 646288943Sdim /// \brief Emit an implicit/explicit barrier for OpenMP threads. 647288943Sdim /// \param Kind Directive for which this implicit barrier call must be 648288943Sdim /// generated. Must be OMPD_barrier for explicit barrier generation. 649296417Sdim /// \param EmitChecks true if need to emit checks for cancellation barriers. 650296417Sdim /// \param ForceSimpleCall true simple barrier call must be emitted, false if 651296417Sdim /// runtime class decides which one to emit (simple or with cancellation 652296417Sdim /// checks). 653280031Sdim /// 654288943Sdim virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, 655288943Sdim OpenMPDirectiveKind Kind, 656296417Sdim bool EmitChecks = true, 657296417Sdim bool ForceSimpleCall = false); 658280031Sdim 659280031Sdim /// \brief Check if the specified \a ScheduleKind is static non-chunked. 660280031Sdim /// This kind of worksharing directive is emitted without outer loop. 661280031Sdim /// \param ScheduleKind Schedule kind specified in the 'schedule' clause. 662280031Sdim /// \param Chunked True if chunk is specified in the clause. 663280031Sdim /// 664280031Sdim virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind, 665280031Sdim bool Chunked) const; 666280031Sdim 667288943Sdim /// \brief Check if the specified \a ScheduleKind is dynamic. 668288943Sdim /// This kind of worksharing directive is emitted without outer loop. 669288943Sdim /// \param ScheduleKind Schedule Kind specified in the 'schedule' clause. 670288943Sdim /// 671288943Sdim virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const; 672288943Sdim 673296417Sdim virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, 674296417Sdim OpenMPScheduleClauseKind SchedKind, 675296417Sdim unsigned IVSize, bool IVSigned, 676296417Sdim bool Ordered, llvm::Value *UB, 677296417Sdim llvm::Value *Chunk = nullptr); 678296417Sdim 679280031Sdim /// \brief Call the appropriate runtime routine to initialize it before start 680280031Sdim /// of loop. 681280031Sdim /// 682280031Sdim /// Depending on the loop schedule, it is nesessary to call some runtime 683280031Sdim /// routine before start of the OpenMP loop to get the loop upper / lower 684280031Sdim /// bounds \a LB and \a UB and stride \a ST. 685280031Sdim /// 686274958Sdim /// \param CGF Reference to current CodeGenFunction. 687274958Sdim /// \param Loc Clang source location. 688280031Sdim /// \param SchedKind Schedule kind, specified by the 'schedule' clause. 689280031Sdim /// \param IVSize Size of the iteration variable in bits. 690280031Sdim /// \param IVSigned Sign of the interation variable. 691288943Sdim /// \param Ordered true if loop is ordered, false otherwise. 692280031Sdim /// \param IL Address of the output variable in which the flag of the 693280031Sdim /// last iteration is returned. 694280031Sdim /// \param LB Address of the output variable in which the lower iteration 695280031Sdim /// number is returned. 696280031Sdim /// \param UB Address of the output variable in which the upper iteration 697280031Sdim /// number is returned. 698280031Sdim /// \param ST Address of the output variable in which the stride value is 699280031Sdim /// returned nesessary to generated the static_chunked scheduled loop. 700280031Sdim /// \param Chunk Value of the chunk for the static_chunked scheduled loop. 701280031Sdim /// For the default (nullptr) value, the chunk 1 will be used. 702274958Sdim /// 703296417Sdim virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, 704296417Sdim OpenMPScheduleClauseKind SchedKind, 705296417Sdim unsigned IVSize, bool IVSigned, bool Ordered, 706296417Sdim Address IL, Address LB, 707296417Sdim Address UB, Address ST, 708296417Sdim llvm::Value *Chunk = nullptr); 709274958Sdim 710280031Sdim /// \brief Call the appropriate runtime routine to notify that we finished 711288943Sdim /// iteration of the ordered loop with the dynamic scheduling. 712288943Sdim /// 713288943Sdim /// \param CGF Reference to current CodeGenFunction. 714288943Sdim /// \param Loc Clang source location. 715288943Sdim /// \param IVSize Size of the iteration variable in bits. 716288943Sdim /// \param IVSigned Sign of the interation variable. 717288943Sdim /// 718288943Sdim virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF, 719288943Sdim SourceLocation Loc, unsigned IVSize, 720288943Sdim bool IVSigned); 721288943Sdim 722288943Sdim /// \brief Call the appropriate runtime routine to notify that we finished 723280031Sdim /// all the work with current loop. 724280031Sdim /// 725274958Sdim /// \param CGF Reference to current CodeGenFunction. 726274958Sdim /// \param Loc Clang source location. 727274958Sdim /// 728288943Sdim virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc); 729274958Sdim 730288943Sdim /// Call __kmpc_dispatch_next( 731288943Sdim /// ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, 732288943Sdim /// kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper, 733288943Sdim /// kmp_int[32|64] *p_stride); 734288943Sdim /// \param IVSize Size of the iteration variable in bits. 735288943Sdim /// \param IVSigned Sign of the interation variable. 736288943Sdim /// \param IL Address of the output variable in which the flag of the 737288943Sdim /// last iteration is returned. 738288943Sdim /// \param LB Address of the output variable in which the lower iteration 739288943Sdim /// number is returned. 740288943Sdim /// \param UB Address of the output variable in which the upper iteration 741288943Sdim /// number is returned. 742288943Sdim /// \param ST Address of the output variable in which the stride value is 743288943Sdim /// returned. 744288943Sdim virtual llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc, 745288943Sdim unsigned IVSize, bool IVSigned, 746296417Sdim Address IL, Address LB, 747296417Sdim Address UB, Address ST); 748288943Sdim 749280031Sdim /// \brief Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 750280031Sdim /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads' 751280031Sdim /// clause. 752280031Sdim /// \param NumThreads An integer value of threads. 753288943Sdim virtual void emitNumThreadsClause(CodeGenFunction &CGF, 754288943Sdim llvm::Value *NumThreads, 755288943Sdim SourceLocation Loc); 756274958Sdim 757288943Sdim /// \brief Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 758288943Sdim /// global_tid, int proc_bind) to generate code for 'proc_bind' clause. 759288943Sdim virtual void emitProcBindClause(CodeGenFunction &CGF, 760288943Sdim OpenMPProcBindClauseKind ProcBind, 761288943Sdim SourceLocation Loc); 762288943Sdim 763280031Sdim /// \brief Returns address of the threadprivate variable for the current 764280031Sdim /// thread. 765280031Sdim /// \param VD Threadprivate variable. 766280031Sdim /// \param VDAddr Address of the global variable \a VD. 767280031Sdim /// \param Loc Location of the reference to threadprivate var. 768280031Sdim /// \return Address of the threadprivate variable for the current thread. 769296417Sdim virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF, 770296417Sdim const VarDecl *VD, 771296417Sdim Address VDAddr, 772296417Sdim SourceLocation Loc); 773274958Sdim 774280031Sdim /// \brief Emit a code for initialization of threadprivate variable. It emits 775280031Sdim /// a call to runtime library which adds initial value to the newly created 776280031Sdim /// threadprivate variable (if it is not constant) and registers destructor 777280031Sdim /// for the variable (if any). 778280031Sdim /// \param VD Threadprivate variable. 779280031Sdim /// \param VDAddr Address of the global variable \a VD. 780280031Sdim /// \param Loc Location of threadprivate declaration. 781280031Sdim /// \param PerformInit true if initialization expression is not constant. 782280031Sdim virtual llvm::Function * 783296417Sdim emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, 784288943Sdim SourceLocation Loc, bool PerformInit, 785288943Sdim CodeGenFunction *CGF = nullptr); 786280031Sdim 787280031Sdim /// \brief Emit flush of the variables specified in 'omp flush' directive. 788280031Sdim /// \param Vars List of variables to flush. 789288943Sdim virtual void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars, 790288943Sdim SourceLocation Loc); 791288943Sdim 792288943Sdim /// \brief Emit task region for the task directive. The task region is 793288943Sdim /// emitted in several steps: 794288943Sdim /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 795288943Sdim /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, 796288943Sdim /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the 797288943Sdim /// function: 798288943Sdim /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) { 799288943Sdim /// TaskFunction(gtid, tt->part_id, tt->shareds); 800288943Sdim /// return 0; 801288943Sdim /// } 802288943Sdim /// 2. Copy a list of shared variables to field shareds of the resulting 803288943Sdim /// structure kmp_task_t returned by the previous call (if any). 804288943Sdim /// 3. Copy a pointer to destructions function to field destructions of the 805288943Sdim /// resulting structure kmp_task_t. 806288943Sdim /// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, 807288943Sdim /// kmp_task_t *new_task), where new_task is a resulting structure from 808288943Sdim /// previous items. 809288943Sdim /// \param D Current task directive. 810288943Sdim /// \param Tied true if the task is tied (the task is tied to the thread that 811288943Sdim /// can suspend its task region), false - untied (the task is not tied to any 812288943Sdim /// thread). 813288943Sdim /// \param Final Contains either constant bool value, or llvm::Value * of i1 814288943Sdim /// type for final clause. If the value is true, the task forces all of its 815288943Sdim /// child tasks to become final and included tasks. 816288943Sdim /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32 817288943Sdim /// /*part_id*/, captured_struct */*__context*/); 818288943Sdim /// \param SharedsTy A type which contains references the shared variables. 819288943Sdim /// \param Shareds Context with the list of shared variables from the \p 820288943Sdim /// TaskFunction. 821288943Sdim /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr 822288943Sdim /// otherwise. 823288943Sdim /// \param PrivateVars List of references to private variables for the task 824288943Sdim /// directive. 825288943Sdim /// \param PrivateCopies List of private copies for each private variable in 826288943Sdim /// \p PrivateVars. 827288943Sdim /// \param FirstprivateVars List of references to private variables for the 828288943Sdim /// task directive. 829288943Sdim /// \param FirstprivateCopies List of private copies for each private variable 830288943Sdim /// in \p FirstprivateVars. 831288943Sdim /// \param FirstprivateInits List of references to auto generated variables 832288943Sdim /// used for initialization of a single array element. Used if firstprivate 833288943Sdim /// variable is of array type. 834288943Sdim /// \param Dependences List of dependences for the 'task' construct, including 835288943Sdim /// original expression and dependency type. 836288943Sdim virtual void emitTaskCall( 837288943Sdim CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, 838288943Sdim bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final, 839296417Sdim llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, 840288943Sdim const Expr *IfCond, ArrayRef<const Expr *> PrivateVars, 841288943Sdim ArrayRef<const Expr *> PrivateCopies, 842288943Sdim ArrayRef<const Expr *> FirstprivateVars, 843288943Sdim ArrayRef<const Expr *> FirstprivateCopies, 844288943Sdim ArrayRef<const Expr *> FirstprivateInits, 845288943Sdim ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependences); 846288943Sdim 847288943Sdim /// \brief Emit code for the directive that does not require outlining. 848288943Sdim /// 849288943Sdim /// \param InnermostKind Kind of innermost directive (for simple directives it 850288943Sdim /// is a directive itself, for combined - its innermost directive). 851288943Sdim /// \param CodeGen Code generation sequence for the \a D directive. 852296417Sdim /// \param HasCancel true if region has inner cancel directive, false 853296417Sdim /// otherwise. 854288943Sdim virtual void emitInlinedDirective(CodeGenFunction &CGF, 855288943Sdim OpenMPDirectiveKind InnermostKind, 856296417Sdim const RegionCodeGenTy &CodeGen, 857296417Sdim bool HasCancel = false); 858288943Sdim /// \brief Emit a code for reduction clause. Next code should be emitted for 859288943Sdim /// reduction: 860288943Sdim /// \code 861288943Sdim /// 862288943Sdim /// static kmp_critical_name lock = { 0 }; 863288943Sdim /// 864288943Sdim /// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { 865288943Sdim /// ... 866288943Sdim /// *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]); 867288943Sdim /// ... 868288943Sdim /// } 869288943Sdim /// 870288943Sdim /// ... 871288943Sdim /// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]}; 872288943Sdim /// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), 873288943Sdim /// RedList, reduce_func, &<lock>)) { 874288943Sdim /// case 1: 875288943Sdim /// ... 876288943Sdim /// <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]); 877288943Sdim /// ... 878288943Sdim /// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>); 879288943Sdim /// break; 880288943Sdim /// case 2: 881288943Sdim /// ... 882288943Sdim /// Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i])); 883288943Sdim /// ... 884288943Sdim /// break; 885288943Sdim /// default:; 886288943Sdim /// } 887288943Sdim /// \endcode 888288943Sdim /// 889296417Sdim /// \param Privates List of private copies for original reduction arguments. 890288943Sdim /// \param LHSExprs List of LHS in \a ReductionOps reduction operations. 891288943Sdim /// \param RHSExprs List of RHS in \a ReductionOps reduction operations. 892288943Sdim /// \param ReductionOps List of reduction operations in form 'LHS binop RHS' 893288943Sdim /// or 'operator binop(LHS, RHS)'. 894288943Sdim /// \param WithNowait true if parent directive has also nowait clause, false 895288943Sdim /// otherwise. 896288943Sdim virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, 897296417Sdim ArrayRef<const Expr *> Privates, 898288943Sdim ArrayRef<const Expr *> LHSExprs, 899288943Sdim ArrayRef<const Expr *> RHSExprs, 900288943Sdim ArrayRef<const Expr *> ReductionOps, 901288943Sdim bool WithNowait, bool SimpleReduction); 902288943Sdim 903288943Sdim /// \brief Emit code for 'taskwait' directive. 904288943Sdim virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc); 905288943Sdim 906288943Sdim /// \brief Emit code for 'cancellation point' construct. 907288943Sdim /// \param CancelRegion Region kind for which the cancellation point must be 908288943Sdim /// emitted. 909288943Sdim /// 910288943Sdim virtual void emitCancellationPointCall(CodeGenFunction &CGF, 911288943Sdim SourceLocation Loc, 912288943Sdim OpenMPDirectiveKind CancelRegion); 913288943Sdim 914288943Sdim /// \brief Emit code for 'cancel' construct. 915296417Sdim /// \param IfCond Condition in the associated 'if' clause, if it was 916296417Sdim /// specified, nullptr otherwise. 917288943Sdim /// \param CancelRegion Region kind for which the cancel must be emitted. 918288943Sdim /// 919288943Sdim virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, 920296417Sdim const Expr *IfCond, 921288943Sdim OpenMPDirectiveKind CancelRegion); 922296417Sdim 923296417Sdim /// \brief Emit outilined function for 'target' directive. 924296417Sdim /// \param D Directive to emit. 925296417Sdim /// \param ParentName Name of the function that encloses the target region. 926296417Sdim /// \param OutlinedFn Outlined function value to be defined by this call. 927296417Sdim /// \param OutlinedFnID Outlined function ID value to be defined by this call. 928296417Sdim /// \param IsOffloadEntry True if the outlined function is an offload entry. 929296417Sdim /// An oulined function may not be an entry if, e.g. the if clause always 930296417Sdim /// evaluates to false. 931296417Sdim virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D, 932296417Sdim StringRef ParentName, 933296417Sdim llvm::Function *&OutlinedFn, 934296417Sdim llvm::Constant *&OutlinedFnID, 935296417Sdim bool IsOffloadEntry); 936296417Sdim 937296417Sdim /// \brief Emit the target offloading code associated with \a D. The emitted 938296417Sdim /// code attempts offloading the execution to the device, an the event of 939296417Sdim /// a failure it executes the host version outlined in \a OutlinedFn. 940296417Sdim /// \param D Directive to emit. 941296417Sdim /// \param OutlinedFn Host version of the code to be offloaded. 942296417Sdim /// \param OutlinedFnID ID of host version of the code to be offloaded. 943296417Sdim /// \param IfCond Expression evaluated in if clause associated with the target 944296417Sdim /// directive, or null if no if clause is used. 945296417Sdim /// \param Device Expression evaluated in device clause associated with the 946296417Sdim /// target directive, or null if no device clause is used. 947296417Sdim /// \param CapturedVars Values captured in the current region. 948296417Sdim virtual void emitTargetCall(CodeGenFunction &CGF, 949296417Sdim const OMPExecutableDirective &D, 950296417Sdim llvm::Value *OutlinedFn, 951296417Sdim llvm::Value *OutlinedFnID, const Expr *IfCond, 952296417Sdim const Expr *Device, 953296417Sdim ArrayRef<llvm::Value *> CapturedVars); 954296417Sdim 955296417Sdim /// \brief Emit the target regions enclosed in \a GD function definition or 956296417Sdim /// the function itself in case it is a valid device function. Returns true if 957296417Sdim /// \a GD was dealt with successfully. 958296417Sdim /// \param GD Function to scan. 959296417Sdim virtual bool emitTargetFunctions(GlobalDecl GD); 960296417Sdim 961296417Sdim /// \brief Emit the global variable if it is a valid device global variable. 962296417Sdim /// Returns true if \a GD was dealt with successfully. 963296417Sdim /// \param GD Variable declaration to emit. 964296417Sdim virtual bool emitTargetGlobalVariable(GlobalDecl GD); 965296417Sdim 966296417Sdim /// \brief Emit the global \a GD if it is meaningful for the target. Returns 967296417Sdim /// if it was emitted succesfully. 968296417Sdim /// \param GD Global to scan. 969296417Sdim virtual bool emitTargetGlobal(GlobalDecl GD); 970296417Sdim 971296417Sdim /// \brief Creates the offloading descriptor in the event any target region 972296417Sdim /// was emitted in the current module and return the function that registers 973296417Sdim /// it. 974296417Sdim virtual llvm::Function *emitRegistrationFunction(); 975274958Sdim}; 976288943Sdim 977274958Sdim} // namespace CodeGen 978274958Sdim} // namespace clang 979274958Sdim 980274958Sdim#endif 981