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