1 //===- IR/OpenMPIRBuilder.h - OpenMP encoding builder for LLVM IR - C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the OpenMPIRBuilder class and helpers used as a convenient 10 // way to create LLVM instructions for OpenMP directives. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_OPENMP_IR_IRBUILDER_H 15 #define LLVM_OPENMP_IR_IRBUILDER_H 16 17 #include "llvm/Frontend/OpenMP/OMPConstants.h" 18 #include "llvm/IR/DebugLoc.h" 19 #include "llvm/IR/IRBuilder.h" 20 #include "llvm/Support/Allocator.h" 21 #include <forward_list> 22 23 namespace llvm { 24 class CanonicalLoopInfo; 25 26 /// An interface to create LLVM-IR for OpenMP directives. 27 /// 28 /// Each OpenMP directive has a corresponding public generator method. 29 class OpenMPIRBuilder { 30 public: 31 /// Create a new OpenMPIRBuilder operating on the given module \p M. This will 32 /// not have an effect on \p M (see initialize). OpenMPIRBuilder(Module & M)33 OpenMPIRBuilder(Module &M) : M(M), Builder(M.getContext()) {} 34 35 /// Initialize the internal state, this will put structures types and 36 /// potentially other helpers into the underlying module. Must be called 37 /// before any other method and only once! 38 void initialize(); 39 40 /// Finalize the underlying module, e.g., by outlining regions. 41 void finalize(); 42 43 /// Add attributes known for \p FnID to \p Fn. 44 void addAttributes(omp::RuntimeFunction FnID, Function &Fn); 45 46 /// Type used throughout for insertion points. 47 using InsertPointTy = IRBuilder<>::InsertPoint; 48 49 /// Callback type for variable finalization (think destructors). 50 /// 51 /// \param CodeGenIP is the insertion point at which the finalization code 52 /// should be placed. 53 /// 54 /// A finalize callback knows about all objects that need finalization, e.g. 55 /// destruction, when the scope of the currently generated construct is left 56 /// at the time, and location, the callback is invoked. 57 using FinalizeCallbackTy = std::function<void(InsertPointTy CodeGenIP)>; 58 59 struct FinalizationInfo { 60 /// The finalization callback provided by the last in-flight invocation of 61 /// createXXXX for the directive of kind DK. 62 FinalizeCallbackTy FiniCB; 63 64 /// The directive kind of the innermost directive that has an associated 65 /// region which might require finalization when it is left. 66 omp::Directive DK; 67 68 /// Flag to indicate if the directive is cancellable. 69 bool IsCancellable; 70 }; 71 72 /// Push a finalization callback on the finalization stack. 73 /// 74 /// NOTE: Temporary solution until Clang CG is gone. pushFinalizationCB(const FinalizationInfo & FI)75 void pushFinalizationCB(const FinalizationInfo &FI) { 76 FinalizationStack.push_back(FI); 77 } 78 79 /// Pop the last finalization callback from the finalization stack. 80 /// 81 /// NOTE: Temporary solution until Clang CG is gone. popFinalizationCB()82 void popFinalizationCB() { FinalizationStack.pop_back(); } 83 84 /// Callback type for body (=inner region) code generation 85 /// 86 /// The callback takes code locations as arguments, each describing a 87 /// location at which code might need to be generated or a location that is 88 /// the target of control transfer. 89 /// 90 /// \param AllocaIP is the insertion point at which new alloca instructions 91 /// should be placed. 92 /// \param CodeGenIP is the insertion point at which the body code should be 93 /// placed. 94 /// \param ContinuationBB is the basic block target to leave the body. 95 /// 96 /// Note that all blocks pointed to by the arguments have terminators. 97 using BodyGenCallbackTy = 98 function_ref<void(InsertPointTy AllocaIP, InsertPointTy CodeGenIP, 99 BasicBlock &ContinuationBB)>; 100 101 /// Callback type for loop body code generation. 102 /// 103 /// \param CodeGenIP is the insertion point where the loop's body code must be 104 /// placed. This will be a dedicated BasicBlock with a 105 /// conditional branch from the loop condition check and 106 /// terminated with an unconditional branch to the loop 107 /// latch. 108 /// \param IndVar is the induction variable usable at the insertion point. 109 using LoopBodyGenCallbackTy = 110 function_ref<void(InsertPointTy CodeGenIP, Value *IndVar)>; 111 112 /// Callback type for variable privatization (think copy & default 113 /// constructor). 114 /// 115 /// \param AllocaIP is the insertion point at which new alloca instructions 116 /// should be placed. 117 /// \param CodeGenIP is the insertion point at which the privatization code 118 /// should be placed. 119 /// \param Original The value being copied/created, should not be used in the 120 /// generated IR. 121 /// \param Inner The equivalent of \p Original that should be used in the 122 /// generated IR; this is equal to \p Original if the value is 123 /// a pointer and can thus be passed directly, otherwise it is 124 /// an equivalent but different value. 125 /// \param ReplVal The replacement value, thus a copy or new created version 126 /// of \p Inner. 127 /// 128 /// \returns The new insertion point where code generation continues and 129 /// \p ReplVal the replacement value. 130 using PrivatizeCallbackTy = function_ref<InsertPointTy( 131 InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &Original, 132 Value &Inner, Value *&ReplVal)>; 133 134 /// Description of a LLVM-IR insertion point (IP) and a debug/source location 135 /// (filename, line, column, ...). 136 struct LocationDescription { 137 template <typename T, typename U> LocationDescriptionLocationDescription138 LocationDescription(const IRBuilder<T, U> &IRB) 139 : IP(IRB.saveIP()), DL(IRB.getCurrentDebugLocation()) {} LocationDescriptionLocationDescription140 LocationDescription(const InsertPointTy &IP) : IP(IP) {} LocationDescriptionLocationDescription141 LocationDescription(const InsertPointTy &IP, const DebugLoc &DL) 142 : IP(IP), DL(DL) {} 143 InsertPointTy IP; 144 DebugLoc DL; 145 }; 146 147 /// Emitter methods for OpenMP directives. 148 /// 149 ///{ 150 151 /// Generator for '#omp barrier' 152 /// 153 /// \param Loc The location where the barrier directive was encountered. 154 /// \param DK The kind of directive that caused the barrier. 155 /// \param ForceSimpleCall Flag to force a simple (=non-cancellation) barrier. 156 /// \param CheckCancelFlag Flag to indicate a cancel barrier return value 157 /// should be checked and acted upon. 158 /// 159 /// \returns The insertion point after the barrier. 160 InsertPointTy createBarrier(const LocationDescription &Loc, omp::Directive DK, 161 bool ForceSimpleCall = false, 162 bool CheckCancelFlag = true); 163 164 /// Generator for '#omp cancel' 165 /// 166 /// \param Loc The location where the directive was encountered. 167 /// \param IfCondition The evaluated 'if' clause expression, if any. 168 /// \param CanceledDirective The kind of directive that is cancled. 169 /// 170 /// \returns The insertion point after the barrier. 171 InsertPointTy createCancel(const LocationDescription &Loc, Value *IfCondition, 172 omp::Directive CanceledDirective); 173 174 /// Generator for '#omp parallel' 175 /// 176 /// \param Loc The insert and source location description. 177 /// \param AllocaIP The insertion points to be used for alloca instructions. 178 /// \param BodyGenCB Callback that will generate the region code. 179 /// \param PrivCB Callback to copy a given variable (think copy constructor). 180 /// \param FiniCB Callback to finalize variable copies. 181 /// \param IfCondition The evaluated 'if' clause expression, if any. 182 /// \param NumThreads The evaluated 'num_threads' clause expression, if any. 183 /// \param ProcBind The value of the 'proc_bind' clause (see ProcBindKind). 184 /// \param IsCancellable Flag to indicate a cancellable parallel region. 185 /// 186 /// \returns The insertion position *after* the parallel. 187 IRBuilder<>::InsertPoint 188 createParallel(const LocationDescription &Loc, InsertPointTy AllocaIP, 189 BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB, 190 FinalizeCallbackTy FiniCB, Value *IfCondition, 191 Value *NumThreads, omp::ProcBindKind ProcBind, 192 bool IsCancellable); 193 194 /// Generator for the control flow structure of an OpenMP canonical loop. 195 /// 196 /// This generator operates on the logical iteration space of the loop, i.e. 197 /// the caller only has to provide a loop trip count of the loop as defined by 198 /// base language semantics. The trip count is interpreted as an unsigned 199 /// integer. The induction variable passed to \p BodyGenCB will be of the same 200 /// type and run from 0 to \p TripCount - 1. It is up to the callback to 201 /// convert the logical iteration variable to the loop counter variable in the 202 /// loop body. 203 /// 204 /// \param Loc The insert and source location description. 205 /// \param BodyGenCB Callback that will generate the loop body code. 206 /// \param TripCount Number of iterations the loop body is executed. 207 /// 208 /// \returns An object representing the created control flow structure which 209 /// can be used for loop-associated directives. 210 CanonicalLoopInfo *createCanonicalLoop(const LocationDescription &Loc, 211 LoopBodyGenCallbackTy BodyGenCB, 212 Value *TripCount); 213 214 /// Generator for the control flow structure of an OpenMP canonical loop. 215 /// 216 /// Instead of a logical iteration space, this allows specifying user-defined 217 /// loop counter values using increment, upper- and lower bounds. To 218 /// disambiguate the terminology when counting downwards, instead of lower 219 /// bounds we use \p Start for the loop counter value in the first body 220 /// iteration. 221 /// 222 /// Consider the following limitations: 223 /// 224 /// * A loop counter space over all integer values of its bit-width cannot be 225 /// represented. E.g using uint8_t, its loop trip count of 256 cannot be 226 /// stored into an 8 bit integer): 227 /// 228 /// DO I = 0, 255, 1 229 /// 230 /// * Unsigned wrapping is only supported when wrapping only "once"; E.g. 231 /// effectively counting downwards: 232 /// 233 /// for (uint8_t i = 100u; i > 0; i += 127u) 234 /// 235 /// 236 /// TODO: May need to add addtional parameters to represent: 237 /// 238 /// * Allow representing downcounting with unsigned integers. 239 /// 240 /// * Sign of the step and the comparison operator might disagree: 241 /// 242 /// for (int i = 0; i < 42; --i) 243 /// 244 // 245 /// \param Loc The insert and source location description. 246 /// \param BodyGenCB Callback that will generate the loop body code. 247 /// \param Start Value of the loop counter for the first iterations. 248 /// \param Stop Loop counter values past this will stop the the 249 /// iterations. 250 /// \param Step Loop counter increment after each iteration; negative 251 /// means counting down. \param IsSigned Whether Start, Stop 252 /// and Stop are signed integers. 253 /// \param InclusiveStop Whether \p Stop itself is a valid value for the loop 254 /// counter. 255 /// 256 /// \returns An object representing the created control flow structure which 257 /// can be used for loop-associated directives. 258 CanonicalLoopInfo *createCanonicalLoop(const LocationDescription &Loc, 259 LoopBodyGenCallbackTy BodyGenCB, 260 Value *Start, Value *Stop, Value *Step, 261 bool IsSigned, bool InclusiveStop); 262 263 /// Modifies the canonical loop to be a statically-scheduled workshare loop. 264 /// 265 /// This takes a \p LoopInfo representing a canonical loop, such as the one 266 /// created by \p createCanonicalLoop and emits additional instructions to 267 /// turn it into a workshare loop. In particular, it calls to an OpenMP 268 /// runtime function in the preheader to obtain the loop bounds to be used in 269 /// the current thread, updates the relevant instructions in the canonical 270 /// loop and calls to an OpenMP runtime finalization function after the loop. 271 /// 272 /// \param Loc The source location description, the insertion location 273 /// is not used. 274 /// \param CLI A descriptor of the canonical loop to workshare. 275 /// \param AllocaIP An insertion point for Alloca instructions usable in the 276 /// preheader of the loop. 277 /// \param NeedsBarrier Indicates whether a barrier must be insterted after 278 /// the loop. 279 /// \param Chunk The size of loop chunk considered as a unit when 280 /// scheduling. If \p nullptr, defaults to 1. 281 /// 282 /// \returns Updated CanonicalLoopInfo. 283 CanonicalLoopInfo *createStaticWorkshareLoop(const LocationDescription &Loc, 284 CanonicalLoopInfo *CLI, 285 InsertPointTy AllocaIP, 286 bool NeedsBarrier, 287 Value *Chunk = nullptr); 288 289 /// Generator for '#omp flush' 290 /// 291 /// \param Loc The location where the flush directive was encountered 292 void createFlush(const LocationDescription &Loc); 293 294 /// Generator for '#omp taskwait' 295 /// 296 /// \param Loc The location where the taskwait directive was encountered. 297 void createTaskwait(const LocationDescription &Loc); 298 299 /// Generator for '#omp taskyield' 300 /// 301 /// \param Loc The location where the taskyield directive was encountered. 302 void createTaskyield(const LocationDescription &Loc); 303 304 ///} 305 306 /// Return the insertion point used by the underlying IRBuilder. getInsertionPoint()307 InsertPointTy getInsertionPoint() { return Builder.saveIP(); } 308 309 /// Update the internal location to \p Loc. updateToLocation(const LocationDescription & Loc)310 bool updateToLocation(const LocationDescription &Loc) { 311 Builder.restoreIP(Loc.IP); 312 Builder.SetCurrentDebugLocation(Loc.DL); 313 return Loc.IP.getBlock() != nullptr; 314 } 315 316 /// Return the function declaration for the runtime function with \p FnID. 317 FunctionCallee getOrCreateRuntimeFunction(Module &M, 318 omp::RuntimeFunction FnID); 319 320 Function *getOrCreateRuntimeFunctionPtr(omp::RuntimeFunction FnID); 321 322 /// Return the (LLVM-IR) string describing the source location \p LocStr. 323 Constant *getOrCreateSrcLocStr(StringRef LocStr); 324 325 /// Return the (LLVM-IR) string describing the default source location. 326 Constant *getOrCreateDefaultSrcLocStr(); 327 328 /// Return the (LLVM-IR) string describing the source location identified by 329 /// the arguments. 330 Constant *getOrCreateSrcLocStr(StringRef FunctionName, StringRef FileName, 331 unsigned Line, unsigned Column); 332 333 /// Return the (LLVM-IR) string describing the source location \p Loc. 334 Constant *getOrCreateSrcLocStr(const LocationDescription &Loc); 335 336 /// Return an ident_t* encoding the source location \p SrcLocStr and \p Flags. 337 /// TODO: Create a enum class for the Reserve2Flags 338 Value *getOrCreateIdent(Constant *SrcLocStr, 339 omp::IdentFlag Flags = omp::IdentFlag(0), 340 unsigned Reserve2Flags = 0); 341 342 // Get the type corresponding to __kmpc_impl_lanemask_t from the deviceRTL 343 Type *getLanemaskType(); 344 345 /// Generate control flow and cleanup for cancellation. 346 /// 347 /// \param CancelFlag Flag indicating if the cancellation is performed. 348 /// \param CanceledDirective The kind of directive that is cancled. 349 void emitCancelationCheckImpl(Value *CancelFlag, 350 omp::Directive CanceledDirective); 351 352 /// Generate a barrier runtime call. 353 /// 354 /// \param Loc The location at which the request originated and is fulfilled. 355 /// \param DK The directive which caused the barrier 356 /// \param ForceSimpleCall Flag to force a simple (=non-cancellation) barrier. 357 /// \param CheckCancelFlag Flag to indicate a cancel barrier return value 358 /// should be checked and acted upon. 359 /// 360 /// \returns The insertion point after the barrier. 361 InsertPointTy emitBarrierImpl(const LocationDescription &Loc, 362 omp::Directive DK, bool ForceSimpleCall, 363 bool CheckCancelFlag); 364 365 /// Generate a flush runtime call. 366 /// 367 /// \param Loc The location at which the request originated and is fulfilled. 368 void emitFlush(const LocationDescription &Loc); 369 370 /// The finalization stack made up of finalize callbacks currently in-flight, 371 /// wrapped into FinalizationInfo objects that reference also the finalization 372 /// target block and the kind of cancellable directive. 373 SmallVector<FinalizationInfo, 8> FinalizationStack; 374 375 /// Return true if the last entry in the finalization stack is of kind \p DK 376 /// and cancellable. isLastFinalizationInfoCancellable(omp::Directive DK)377 bool isLastFinalizationInfoCancellable(omp::Directive DK) { 378 return !FinalizationStack.empty() && 379 FinalizationStack.back().IsCancellable && 380 FinalizationStack.back().DK == DK; 381 } 382 383 /// Generate a taskwait runtime call. 384 /// 385 /// \param Loc The location at which the request originated and is fulfilled. 386 void emitTaskwaitImpl(const LocationDescription &Loc); 387 388 /// Generate a taskyield runtime call. 389 /// 390 /// \param Loc The location at which the request originated and is fulfilled. 391 void emitTaskyieldImpl(const LocationDescription &Loc); 392 393 /// Return the current thread ID. 394 /// 395 /// \param Ident The ident (ident_t*) describing the query origin. 396 Value *getOrCreateThreadID(Value *Ident); 397 398 /// The underlying LLVM-IR module 399 Module &M; 400 401 /// The LLVM-IR Builder used to create IR. 402 IRBuilder<> Builder; 403 404 /// Map to remember source location strings 405 StringMap<Constant *> SrcLocStrMap; 406 407 /// Map to remember existing ident_t*. 408 DenseMap<std::pair<Constant *, uint64_t>, Value *> IdentMap; 409 410 /// Helper that contains information about regions we need to outline 411 /// during finalization. 412 struct OutlineInfo { 413 using PostOutlineCBTy = std::function<void(Function &)>; 414 PostOutlineCBTy PostOutlineCB; 415 BasicBlock *EntryBB, *ExitBB; 416 417 /// Collect all blocks in between EntryBB and ExitBB in both the given 418 /// vector and set. 419 void collectBlocks(SmallPtrSetImpl<BasicBlock *> &BlockSet, 420 SmallVectorImpl<BasicBlock *> &BlockVector); 421 }; 422 423 /// Collection of regions that need to be outlined during finalization. 424 SmallVector<OutlineInfo, 16> OutlineInfos; 425 426 /// Collection of owned canonical loop objects that eventually need to be 427 /// free'd. 428 std::forward_list<CanonicalLoopInfo> LoopInfos; 429 430 /// Add a new region that will be outlined later. addOutlineInfo(OutlineInfo && OI)431 void addOutlineInfo(OutlineInfo &&OI) { OutlineInfos.emplace_back(OI); } 432 433 /// An ordered map of auto-generated variables to their unique names. 434 /// It stores variables with the following names: 1) ".gomp_critical_user_" + 435 /// <critical_section_name> + ".var" for "omp critical" directives; 2) 436 /// <mangled_name_for_global_var> + ".cache." for cache for threadprivate 437 /// variables. 438 StringMap<AssertingVH<Constant>, BumpPtrAllocator> InternalVars; 439 440 public: 441 /// Generator for __kmpc_copyprivate 442 /// 443 /// \param Loc The source location description. 444 /// \param BufSize Number of elements in the buffer. 445 /// \param CpyBuf List of pointers to data to be copied. 446 /// \param CpyFn function to call for copying data. 447 /// \param DidIt flag variable; 1 for 'single' thread, 0 otherwise. 448 /// 449 /// \return The insertion position *after* the CopyPrivate call. 450 451 InsertPointTy createCopyPrivate(const LocationDescription &Loc, 452 llvm::Value *BufSize, llvm::Value *CpyBuf, 453 llvm::Value *CpyFn, llvm::Value *DidIt); 454 455 /// Generator for '#omp single' 456 /// 457 /// \param Loc The source location description. 458 /// \param BodyGenCB Callback that will generate the region code. 459 /// \param FiniCB Callback to finalize variable copies. 460 /// \param DidIt Local variable used as a flag to indicate 'single' thread 461 /// 462 /// \returns The insertion position *after* the single call. 463 InsertPointTy createSingle(const LocationDescription &Loc, 464 BodyGenCallbackTy BodyGenCB, 465 FinalizeCallbackTy FiniCB, llvm::Value *DidIt); 466 467 /// Generator for '#omp master' 468 /// 469 /// \param Loc The insert and source location description. 470 /// \param BodyGenCB Callback that will generate the region code. 471 /// \param FiniCB Callback to finalize variable copies. 472 /// 473 /// \returns The insertion position *after* the master. 474 InsertPointTy createMaster(const LocationDescription &Loc, 475 BodyGenCallbackTy BodyGenCB, 476 FinalizeCallbackTy FiniCB); 477 478 /// Generator for '#omp critical' 479 /// 480 /// \param Loc The insert and source location description. 481 /// \param BodyGenCB Callback that will generate the region body code. 482 /// \param FiniCB Callback to finalize variable copies. 483 /// \param CriticalName name of the lock used by the critical directive 484 /// \param HintInst Hint Instruction for hint clause associated with critical 485 /// 486 /// \returns The insertion position *after* the master. 487 InsertPointTy createCritical(const LocationDescription &Loc, 488 BodyGenCallbackTy BodyGenCB, 489 FinalizeCallbackTy FiniCB, 490 StringRef CriticalName, Value *HintInst); 491 492 /// Generate conditional branch and relevant BasicBlocks through which private 493 /// threads copy the 'copyin' variables from Master copy to threadprivate 494 /// copies. 495 /// 496 /// \param IP insertion block for copyin conditional 497 /// \param MasterVarPtr a pointer to the master variable 498 /// \param PrivateVarPtr a pointer to the threadprivate variable 499 /// \param IntPtrTy Pointer size type 500 /// \param BranchtoEnd Create a branch between the copyin.not.master blocks 501 // and copy.in.end block 502 /// 503 /// \returns The insertion point where copying operation to be emitted. 504 InsertPointTy createCopyinClauseBlocks(InsertPointTy IP, Value *MasterAddr, 505 Value *PrivateAddr, 506 llvm::IntegerType *IntPtrTy, 507 bool BranchtoEnd = true); 508 509 /// Create a runtime call for kmpc_Alloc 510 /// 511 /// \param Loc The insert and source location description. 512 /// \param Size Size of allocated memory space 513 /// \param Allocator Allocator information instruction 514 /// \param Name Name of call Instruction for OMP_alloc 515 /// 516 /// \returns CallInst to the OMP_Alloc call 517 CallInst *createOMPAlloc(const LocationDescription &Loc, Value *Size, 518 Value *Allocator, std::string Name = ""); 519 520 /// Create a runtime call for kmpc_free 521 /// 522 /// \param Loc The insert and source location description. 523 /// \param Addr Address of memory space to be freed 524 /// \param Allocator Allocator information instruction 525 /// \param Name Name of call Instruction for OMP_Free 526 /// 527 /// \returns CallInst to the OMP_Free call 528 CallInst *createOMPFree(const LocationDescription &Loc, Value *Addr, 529 Value *Allocator, std::string Name = ""); 530 531 /// Create a runtime call for kmpc_threadprivate_cached 532 /// 533 /// \param Loc The insert and source location description. 534 /// \param Pointer pointer to data to be cached 535 /// \param Size size of data to be cached 536 /// \param Name Name of call Instruction for callinst 537 /// 538 /// \returns CallInst to the thread private cache call. 539 CallInst *createCachedThreadPrivate(const LocationDescription &Loc, 540 llvm::Value *Pointer, 541 llvm::ConstantInt *Size, 542 const llvm::Twine &Name = Twine("")); 543 544 /// Declarations for LLVM-IR types (simple, array, function and structure) are 545 /// generated below. Their names are defined and used in OpenMPKinds.def. Here 546 /// we provide the declarations, the initializeTypes function will provide the 547 /// values. 548 /// 549 ///{ 550 #define OMP_TYPE(VarName, InitValue) Type *VarName = nullptr; 551 #define OMP_ARRAY_TYPE(VarName, ElemTy, ArraySize) \ 552 ArrayType *VarName##Ty = nullptr; \ 553 PointerType *VarName##PtrTy = nullptr; 554 #define OMP_FUNCTION_TYPE(VarName, IsVarArg, ReturnType, ...) \ 555 FunctionType *VarName = nullptr; \ 556 PointerType *VarName##Ptr = nullptr; 557 #define OMP_STRUCT_TYPE(VarName, StrName, ...) \ 558 StructType *VarName = nullptr; \ 559 PointerType *VarName##Ptr = nullptr; 560 #include "llvm/Frontend/OpenMP/OMPKinds.def" 561 562 ///} 563 564 private: 565 /// Create all simple and struct types exposed by the runtime and remember 566 /// the llvm::PointerTypes of them for easy access later. 567 void initializeTypes(Module &M); 568 569 /// Common interface for generating entry calls for OMP Directives. 570 /// if the directive has a region/body, It will set the insertion 571 /// point to the body 572 /// 573 /// \param OMPD Directive to generate entry blocks for 574 /// \param EntryCall Call to the entry OMP Runtime Function 575 /// \param ExitBB block where the region ends. 576 /// \param Conditional indicate if the entry call result will be used 577 /// to evaluate a conditional of whether a thread will execute 578 /// body code or not. 579 /// 580 /// \return The insertion position in exit block 581 InsertPointTy emitCommonDirectiveEntry(omp::Directive OMPD, Value *EntryCall, 582 BasicBlock *ExitBB, 583 bool Conditional = false); 584 585 /// Common interface to finalize the region 586 /// 587 /// \param OMPD Directive to generate exiting code for 588 /// \param FinIP Insertion point for emitting Finalization code and exit call 589 /// \param ExitCall Call to the ending OMP Runtime Function 590 /// \param HasFinalize indicate if the directive will require finalization 591 /// and has a finalization callback in the stack that 592 /// should be called. 593 /// 594 /// \return The insertion position in exit block 595 InsertPointTy emitCommonDirectiveExit(omp::Directive OMPD, 596 InsertPointTy FinIP, 597 Instruction *ExitCall, 598 bool HasFinalize = true); 599 600 /// Common Interface to generate OMP inlined regions 601 /// 602 /// \param OMPD Directive to generate inlined region for 603 /// \param EntryCall Call to the entry OMP Runtime Function 604 /// \param ExitCall Call to the ending OMP Runtime Function 605 /// \param BodyGenCB Body code generation callback. 606 /// \param FiniCB Finalization Callback. Will be called when finalizing region 607 /// \param Conditional indicate if the entry call result will be used 608 /// to evaluate a conditional of whether a thread will execute 609 /// body code or not. 610 /// \param HasFinalize indicate if the directive will require finalization 611 /// and has a finalization callback in the stack that 612 /// should be called. 613 /// 614 /// \return The insertion point after the region 615 616 InsertPointTy 617 EmitOMPInlinedRegion(omp::Directive OMPD, Instruction *EntryCall, 618 Instruction *ExitCall, BodyGenCallbackTy BodyGenCB, 619 FinalizeCallbackTy FiniCB, bool Conditional = false, 620 bool HasFinalize = true); 621 622 /// Get the platform-specific name separator. 623 /// \param Parts different parts of the final name that needs separation 624 /// \param FirstSeparator First separator used between the initial two 625 /// parts of the name. 626 /// \param Separator separator used between all of the rest consecutive 627 /// parts of the name 628 static std::string getNameWithSeparators(ArrayRef<StringRef> Parts, 629 StringRef FirstSeparator, 630 StringRef Separator); 631 632 /// Gets (if variable with the given name already exist) or creates 633 /// internal global variable with the specified Name. The created variable has 634 /// linkage CommonLinkage by default and is initialized by null value. 635 /// \param Ty Type of the global variable. If it is exist already the type 636 /// must be the same. 637 /// \param Name Name of the variable. 638 Constant *getOrCreateOMPInternalVariable(Type *Ty, const Twine &Name, 639 unsigned AddressSpace = 0); 640 641 /// Returns corresponding lock object for the specified critical region 642 /// name. If the lock object does not exist it is created, otherwise the 643 /// reference to the existing copy is returned. 644 /// \param CriticalName Name of the critical region. 645 /// 646 Value *getOMPCriticalRegionLock(StringRef CriticalName); 647 }; 648 649 /// Class to represented the control flow structure of an OpenMP canonical loop. 650 /// 651 /// The control-flow structure is standardized for easy consumption by 652 /// directives associated with loops. For instance, the worksharing-loop 653 /// construct may change this control flow such that each loop iteration is 654 /// executed on only one thread. 655 /// 656 /// The control flow can be described as follows: 657 /// 658 /// Preheader 659 /// | 660 /// /-> Header 661 /// | | 662 /// | Cond---\ 663 /// | | | 664 /// | Body | 665 /// | | | | 666 /// | <...> | 667 /// | | | | 668 /// \--Latch | 669 /// | 670 /// Exit 671 /// | 672 /// After 673 /// 674 /// Code in the header, condition block, latch and exit block must not have any 675 /// side-effect. The body block is the single entry point into the loop body, 676 /// which may contain arbitrary control flow as long as all control paths 677 /// eventually branch to the latch block. 678 /// 679 /// Defined outside OpenMPIRBuilder because one cannot forward-declare nested 680 /// classes. 681 class CanonicalLoopInfo { 682 friend class OpenMPIRBuilder; 683 684 private: 685 /// Whether this object currently represents a loop. 686 bool IsValid = false; 687 688 BasicBlock *Preheader; 689 BasicBlock *Header; 690 BasicBlock *Cond; 691 BasicBlock *Body; 692 BasicBlock *Latch; 693 BasicBlock *Exit; 694 BasicBlock *After; 695 696 /// Delete this loop if unused. 697 void eraseFromParent(); 698 699 public: 700 /// The preheader ensures that there is only a single edge entering the loop. 701 /// Code that must be execute before any loop iteration can be emitted here, 702 /// such as computing the loop trip count and begin lifetime markers. Code in 703 /// the preheader is not considered part of the canonical loop. getPreheader()704 BasicBlock *getPreheader() const { return Preheader; } 705 706 /// The header is the entry for each iteration. In the canonical control flow, 707 /// it only contains the PHINode for the induction variable. getHeader()708 BasicBlock *getHeader() const { return Header; } 709 710 /// The condition block computes whether there is another loop iteration. If 711 /// yes, branches to the body; otherwise to the exit block. getCond()712 BasicBlock *getCond() const { return Cond; } 713 714 /// The body block is the single entry for a loop iteration and not controlled 715 /// by CanonicalLoopInfo. It can contain arbitrary control flow but must 716 /// eventually branch to the \p Latch block. getBody()717 BasicBlock *getBody() const { return Body; } 718 719 /// Reaching the latch indicates the end of the loop body code. In the 720 /// canonical control flow, it only contains the increment of the induction 721 /// variable. getLatch()722 BasicBlock *getLatch() const { return Latch; } 723 724 /// Reaching the exit indicates no more iterations are being executed. getExit()725 BasicBlock *getExit() const { return Exit; } 726 727 /// The after block is intended for clean-up code such as lifetime end 728 /// markers. It is separate from the exit block to ensure, analogous to the 729 /// preheader, it having just a single entry edge and being free from PHI 730 /// nodes should there be multiple loop exits (such as from break 731 /// statements/cancellations). getAfter()732 BasicBlock *getAfter() const { return After; } 733 734 /// Returns the llvm::Value containing the number of loop iterations. It must 735 /// be valid in the preheader and always interpreted as an unsigned integer of 736 /// any bit-width. getTripCount()737 Value *getTripCount() const { 738 Instruction *CmpI = &Cond->front(); 739 assert(isa<CmpInst>(CmpI) && "First inst must compare IV with TripCount"); 740 return CmpI->getOperand(1); 741 } 742 743 /// Returns the instruction representing the current logical induction 744 /// variable. Always unsigned, always starting at 0 with an increment of one. getIndVar()745 Instruction *getIndVar() const { 746 Instruction *IndVarPHI = &Header->front(); 747 assert(isa<PHINode>(IndVarPHI) && "First inst must be the IV PHI"); 748 return IndVarPHI; 749 } 750 751 /// Return the insertion point for user code after the loop. getAfterIP()752 OpenMPIRBuilder::InsertPointTy getAfterIP() const { 753 return {After, After->begin()}; 754 }; 755 756 /// Consistency self-check. 757 void assertOK() const; 758 }; 759 760 } // end namespace llvm 761 762 #endif // LLVM_IR_IRBUILDER_H 763