LLVM 24.0.0git
OMPIRBuilder.h
Go to the documentation of this file.
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_FRONTEND_OPENMP_OMPIRBUILDER_H
15#define LLVM_FRONTEND_OPENMP_OMPIRBUILDER_H
16
17#include "llvm/ADT/APSInt.h"
18#include "llvm/ADT/SetVector.h"
22#include "llvm/IR/CallingConv.h"
23#include "llvm/IR/DebugLoc.h"
24#include "llvm/IR/IRBuilder.h"
25#include "llvm/IR/Module.h"
26#include "llvm/IR/ValueMap.h"
29#include "llvm/Support/Error.h"
32#include <forward_list>
33#include <map>
34#include <optional>
35
36namespace llvm {
38class CodeExtractor;
39class ScanInfo;
42class OpenMPIRBuilder;
43class Loop;
44class LoopAnalysis;
45class LoopInfo;
46
47/// Move the instruction after an InsertPoint to the beginning of another
48/// BasicBlock.
49///
50/// The instructions after \p IP are moved to the beginning of \p New which must
51/// not have any PHINodes. If \p CreateBranch is true, a branch instruction to
52/// \p New will be added such that there is no semantic change. Otherwise, the
53/// \p IP insert block remains degenerate and it is up to the caller to insert a
54/// terminator. \p DL is used as the debug location for the branch instruction
55/// if one is created.
57 bool CreateBranch, DebugLoc DL);
58
59/// Splice a BasicBlock at an IRBuilder's current insertion point. Its new
60/// insert location will stick to after the instruction before the insertion
61/// point (instead of moving with the instruction the InsertPoint stores
62/// internally).
63LLVM_ABI void spliceBB(IRBuilder<> &Builder, BasicBlock *New,
64 bool CreateBranch);
65
66/// Split a BasicBlock at an InsertPoint, even if the block is degenerate
67/// (missing the terminator).
68///
69/// llvm::SplitBasicBlock and BasicBlock::splitBasicBlock require a well-formed
70/// BasicBlock. \p Name is used for the new successor block. If \p CreateBranch
71/// is true, a branch to the new successor will new created such that
72/// semantically there is no change; otherwise the block of the insertion point
73/// remains degenerate and it is the caller's responsibility to insert a
74/// terminator. \p DL is used as the debug location for the branch instruction
75/// if one is created. Returns the new successor block.
77 DebugLoc DL, llvm::Twine Name = {});
78
79/// Split a BasicBlock at \p Builder's insertion point, even if the block is
80/// degenerate (missing the terminator). Its new insert location will stick to
81/// after the instruction before the insertion point (instead of moving with the
82/// instruction the InsertPoint stores internally).
83LLVM_ABI BasicBlock *splitBB(IRBuilderBase &Builder, bool CreateBranch,
84 llvm::Twine Name = {});
85
86/// Split a BasicBlock at \p Builder's insertion point, even if the block is
87/// degenerate (missing the terminator). Its new insert location will stick to
88/// after the instruction before the insertion point (instead of moving with the
89/// instruction the InsertPoint stores internally).
90LLVM_ABI BasicBlock *splitBB(IRBuilder<> &Builder, bool CreateBranch,
91 llvm::Twine Name);
92
93/// Like splitBB, but reuses the current block's name for the new name.
95 bool CreateBranch,
96 llvm::Twine Suffix = ".split");
97
98/// Captures attributes that affect generating LLVM-IR using the
99/// OpenMPIRBuilder and related classes. Note that not all attributes are
100/// required for all classes or functions. In some use cases the configuration
101/// is not necessary at all, because because the only functions that are called
102/// are ones that are not dependent on the configuration.
104public:
105 /// Representation of a collapsed iteration space.
106 enum class CollapseIVMapping {
107 /// Decode source indices from the logical index using division and
108 /// remainder in each iteration.
110 /// Retain the physical nest and decode each assigned range once.
112 };
113
114 /// Mapping used for collapsed loops.
116
117 /// Flag to define whether to generate code for the role of the OpenMP host
118 /// (if set to false) or device (if set to true) in an offloading context. It
119 /// is set when the -fopenmp-is-target-device compiler frontend option is
120 /// specified.
121 std::optional<bool> IsTargetDevice;
122
123 /// Flag for specifying if the compilation is done for an accelerator. It is
124 /// set according to the architecture of the target triple and currently only
125 /// true when targeting AMDGPU or NVPTX. Today, these targets can only perform
126 /// the role of an OpenMP target device, so `IsTargetDevice` must also be true
127 /// if `IsGPU` is true. This restriction might be lifted if an accelerator-
128 /// like target with the ability to work as the OpenMP host is added, or if
129 /// the capabilities of the currently supported GPU architectures are
130 /// expanded.
131 std::optional<bool> IsGPU;
132
133 /// Flag for specifying if LLVMUsed information should be emitted.
134 std::optional<bool> EmitLLVMUsedMetaInfo;
135
136 /// Flag for specifying if offloading is mandatory.
137 std::optional<bool> OpenMPOffloadMandatory;
138
139 /// First separator used between the initial two parts of a name.
140 std::optional<StringRef> FirstSeparator;
141 /// Separator used between all of the rest consecutive parts of s name.
142 std::optional<StringRef> Separator;
143
144 /// Flag for specifying whether the no-signed-wrap (nsw) flag should be added
145 /// to loop induction variable arithmetic. Set when the frontend guarantees
146 /// that signed integer overflow is undefined (with -fno-wrapv).
147 std::optional<bool> NoSignedWrap;
148
149 // Grid Value for the GPU target.
150 std::optional<omp::GV> GridValue;
151
152 /// When compilation is being done for the OpenMP host (i.e. `IsTargetDevice =
153 /// false`), this contains the list of offloading triples associated, if any.
155
156 // Default address space for the target.
157 unsigned DefaultTargetAS = 0;
158
160
164 bool HasRequiresReverseOffload,
165 bool HasRequiresUnifiedAddress,
166 bool HasRequiresUnifiedSharedMemory,
167 bool HasRequiresDynamicAllocators);
168
169 // Getters functions that assert if the required values are not present.
170 bool isTargetDevice() const {
171 assert(IsTargetDevice.has_value() && "IsTargetDevice is not set");
172 return *IsTargetDevice;
173 }
174
175 bool isGPU() const {
176 assert(IsGPU.has_value() && "IsGPU is not set");
177 return *IsGPU;
178 }
179
181 assert(OpenMPOffloadMandatory.has_value() &&
182 "OpenMPOffloadMandatory is not set");
184 }
185
187 assert(GridValue.has_value() && "GridValue is not set");
188 return *GridValue;
189 }
190
191 unsigned getDefaultTargetAS() const { return DefaultTargetAS; }
192
193 bool hasNoSignedWrap() const { return NoSignedWrap.value_or(false); }
195
197
198 bool hasRequiresFlags() const { return RequiresFlags; }
203
204 /// Returns requires directive clauses as flags compatible with those expected
205 /// by libomptarget.
206 LLVM_ABI int64_t getRequiresFlags() const;
207
208 // Returns the FirstSeparator if set, otherwise use the default separator
209 // depending on isGPU
211 if (FirstSeparator.has_value())
212 return *FirstSeparator;
213 if (isGPU())
214 return "_";
215 return ".";
216 }
217
218 // Returns the Separator if set, otherwise use the default separator depending
219 // on isGPU
221 if (Separator.has_value())
222 return *Separator;
223 if (isGPU())
224 return "$";
225 return ".";
226 }
227
229 void setIsGPU(bool Value) { IsGPU = Value; }
235 void setDefaultTargetAS(unsigned AS) { DefaultTargetAS = AS; }
237
242
243private:
244 /// Flags for specifying which requires directive clauses are present.
245 int64_t RequiresFlags;
246};
247
248/// Data structure to contain the information needed to uniquely identify
249/// a target entry.
251 /// The prefix used for kernel names.
252 static constexpr const char *KernelNamePrefix = "__omp_offloading_";
253
254 std::string ParentName;
255 unsigned DeviceID;
256 unsigned FileID;
257 unsigned Line;
258 unsigned Count;
259
262 unsigned FileID, unsigned Line, unsigned Count = 0)
264 Count(Count) {}
265
266 LLVM_ABI static void
268 unsigned DeviceID, unsigned FileID, unsigned Line,
269 unsigned Count);
270
272 return std::make_tuple(ParentName, DeviceID, FileID, Line, Count) <
273 std::make_tuple(RHS.ParentName, RHS.DeviceID, RHS.FileID, RHS.Line,
274 RHS.Count);
275 }
276};
277
278/// Class that manages information about offload code regions and data
280 /// Number of entries registered so far.
281 OpenMPIRBuilder *OMPBuilder;
282 unsigned OffloadingEntriesNum = 0;
283
284public:
285 /// Base class of the entries info.
287 public:
288 /// Kind of a given entry.
289 enum OffloadingEntryInfoKinds : unsigned {
290 /// Entry is a target region.
292 /// Entry is a declare target variable.
294 /// Invalid entry info.
296 };
297
298 protected:
300 explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind) : Kind(Kind) {}
301 explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order,
302 uint32_t Flags)
303 : Flags(Flags), Order(Order), Kind(Kind) {}
304 ~OffloadEntryInfo() = default;
305
306 public:
307 bool isValid() const { return Order != ~0u; }
308 unsigned getOrder() const { return Order; }
309 OffloadingEntryInfoKinds getKind() const { return Kind; }
310 uint32_t getFlags() const { return Flags; }
311 void setFlags(uint32_t NewFlags) { Flags = NewFlags; }
312 Constant *getAddress() const { return cast_or_null<Constant>(Addr); }
314 assert(!Addr.pointsToAliveValue() && "Address has been set before!");
315 Addr = V;
316 }
317 static bool classof(const OffloadEntryInfo *Info) { return true; }
318
319 private:
320 /// Address of the entity that has to be mapped for offloading.
321 WeakTrackingVH Addr;
322
323 /// Flags associated with the device global.
324 uint32_t Flags = 0u;
325
326 /// Order this entry was emitted.
327 unsigned Order = ~0u;
328
329 OffloadingEntryInfoKinds Kind = OffloadingEntryInfoInvalid;
330 };
331
332 /// Return true if a there are no entries defined.
333 LLVM_ABI bool empty() const;
334 /// Return number of entries defined so far.
335 unsigned size() const { return OffloadingEntriesNum; }
336
337 OffloadEntriesInfoManager(OpenMPIRBuilder *builder) : OMPBuilder(builder) {}
338
339 //
340 // Target region entries related.
341 //
342
343 /// Kind of the target registry entry.
345 /// Mark the entry as target region.
347 };
348
349 /// Target region entries info.
351 /// Address that can be used as the ID of the entry.
352 Constant *ID = nullptr;
353
354 public:
357 explicit OffloadEntryInfoTargetRegion(unsigned Order, Constant *Addr,
358 Constant *ID,
361 ID(ID) {
362 setAddress(Addr);
363 }
364
365 Constant *getID() const { return ID; }
366 void setID(Constant *V) {
367 assert(!ID && "ID has been set before!");
368 ID = V;
369 }
370 static bool classof(const OffloadEntryInfo *Info) {
371 return Info->getKind() == OffloadingEntryInfoTargetRegion;
372 }
373 };
374
375 /// Initialize target region entry.
376 /// This is ONLY needed for DEVICE compilation.
377 LLVM_ABI void
379 unsigned Order);
380 /// Register target region entry.
382 Constant *Addr, Constant *ID,
384 /// Return true if a target region entry with the provided information
385 /// exists.
387 bool IgnoreAddressId = false) const;
388
389 // Return the Name based on \a EntryInfo using the next available Count.
390 LLVM_ABI void
392 const TargetRegionEntryInfo &EntryInfo);
393
394 /// brief Applies action \a Action on all registered entries.
395 typedef function_ref<void(const TargetRegionEntryInfo &EntryInfo,
396 const OffloadEntryInfoTargetRegion &)>
398 LLVM_ABI void
400
401 //
402 // Device global variable entries related.
403 //
404
405 /// Kind of the global variable entry..
407 /// Mark the entry as a to declare target.
409 /// Mark the entry as a to declare target link.
411 /// Mark the entry as a declare target enter.
413 /// Mark the entry as having no declare target entry kind.
415 /// Mark the entry as a declare target indirect global.
417 /// Mark the entry as a register requires global.
419 /// Mark the entry as a declare target indirect vtable.
421 };
422
423 /// Kind of device clause for declare target variables
424 /// and functions
425 /// NOTE: Currently not used as a part of a variable entry
426 /// used for Flang and Clang to interface with the variable
427 /// related registration functions
429 /// The target is marked for all devices
431 /// The target is marked for non-host devices
433 /// The target is marked for host devices
435 /// The target is marked as having no clause
437 };
438
439 /// Device global variable entries info.
441 /// Type of the global variable.
442 int64_t VarSize;
444 const std::string VarName;
445
446 public:
452 explicit OffloadEntryInfoDeviceGlobalVar(unsigned Order, Constant *Addr,
453 int64_t VarSize,
456 const std::string &VarName)
458 VarSize(VarSize), Linkage(Linkage), VarName(VarName) {
459 setAddress(Addr);
460 }
461
462 int64_t getVarSize() const { return VarSize; }
463 StringRef getVarName() const { return VarName; }
464 void setVarSize(int64_t Size) { VarSize = Size; }
465 GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
466 void setLinkage(GlobalValue::LinkageTypes LT) { Linkage = LT; }
467 static bool classof(const OffloadEntryInfo *Info) {
468 return Info->getKind() == OffloadingEntryInfoDeviceGlobalVar;
469 }
470 };
471
472 /// Initialize device global variable entry.
473 /// This is ONLY used for DEVICE compilation.
475 StringRef Name, OMPTargetGlobalVarEntryKind Flags, unsigned Order);
476
477 /// Register device global variable entry.
479 StringRef VarName, Constant *Addr, int64_t VarSize,
481 /// Checks if the variable with the given name has been registered already.
483 return OffloadEntriesDeviceGlobalVar.count(VarName) > 0;
484 }
485 /// Applies action \a Action on all registered entries.
486 typedef function_ref<void(StringRef, const OffloadEntryInfoDeviceGlobalVar &)>
490
491private:
492 /// Return the count of entries at a particular source location.
493 unsigned
494 getTargetRegionEntryInfoCount(const TargetRegionEntryInfo &EntryInfo) const;
495
496 /// Update the count of entries at a particular source location.
497 void
498 incrementTargetRegionEntryInfoCount(const TargetRegionEntryInfo &EntryInfo);
499
501 getTargetRegionEntryCountKey(const TargetRegionEntryInfo &EntryInfo) {
502 return TargetRegionEntryInfo(EntryInfo.ParentName, EntryInfo.DeviceID,
503 EntryInfo.FileID, EntryInfo.Line, 0);
504 }
505
506 // Count of entries at a location.
507 std::map<TargetRegionEntryInfo, unsigned> OffloadEntriesTargetRegionCount;
508
509 // Storage for target region entries kind.
510 typedef std::map<TargetRegionEntryInfo, OffloadEntryInfoTargetRegion>
511 OffloadEntriesTargetRegionTy;
512 OffloadEntriesTargetRegionTy OffloadEntriesTargetRegion;
513 /// Storage for device global variable entries kind. The storage is to be
514 /// indexed by mangled name.
516 OffloadEntriesDeviceGlobalVarTy;
517 OffloadEntriesDeviceGlobalVarTy OffloadEntriesDeviceGlobalVar;
518};
519
520/// An interface to create LLVM-IR for OpenMP directives.
521///
522/// Each OpenMP directive has a corresponding public generator method.
524public:
525 /// Create a new OpenMPIRBuilder operating on the given module \p M. This will
526 /// not have an effect on \p M (see initialize)
528 : M(M), Builder(M), OffloadInfoManager(this), T(M.getTargetTriple()),
529 IsFinalized(false) {
530 Builder.disableGEPCanonicalization();
531 }
533
535 llvm::Value *AtomicVar;
536
537 public:
545
546 llvm::Value *getAtomicPointer() const override { return AtomicVar; }
549 const llvm::Twine &Name) const override {
550 llvm::AllocaInst *allocaInst = Builder->CreateAlloca(Ty);
551 allocaInst->setName(Name);
552 return allocaInst;
553 }
554 };
555 /// Initialize the internal state, this will put structures types and
556 /// potentially other helpers into the underlying module. Must be called
557 /// before any other method and only once! This internal state includes types
558 /// used in the OpenMPIRBuilder generated from OMPKinds.def.
559 LLVM_ABI void initialize();
560
562
563 /// Finalize the underlying module, e.g., by outlining regions.
564 /// \param Fn The function to be finalized. If not used,
565 /// all functions are finalized.
566 LLVM_ABI void finalize(Function *Fn = nullptr);
567
568 /// Check whether the finalize function has already run
569 /// \return true if the finalize function has already run
570 LLVM_ABI bool isFinalized();
571
572 /// Add attributes known for \p FnID to \p Fn.
574
575 /// Type used throughout for insertion points.
577
578 /// Type used to represent an insertion point or an error value.
580
581 /// Get the create a name using the platform specific separators.
582 /// \param Parts parts of the final name that needs separation
583 /// The created name has a first separator between the first and second part
584 /// and a second separator between all other parts.
585 /// E.g. with FirstSeparator "$" and Separator "." and
586 /// parts: "p1", "p2", "p3", "p4"
587 /// The resulting name is "p1$p2.p3.p4"
588 /// The separators are retrieved from the OpenMPIRBuilderConfig.
589 LLVM_ABI std::string
591
592 /// Callback type for variable finalization (think destructors).
593 ///
594 /// \param CodeGenIP is the insertion point at which the finalization code
595 /// should be placed.
596 ///
597 /// A finalize callback knows about all objects that need finalization, e.g.
598 /// destruction, when the scope of the currently generated construct is left
599 /// at the time, and location, the callback is invoked.
600 using FinalizeCallbackTy = std::function<Error(InsertPointTy CodeGenIP)>;
601
603 FinalizationInfo(FinalizeCallbackTy FiniCB, omp::Directive DK,
604 bool IsCancellable)
605 : DK(DK), IsCancellable(IsCancellable), FiniCB(std::move(FiniCB)) {}
606 /// The directive kind of the innermost directive that has an associated
607 /// region which might require finalization when it is left.
608 const omp::Directive DK;
609
610 /// Flag to indicate if the directive is cancellable.
611 const bool IsCancellable;
612
613 /// The basic block to which control should be transferred to
614 /// implement the FiniCB. Memoized to avoid generating finalization
615 /// multiple times.
617
618 /// For cases where there is an unavoidable existing finalization block
619 /// (e.g. loop finialization after omp sections). The existing finalization
620 /// block must not contain any non-finalization code.
622 BasicBlock *ExistingFiniBB);
623
624 private:
625 /// Access via getFiniBB.
626 BasicBlock *FiniBB = nullptr;
627
628 /// The finalization callback provided by the last in-flight invocation of
629 /// createXXXX for the directive of kind DK.
630 FinalizeCallbackTy FiniCB;
631 };
632
633 /// Push a finalization callback on the finalization stack.
634 ///
635 /// NOTE: Temporary solution until Clang CG is gone.
637 FinalizationStack.push_back(FI);
638 }
639
640 /// Pop the last finalization callback from the finalization stack.
641 ///
642 /// NOTE: Temporary solution until Clang CG is gone.
644
645 /// Callback type for body (=inner region) code generation
646 ///
647 /// The callback takes code locations as arguments, each describing a
648 /// location where additional instructions can be inserted.
649 ///
650 /// The CodeGenIP may be in the middle of a basic block or point to the end of
651 /// it. The basic block may have a terminator or be degenerate. The callback
652 /// function may just insert instructions at that position, but also split the
653 /// block (without the Before argument of BasicBlock::splitBasicBlock such
654 /// that the identify of the split predecessor block is preserved) and insert
655 /// additional control flow, including branches that do not lead back to what
656 /// follows the CodeGenIP. Note that since the callback is allowed to split
657 /// the block, callers must assume that InsertPoints to positions in the
658 /// BasicBlock after CodeGenIP including CodeGenIP itself are invalidated. If
659 /// such InsertPoints need to be preserved, it can split the block itself
660 /// before calling the callback.
661 ///
662 /// AllocaIP and CodeGenIP must not point to the same position.
663 ///
664 /// \param AllocaIP is the insertion point at which new allocations should
665 /// be placed. The BasicBlock it is pointing to must not be
666 /// split.
667 /// \param CodeGenIP is the insertion point at which the body code should be
668 /// placed.
669 /// \param DeallocBlocks is the list of insertion blocks where explicit
670 /// deallocations, if needed, should be placed.
671 /// \return an error, if any were triggered during execution.
673 function_ref<Error(InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
674 ArrayRef<BasicBlock *> DeallocBlocks)>;
675
676 /// Callback type for task duplication function code generation. This is the
677 /// task duplication function passed to __kmpc_taskloop. It is expected that
678 /// this function will set up (first)private variables in the duplicated task
679 /// which have non-trivial (copy-)constructors. Insertion points are handled
680 /// the same way as for BodyGenCallbackTy.
681 ///
682 /// \ref createTaskloop lays out the task's auxiliary data structure as:
683 /// `{ lower bound, upper bound, step, data... }`. DestPtr and SrcPtr point
684 /// to this data.
685 ///
686 /// It is acceptable for the callback to be set to nullptr. In that case no
687 /// function will be generated and nullptr will be passed as the task
688 /// duplication function to __kmpc_taskloop.
689 ///
690 /// \param AllocaIP is the insertion point at which new alloca instructions
691 /// should be placed. The BasicBlock it is pointing to must
692 /// not be split.
693 /// \param CodeGenIP is the insertion point at which the body code should be
694 /// placed.
695 /// \param DestPtr This is a pointer to data inside the newly duplicated
696 /// task's auxiliary data structure (allocated after the task
697 /// descriptor.)
698 /// \param SrcPtr This is a pointer to data inside the original task's
699 /// auxiliary data structure (allocated after the task
700 /// descriptor.)
701 ///
702 /// \return The insertion point immediately after the generated code, or an
703 /// error if any occured.
705 InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value *DestPtr,
706 Value *SrcPtr)>;
707
708 // This is created primarily for sections construct as llvm::function_ref
709 // (BodyGenCallbackTy) is not storable (as described in the comments of
710 // function_ref class - function_ref contains non-ownable reference
711 // to the callable.
712 ///
713 /// \return an error, if any were triggered during execution.
715 std::function<Error(InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
716 ArrayRef<BasicBlock *> DeallocBlocks)>;
717
718 /// Callback type for loop body code generation.
719 ///
720 /// \param CodeGenIP is the insertion point where the loop's body code must be
721 /// placed. This will be a dedicated BasicBlock with a
722 /// conditional branch from the loop condition check and
723 /// terminated with an unconditional branch to the loop
724 /// latch.
725 /// \param IndVar is the induction variable usable at the insertion point.
726 ///
727 /// \return an error, if any were triggered during execution.
729 function_ref<Error(InsertPointTy CodeGenIP, Value *IndVar)>;
730
731 /// Callback type for variable privatization (think copy & default
732 /// constructor).
733 ///
734 /// \param AllocaIP is the insertion point at which new alloca instructions
735 /// should be placed.
736 /// \param CodeGenIP is the insertion point at which the privatization code
737 /// should be placed.
738 /// \param Original The value being copied/created, should not be used in the
739 /// generated IR.
740 /// \param Inner The equivalent of \p Original that should be used in the
741 /// generated IR; this is equal to \p Original if the value is
742 /// a pointer and can thus be passed directly, otherwise it is
743 /// an equivalent but different value.
744 /// \param ReplVal The replacement value, thus a copy or new created version
745 /// of \p Inner.
746 ///
747 /// \returns The new insertion point where code generation continues and
748 /// \p ReplVal the replacement value.
750 InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &Original,
751 Value &Inner, Value *&ReplVal)>;
752
753 /// Description of a LLVM-IR insertion point (IP) and a debug/source location
754 /// (filename, line, column, ...).
757 : IP(IRB.saveIP()), DL(IRB.getCurrentDebugLocation()) {}
759 : IP(IP), DL(DL) {}
762 };
763
764 /// Emitter methods for OpenMP directives.
765 ///
766 ///{
767
768 /// Generator for '#omp barrier'
769 ///
770 /// \param Loc The location where the barrier directive was encountered.
771 /// \param Kind The kind of directive that caused the barrier.
772 /// \param ForceSimpleCall Flag to force a simple (=non-cancellation) barrier.
773 /// \param CheckCancelFlag Flag to indicate a cancel barrier return value
774 /// should be checked and acted upon.
775 /// \param ThreadID Optional parameter to pass in any existing ThreadID value.
776 ///
777 /// \returns The insertion point after the barrier.
779 omp::Directive Kind,
780 bool ForceSimpleCall = false,
781 bool CheckCancelFlag = true);
782
783 /// Generator for '#omp cancel'
784 ///
785 /// \param Loc The location where the directive was encountered.
786 /// \param IfCondition The evaluated 'if' clause expression, if any.
787 /// \param CanceledDirective The kind of directive that is cancled.
788 ///
789 /// \returns The insertion point after the barrier.
791 Value *IfCondition,
792 omp::Directive CanceledDirective);
793
794 /// Generator for '#omp cancellation point'
795 ///
796 /// \param Loc The location where the directive was encountered.
797 /// \param CanceledDirective The kind of directive that is cancled.
798 ///
799 /// \returns The insertion point after the barrier.
801 const LocationDescription &Loc, omp::Directive CanceledDirective);
802
803 /// Creates a ScanInfo object, allocates and returns the pointer.
805
806 /// Generator for '#omp parallel'
807 ///
808 /// \param Loc The insert and source location description.
809 /// \param AllocaIP The insertion point to be used for allocations.
810 /// \param DeallocBlocks The insertion blocks to be used for explicit
811 /// deallocations, if needed.
812 /// \param BodyGenCB Callback that will generate the region code.
813 /// \param PrivCB Callback to copy a given variable (think copy constructor).
814 /// \param FiniCB Callback to finalize variable copies.
815 /// \param IfCondition The evaluated 'if' clause expression, if any.
816 /// \param NumThreads The evaluated 'num_threads' clause expression, if any.
817 /// \param ProcBind The value of the 'proc_bind' clause (see ProcBindKind).
818 /// \param IsCancellable Flag to indicate a cancellable parallel region.
819 ///
820 /// \returns The insertion position *after* the parallel.
822 const LocationDescription &Loc, InsertPointTy AllocaIP,
823 ArrayRef<BasicBlock *> DeallocBlocks, BodyGenCallbackTy BodyGenCB,
824 PrivatizeCallbackTy PrivCB, FinalizeCallbackTy FiniCB, Value *IfCondition,
825 Value *NumThreads, omp::ProcBindKind ProcBind, bool IsCancellable);
826
827 /// Generator for the control flow structure of an OpenMP canonical loop.
828 ///
829 /// This generator operates on the logical iteration space of the loop, i.e.
830 /// the caller only has to provide a loop trip count of the loop as defined by
831 /// base language semantics. The trip count is interpreted as an unsigned
832 /// integer. The induction variable passed to \p BodyGenCB will be of the same
833 /// type and run from 0 to \p TripCount - 1. It is up to the callback to
834 /// convert the logical iteration variable to the loop counter variable in the
835 /// loop body.
836 ///
837 /// \param Loc The insert and source location description. The insert
838 /// location can be between two instructions or the end of a
839 /// degenerate block (e.g. a BB under construction).
840 /// \param BodyGenCB Callback that will generate the loop body code.
841 /// \param TripCount Number of iterations the loop body is executed.
842 /// \param Name Base name used to derive BB and instruction names.
843 ///
844 /// \returns An object representing the created control flow structure which
845 /// can be used for loop-associated directives.
848 LoopBodyGenCallbackTy BodyGenCB, Value *TripCount,
849 const Twine &Name = "loop");
850
851 /// Generator for the control flow structure of an OpenMP canonical loops if
852 /// the parent directive has an `inscan` modifier specified.
853 /// If the `inscan` modifier is specified, the region of the parent is
854 /// expected to have a `scan` directive. Based on the clauses in
855 /// scan directive, the body of the loop is split into two loops: Input loop
856 /// and Scan Loop. Input loop contains the code generated for input phase of
857 /// scan and Scan loop contains the code generated for scan phase of scan.
858 /// From the bodyGen callback of these loops, `createScan` would be called
859 /// when a scan directive is encountered from the loop body. `createScan`
860 /// based on whether 1. inclusive or exclusive scan is specified and, 2. input
861 /// loop or scan loop is generated, lowers the body of the for loop
862 /// accordingly.
863 ///
864 /// \param Loc The insert and source location description.
865 /// \param BodyGenCB Callback that will generate the loop body code.
866 /// \param Start Value of the loop counter for the first iterations.
867 /// \param Stop Loop counter values past this will stop the loop.
868 /// \param Step Loop counter increment after each iteration; negative
869 /// means counting down.
870 /// \param IsSigned Whether Start, Stop and Step are signed integers.
871 /// \param InclusiveStop Whether \p Stop itself is a valid value for the loop
872 /// counter.
873 /// \param ComputeIP Insertion point for instructions computing the trip
874 /// count. Can be used to ensure the trip count is available
875 /// at the outermost loop of a loop nest. If not set,
876 /// defaults to the preheader of the generated loop.
877 /// \param Name Base name used to derive BB and instruction names.
878 /// \param ScanRedInfo Pointer to the ScanInfo objected created using
879 /// `ScanInfoInitialize`.
880 ///
881 /// \returns A vector containing Loop Info of Input Loop and Scan Loop.
884 LoopBodyGenCallbackTy BodyGenCB, Value *Start,
885 Value *Stop, Value *Step, bool IsSigned,
886 bool InclusiveStop, InsertPointTy ComputeIP,
887 const Twine &Name, ScanInfo *ScanRedInfo);
888
889 /// Calculate the trip count of a canonical loop.
890 ///
891 /// This allows specifying user-defined loop counter values using increment,
892 /// upper- and lower bounds. To disambiguate the terminology when counting
893 /// downwards, instead of lower bounds we use \p Start for the loop counter
894 /// value in the first body iteration.
895 ///
896 /// Consider the following limitations:
897 ///
898 /// * A loop counter space over all integer values of its bit-width cannot be
899 /// represented. E.g using uint8_t, its loop trip count of 256 cannot be
900 /// stored into an 8 bit integer):
901 ///
902 /// DO I = 0, 255, 1
903 ///
904 /// * Unsigned wrapping is only supported when wrapping only "once"; E.g.
905 /// effectively counting downwards:
906 ///
907 /// for (uint8_t i = 100u; i > 0; i += 127u)
908 ///
909 ///
910 /// TODO: May need to add additional parameters to represent:
911 ///
912 /// * Allow representing downcounting with unsigned integers.
913 ///
914 /// * Sign of the step and the comparison operator might disagree:
915 ///
916 /// for (int i = 0; i < 42; i -= 1u)
917 ///
918 /// \param Loc The insert and source location description.
919 /// \param Start Value of the loop counter for the first iterations.
920 /// \param Stop Loop counter values past this will stop the loop.
921 /// \param Step Loop counter increment after each iteration; negative
922 /// means counting down.
923 /// \param IsSigned Whether Start, Stop and Step are signed integers.
924 /// \param InclusiveStop Whether \p Stop itself is a valid value for the loop
925 /// counter.
926 /// \param Name Base name used to derive instruction names.
927 ///
928 /// \returns The value holding the calculated trip count.
930 const LocationDescription &Loc, Value *Start, Value *Stop, Value *Step,
931 bool IsSigned, bool InclusiveStop, const Twine &Name = "loop");
932
933 /// Generator for the control flow structure of an OpenMP canonical loop.
934 ///
935 /// Instead of a logical iteration space, this allows specifying user-defined
936 /// loop counter values using increment, upper- and lower bounds. To
937 /// disambiguate the terminology when counting downwards, instead of lower
938 /// bounds we use \p Start for the loop counter value in the first body
939 ///
940 /// It calls \see calculateCanonicalLoopTripCount for trip count calculations,
941 /// so limitations of that method apply here as well.
942 ///
943 /// \param Loc The insert and source location description.
944 /// \param BodyGenCB Callback that will generate the loop body code.
945 /// \param Start Value of the loop counter for the first iterations.
946 /// \param Stop Loop counter values past this will stop the loop.
947 /// \param Step Loop counter increment after each iteration; negative
948 /// means counting down.
949 /// \param IsSigned Whether Start, Stop and Step are signed integers.
950 /// \param InclusiveStop Whether \p Stop itself is a valid value for the loop
951 /// counter.
952 /// \param ComputeIP Insertion point for instructions computing the trip
953 /// count. Can be used to ensure the trip count is available
954 /// at the outermost loop of a loop nest. If not set,
955 /// defaults to the preheader of the generated loop.
956 /// \param Name Base name used to derive BB and instruction names.
957 /// \param InScan Whether loop has a scan reduction specified.
958 /// \param ScanRedInfo Pointer to the ScanInfo objected created using
959 /// `ScanInfoInitialize`.
960 ///
961 /// \returns An object representing the created control flow structure which
962 /// can be used for loop-associated directives.
965 Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
966 InsertPointTy ComputeIP = {}, const Twine &Name = "loop",
967 bool InScan = false, ScanInfo *ScanRedInfo = nullptr);
968
969 /// Strategy used to derive the original induction variables after collapse.
971
972 /// Collapse a loop nest using Config.CollapseMapping.
973 /// Two mappings are supported: DivMod and Virtual.
974 ///
975 /// The DivMod mapping works as follows.
976 ///
977 /// Merges loops of a loop nest into a single CanonicalLoopNest representation
978 /// that has the same number of innermost loop iterations as the origin loop
979 /// nest. The induction variables of the input loops are derived from the
980 /// collapsed loop's induction variable. This is intended to be used to
981 /// implement OpenMP's collapse clause. Before applying a directive,
982 /// collapseLoops normalizes a loop nest to contain only a single loop and the
983 /// directive's implementation does not need to handle multiple loops itself.
984 /// This does not remove the need to handle all loop nest handling by
985 /// directives, such as the ordered(<n>) clause or the simd schedule-clause
986 /// modifier of the worksharing-loop directive.
987 ///
988 /// Example:
989 /// \code
990 /// for (int i = 0; i < 7; ++i) // Canonical loop "i"
991 /// for (int j = 0; j < 9; ++j) // Canonical loop "j"
992 /// body(i, j);
993 /// \endcode
994 ///
995 /// After collapsing with Loops={i,j}, the loop is changed to
996 /// \code
997 /// for (int ij = 0; ij < 63; ++ij) {
998 /// int i = ij / 9;
999 /// int j = ij % 9;
1000 /// body(i, j);
1001 /// }
1002 /// \endcode
1003 ///
1004 /// In the current implementation, the following limitations apply:
1005 ///
1006 /// * All input loops have an induction variable of the same type.
1007 ///
1008 /// * The collapsed loop will have the same trip count integer type as the
1009 /// input loops. Therefore it is possible that the collapsed loop cannot
1010 /// represent all iterations of the input loops. For instance, assuming a
1011 /// 32 bit integer type, and two input loops both iterating 2^16 times, the
1012 /// theoretical trip count of the collapsed loop would be 2^32 iteration,
1013 /// which cannot be represented in an 32-bit integer. Behavior is undefined
1014 /// in this case.
1015 ///
1016 /// * The trip counts of every input loop must be available at \p ComputeIP.
1017 /// Non-rectangular loops are not yet supported.
1018 ///
1019 /// * At each nest level, code between a surrounding loop and its nested loop
1020 /// is hoisted into the loop body, and such code will be executed more
1021 /// often than before collapsing (or not at all if any inner loop iteration
1022 /// has a trip count of 0). This is permitted by the OpenMP specification.
1023 ///
1024 /// The Virtual mapping retains the nest. Threads receive ranges of one
1025 /// unsigned logical index spanning inner-loop invocations. For [b,b+n),
1026 /// decode the start once and use a remaining-iteration budget:
1027 ///
1028 /// if (n != 0) {
1029 /// unsigned remaining = n + b % 9;
1030 /// for (unsigned i = b / 9, start = b % 9; i < 7; ++i, start = 0) {
1031 /// for (unsigned j = start; j < min(remaining, 9u); ++j)
1032 /// body(i, j);
1033 /// if (remaining <= 9) break;
1034 /// remaining -= 9;
1035 /// }
1036 /// }
1037 ///
1038 /// Virtual shares DivMod's type and trip-count limits. Intervening code stays
1039 /// at its level, once per range touching that row; empty ranges skip it.
1040 /// Two constant-count loops and direct body-to-preheader/after-to-latch edges
1041 /// are required. Controls must retain form and be unobserved after the nest.
1042 /// Only host static worksharing without chunk or ordered is supported.
1043 /// SIMD, transforms of the result and logical body/IV access are unsupported.
1044 /// MLIR falls back to DivMod; API callers must choose a supported mapping.
1045 ///
1046 /// \param DL Debug location for instructions added for collapsing,
1047 /// such as instructions to compute/derive the input loop's
1048 /// induction variables.
1049 /// \param Loops Loops in the loop nest to collapse. Loops are specified
1050 /// from outermost-to-innermost and every control flow of a
1051 /// loop's body must pass through its directly nested loop.
1052 /// \param ComputeIP Where additional instruction that compute the collapsed
1053 /// trip count. If not set, defaults to before the generated
1054 /// loop.
1055 ///
1056 /// \returns The CanonicalLoopInfo object representing the collapsed loop.
1059 InsertPointTy ComputeIP);
1060
1061 /// Get the default alignment value for given target
1062 ///
1063 /// \param TargetTriple Target triple
1064 /// \param Features StringMap which describes extra CPU features
1065 LLVM_ABI static unsigned
1066 getOpenMPDefaultSimdAlign(const Triple &TargetTriple,
1067 const StringMap<bool> &Features);
1068
1069 /// Retrieve (or create if non-existent) the address of a declare
1070 /// target variable, used in conjunction with registerTargetGlobalVariable
1071 /// to create declare target global variables.
1072 ///
1073 /// \param CaptureClause - enumerator corresponding to the OpenMP capture
1074 /// clause used in conjunction with the variable being registered (link,
1075 /// to, enter).
1076 /// \param DeviceClause - enumerator corresponding to the OpenMP capture
1077 /// clause used in conjunction with the variable being registered (nohost,
1078 /// host, any)
1079 /// \param IsDeclaration - boolean stating if the variable being registered
1080 /// is a declaration-only and not a definition
1081 /// \param IsExternallyVisible - boolean stating if the variable is externally
1082 /// visible
1083 /// \param EntryInfo - Unique entry information for the value generated
1084 /// using getTargetEntryUniqueInfo, used to name generated pointer references
1085 /// to the declare target variable
1086 /// \param MangledName - the mangled name of the variable being registered
1087 /// \param GeneratedRefs - references generated by invocations of
1088 /// registerTargetGlobalVariable invoked from getAddrOfDeclareTargetVar,
1089 /// these are required by Clang for book keeping.
1090 /// \param OpenMPSIMD - if OpenMP SIMD mode is currently enabled
1091 /// \param TargetTriple - The OpenMP device target triple we are compiling
1092 /// for
1093 /// \param LlvmPtrTy - The type of the variable we are generating or
1094 /// retrieving an address for
1095 /// \param GlobalInitializer - a lambda function which creates a constant
1096 /// used for initializing a pointer reference to the variable in certain
1097 /// cases. If a nullptr is passed, it will default to utilising the original
1098 /// variable to initialize the pointer reference.
1099 /// \param VariableLinkage - a lambda function which returns the variables
1100 /// linkage type, if unspecified and a nullptr is given, it will instead
1101 /// utilise the linkage stored on the existing global variable in the
1102 /// LLVMModule.
1106 bool IsDeclaration, bool IsExternallyVisible,
1107 TargetRegionEntryInfo EntryInfo, StringRef MangledName,
1108 std::vector<GlobalVariable *> &GeneratedRefs, bool OpenMPSIMD,
1109 std::vector<Triple> TargetTriple, Type *LlvmPtrTy,
1110 std::function<Constant *()> GlobalInitializer,
1111 std::function<GlobalValue::LinkageTypes()> VariableLinkage);
1112
1113 /// Registers a target variable for device or host.
1114 ///
1115 /// \param CaptureClause - enumerator corresponding to the OpenMP capture
1116 /// clause used in conjunction with the variable being registered (link,
1117 /// to, enter).
1118 /// \param DeviceClause - enumerator corresponding to the OpenMP capture
1119 /// clause used in conjunction with the variable being registered (nohost,
1120 /// host, any)
1121 /// \param IsDeclaration - boolean stating if the variable being registered
1122 /// is a declaration-only and not a definition
1123 /// \param IsExternallyVisible - boolean stating if the variable is externally
1124 /// visible
1125 /// \param EntryInfo - Unique entry information for the value generated
1126 /// using getTargetEntryUniqueInfo, used to name generated pointer references
1127 /// to the declare target variable
1128 /// \param MangledName - the mangled name of the variable being registered
1129 /// \param GeneratedRefs - references generated by invocations of
1130 /// registerTargetGlobalVariable these are required by Clang for book
1131 /// keeping.
1132 /// \param OpenMPSIMD - if OpenMP SIMD mode is currently enabled
1133 /// \param TargetTriple - The OpenMP device target triple we are compiling
1134 /// for
1135 /// \param GlobalInitializer - a lambda function which creates a constant
1136 /// used for initializing a pointer reference to the variable in certain
1137 /// cases. If a nullptr is passed, it will default to utilising the original
1138 /// variable to initialize the pointer reference.
1139 /// \param VariableLinkage - a lambda function which returns the variables
1140 /// linkage type, if unspecified and a nullptr is given, it will instead
1141 /// utilise the linkage stored on the existing global variable in the
1142 /// LLVMModule.
1143 /// \param LlvmPtrTy - The type of the variable we are generating or
1144 /// retrieving an address for
1145 /// \param Addr - the original llvm value (addr) of the variable to be
1146 /// registered
1150 bool IsDeclaration, bool IsExternallyVisible,
1151 TargetRegionEntryInfo EntryInfo, StringRef MangledName,
1152 std::vector<GlobalVariable *> &GeneratedRefs, bool OpenMPSIMD,
1153 std::vector<Triple> TargetTriple,
1154 std::function<Constant *()> GlobalInitializer,
1155 std::function<GlobalValue::LinkageTypes()> VariableLinkage,
1156 Type *LlvmPtrTy, Constant *Addr);
1157
1158 /// Register a module-scope replacement of a declare target global variable.
1159 /// During lowering new globals are generated for certain combinations of
1160 /// declare target input, and these new globals require substitution with
1161 /// the originals. This replacement occurs during finalization where uses
1162 /// of \p Original are rewritten to reference \p Replacement. This is
1163 /// predominantly required for lowering through the LLVM-IR + OpenMP
1164 /// dialect infrastructure where the lowering pattern to LLVM-IR prevents
1165 /// immediate use rewrites.
1166 ///
1167 /// This infrastructure is utilised for the device pass only currently,
1168 /// and host passes will skip the finalization process even if replacements
1169 /// are registered.
1170 ///
1171 /// \param Original - The original global variable that will be replaced.
1172 /// \param Replacement - The replacement reference pointer generated by the
1173 /// declare target infrastructure (declare target link or unified shared
1174 /// memory globals).
1175 LLVM_ABI void
1177 GlobalValue *Replacement);
1178
1179 /// Get the offset of the OMP_MAP_MEMBER_OF field.
1180 LLVM_ABI unsigned getFlagMemberOffset();
1181
1182 /// Get OMP_MAP_MEMBER_OF flag with extra bits reserved based on
1183 /// the position given.
1184 /// \param Position - A value indicating the position of the parent
1185 /// of the member in the kernel argument structure, often retrieved
1186 /// by the parents position in the combined information vectors used
1187 /// to generate the structure itself. Multiple children (member's of)
1188 /// with the same parent will use the same returned member flag.
1190
1191 /// Given an initial flag set, this function modifies it to contain
1192 /// the passed in MemberOfFlag generated from the getMemberOfFlag
1193 /// function. The results are dependent on the existing flag bits
1194 /// set in the original flag set.
1195 /// \param Flags - The original set of flags to be modified with the
1196 /// passed in MemberOfFlag.
1197 /// \param MemberOfFlag - A modified OMP_MAP_MEMBER_OF flag, adjusted
1198 /// slightly based on the getMemberOfFlag which adjusts the flag bits
1199 /// based on the members position in its parent.
1200 LLVM_ABI void
1202 omp::OpenMPOffloadMappingFlags MemberOfFlag);
1203
1204private:
1205 /// Attach unroll metadata only to supported logical iteration loops.
1206 void addUnrollMetadata(CanonicalLoopInfo *Loop,
1207 ArrayRef<Metadata *> Properties);
1208 /// Input loop blocks, induction variables, and inner comparison used to
1209 /// build the Virtual row executor. Collected before modifying the CFG.
1210 struct VirtualRowPlan;
1211 /// Collect the input loop blocks, induction variables, and inner comparison.
1212 /// Require direct nesting; reject an indirectbr terminator in the innermost
1213 /// after block. Report a fatal error before changing IR.
1215 /// Generate IR for Count logical iterations starting at Begin, keeping the
1216 /// original loops. Decode Begin once in Entry, limit the final inner-loop
1217 /// execution, and exit the nest when the assigned range is complete.
1218 void createVirtualRowExecutor(CanonicalLoopInfo *Result,
1219 const VirtualRowPlan &Plan,
1220 ArrayRef<Value *> TripCounts, Value *Begin,
1221 Value *Count, BasicBlock *Entry);
1222 /// Create a Virtual CanonicalLoopInfo using the outer loop's control blocks.
1223 /// Initialize Begin/Count for the full nest and skip empty ranges. Build the
1224 /// executor, then invalidate the input CanonicalLoopInfo objects.
1226 createVirtualCollapsedLoop(DebugLoc DL, ArrayRef<CanonicalLoopInfo *> Loops,
1227 const VirtualRowPlan &Plan,
1228 ArrayRef<Value *> TripCounts,
1229 Value *CollapsedTripCount);
1230 /// Update the Begin and Count copies with the scheduler's range.
1231 /// Use the scheduler's values unchanged, without validation or clipping.
1232 void bindCollapsedRange(CanonicalLoopInfo *Loop, Value *Begin, Value *Count);
1233
1234 /// Modifies the canonical loop to be a statically-scheduled workshare loop
1235 /// which is executed on the device
1236 ///
1237 /// This takes a \p CLI representing a canonical loop, such as the one
1238 /// created by \see createCanonicalLoop and emits additional instructions to
1239 /// turn it into a workshare loop. In particular, it calls to an OpenMP
1240 /// runtime function in the preheader to call OpenMP device rtl function
1241 /// which handles worksharing of loop body interations.
1242 ///
1243 /// \param DL Debug location for instructions added for the
1244 /// workshare-loop construct itself.
1245 /// \param CLI A descriptor of the canonical loop to workshare.
1246 /// \param AllocaIP An insertion point for Alloca instructions usable in the
1247 /// preheader of the loop.
1248 /// \param LoopType Information about type of loop worksharing.
1249 /// It corresponds to type of loop workshare OpenMP pragma.
1250 /// \param NeedsBarrier Indicates whether a barrier must be inserted after
1251 /// the loop.
1252 /// \param NoLoop If true, no-loop code is generated.
1253 /// \param NeedsLastIter If true, the last iteration variable is emitted.
1254 ///
1255 /// \returns Point where to insert code after the workshare construct.
1257 applyWorkshareLoopTarget(DebugLoc DL, CanonicalLoopInfo *CLI,
1258 InsertPointTy AllocaIP,
1259 omp::WorksharingLoopType LoopType, bool NeedsBarrier,
1260 bool NoLoop, bool NeedsLastIter);
1261
1262 /// Modifies the canonical loop to be a statically-scheduled workshare loop.
1263 ///
1264 /// This takes a \p LoopInfo representing a canonical loop, such as the one
1265 /// created by \p createCanonicalLoop and emits additional instructions to
1266 /// turn it into a workshare loop. In particular, it calls to an OpenMP
1267 /// runtime function in the preheader to obtain the loop bounds to be used in
1268 /// the current thread, updates the relevant instructions in the canonical
1269 /// loop and calls to an OpenMP runtime finalization function after the loop.
1270 ///
1271 /// \param DL Debug location for instructions added for the
1272 /// workshare-loop construct itself.
1273 /// \param CLI A descriptor of the canonical loop to workshare.
1274 /// \param AllocaIP An insertion point for Alloca instructions usable in the
1275 /// preheader of the loop.
1276 /// \param NeedsBarrier Indicates whether a barrier must be inserted after
1277 /// the loop.
1278 /// \param LoopType Type of workshare loop.
1279 /// \param HasDistSchedule Defines if the clause being lowered is
1280 /// dist_schedule as this is handled slightly differently
1281 /// \param DistScheduleSchedType Defines the Schedule Type for the Distribute
1282 /// loop. Defaults to None if no Distribute loop is present.
1283 ///
1284 /// \returns Point where to insert code after the workshare construct.
1285 InsertPointOrErrorTy applyStaticWorkshareLoop(
1287 omp::WorksharingLoopType LoopType, bool NeedsBarrier,
1288 bool HasDistSchedule = false,
1289 omp::OMPScheduleType DistScheduleSchedType = omp::OMPScheduleType::None);
1290
1291 /// Modifies the canonical loop a statically-scheduled workshare loop with a
1292 /// user-specified chunk size.
1293 ///
1294 /// \param DL Debug location for instructions added for the
1295 /// workshare-loop construct itself.
1296 /// \param CLI A descriptor of the canonical loop to workshare.
1297 /// \param AllocaIP An insertion point for Alloca instructions usable in
1298 /// the preheader of the loop.
1299 /// \param NeedsBarrier Indicates whether a barrier must be inserted after the
1300 /// loop.
1301 /// \param ChunkSize The user-specified chunk size.
1302 /// \param SchedType Optional type of scheduling to be passed to the init
1303 /// function.
1304 /// \param DistScheduleChunkSize The size of dist_shcedule chunk considered
1305 /// as a unit when
1306 /// scheduling. If \p nullptr, defaults to 1.
1307 /// \param DistScheduleSchedType Defines the Schedule Type for the Distribute
1308 /// loop. Defaults to None if no Distribute loop is present.
1309 ///
1310 /// \returns Point where to insert code after the workshare construct.
1311 InsertPointOrErrorTy applyStaticChunkedWorkshareLoop(
1313 bool NeedsBarrier, Value *ChunkSize,
1314 omp::OMPScheduleType SchedType =
1316 Value *DistScheduleChunkSize = nullptr,
1317 omp::OMPScheduleType DistScheduleSchedType = omp::OMPScheduleType::None);
1318
1319 /// Modifies the canonical loop to be a dynamically-scheduled workshare loop.
1320 ///
1321 /// This takes a \p LoopInfo representing a canonical loop, such as the one
1322 /// created by \p createCanonicalLoop and emits additional instructions to
1323 /// turn it into a workshare loop. In particular, it calls to an OpenMP
1324 /// runtime function in the preheader to obtain, and then in each iteration
1325 /// to update the loop counter.
1326 ///
1327 /// \param DL Debug location for instructions added for the
1328 /// workshare-loop construct itself.
1329 /// \param CLI A descriptor of the canonical loop to workshare.
1330 /// \param AllocaIP An insertion point for Alloca instructions usable in the
1331 /// preheader of the loop.
1332 /// \param SchedType Type of scheduling to be passed to the init function.
1333 /// \param NeedsBarrier Indicates whether a barrier must be insterted after
1334 /// the loop.
1335 /// \param Chunk The size of loop chunk considered as a unit when
1336 /// scheduling. If \p nullptr, defaults to 1.
1337 ///
1338 /// \returns Point where to insert code after the workshare construct.
1339 InsertPointOrErrorTy applyDynamicWorkshareLoop(DebugLoc DL,
1340 CanonicalLoopInfo *CLI,
1341 InsertPointTy AllocaIP,
1342 omp::OMPScheduleType SchedType,
1343 bool NeedsBarrier,
1344 Value *Chunk = nullptr);
1345
1346 /// Create alternative version of the loop to support if clause
1347 ///
1348 /// OpenMP if clause can require to generate second loop. This loop
1349 /// will be executed when if clause condition is not met. createIfVersion
1350 /// adds branch instruction to the copied loop if \p ifCond is not met.
1351 ///
1352 /// \param Loop Original loop which should be versioned.
1353 /// \param IfCond Value which corresponds to if clause condition
1354 /// \param VMap Value to value map to define relation between
1355 /// original and copied loop values and loop blocks.
1356 /// \param NamePrefix Optional name prefix for if.then if.else blocks.
1357 void createIfVersion(CanonicalLoopInfo *Loop, Value *IfCond,
1359 LoopAnalysis &LIA, LoopInfo &LI, llvm::Loop *L,
1360 const Twine &NamePrefix = "");
1361
1362 /// Creates a task duplication function to be passed to kmpc_taskloop.
1363 ///
1364 /// The OpenMP runtime defines this function as taking the destination
1365 /// kmp_task_t, source kmp_task_t, and a lastprivate flag. This function is
1366 /// called on the source and destination tasks after the source task has been
1367 /// duplicated to create the destination task. At this point the destination
1368 /// task has been otherwise set up from the runtime's perspective, but this
1369 /// function is needed to fix up any data for the duplicated task e.g. private
1370 /// variables with non-trivial constructors.
1371 ///
1372 /// \param PrivatesTy The type of the privates structure for the task.
1373 /// \param PrivatesIndex The index inside the privates structure containing
1374 /// the data for the callback.
1375 /// \param DupCB The callback to generate the duplication code. See
1376 /// documentation for \ref TaskDupCallbackTy. This can be
1377 /// nullptr.
1378 Expected<Value *> createTaskDuplicationFunction(Type *PrivatesTy,
1379 int32_t PrivatesIndex,
1380 TaskDupCallbackTy DupCB);
1381
1382public:
1383 /// Modifies the canonical loop to be a workshare loop.
1384 ///
1385 /// This takes a \p LoopInfo representing a canonical loop, such as the one
1386 /// created by \p createCanonicalLoop and emits additional instructions to
1387 /// turn it into a workshare loop. In particular, it calls to an OpenMP
1388 /// runtime function in the preheader to obtain the loop bounds to be used in
1389 /// the current thread, updates the relevant instructions in the canonical
1390 /// loop and calls to an OpenMP runtime finalization function after the loop.
1391 ///
1392 /// The concrete transformation is done by applyStaticWorkshareLoop,
1393 /// applyStaticChunkedWorkshareLoop, or applyDynamicWorkshareLoop, depending
1394 /// on the value of \p SchedKind and \p ChunkSize.
1395 ///
1396 /// \param DL Debug location for instructions added for the
1397 /// workshare-loop construct itself.
1398 /// \param CLI A descriptor of the canonical loop to workshare.
1399 /// \param AllocaIP An insertion point for Alloca instructions usable in the
1400 /// preheader of the loop.
1401 /// \param NeedsBarrier Indicates whether a barrier must be insterted after
1402 /// the loop.
1403 /// \param SchedKind Scheduling algorithm to use.
1404 /// \param ChunkSize The chunk size for the inner loop.
1405 /// \param HasSimdModifier Whether the simd modifier is present in the
1406 /// schedule clause.
1407 /// \param HasMonotonicModifier Whether the monotonic modifier is present in
1408 /// the schedule clause.
1409 /// \param HasNonmonotonicModifier Whether the nonmonotonic modifier is
1410 /// present in the schedule clause.
1411 /// \param HasOrderedClause Whether the (parameterless) ordered clause is
1412 /// present.
1413 /// \param LoopType Information about type of loop worksharing.
1414 /// It corresponds to type of loop workshare OpenMP pragma.
1415 /// \param NoLoop If true, no-loop code is generated.
1416 /// \param HasDistSchedule Defines if the clause being lowered is
1417 /// dist_schedule as this is handled slightly differently
1418 /// \param DistScheduleChunkSize The chunk size for dist_schedule loop
1419 /// \param NeedsLastIter If true, the last iteration variable is emitted.
1420 ///
1421 /// \returns Point where to insert code after the workshare construct.
1424 bool NeedsBarrier,
1425 llvm::omp::ScheduleKind SchedKind = llvm::omp::OMP_SCHEDULE_Default,
1426 Value *ChunkSize = nullptr, bool HasSimdModifier = false,
1427 bool HasMonotonicModifier = false, bool HasNonmonotonicModifier = false,
1428 bool HasOrderedClause = false,
1429 omp::WorksharingLoopType LoopType =
1431 bool NoLoop = false, bool HasDistSchedule = false,
1432 Value *DistScheduleChunkSize = nullptr, bool NeedsLastIter = false);
1433
1434 /// Tile a loop nest.
1435 ///
1436 /// Tiles the loops of \p Loops by the tile sizes in \p TileSizes. Loops in
1437 /// \p/ Loops must be perfectly nested, from outermost to innermost loop
1438 /// (i.e. Loops.front() is the outermost loop). The trip count llvm::Value
1439 /// of every loop and every tile sizes must be usable in the outermost
1440 /// loop's preheader. This implies that the loop nest is rectangular.
1441 ///
1442 /// Example:
1443 /// \code
1444 /// for (int i = 0; i < 15; ++i) // Canonical loop "i"
1445 /// for (int j = 0; j < 14; ++j) // Canonical loop "j"
1446 /// body(i, j);
1447 /// \endcode
1448 ///
1449 /// After tiling with Loops={i,j} and TileSizes={5,7}, the loop is changed to
1450 /// \code
1451 /// for (int i1 = 0; i1 < 3; ++i1)
1452 /// for (int j1 = 0; j1 < 2; ++j1)
1453 /// for (int i2 = 0; i2 < 5; ++i2)
1454 /// for (int j2 = 0; j2 < 7; ++j2)
1455 /// body(i1*3+i2, j1*3+j2);
1456 /// \endcode
1457 ///
1458 /// The returned vector are the loops {i1,j1,i2,j2}. The loops i1 and j1 are
1459 /// referred to the floor, and the loops i2 and j2 are the tiles. Tiling also
1460 /// handles non-constant trip counts, non-constant tile sizes and trip counts
1461 /// that are not multiples of the tile size. In the latter case the tile loop
1462 /// of the last floor-loop iteration will have fewer iterations than specified
1463 /// as its tile size.
1464 ///
1465 ///
1466 /// @param DL Debug location for instructions added by tiling, for
1467 /// instance the floor- and tile trip count computation.
1468 /// @param Loops Loops to tile. The CanonicalLoopInfo objects are
1469 /// invalidated by this method, i.e. should not used after
1470 /// tiling.
1471 /// @param TileSizes For each loop in \p Loops, the tile size for that
1472 /// dimensions.
1473 ///
1474 /// \returns A list of generated loops. Contains twice as many loops as the
1475 /// input loop nest; the first half are the floor loops and the
1476 /// second half are the tile loops.
1477 LLVM_ABI std::vector<CanonicalLoopInfo *>
1479 ArrayRef<Value *> TileSizes);
1480
1481 /// Fuse a sequence of loops.
1482 ///
1483 /// Fuses the loops of \p Loops.
1484 /// The merging of the loops is done in the following structure:
1485 ///
1486 /// Example:
1487 /// \code
1488 /// for (int i = lb0; i < ub0; i += st0) // trip count is calculated as:
1489 /// body(i) // tc0 = (ub0 - lb0 + st0) / st0
1490 /// for (int j = lb1; j < ub1; j += st1)
1491 /// body(j);
1492 ///
1493 /// ...
1494 ///
1495 /// for (int k = lbk; j < ubk; j += stk)
1496 /// body(k);
1497 /// \endcode
1498 ///
1499 /// After fusing the loops a single loop is left:
1500 /// \code
1501 /// for (fuse.index = 0; fuse.index < max(tc0, tc1, ... tck); ++fuse.index) {
1502 /// if (fuse.index < tc0){
1503 /// iv0 = lb0 + st0 * fuse.index;
1504 /// original.index0 = iv0
1505 /// body(0);
1506 /// }
1507 /// if (fuse.index < tc1){
1508 /// iv1 = lb1 + st1 * fuse.index;
1509 /// original.index1 = iv1
1510 /// body(1);
1511 /// }
1512 ///
1513 /// ...
1514 ///
1515 /// if (fuse.index < tck){
1516 /// ivk = lbk + stk * fuse.index;
1517 /// original.indexk = ivk
1518 /// body(k);
1519 /// }
1520 /// }
1521 /// \endcode
1522 ///
1523 ///
1524 /// @param DL Debug location for instructions added by fusion.
1525 ///
1526 /// @param Loops Loops to fuse. The CanonicalLoopInfo objects are
1527 /// invalidated by this method, i.e. should not used after
1528 /// fusion.
1529 ///
1530 /// \returns A single loop generated by the loop fusion
1533
1534 /// Fully unroll a loop.
1535 ///
1536 /// Instead of unrolling the loop immediately (and duplicating its body
1537 /// instructions), it is deferred to LLVM's LoopUnrollPass by adding loop
1538 /// metadata.
1539 ///
1540 /// \param DL Debug location for instructions added by unrolling.
1541 /// \param Loop The loop to unroll. The loop will be invalidated.
1543
1544 /// Fully or partially unroll a loop. How the loop is unrolled is determined
1545 /// using LLVM's LoopUnrollPass.
1546 ///
1547 /// \param DL Debug location for instructions added by unrolling.
1548 /// \param Loop The loop to unroll. The loop will be invalidated.
1550
1551 /// Partially unroll a loop.
1552 ///
1553 /// The CanonicalLoopInfo of the unrolled loop for use with chained
1554 /// loop-associated directive can be requested using \p UnrolledCLI. Not
1555 /// needing the CanonicalLoopInfo allows more efficient code generation by
1556 /// deferring the actual unrolling to the LoopUnrollPass using loop metadata.
1557 /// A loop-associated directive applied to the unrolled loop needs to know the
1558 /// new trip count, so if the CanonicalLoopInfo is requested with \p Factor ==
1559 /// 0, omp::DefaultPartialUnrollFactor is used.
1560 ///
1561 /// \param DL Debug location for instructions added by unrolling.
1562 /// \param Loop The loop to unroll. The loop will be invalidated.
1563 /// \param Factor The factor to unroll the loop by. A factor of 0
1564 /// leaves the choice of unroll-factor to the
1565 /// implementation.
1566 /// \param UnrolledCLI If non-null, receives the CanonicalLoopInfo of the
1567 /// partially unrolled loop. Otherwise, uses loop metadata
1568 /// to defer unrolling to the LoopUnrollPass.
1570 int32_t Factor,
1571 CanonicalLoopInfo **UnrolledCLI);
1572
1573 /// Add metadata to simd-ize a loop. If IfCond is not nullptr, the loop
1574 /// is cloned. The metadata which prevents vectorization is added to
1575 /// to the cloned loop. The cloned loop is executed when ifCond is evaluated
1576 /// to false.
1577 ///
1578 /// \param Loop The loop to simd-ize.
1579 /// \param AlignedVars The map which containts pairs of the pointer
1580 /// and its corresponding alignment.
1581 /// \param IfCond The value which corresponds to the if clause
1582 /// condition.
1583 /// \param Order The enum to map order clause.
1584 /// \param Simdlen The Simdlen length to apply to the simd loop.
1585 /// \param Safelen The Safelen length to apply to the simd loop.
1587 MapVector<Value *, Value *> AlignedVars,
1588 Value *IfCond, omp::OrderKind Order,
1589 ConstantInt *Simdlen, ConstantInt *Safelen);
1590
1591 /// Generator for '#omp flush'
1592 ///
1593 /// \param Loc The location where the flush directive was encountered
1595
1596 /// Generate a call to the runtime to emit the diagnostic of an OpenMP
1597 /// `error` directive with `at(execution)`.
1598 ///
1599 /// \param Loc The location where the error directive was encountered; it is
1600 /// used to build the `ident_t` passed to the runtime.
1601 /// \param IsFatal Selects `severity(fatal)` (true) or `severity(warning)`
1602 /// (false).
1603 /// \param Message The message string (an `i8*`) to display, or null when no
1604 /// `message` clause is present.
1605 LLVM_ABI void createError(const LocationDescription &Loc, bool IsFatal,
1606 Value *Message);
1607
1608 /// Generator for '#omp taskyield'
1609 ///
1610 /// \param Loc The location where the taskyield directive was encountered.
1612
1613 /// A struct to pack the relevant information for an OpenMP depend clause.
1623
1624 /// A struct to pack static and dynamic dependency information for a task.
1625 ///
1626 /// For fixed-count (non-iterator) dependencies, callers populate \p Deps
1627 /// and the builder allocates and fills the kmp_depend_info array internally.
1628 /// For iterator-based dependencies, the caller pre-builds the array and
1629 /// sets \p NumDeps and \p DepArray directly.
1631 SmallVector<DependData> Deps; // vector of dependencies
1632 Value *NumDeps; // number of kmp_depend_info entries (used by iterator path)
1633 Value *DepArray; // kmp_depend_info array (used by iterator path)
1634
1635 DependenciesInfo() : Deps(), NumDeps(nullptr), DepArray(nullptr) {}
1638
1639 bool empty() const { return Deps.empty() && DepArray == nullptr; }
1640 };
1641
1642 /// Store one kmp_depend_info entry at the given \p Entry pointer.
1643 LLVM_ABI void emitTaskDependency(IRBuilderBase &Builder, Value *Entry,
1644 const DependData &Dep);
1645
1646 /// Generator for '#omp taskwait'
1647 ///
1648 /// \param Loc The location where the taskwait directive was encountered.
1649 /// \param Dependencies dependencies as specified by the 'depend' clause.
1650 /// \param IsNowait True when a 'nowait' clause is present
1651 LLVM_ABI void createTaskwait(const LocationDescription &Loc,
1652 DependenciesInfo Dependencies = {},
1653 bool IsNowait = false);
1654
1655 /// Return the LLVM struct type matching runtime `kmp_task_affinity_info_t`.
1656 /// `{ kmp_intptr_t base_addr; size_t len; flags (bitfield storage as i32) }`
1658
1659 /// A struct to pack the relevant information for an OpenMP affinity clause.
1661 Value *Count; // number of kmp_task_affinity_info_t entries
1662 Value *Info; // kmp_task_affinity_info_t
1663 };
1664
1665 /// Generator for `#omp taskloop`
1666 ///
1667 /// \param Loc The location where the taskloop construct was encountered.
1668 /// \param AllocaIP The insertion point to be used for alloca instructions.
1669 /// \param DeallocBlocks The list of insertion blocks where explicit
1670 /// deallocations, if needed, should be placed.
1671 /// \param BodyGenCB Callback that will generate the region code.
1672 /// \param LoopInfo Callback that return the CLI
1673 /// \param LBVal Lowerbound value of loop
1674 /// \param UBVal Upperbound value of loop
1675 /// \param StepVal Step value of loop
1676 /// \param Untied True if the task is untied, false if the task is tied.
1677 /// \param IfCond i1 value. If it evaluates to `false`, an undeferred
1678 /// task is generated, and the encountering thread must
1679 /// suspend the current task region, for which execution
1680 /// cannot be resumed until execution of the structured
1681 /// block that is associated with the generated task is
1682 /// completed.
1683 /// \param GrainSize Value of the GrainSize/Num of Tasks if present
1684 /// \param NoGroup False if NoGroup is defined, true if not
1685 /// \param Sched If Grainsize is defined, Sched is 1. Num Tasks, Shed is 2.
1686 /// Otherwise Sched is 0
1687 /// \param Final i1 value which is `true` if the task is final, `false` if the
1688 /// task is not final.
1689 /// \param Mergeable If the given task is `mergeable`
1690 /// \param Priority `priority-value' specifies the execution order of the
1691 /// tasks that is generated by the construct
1692 /// \param NumOfCollapseLoops Defines the number of loops that are being
1693 /// collapsed. The default value is 1, as thats the value when collapse is not
1694 /// used.
1695 /// \param DupCB The callback to generate the duplication code. See
1696 /// documentation for \ref TaskDupCallbackTy. This can be nullptr.
1697 /// \param TaskContextStructPtrVal If non-null, a pointer to to be placed
1698 /// immediately after the {lower bound, upper
1699 /// bound, step} values in the task data.
1700 /// \param FreeAgent If `true`, the generated tasks are eligible to be
1701 /// executed by a free-agent thread (threadset(omp_pool)).
1702 LLVM_ABI InsertPointOrErrorTy createTaskloop(
1703 const LocationDescription &Loc, InsertPointTy AllocaIP,
1704 ArrayRef<BasicBlock *> DeallocBlocks, BodyGenCallbackTy BodyGenCB,
1706 Value *LBVal, Value *UBVal, Value *StepVal, bool Untied = false,
1707 Value *IfCond = nullptr, Value *GrainSize = nullptr, bool NoGroup = false,
1708 int Sched = 0, Value *Final = nullptr, bool Mergeable = false,
1709 Value *Priority = nullptr, uint64_t NumOfCollapseLoops = 1,
1710 TaskDupCallbackTy DupCB = nullptr,
1711 Value *TaskContextStructPtrVal = nullptr, bool FreeAgent = false);
1712
1713 /// Generator for `#omp task`
1714 ///
1715 /// \param Loc The location where the task construct was encountered.
1716 /// \param AllocaIP The insertion point to be used for allocations.
1717 /// \param DeallocBlocks The insertion blocks to be used for explicit
1718 /// deallocations, if needed.
1719 /// \param BodyGenCB Callback that will generate the region code.
1720 /// \param Tied True if the task is tied, false if the task is untied.
1721 /// \param Final i1 value which is `true` if the task is final, `false` if the
1722 /// task is not final.
1723 /// \param IfCondition i1 value. If it evaluates to `false`, an undeferred
1724 /// task is generated, and the encountering thread must
1725 /// suspend the current task region, for which execution
1726 /// cannot be resumed until execution of the structured
1727 /// block that is associated with the generated task is
1728 /// completed.
1729 /// \param Dependencies Dependencies info holding either a vector of
1730 /// DependData objects or a pre-built dependency array.
1731 /// \param Affinities AffinityData object holding information of accumulated
1732 /// affinities as specified by the 'affinity' clause.
1733 /// \param EventHandle If present, signifies the event handle as part of
1734 /// the detach clause
1735 /// \param Mergeable If the given task is `mergeable`
1736 /// \param priority `priority-value' specifies the execution order of the
1737 /// tasks that is generated by the construct
1738 /// \param FreeAgent If `true`, the task is eligible to be executed by a
1739 /// free-agent thread (threadset(omp_pool)).
1741 const LocationDescription &Loc, InsertPointTy AllocaIP,
1742 ArrayRef<BasicBlock *> DeallocBlocks, BodyGenCallbackTy BodyGenCB,
1743 bool Tied = true, Value *Final = nullptr, Value *IfCondition = nullptr,
1744 const DependenciesInfo &Dependencies = {},
1745 const AffinityData &Affinities = {}, bool Mergeable = false,
1746 Value *EventHandle = nullptr, Value *Priority = nullptr,
1747 bool FreeAgent = false);
1748
1749 /// Generator for the taskgroup construct
1750 ///
1751 /// \param Loc The location where the taskgroup construct was encountered.
1752 /// \param AllocaIP The insertion point to be used for allocations.
1753 /// \param DeallocBlocks The insertion blocks to be used for explicit
1754 /// deallocation instructions, if needed.
1755 /// \param BodyGenCB Callback that will generate the region code.
1757 const LocationDescription &Loc, InsertPointTy AllocaIP,
1758 ArrayRef<BasicBlock *> DeallocBlocks, BodyGenCallbackTy BodyGenCB);
1759
1761 std::function<std::tuple<std::string, uint64_t>()>;
1762
1763 /// Creates a unique info for a target entry when provided a filename and
1764 /// line number from.
1765 ///
1766 /// \param CallBack A callback function which should return filename the entry
1767 /// resides in as well as the line number for the target entry
1768 /// \param ParentName The name of the parent the target entry resides in, if
1769 /// any.
1772 vfs::FileSystem &VFS, StringRef ParentName = "");
1773
1774 /// Enum class for the RedctionGen CallBack type to be used.
1776
1777 /// ReductionGen CallBack for Clang
1778 ///
1779 /// \param CodeGenIP InsertPoint for CodeGen.
1780 /// \param Index Index of the ReductionInfo to generate code for.
1781 /// \param LHSPtr Optionally used by Clang to return the LHSPtr it used for
1782 /// codegen, used for fixup later.
1783 /// \param RHSPtr Optionally used by Clang to
1784 /// return the RHSPtr it used for codegen, used for fixup later.
1785 /// \param CurFn Optionally used by Clang to pass in the Current Function as
1786 /// Clang context may be old.
1788 std::function<InsertPointTy(InsertPointTy CodeGenIP, unsigned Index,
1789 Value **LHS, Value **RHS, Function *CurFn)>;
1790
1791 /// ReductionGen CallBack for MLIR
1792 ///
1793 /// \param CodeGenIP InsertPoint for CodeGen.
1794 /// \param LHS Pass in the LHS Value to be used for CodeGen.
1795 /// \param RHS Pass in the RHS Value to be used for CodeGen.
1797 InsertPointTy CodeGenIP, Value *LHS, Value *RHS, Value *&Res)>;
1798
1799 /// Functions used to generate atomic reductions. Such functions take two
1800 /// Values representing pointers to LHS and RHS of the reduction, as well as
1801 /// the element type of these pointers. They are expected to atomically
1802 /// update the LHS to the reduced value.
1804 InsertPointTy, Type *, Value *, Value *)>;
1805
1807 InsertPointTy, Value *ByRefVal, Value *&Res)>;
1808
1809 /// Enum class for reduction evaluation types scalar, complex and aggregate.
1811
1812 /// Information about an OpenMP reduction.
1827
1833
1834 /// Reduction element type, must match pointee type of variable. For by-ref
1835 /// reductions, this would be just an opaque `ptr`.
1837
1838 /// Reduction variable of pointer type.
1840
1841 /// Thread-private partial reduction variable.
1843
1844 /// Reduction evaluation kind - scalar, complex or aggregate.
1846
1847 /// Callback for generating the reduction body. The IR produced by this will
1848 /// be used to combine two values in a thread-safe context, e.g., under
1849 /// lock or within the same thread, and therefore need not be atomic.
1851
1852 /// Clang callback for generating the reduction body. The IR produced by
1853 /// this will be used to combine two values in a thread-safe context, e.g.,
1854 /// under lock or within the same thread, and therefore need not be atomic.
1856
1857 /// Callback for generating the atomic reduction body, may be null. The IR
1858 /// produced by this will be used to atomically combine two values during
1859 /// reduction. If null, the implementation will use the non-atomic version
1860 /// along with the appropriate synchronization mechanisms.
1862
1864
1865 /// For by-ref reductions, we need to keep track of 2 extra types that are
1866 /// potentially different:
1867 /// * The allocated type is the type of the storage allocated by the
1868 /// reduction op's `alloc` region. For example, for allocatables and arrays,
1869 /// this type would be the descriptor/box struct.
1871
1872 /// * The by-ref element type is the type of the actual storage needed for
1873 /// the data of the allocatable or array. For example, an float allocatable
1874 /// of would need some float storage to store intermediate reduction
1875 /// results.
1877 };
1878
1879 enum class CopyAction : unsigned {
1880 // RemoteLaneToThread: Copy over a Reduce list from a remote lane in
1881 // the warp using shuffle instructions.
1883 // ThreadCopy: Make a copy of a Reduce list on the thread's stack.
1885 };
1886
1892
1893 /// Supporting functions for Reductions CodeGen.
1894private:
1895 /// Get the id of the current thread on the GPU.
1896 Value *getGPUThreadID();
1897
1898 /// Get the GPU warp size.
1899 Value *getGPUWarpSize();
1900
1901 /// Get the id of the warp in the block.
1902 /// We assume that the warp size is 32, which is always the case
1903 /// on the NVPTX device, to generate more efficient code.
1904 Value *getNVPTXWarpID();
1905
1906 /// Get the id of the current lane in the Warp.
1907 /// We assume that the warp size is 32, which is always the case
1908 /// on the NVPTX device, to generate more efficient code.
1909 Value *getNVPTXLaneID();
1910
1911 /// Cast value to the specified type.
1912 Value *castValueToType(InsertPointTy AllocaIP, Value *From, Type *ToType);
1913
1914 /// This function creates calls to one of two shuffle functions to copy
1915 /// variables between lanes in a warp. The returned value has \p ElementType,
1916 /// even though the shuffle runtime functions operate on 32- or 64-bit values.
1917 Value *createRuntimeShuffleFunction(InsertPointTy AllocaIP, Value *Element,
1918 Type *ElementType, Value *Offset);
1919
1920 /// Function to shuffle over the value from the remote lane.
1921 void shuffleAndStore(InsertPointTy AllocaIP, Value *SrcAddr, Value *DstAddr,
1922 Type *ElementType, Value *Offset, Type *ReductionArrayTy,
1923 bool IsByRefElem);
1924
1925 /// Emit instructions to copy a Reduce list, which contains partially
1926 /// aggregated values, in the specified direction.
1927 Error emitReductionListCopy(
1928 InsertPointTy AllocaIP, CopyAction Action, Type *ReductionArrayTy,
1929 ArrayRef<ReductionInfo> ReductionInfos, Value *SrcBase, Value *DestBase,
1930 ArrayRef<bool> IsByRef,
1931 CopyOptionsTy CopyOptions = {nullptr, nullptr, nullptr});
1932
1933 /// Emit a helper that reduces data across two OpenMP threads (lanes)
1934 /// in the same warp. It uses shuffle instructions to copy over data from
1935 /// a remote lane's stack. The reduction algorithm performed is specified
1936 /// by the fourth parameter.
1937 ///
1938 /// Algorithm Versions.
1939 /// Full Warp Reduce (argument value 0):
1940 /// This algorithm assumes that all 32 lanes are active and gathers
1941 /// data from these 32 lanes, producing a single resultant value.
1942 /// Contiguous Partial Warp Reduce (argument value 1):
1943 /// This algorithm assumes that only a *contiguous* subset of lanes
1944 /// are active. This happens for the last warp in a parallel region
1945 /// when the user specified num_threads is not an integer multiple of
1946 /// 32. This contiguous subset always starts with the zeroth lane.
1947 /// Partial Warp Reduce (argument value 2):
1948 /// This algorithm gathers data from any number of lanes at any position.
1949 /// All reduced values are stored in the lowest possible lane. The set
1950 /// of problems every algorithm addresses is a super set of those
1951 /// addressable by algorithms with a lower version number. Overhead
1952 /// increases as algorithm version increases.
1953 ///
1954 /// Terminology
1955 /// Reduce element:
1956 /// Reduce element refers to the individual data field with primitive
1957 /// data types to be combined and reduced across threads.
1958 /// Reduce list:
1959 /// Reduce list refers to a collection of local, thread-private
1960 /// reduce elements.
1961 /// Remote Reduce list:
1962 /// Remote Reduce list refers to a collection of remote (relative to
1963 /// the current thread) reduce elements.
1964 ///
1965 /// We distinguish between three states of threads that are important to
1966 /// the implementation of this function.
1967 /// Alive threads:
1968 /// Threads in a warp executing the SIMT instruction, as distinguished from
1969 /// threads that are inactive due to divergent control flow.
1970 /// Active threads:
1971 /// The minimal set of threads that has to be alive upon entry to this
1972 /// function. The computation is correct iff active threads are alive.
1973 /// Some threads are alive but they are not active because they do not
1974 /// contribute to the computation in any useful manner. Turning them off
1975 /// may introduce control flow overheads without any tangible benefits.
1976 /// Effective threads:
1977 /// In order to comply with the argument requirements of the shuffle
1978 /// function, we must keep all lanes holding data alive. But at most
1979 /// half of them perform value aggregation; we refer to this half of
1980 /// threads as effective. The other half is simply handing off their
1981 /// data.
1982 ///
1983 /// Procedure
1984 /// Value shuffle:
1985 /// In this step active threads transfer data from higher lane positions
1986 /// in the warp to lower lane positions, creating Remote Reduce list.
1987 /// Value aggregation:
1988 /// In this step, effective threads combine their thread local Reduce list
1989 /// with Remote Reduce list and store the result in the thread local
1990 /// Reduce list.
1991 /// Value copy:
1992 /// In this step, we deal with the assumption made by algorithm 2
1993 /// (i.e. contiguity assumption). When we have an odd number of lanes
1994 /// active, say 2k+1, only k threads will be effective and therefore k
1995 /// new values will be produced. However, the Reduce list owned by the
1996 /// (2k+1)th thread is ignored in the value aggregation. Therefore
1997 /// we copy the Reduce list from the (2k+1)th lane to (k+1)th lane so
1998 /// that the contiguity assumption still holds.
1999 ///
2000 /// \param ReductionInfos Array type containing the ReductionOps.
2001 /// \param ReduceFn The reduction function.
2002 /// \param FuncAttrs Optional param to specify any function attributes that
2003 /// need to be copied to the new function.
2004 /// \param IsByRef For each reduction clause, whether the reduction is by-ref
2005 /// or not.
2006 ///
2007 /// \return The ShuffleAndReduce function.
2008 Expected<Function *> emitShuffleAndReduceFunction(
2010 Function *ReduceFn, AttributeList FuncAttrs, ArrayRef<bool> IsByRef);
2011
2012 /// Helper function for CreateCanonicalScanLoops to create InputLoop
2013 /// in the firstGen and Scan Loop in the SecondGen
2014 /// \param InputLoopGen Callback for generating the loop for input phase
2015 /// \param ScanLoopGen Callback for generating the loop for scan phase
2016 /// \param ScanRedInfo Pointer to the ScanInfo objected created using
2017 /// `ScanInfoInitialize`.
2018 ///
2019 /// \return error if any produced, else return success.
2020 Error emitScanBasedDirectiveIR(
2021 llvm::function_ref<Error()> InputLoopGen,
2022 llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen,
2023 ScanInfo *ScanRedInfo);
2024
2025 /// Creates the basic blocks required for scan reduction.
2026 /// \param ScanRedInfo Pointer to the ScanInfo objected created using
2027 /// `ScanInfoInitialize`.
2028 void createScanBBs(ScanInfo *ScanRedInfo);
2029
2030 /// Dynamically allocates the buffer needed for scan reduction.
2031 /// \param AllocaIP The IP where possibly-shared pointer of buffer needs to
2032 /// be declared.
2033 /// \param ScanVars Scan Variables.
2034 /// \param ScanRedInfo Pointer to the ScanInfo objected created using
2035 /// `ScanInfoInitialize`.
2036 ///
2037 /// \return error if any produced, else return success.
2038 Error emitScanBasedDirectiveDeclsIR(InsertPointTy AllocaIP,
2039 ArrayRef<llvm::Value *> ScanVars,
2040 ArrayRef<llvm::Type *> ScanVarsType,
2041 ScanInfo *ScanRedInfo);
2042
2043 /// Copies the result back to the reduction variable.
2044 /// \param ReductionInfos Array type containing the ReductionOps.
2045 /// \param ScanRedInfo Pointer to the ScanInfo objected created using
2046 /// `ScanInfoInitialize`.
2047 ///
2048 /// \return error if any produced, else return success.
2049 Error emitScanBasedDirectiveFinalsIR(
2052
2053 /// This function emits a helper that gathers Reduce lists from the first
2054 /// lane of every active warp to lanes in the first warp.
2055 ///
2056 /// void inter_warp_copy_func(void* reduce_data, num_warps)
2057 /// shared smem[warp_size];
2058 /// For all data entries D in reduce_data:
2059 /// sync
2060 /// If (I am the first lane in each warp)
2061 /// Copy my local D to smem[warp_id]
2062 /// sync
2063 /// if (I am the first warp)
2064 /// Copy smem[thread_id] to my local D
2065 ///
2066 /// \param Loc The insert and source location description.
2067 /// \param ReductionInfos Array type containing the ReductionOps.
2068 /// \param FuncAttrs Optional param to specify any function attributes that
2069 /// need to be copied to the new function.
2070 /// \param IsByRef For each reduction clause, whether the reduction is by-ref
2071 /// or not.
2072 ///
2073 /// \return The InterWarpCopy function.
2075 emitInterWarpCopyFunction(const LocationDescription &Loc,
2076 ArrayRef<ReductionInfo> ReductionInfos,
2077 AttributeList FuncAttrs, ArrayRef<bool> IsByRef);
2078
2079 /// This function emits a helper that copies all the reduction variables from
2080 /// the team into the provided global buffer for the reduction variables.
2081 ///
2082 /// void list_to_global_copy_func(void *buffer, int Idx, void *reduce_data)
2083 /// For all data entries D in reduce_data:
2084 /// Copy local D to buffer.D[Idx]
2085 ///
2086 /// \param ReductionInfos Array type containing the ReductionOps.
2087 /// \param ReductionsBufferTy The StructTy for the reductions buffer.
2088 /// \param FuncAttrs Optional param to specify any function attributes that
2089 /// need to be copied to the new function.
2090 ///
2091 /// \return The ListToGlobalCopy function.
2093 emitListToGlobalCopyFunction(ArrayRef<ReductionInfo> ReductionInfos,
2094 Type *ReductionsBufferTy,
2095 AttributeList FuncAttrs, ArrayRef<bool> IsByRef);
2096
2097 /// This function emits a helper that copies all the reduction variables from
2098 /// the team into the provided global buffer for the reduction variables.
2099 ///
2100 /// void list_to_global_copy_func(void *buffer, int Idx, void *reduce_data)
2101 /// For all data entries D in reduce_data:
2102 /// Copy buffer.D[Idx] to local D;
2103 ///
2104 /// \param ReductionInfos Array type containing the ReductionOps.
2105 /// \param ReductionsBufferTy The StructTy for the reductions buffer.
2106 /// \param FuncAttrs Optional param to specify any function attributes that
2107 /// need to be copied to the new function.
2108 ///
2109 /// \return The GlobalToList function.
2111 emitGlobalToListCopyFunction(ArrayRef<ReductionInfo> ReductionInfos,
2112 Type *ReductionsBufferTy,
2113 AttributeList FuncAttrs, ArrayRef<bool> IsByRef);
2114
2115 /// This function emits a helper that reduces all the reduction variables from
2116 /// the team into the provided global buffer for the reduction variables.
2117 ///
2118 /// void list_to_global_reduce_func(void *buffer, int Idx, void *reduce_data)
2119 /// void *GlobPtrs[];
2120 /// GlobPtrs[0] = (void*)&buffer.D0[Idx];
2121 /// ...
2122 /// GlobPtrs[N] = (void*)&buffer.DN[Idx];
2123 /// reduce_function(GlobPtrs, reduce_data);
2124 ///
2125 /// \param ReductionInfos Array type containing the ReductionOps.
2126 /// \param ReduceFn The reduction function.
2127 /// \param ReductionsBufferTy The StructTy for the reductions buffer.
2128 /// \param FuncAttrs Optional param to specify any function attributes that
2129 /// need to be copied to the new function.
2130 ///
2131 /// \return The ListToGlobalReduce function.
2133 emitListToGlobalReduceFunction(ArrayRef<ReductionInfo> ReductionInfos,
2134 Function *ReduceFn, Type *ReductionsBufferTy,
2135 AttributeList FuncAttrs,
2136 ArrayRef<bool> IsByRef);
2137
2138 /// This function emits a helper that reduces all the reduction variables from
2139 /// the team into the provided global buffer for the reduction variables.
2140 ///
2141 /// void global_to_list_reduce_func(void *buffer, int Idx, void *reduce_data)
2142 /// void *GlobPtrs[];
2143 /// GlobPtrs[0] = (void*)&buffer.D0[Idx];
2144 /// ...
2145 /// GlobPtrs[N] = (void*)&buffer.DN[Idx];
2146 /// reduce_function(reduce_data, GlobPtrs);
2147 ///
2148 /// \param ReductionInfos Array type containing the ReductionOps.
2149 /// \param ReduceFn The reduction function.
2150 /// \param ReductionsBufferTy The StructTy for the reductions buffer.
2151 /// \param FuncAttrs Optional param to specify any function attributes that
2152 /// need to be copied to the new function.
2153 ///
2154 /// \return The GlobalToListReduce function.
2156 emitGlobalToListReduceFunction(ArrayRef<ReductionInfo> ReductionInfos,
2157 Function *ReduceFn, Type *ReductionsBufferTy,
2158 AttributeList FuncAttrs,
2159 ArrayRef<bool> IsByRef);
2160
2161 /// Get the function name of a reduction function.
2162 std::string getReductionFuncName(StringRef Name) const;
2163
2164 /// Generate a Fortran descriptor for array reductions
2165 ///
2166 /// \param DescriptorAddr Address of the descriptor to initialize
2167 /// \param DataPtr Pointer to the actual data the descriptor should reference
2168 /// \param SrcDescriptorAddr Address of the descriptor to copy metadata from
2169 /// \param DescriptorType Type of the descriptor structure
2170 /// \param DataPtrPtrGen Callback to get the base_ptr field in the descriptor
2171 ///
2172 /// \return Error if DataPtrPtrGen fails, otherwise success.
2173 InsertPointOrErrorTy generateReductionDescriptor(
2174 Value *DescriptorAddr, Value *DataPtr, Value *SrcDescriptorAddr,
2175 Type *DescriptorType,
2177 DataPtrPtrGen);
2178
2179 /// Allocate a by-ref reduction descriptor, copy \p SrcDescriptorAddr into it,
2180 /// and update its data pointer to reference \p DataPtr.
2181 ///
2182 /// \param AllocaIP Insertion point for the descriptor allocation.
2183 /// \param RI Reduction info containing descriptor type and access callback.
2184 /// \param DataPtr Pointer to the actual data the descriptor should reference.
2185 /// \param SrcDescriptorAddr Address of the descriptor to copy metadata from.
2186 /// \param DescriptorPtrTy Pointer type expected by the descriptor consumer.
2187 ///
2188 /// \return The new descriptor address, or an Error if descriptor generation
2189 /// fails.
2190 Expected<Value *> createReductionDescriptorCopy(
2191 InsertPointTy AllocaIP, const ReductionInfo &RI, Value *DataPtr,
2192 Value *SrcDescriptorAddr, Type *DescriptorPtrTy,
2193 const Twine &Name = ".omp.reduction.byref_descriptor");
2194
2195 /// Emits reduction function.
2196 /// \param ReducerName Name of the function calling the reduction.
2197 /// \param ReductionInfos Array type containing the ReductionOps.
2198 /// \param ReductionGenCBKind Optional param to specify Clang or MLIR
2199 /// CodeGenCB kind.
2200 /// \param FuncAttrs Optional param to specify any function attributes that
2201 /// need to be copied to the new function.
2202 ///
2203 /// \return The reduction function.
2204 Expected<Function *> createReductionFunction(
2205 StringRef ReducerName, ArrayRef<ReductionInfo> ReductionInfos,
2206 ArrayRef<bool> IsByRef,
2208 AttributeList FuncAttrs = {});
2209
2210 /// Rewrites uses of registered declare target globals to their
2211 /// replacements if we are processing a device module.
2212 void applyDeclareTargetGlobalReplacements();
2213
2214public:
2215 ///
2216 /// Design of OpenMP reductions on the GPU
2217 ///
2218 /// Consider a typical OpenMP program with one or more reduction
2219 /// clauses:
2220 ///
2221 /// float foo;
2222 /// double bar;
2223 /// #pragma omp target teams distribute parallel for \
2224 /// reduction(+:foo) reduction(*:bar)
2225 /// for (int i = 0; i < N; i++) {
2226 /// foo += A[i]; bar *= B[i];
2227 /// }
2228 ///
2229 /// where 'foo' and 'bar' are reduced across all OpenMP threads in
2230 /// all teams. In our OpenMP implementation on the NVPTX device an
2231 /// OpenMP team is mapped to a CUDA threadblock and OpenMP threads
2232 /// within a team are mapped to CUDA threads within a threadblock.
2233 /// Our goal is to efficiently aggregate values across all OpenMP
2234 /// threads such that:
2235 ///
2236 /// - the compiler and runtime are logically concise, and
2237 /// - the reduction is performed efficiently in a hierarchical
2238 /// manner as follows: within OpenMP threads in the same warp,
2239 /// across warps in a threadblock, and finally across teams on
2240 /// the NVPTX device.
2241 ///
2242 /// Introduction to Decoupling
2243 ///
2244 /// We would like to decouple the compiler and the runtime so that the
2245 /// latter is ignorant of the reduction variables (number, data types)
2246 /// and the reduction operators. This allows a simpler interface
2247 /// and implementation while still attaining good performance.
2248 ///
2249 /// Pseudocode for the aforementioned OpenMP program generated by the
2250 /// compiler is as follows:
2251 ///
2252 /// 1. Create private copies of reduction variables on each OpenMP
2253 /// thread: 'foo_private', 'bar_private'
2254 /// 2. Each OpenMP thread reduces the chunk of 'A' and 'B' assigned
2255 /// to it and writes the result in 'foo_private' and 'bar_private'
2256 /// respectively.
2257 /// 3. Call the OpenMP runtime on the GPU to reduce within a team
2258 /// and store the result on the team master:
2259 ///
2260 /// __kmpc_nvptx_parallel_reduce_nowait_v2(...,
2261 /// reduceData, shuffleReduceFn, interWarpCpyFn)
2262 ///
2263 /// where:
2264 /// struct ReduceData {
2265 /// double *foo;
2266 /// double *bar;
2267 /// } reduceData
2268 /// reduceData.foo = &foo_private
2269 /// reduceData.bar = &bar_private
2270 ///
2271 /// 'shuffleReduceFn' and 'interWarpCpyFn' are pointers to two
2272 /// auxiliary functions generated by the compiler that operate on
2273 /// variables of type 'ReduceData'. They aid the runtime perform
2274 /// algorithmic steps in a data agnostic manner.
2275 ///
2276 /// 'shuffleReduceFn' is a pointer to a function that reduces data
2277 /// of type 'ReduceData' across two OpenMP threads (lanes) in the
2278 /// same warp. It takes the following arguments as input:
2279 ///
2280 /// a. variable of type 'ReduceData' on the calling lane,
2281 /// b. its lane_id,
2282 /// c. an offset relative to the current lane_id to generate a
2283 /// remote_lane_id. The remote lane contains the second
2284 /// variable of type 'ReduceData' that is to be reduced.
2285 /// d. an algorithm version parameter determining which reduction
2286 /// algorithm to use.
2287 ///
2288 /// 'shuffleReduceFn' retrieves data from the remote lane using
2289 /// efficient GPU shuffle intrinsics and reduces, using the
2290 /// algorithm specified by the 4th parameter, the two operands
2291 /// element-wise. The result is written to the first operand.
2292 ///
2293 /// Different reduction algorithms are implemented in different
2294 /// runtime functions, all calling 'shuffleReduceFn' to perform
2295 /// the essential reduction step. Therefore, based on the 4th
2296 /// parameter, this function behaves slightly differently to
2297 /// cooperate with the runtime to ensure correctness under
2298 /// different circumstances.
2299 ///
2300 /// 'InterWarpCpyFn' is a pointer to a function that transfers
2301 /// reduced variables across warps. It tunnels, through CUDA
2302 /// shared memory, the thread-private data of type 'ReduceData'
2303 /// from lane 0 of each warp to a lane in the first warp.
2304 /// 4. Call the OpenMP runtime on the GPU to reduce across teams.
2305 /// The last team writes the global reduced value to memory.
2306 ///
2307 /// ret = __kmpc_gpu_teams_reduce_nowait(...,
2308 /// reduceData, shuffleReduceFn, interWarpCpyFn,
2309 /// scratchpadCopyFn, loadAndReduceFn)
2310 ///
2311 /// 'scratchpadCopyFn' is a helper that stores reduced
2312 /// data from the team master to a scratchpad array in
2313 /// global memory.
2314 ///
2315 /// 'loadAndReduceFn' is a helper that loads data from
2316 /// the scratchpad array and reduces it with the input
2317 /// operand.
2318 ///
2319 /// These compiler generated functions hide address
2320 /// calculation and alignment information from the runtime.
2321 /// 5. if ret == 1:
2322 /// The team master of the last team stores the reduced
2323 /// result to the globals in memory.
2324 /// foo += reduceData.foo; bar *= reduceData.bar
2325 ///
2326 ///
2327 /// Warp Reduction Algorithms
2328 ///
2329 /// On the warp level, we have three algorithms implemented in the
2330 /// OpenMP runtime depending on the number of active lanes:
2331 ///
2332 /// Full Warp Reduction
2333 ///
2334 /// The reduce algorithm within a warp where all lanes are active
2335 /// is implemented in the runtime as follows:
2336 ///
2337 /// full_warp_reduce(void *reduce_data,
2338 /// kmp_ShuffleReductFctPtr ShuffleReduceFn) {
2339 /// for (int offset = WARPSIZE/2; offset > 0; offset /= 2)
2340 /// ShuffleReduceFn(reduce_data, 0, offset, 0);
2341 /// }
2342 ///
2343 /// The algorithm completes in log(2, WARPSIZE) steps.
2344 ///
2345 /// 'ShuffleReduceFn' is used here with lane_id set to 0 because it is
2346 /// not used therefore we save instructions by not retrieving lane_id
2347 /// from the corresponding special registers. The 4th parameter, which
2348 /// represents the version of the algorithm being used, is set to 0 to
2349 /// signify full warp reduction.
2350 ///
2351 /// In this version, 'ShuffleReduceFn' behaves, per element, as follows:
2352 ///
2353 /// #reduce_elem refers to an element in the local lane's data structure
2354 /// #remote_elem is retrieved from a remote lane
2355 /// remote_elem = shuffle_down(reduce_elem, offset, WARPSIZE);
2356 /// reduce_elem = reduce_elem REDUCE_OP remote_elem;
2357 ///
2358 /// Contiguous Partial Warp Reduction
2359 ///
2360 /// This reduce algorithm is used within a warp where only the first
2361 /// 'n' (n <= WARPSIZE) lanes are active. It is typically used when the
2362 /// number of OpenMP threads in a parallel region is not a multiple of
2363 /// WARPSIZE. The algorithm is implemented in the runtime as follows:
2364 ///
2365 /// void
2366 /// contiguous_partial_reduce(void *reduce_data,
2367 /// kmp_ShuffleReductFctPtr ShuffleReduceFn,
2368 /// int size, int lane_id) {
2369 /// int curr_size;
2370 /// int offset;
2371 /// curr_size = size;
2372 /// mask = curr_size/2;
2373 /// while (offset>0) {
2374 /// ShuffleReduceFn(reduce_data, lane_id, offset, 1);
2375 /// curr_size = (curr_size+1)/2;
2376 /// offset = curr_size/2;
2377 /// }
2378 /// }
2379 ///
2380 /// In this version, 'ShuffleReduceFn' behaves, per element, as follows:
2381 ///
2382 /// remote_elem = shuffle_down(reduce_elem, offset, WARPSIZE);
2383 /// if (lane_id < offset)
2384 /// reduce_elem = reduce_elem REDUCE_OP remote_elem
2385 /// else
2386 /// reduce_elem = remote_elem
2387 ///
2388 /// This algorithm assumes that the data to be reduced are located in a
2389 /// contiguous subset of lanes starting from the first. When there is
2390 /// an odd number of active lanes, the data in the last lane is not
2391 /// aggregated with any other lane's dat but is instead copied over.
2392 ///
2393 /// Dispersed Partial Warp Reduction
2394 ///
2395 /// This algorithm is used within a warp when any discontiguous subset of
2396 /// lanes are active. It is used to implement the reduction operation
2397 /// across lanes in an OpenMP simd region or in a nested parallel region.
2398 ///
2399 /// void
2400 /// dispersed_partial_reduce(void *reduce_data,
2401 /// kmp_ShuffleReductFctPtr ShuffleReduceFn) {
2402 /// int size, remote_id;
2403 /// int logical_lane_id = number_of_active_lanes_before_me() * 2;
2404 /// do {
2405 /// remote_id = next_active_lane_id_right_after_me();
2406 /// # the above function returns 0 of no active lane
2407 /// # is present right after the current lane.
2408 /// size = number_of_active_lanes_in_this_warp();
2409 /// logical_lane_id /= 2;
2410 /// ShuffleReduceFn(reduce_data, logical_lane_id,
2411 /// remote_id-1-threadIdx.x, 2);
2412 /// } while (logical_lane_id % 2 == 0 && size > 1);
2413 /// }
2414 ///
2415 /// There is no assumption made about the initial state of the reduction.
2416 /// Any number of lanes (>=1) could be active at any position. The reduction
2417 /// result is returned in the first active lane.
2418 ///
2419 /// In this version, 'ShuffleReduceFn' behaves, per element, as follows:
2420 ///
2421 /// remote_elem = shuffle_down(reduce_elem, offset, WARPSIZE);
2422 /// if (lane_id % 2 == 0 && offset > 0)
2423 /// reduce_elem = reduce_elem REDUCE_OP remote_elem
2424 /// else
2425 /// reduce_elem = remote_elem
2426 ///
2427 ///
2428 /// Intra-Team Reduction
2429 ///
2430 /// This function, as implemented in the runtime call
2431 /// '__kmpc_nvptx_parallel_reduce_nowait_v2', aggregates data across OpenMP
2432 /// threads in a team. It first reduces within a warp using the
2433 /// aforementioned algorithms. We then proceed to gather all such
2434 /// reduced values at the first warp.
2435 ///
2436 /// The runtime makes use of the function 'InterWarpCpyFn', which copies
2437 /// data from each of the "warp master" (zeroth lane of each warp, where
2438 /// warp-reduced data is held) to the zeroth warp. This step reduces (in
2439 /// a mathematical sense) the problem of reduction across warp masters in
2440 /// a block to the problem of warp reduction.
2441 ///
2442 ///
2443 /// Inter-Team Reduction
2444 ///
2445 /// Once a team has reduced its data to a single value, it is stored in
2446 /// a global scratchpad array. Since each team has a distinct slot, this
2447 /// can be done without locking.
2448 ///
2449 /// The last team to write to the scratchpad array proceeds to reduce the
2450 /// scratchpad array. One or more workers in the last team use the helper
2451 /// 'loadAndReduceDataFn' to load and reduce values from the array, i.e.,
2452 /// the k'th worker reduces every k'th element.
2453 ///
2454 /// Finally, a call is made to '__kmpc_nvptx_parallel_reduce_nowait_v2' to
2455 /// reduce across workers and compute a globally reduced value.
2456 ///
2457 /// \param Loc The location where the reduction was
2458 /// encountered. Must be within the associate
2459 /// directive and after the last local access to the
2460 /// reduction variables.
2461 /// \param AllocaIP An insertion point suitable for allocas usable
2462 /// in reductions.
2463 /// \param CodeGenIP An insertion point suitable for code
2464 /// generation.
2465 /// \param ReductionInfos A list of info on each reduction
2466 /// variable.
2467 /// \param IsNoWait Optional flag set if the reduction is
2468 /// marked as nowait.
2469 /// \param IsByRef For each reduction clause, whether the reduction is by-ref.
2470 /// \param IsTeamsReduction Optional flag set if it is a teams
2471 /// reduction.
2472 /// \param IsSPMD Optional flag set when the surrounding kernel
2473 /// is compiled in SPMD execution mode (every
2474 /// reduction private is then known to be a
2475 /// per-thread scratch alloca). When false, the
2476 /// teams-reduction call site emits per-thread
2477 /// scratch and copies the team-local value in so
2478 /// the runtime's cross-team work cannot race on
2479 /// team-shared LDS storage produced by Generic
2480 /// globalization (Generic-SPMD case after
2481 /// OpenMPOpt SPMD-ization).
2482 /// \param GridValue Optional GPU grid value.
2483 /// used for teams reduction.
2484 /// \param SrcLocInfo Source location information global.
2486 const LocationDescription &Loc, InsertPointTy AllocaIP,
2487 InsertPointTy CodeGenIP, ArrayRef<ReductionInfo> ReductionInfos,
2488 ArrayRef<bool> IsByRef, bool IsNoWait = false,
2489 bool IsTeamsReduction = false, bool IsSPMD = false,
2491 std::optional<omp::GV> GridValue = {}, Value *SrcLocInfo = nullptr);
2492
2493 // TODO: provide atomic and non-atomic reduction generators for reduction
2494 // operators defined by the OpenMP specification.
2495
2496 /// Generator for '#omp reduction'.
2497 ///
2498 /// Emits the IR instructing the runtime to perform the specific kind of
2499 /// reductions. Expects reduction variables to have been privatized and
2500 /// initialized to reduction-neutral values separately. Emits the calls to
2501 /// runtime functions as well as the reduction function and the basic blocks
2502 /// performing the reduction atomically and non-atomically.
2503 ///
2504 /// The code emitted for the following:
2505 ///
2506 /// \code
2507 /// type var_1;
2508 /// type var_2;
2509 /// #pragma omp <directive> reduction(reduction-op:var_1,var_2)
2510 /// /* body */;
2511 /// \endcode
2512 ///
2513 /// corresponds to the following sketch.
2514 ///
2515 /// \code
2516 /// void _outlined_par() {
2517 /// // N is the number of different reductions.
2518 /// void *red_array[] = {privatized_var_1, privatized_var_2, ...};
2519 /// switch(__kmpc_reduce(..., N, /*size of data in red array*/, red_array,
2520 /// _omp_reduction_func,
2521 /// _gomp_critical_user.reduction.var)) {
2522 /// case 1: {
2523 /// var_1 = var_1 <reduction-op> privatized_var_1;
2524 /// var_2 = var_2 <reduction-op> privatized_var_2;
2525 /// // ...
2526 /// __kmpc_end_reduce(...);
2527 /// break;
2528 /// }
2529 /// case 2: {
2530 /// _Atomic<ReductionOp>(var_1, privatized_var_1);
2531 /// _Atomic<ReductionOp>(var_2, privatized_var_2);
2532 /// // ...
2533 /// break;
2534 /// }
2535 /// default: break;
2536 /// }
2537 /// }
2538 ///
2539 /// void _omp_reduction_func(void **lhs, void **rhs) {
2540 /// *(type *)lhs[0] = *(type *)lhs[0] <reduction-op> *(type *)rhs[0];
2541 /// *(type *)lhs[1] = *(type *)lhs[1] <reduction-op> *(type *)rhs[1];
2542 /// // ...
2543 /// }
2544 /// \endcode
2545 ///
2546 /// \param Loc The location where the reduction was
2547 /// encountered. Must be within the associate
2548 /// directive and after the last local access to the
2549 /// reduction variables.
2550 /// \param AllocaIP An insertion point suitable for allocas usable
2551 /// in reductions.
2552 /// \param ReductionInfos A list of info on each reduction variable.
2553 /// \param IsNoWait A flag set if the reduction is marked as nowait.
2554 /// \param IsByRef A flag set if the reduction is using reference
2555 /// or direct value.
2556 /// \param IsTeamsReduction Optional flag set if it is a teams
2557 /// reduction.
2559 const LocationDescription &Loc, InsertPointTy AllocaIP,
2560 ArrayRef<ReductionInfo> ReductionInfos, ArrayRef<bool> IsByRef,
2561 bool IsNoWait = false, bool IsTeamsReduction = false);
2562
2563 ///}
2564
2565 /// Emit the host runtime lookups that redirect the `in_reduction`
2566 /// list items of an `omp.target` region to their per-task reduction-private
2567 /// storage.
2568 ///
2569 /// This owns the complete runtime-generation path for target `in_reduction`.
2570 /// It computes the executing thread's gtid once for the whole target body (so
2571 /// a target with several in_reduction items does not emit a redundant
2572 /// `__kmpc_global_thread_num` per item), then for each item emits
2573 /// `__kmpc_task_reduction_get_th_data(gtid, /*descriptor=*/null, origPtr)`
2574 /// with the address-space normalization required by the runtime entry point.
2575 /// The NULL descriptor makes the runtime walk the enclosing taskgroups to
2576 /// find the matching `task_reduction` registration for the item. The lookups
2577 /// are emitted at \p Loc, which must be inside the target task body.
2578 ///
2579 /// The front-end-specific work (matching each `in_reduction` item to its
2580 /// mapped storage and binding the generated private pointer back to the
2581 /// right value) stays with the caller: each generated private pointer is
2582 /// handed back through \p MapPrivateCB.
2583 ///
2584 /// \param Loc Insertion point for the target body.
2585 /// \param OrigPtrs Per item, the mapped original pointer used as the
2586 /// runtime `orig` argument.
2587 /// \param ResultPtrTys Per item, the type the returned private pointer must
2588 /// have (for address-space normalization). Must have the
2589 /// same length as \p OrigPtrs.
2590 /// \param MapPrivateCB Called once per item, in list order, with the item
2591 /// index and the generated per-task private pointer.
2592 /// \returns The insertion point after the emitted lookups.
2593 LLVM_ABI InsertPointTy createTargetInReduction(
2594 const LocationDescription &Loc, ArrayRef<Value *> OrigPtrs,
2595 ArrayRef<Type *> ResultPtrTys,
2596 function_ref<void(unsigned, Value *)> MapPrivateCB);
2597
2598 /// Return the insertion point used by the underlying IRBuilder.
2600
2601 /// Update the internal location to \p Loc.
2603 Builder.restoreIP(Loc.IP);
2604 Builder.SetCurrentDebugLocation(Loc.DL);
2605 return Loc.IP.isValid();
2606 }
2607
2608 /// Return the function declaration for the runtime function with \p FnID.
2611
2613
2615 ArrayRef<Value *> Args,
2616 StringRef Name = "");
2617
2618 /// Return the (LLVM-IR) string describing the source location \p LocStr.
2620 uint32_t &SrcLocStrSize);
2621
2622 /// Return the (LLVM-IR) string describing the default source location.
2624
2625 /// Return the (LLVM-IR) string describing the source location identified by
2626 /// the arguments.
2628 StringRef FileName, unsigned Line,
2629 unsigned Column,
2630 uint32_t &SrcLocStrSize);
2631
2632 /// Return the (LLVM-IR) string describing the DebugLoc \p DL. Use \p F as
2633 /// fallback if \p DL does not specify the function name.
2635 const Function *F = nullptr);
2636
2637 /// Return the (LLVM-IR) string describing the source location \p Loc.
2638 LLVM_ABI Constant *getOrCreateSrcLocStr(const LocationDescription &Loc,
2639 uint32_t &SrcLocStrSize);
2640
2641 /// Return an ident_t* encoding the source location \p SrcLocStr and \p Flags.
2642 /// TODO: Create a enum class for the Reserve2Flags
2644 uint32_t SrcLocStrSize,
2645 omp::IdentFlag Flags = omp::IdentFlag(0),
2646 unsigned Reserve2Flags = 0);
2647
2648 /// Create a hidden global flag \p Name in the module with initial value \p
2649 /// Value.
2651
2652 /// Emit the llvm.used metadata.
2654
2655 /// Emit the kernel execution mode.
2658
2659 /// Generate control flow and cleanup for cancellation.
2660 ///
2661 /// \param CancelFlag Flag indicating if the cancellation is performed.
2662 /// \param CanceledDirective The kind of directive that is cancled.
2663 /// \param ExitCB Extra code to be generated in the exit block.
2664 ///
2665 /// \return an error, if any were triggered during execution.
2667 omp::Directive CanceledDirective);
2668
2669 /// Generate a target region entry call.
2670 ///
2671 /// \param Loc The location at which the request originated and is fulfilled.
2672 /// \param AllocaIP The insertion point to be used for alloca instructions.
2673 /// \param Return Return value of the created function returned by reference.
2674 /// \param DeviceID Identifier for the device via the 'device' clause.
2675 /// \param NumTeams Numer of teams for the region via the 'num_teams' clause
2676 /// or 0 if unspecified and -1 if there is no 'teams' clause.
2677 /// \param NumThreads Number of threads via the 'thread_limit' clause.
2678 /// \param HostPtr Pointer to the host-side pointer of the target kernel.
2679 /// \param KernelArgs Array of arguments to the kernel.
2680 LLVM_ABI InsertPointTy emitTargetKernel(const LocationDescription &Loc,
2681 InsertPointTy AllocaIP,
2682 Value *&Return, Value *Ident,
2683 Value *DeviceID, Value *NumTeams,
2684 Value *NumThreads, Value *HostPtr,
2685 ArrayRef<Value *> KernelArgs);
2686
2687 /// Generate a flush runtime call.
2688 ///
2689 /// \param Loc The location at which the request originated and is fulfilled.
2690 LLVM_ABI void emitFlush(const LocationDescription &Loc);
2691
2692 /// The finalization stack made up of finalize callbacks currently in-flight,
2693 /// wrapped into FinalizationInfo objects that reference also the finalization
2694 /// target block and the kind of cancellable directive.
2696
2697 /// Return true if the last entry in the finalization stack is of kind \p DK
2698 /// and cancellable.
2699 bool isLastFinalizationInfoCancellable(omp::Directive DK) {
2700 return !FinalizationStack.empty() &&
2701 FinalizationStack.back().IsCancellable &&
2702 FinalizationStack.back().DK == DK;
2703 }
2704
2705 /// Generate a taskwait runtime call.
2706 ///
2707 /// \param Loc The location at which the request originated and is fulfilled.
2708 LLVM_ABI void emitTaskwaitImpl(const LocationDescription &Loc);
2709
2710 /// Generate a taskyield runtime call.
2711 ///
2712 /// \param Loc The location at which the request originated and is fulfilled.
2713 LLVM_ABI void emitTaskyieldImpl(const LocationDescription &Loc);
2714
2715 /// Return the current thread ID.
2716 ///
2717 /// \param Ident The ident (ident_t*) describing the query origin.
2719
2720 /// The OpenMPIRBuilder Configuration
2722
2723 /// The underlying LLVM-IR module
2725
2726 /// The LLVM-IR Builder used to create IR.
2728
2729 /// Map to remember source location strings
2731
2732 /// Map to remember existing ident_t*.
2734
2735 /// Info manager to keep track of target regions.
2737
2738 /// The target triple of the underlying module.
2739 const Triple T;
2740
2741 /// Helper that contains information about regions we need to outline
2742 /// during finalization.
2744 using PostOutlineCBTy = std::function<void(Function &)>;
2750 // TODO: this should be safe to enable by default
2752
2753 virtual ~OutlineInfo() = default;
2754
2755 /// Collect all blocks in between EntryBB and ExitBB in both the given
2756 /// vector and set.
2758 SmallVectorImpl<BasicBlock *> &BlockVector);
2759
2760 /// Create a CodeExtractor instance based on the information stored in this
2761 /// structure, the list of collected blocks from a previous call to
2762 /// \c collectBlocks and a flag stating whether arguments must be passed in
2763 /// address space 0.
2764 virtual std::unique_ptr<CodeExtractor>
2766 bool ArgsInZeroAddressSpace, Twine Suffix = Twine(""));
2767
2768 /// Return the function that contains the region to be outlined.
2769 Function *getFunction() const { return EntryBB->getParent(); }
2770 };
2771
2772 /// Collection of regions that need to be outlined during finalization.
2774
2775 /// A collection of candidate target functions that's constant allocas will
2776 /// attempt to be raised on a call of finalize after all currently enqueued
2777 /// outline info's have been processed.
2779
2780 /// Describes a declare target global variable replacement to be applied
2781 /// during finalization.
2786
2787 /// Collection of declare target globals to rewrite uses of during
2788 /// device module finalizaiton.
2791
2792 /// Collection of owned canonical loop objects that eventually need to be
2793 /// free'd.
2794 std::forward_list<CanonicalLoopInfo> LoopInfos;
2795
2796 /// Collection of owned ScanInfo objects that eventually need to be free'd.
2797 std::forward_list<ScanInfo> ScanInfos;
2798
2799 /// Add a new region that will be outlined later.
2800 void addOutlineInfo(std::unique_ptr<OutlineInfo> &&OI) {
2801 OutlineInfos.emplace_back(std::move(OI));
2802 }
2803
2804 /// An ordered map of auto-generated variables to their unique names.
2805 /// It stores variables with the following names: 1) ".gomp_critical_user_" +
2806 /// <critical_section_name> + ".var" for "omp critical" directives; 2)
2807 /// <mangled_name_for_global_var> + ".cache." for cache for threadprivate
2808 /// variables.
2810
2811 /// Computes the size of type in bytes.
2813
2814 // Emit a branch from the current block to the Target block only if
2815 // the current block has a terminator.
2817
2818 // If BB has no use then delete it and return. Else place BB after the current
2819 // block, if possible, or else at the end of the function. Also add a branch
2820 // from current block to BB if current block does not have a terminator.
2821 LLVM_ABI void emitBlock(BasicBlock *BB, Function *CurFn,
2822 bool IsFinished = false);
2823
2824 /// Emits code for OpenMP 'if' clause using specified \a BodyGenCallbackTy
2825 /// Here is the logic:
2826 /// if (Cond) {
2827 /// ThenGen();
2828 /// } else {
2829 /// ElseGen();
2830 /// }
2831 ///
2832 /// \return an error, if any were triggered during execution.
2834 BodyGenCallbackTy ElseGen,
2835 InsertPointTy AllocaIP = {},
2836 ArrayRef<BasicBlock *> DeallocBlocks = {});
2837
2838 /// Create the global variable holding the offload mappings information.
2839 LLVM_ABI GlobalVariable *
2840 createOffloadMaptypes(SmallVectorImpl<uint64_t> &Mappings,
2841 std::string VarName);
2842
2843 /// Create the global variable holding the offload names information.
2844 LLVM_ABI GlobalVariable *
2845 createOffloadMapnames(SmallVectorImpl<llvm::Constant *> &Names,
2846 std::string VarName);
2847
2850 AllocaInst *Args = nullptr;
2852 };
2853
2854 /// Create the allocas instruction used in call to mapper functions.
2856 InsertPointTy AllocaIP,
2857 unsigned NumOperands,
2859
2860 /// Create the call for the target mapper function.
2861 /// \param Loc The source location description.
2862 /// \param MapperFunc Function to be called.
2863 /// \param SrcLocInfo Source location information global.
2864 /// \param MaptypesArg The argument types.
2865 /// \param MapnamesArg The argument names.
2866 /// \param MapperAllocas The AllocaInst used for the call.
2867 /// \param DeviceID Device ID for the call.
2868 /// \param NumOperands Number of operands in the call.
2870 Function *MapperFunc, Value *SrcLocInfo,
2871 Value *MaptypesArg, Value *MapnamesArg,
2873 int64_t DeviceID, unsigned NumOperands);
2874
2875 /// Container for the arguments used to pass data to the runtime library.
2877 /// The array of base pointer passed to the runtime library.
2879 /// The array of section pointers passed to the runtime library.
2881 /// The array of sizes passed to the runtime library.
2882 Value *SizesArray = nullptr;
2883 /// The array of map types passed to the runtime library for the beginning
2884 /// of the region or for the entire region if there are no separate map
2885 /// types for the region end.
2887 /// The array of map types passed to the runtime library for the end of the
2888 /// region, or nullptr if there are no separate map types for the region
2889 /// end.
2891 /// The array of user-defined mappers passed to the runtime library.
2893 /// The array of original declaration names of mapped pointers sent to the
2894 /// runtime library for debugging
2896
2897 explicit TargetDataRTArgs() = default;
2906 };
2907
2908 /// Container to pass the default attributes with which a kernel must be
2909 /// launched, used to set kernel attributes and populate associated static
2910 /// structures.
2911 ///
2912 /// For max values, < 0 means unset, == 0 means set but unknown at compile
2913 /// time. The number of max values will be 1 except for the case where
2914 /// ompx_bare is set.
2924
2925 /// Container to pass LLVM IR runtime values or constants related to the
2926 /// number of teams and threads with which the kernel must be launched, as
2927 /// well as the trip count of the loop, if it is an SPMD or Generic-SPMD
2928 /// kernel. These must be defined in the host prior to the call to the kernel
2929 /// launch OpenMP RTL function.
2935
2936 /// 'parallel' construct 'num_threads' clause value, if present and it is an
2937 /// SPMD kernel.
2939
2940 /// Total number of iterations of the SPMD or Generic-SPMD kernel or null if
2941 /// it is a generic kernel.
2943
2944 /// Device ID value used in the kernel launch.
2945 Value *DeviceID = nullptr;
2946 };
2947
2948 /// Data structure that contains the needed information to construct the
2949 /// kernel args vector.
2951 /// Number of arguments passed to the runtime library.
2952 unsigned NumTargetItems = 0;
2953 /// Arguments passed to the runtime library
2955 /// The number of iterations
2957 /// The number of teams.
2959 /// The number of threads.
2961 /// The size of the dynamic shared memory.
2963 /// True if the kernel has 'no wait' clause.
2964 bool HasNoWait = false;
2965 /// True if the kernel strictly requires the number of blocks and threads
2966 /// above to run.
2967 bool StrictBlocks = false;
2968 bool StrictThreads = false;
2969 /// The fallback mechanism for the shared memory.
2972
2973 // Constructors for TargetKernelArgs.
2974 TargetKernelArgs() = default;
2986 };
2987
2988 /// Create the kernel args vector used by emitTargetKernel. This function
2989 /// creates various constant values that are used in the resulting args
2990 /// vector.
2991 LLVM_ABI static void getKernelArgsVector(TargetKernelArgs &KernelArgs,
2992 IRBuilderBase &Builder,
2993 SmallVector<Value *> &ArgsVector);
2994
2995 /// Struct that keeps the information that should be kept throughout
2996 /// a 'target data' region.
2998 /// Set to true if device pointer information have to be obtained.
2999 bool RequiresDevicePointerInfo = false;
3000 /// Set to true if Clang emits separate runtime calls for the beginning and
3001 /// end of the region. These calls might have separate map type arrays.
3002 bool SeparateBeginEndCalls = false;
3003
3004 public:
3006
3009
3010 /// Indicate whether any user-defined mapper exists.
3011 bool HasMapper = false;
3012 /// The total number of pointers passed to the runtime library.
3013 unsigned NumberOfPtrs = 0u;
3014
3015 bool EmitDebug = false;
3016
3017 /// Whether the `target ... data` directive has a `nowait` clause.
3018 bool HasNoWait = false;
3019
3020 explicit TargetDataInfo() = default;
3021 explicit TargetDataInfo(bool RequiresDevicePointerInfo,
3022 bool SeparateBeginEndCalls)
3023 : RequiresDevicePointerInfo(RequiresDevicePointerInfo),
3024 SeparateBeginEndCalls(SeparateBeginEndCalls) {}
3025 /// Clear information about the data arrays.
3028 HasMapper = false;
3029 NumberOfPtrs = 0u;
3030 }
3031 /// Return true if the current target data information has valid arrays.
3032 bool isValid() {
3033 return RTArgs.BasePointersArray && RTArgs.PointersArray &&
3034 RTArgs.SizesArray && RTArgs.MapTypesArray &&
3035 (!HasMapper || RTArgs.MappersArray) && NumberOfPtrs;
3036 }
3037 bool requiresDevicePointerInfo() { return RequiresDevicePointerInfo; }
3038 bool separateBeginEndCalls() { return SeparateBeginEndCalls; }
3039 };
3040
3049
3050 /// This structure contains combined information generated for mappable
3051 /// clauses, including base pointers, pointers, sizes, map types, user-defined
3052 /// mappers, and non-contiguous information.
3053 struct MapInfosTy {
3067 /// True for entries that have an attach ptr, and thus an accompanying
3068 /// ATTACH entry linking that ptr to its ptee.
3069 ///
3070 /// This is a property of the storage block an entry describes, not of the
3071 /// map clause list item: it is true iff the entry's storage is the pointee
3072 /// storage reached through some attach ptr. So, for `int *p; map(p[1:10])`,
3073 /// which produces
3074 /// &p[1], &p[1], 10*sizeof(int), TO|FROM <- HasAttachPtr = true
3075 /// &p, &p[1], sizeof(void*), ATTACH <- HasAttachPtr = false
3076 /// it is set on the pointee entry only. It is never set on the ATTACH entry
3077 /// itself, nor on an entry that maps the pointer as an object in its own
3078 /// right (e.g. the `map(p)` entry for the pointer's own storage).
3079 ///
3080 /// It is set on every entry whose storage lies in a pointee block,
3081 /// including a combined struct entry for such a block and the individual
3082 /// member entries that are MEMBER_OF it. e.g. for
3083 /// `map(s2.s1p->x, s2.s1p->y)`:
3084 /// &s2.s1p[0], &s2.s1p->x, sizeof(x..y), ALLOC <- true
3085 /// &s2.s1p[0], &s2.s1p->x, 4, MEMBER_OF(1)|TO|FROM <- true
3086 /// &s2.s1p[0], &s2.s1p->y, 4, MEMBER_OF(1)|TO|FROM <- true
3087 /// &s2.s1p, &s2.s1p->x, sizeof(void*), ATTACH <- false
3088 /// with s2.s1p as the attach ptr for all three.
3091
3092 /// Append arrays in \a CurInfo.
3093 void append(MapInfosTy &CurInfo) {
3094 BasePointers.append(CurInfo.BasePointers.begin(),
3095 CurInfo.BasePointers.end());
3096 Pointers.append(CurInfo.Pointers.begin(), CurInfo.Pointers.end());
3097 DevicePointers.append(CurInfo.DevicePointers.begin(),
3098 CurInfo.DevicePointers.end());
3099 Sizes.append(CurInfo.Sizes.begin(), CurInfo.Sizes.end());
3100 Types.append(CurInfo.Types.begin(), CurInfo.Types.end());
3101 Names.append(CurInfo.Names.begin(), CurInfo.Names.end());
3102 HasAttachPtr.append(CurInfo.HasAttachPtr.begin(),
3103 CurInfo.HasAttachPtr.end());
3104 NonContigInfo.Dims.append(CurInfo.NonContigInfo.Dims.begin(),
3105 CurInfo.NonContigInfo.Dims.end());
3106 NonContigInfo.Offsets.append(CurInfo.NonContigInfo.Offsets.begin(),
3107 CurInfo.NonContigInfo.Offsets.end());
3108 NonContigInfo.Counts.append(CurInfo.NonContigInfo.Counts.begin(),
3109 CurInfo.NonContigInfo.Counts.end());
3110 NonContigInfo.Strides.append(CurInfo.NonContigInfo.Strides.begin(),
3111 CurInfo.NonContigInfo.Strides.end());
3112 }
3113 };
3115
3116 /// Callback function type for functions emitting the host fallback code that
3117 /// is executed when the kernel launch fails. It takes an insertion point as
3118 /// parameter where the code should be emitted. It returns an insertion point
3119 /// that points right after after the emitted code.
3122
3123 // Callback function type for emitting and fetching user defined custom
3124 // mappers.
3126 function_ref<Expected<Function *>(unsigned int)>;
3127
3128 /// Generate a target region entry call and host fallback call.
3129 ///
3130 /// \param Loc The location at which the request originated and is fulfilled.
3131 /// \param OutlinedFnID The ooulined function ID.
3132 /// \param EmitTargetCallFallbackCB Call back function to generate host
3133 /// fallback code.
3134 /// \param Args Data structure holding information about the kernel arguments.
3135 /// \param DeviceID Identifier for the device via the 'device' clause.
3136 /// \param RTLoc Source location identifier
3137 /// \param AllocaIP The insertion point to be used for alloca instructions.
3139 const LocationDescription &Loc, Value *OutlinedFnID,
3140 EmitFallbackCallbackTy EmitTargetCallFallbackCB, TargetKernelArgs &Args,
3141 Value *DeviceID, Value *RTLoc, InsertPointTy AllocaIP);
3142
3143 /// Callback type for generating the bodies of device directives that require
3144 /// outer target tasks (e.g. in case of having `nowait` or `depend` clauses).
3145 ///
3146 /// \param DeviceID The ID of the device on which the target region will
3147 /// execute.
3148 /// \param RTLoc Source location identifier
3149 /// \Param TargetTaskAllocaIP Insertion point for the alloca block of the
3150 /// generated task.
3151 ///
3152 /// \return an error, if any were triggered during execution.
3154 function_ref<Error(Value *DeviceID, Value *RTLoc,
3155 IRBuilderBase::InsertPoint TargetTaskAllocaIP)>;
3156
3157 /// Generate a target-task for the target construct
3158 ///
3159 /// \param TaskBodyCB Callback to generate the actual body of the target task.
3160 /// \param DeviceID Identifier for the device via the 'device' clause.
3161 /// \param RTLoc Source location identifier
3162 /// \param AllocaIP The insertion point to be used for alloca instructions.
3163 /// \param Dependencies Dependencies info as specified by the 'depend' clause.
3164 /// \param HasNoWait True if the target construct had 'nowait' on it, false
3165 /// otherwise
3167 emitTargetTask(TargetTaskBodyCallbackTy TaskBodyCB, Value *DeviceID,
3168 Value *RTLoc, OpenMPIRBuilder::InsertPointTy AllocaIP,
3169 const DependenciesInfo &Dependencies,
3170 const TargetDataRTArgs &RTArgs, bool HasNoWait);
3171
3172 /// Emit the arguments to be passed to the runtime library based on the
3173 /// arrays of base pointers, pointers, sizes, map types, and mappers. If
3174 /// ForEndCall, emit map types to be passed for the end of the region instead
3175 /// of the beginning.
3178 OpenMPIRBuilder::TargetDataInfo &Info, bool ForEndCall = false);
3179
3180 /// Emit an array of struct descriptors to be assigned to the offload args.
3182 InsertPointTy CodeGenIP,
3183 MapInfosTy &CombinedInfo,
3184 TargetDataInfo &Info);
3185
3186 /// Emit the arrays used to pass the captures and map information to the
3187 /// offloading runtime library. If there is no map or capture information,
3188 /// return nullptr by reference. Accepts a reference to a MapInfosTy object
3189 /// that contains information generated for mappable clauses,
3190 /// including base pointers, pointers, sizes, map types, user-defined mappers.
3192 InsertPointTy AllocaIP, InsertPointTy CodeGenIP, MapInfosTy &CombinedInfo,
3193 TargetDataInfo &Info, CustomMapperCallbackTy CustomMapperCB,
3194 bool IsNonContiguous = false,
3195 function_ref<void(unsigned int, Value *)> DeviceAddrCB = nullptr);
3196
3197 /// Allocates memory for and populates the arrays required for offloading
3198 /// (offload_{baseptrs|ptrs|mappers|sizes|maptypes|mapnames}). Then, it
3199 /// emits their base addresses as arguments to be passed to the runtime
3200 /// library. In essence, this function is a combination of
3201 /// emitOffloadingArrays and emitOffloadingArraysArgument and should arguably
3202 /// be preferred by clients of OpenMPIRBuilder.
3204 InsertPointTy AllocaIP, InsertPointTy CodeGenIP, TargetDataInfo &Info,
3205 TargetDataRTArgs &RTArgs, MapInfosTy &CombinedInfo,
3206 CustomMapperCallbackTy CustomMapperCB, bool IsNonContiguous = false,
3207 bool ForEndCall = false,
3208 function_ref<void(unsigned int, Value *)> DeviceAddrCB = nullptr);
3209
3210 /// Creates offloading entry for the provided entry ID \a ID, address \a
3211 /// Addr, size \a Size, and flags \a Flags.
3213 int32_t Flags, GlobalValue::LinkageTypes,
3214 StringRef Name = "");
3215
3216 /// The kind of errors that can occur when emitting the offload entries and
3217 /// metadata.
3224
3225 /// Callback function type
3227 std::function<void(EmitMetadataErrorKind, TargetRegionEntryInfo)>;
3228
3229 // Emit the offloading entries and metadata so that the device codegen side
3230 // can easily figure out what to emit. The produced metadata looks like
3231 // this:
3232 //
3233 // !omp_offload.info = !{!1, ...}
3234 //
3235 // We only generate metadata for function that contain target regions.
3237 EmitMetadataErrorReportFunctionTy &ErrorReportFunction);
3238
3239public:
3240 /// Generator for __kmpc_copyprivate
3241 ///
3242 /// \param Loc The source location description.
3243 /// \param BufSize Number of elements in the buffer.
3244 /// \param CpyBuf List of pointers to data to be copied.
3245 /// \param CpyFn function to call for copying data.
3246 /// \param DidIt flag variable; 1 for 'single' thread, 0 otherwise.
3247 ///
3248 /// \return The insertion position *after* the CopyPrivate call.
3249
3251 llvm::Value *BufSize,
3252 llvm::Value *CpyBuf,
3253 llvm::Value *CpyFn,
3254 llvm::Value *DidIt);
3255
3256 /// Generator for '#omp single'
3257 ///
3258 /// \param Loc The source location description.
3259 /// \param BodyGenCB Callback that will generate the region code.
3260 /// \param FiniCB Callback to finalize variable copies.
3261 /// \param IsNowait If false, a barrier is emitted.
3262 /// \param CPVars copyprivate variables.
3263 /// \param CPFuncs copy functions to use for each copyprivate variable.
3264 ///
3265 /// \returns The insertion position *after* the single call.
3268 FinalizeCallbackTy FiniCB, bool IsNowait,
3269 ArrayRef<llvm::Value *> CPVars = {},
3270 ArrayRef<llvm::Function *> CPFuncs = {});
3271
3272 /// Generator for '#omp scope'
3273 ///
3274 /// \param Loc The source location description.
3275 /// \param BodyGenCB Callback that will generate the region code.
3276 /// \param FiniCB Callback to finalize variable copies.
3277 /// \param IsNowait If false, a barrier is emitted.
3278 ///
3279 /// \returns The insertion position *after* the scope.
3280 LLVM_ABI InsertPointOrErrorTy createScope(const LocationDescription &Loc,
3281 BodyGenCallbackTy BodyGenCB,
3282 FinalizeCallbackTy FiniCB,
3283 bool IsNowait);
3284
3285 /// Generator for '#omp master'
3286 ///
3287 /// \param Loc The insert and source location description.
3288 /// \param BodyGenCB Callback that will generate the region code.
3289 /// \param FiniCB Callback to finalize variable copies.
3290 ///
3291 /// \returns The insertion position *after* the master.
3292 LLVM_ABI InsertPointOrErrorTy createMaster(const LocationDescription &Loc,
3293 BodyGenCallbackTy BodyGenCB,
3294 FinalizeCallbackTy FiniCB);
3295
3296 /// Generator for '#omp masked'
3297 ///
3298 /// \param Loc The insert and source location description.
3299 /// \param BodyGenCB Callback that will generate the region code.
3300 /// \param FiniCB Callback to finialize variable copies.
3301 ///
3302 /// \returns The insertion position *after* the masked.
3303 LLVM_ABI InsertPointOrErrorTy createMasked(const LocationDescription &Loc,
3304 BodyGenCallbackTy BodyGenCB,
3305 FinalizeCallbackTy FiniCB,
3306 Value *Filter);
3307
3308 /// This function performs the scan reduction of the values updated in
3309 /// the input phase. The reduction logic needs to be emitted between input
3310 /// and scan loop returned by `CreateCanonicalScanLoops`. The following
3311 /// is the code that is generated, `buffer` and `span` are expected to be
3312 /// populated before executing the generated code.
3313 /// \code{c}
3314 /// for (int k = 0; k != ceil(log2(span)); ++k) {
3315 /// i=pow(2,k)
3316 /// for (size cnt = last_iter; cnt >= i; --cnt)
3317 /// buffer[cnt] op= buffer[cnt-i];
3318 /// }
3319 /// \endcode
3320 /// \param Loc The insert and source location description.
3321 /// \param ReductionInfos Array type containing the ReductionOps.
3322 /// \param ScanRedInfo Pointer to the ScanInfo objected created using
3323 /// `ScanInfoInitialize`.
3324 ///
3325 /// \returns The insertion position *after* the masked.
3327 const LocationDescription &Loc,
3329 ScanInfo *ScanRedInfo);
3330
3331 /// This directive split and directs the control flow to input phase
3332 /// blocks or scan phase blocks based on 1. whether input loop or scan loop
3333 /// is executed, 2. whether exclusive or inclusive scan is used.
3334 ///
3335 /// \param Loc The insert and source location description.
3336 /// \param AllocaIP The IP where the temporary buffer for scan reduction
3337 // needs to be allocated.
3338 /// \param ScanVars Scan Variables.
3339 /// \param IsInclusive Whether it is an inclusive or exclusive scan.
3340 /// \param ScanRedInfo Pointer to the ScanInfo objected created using
3341 /// `ScanInfoInitialize`.
3342 ///
3343 /// \returns The insertion position *after* the scan.
3344 LLVM_ABI InsertPointOrErrorTy createScan(const LocationDescription &Loc,
3345 InsertPointTy AllocaIP,
3346 ArrayRef<llvm::Value *> ScanVars,
3347 ArrayRef<llvm::Type *> ScanVarsType,
3348 bool IsInclusive,
3349 ScanInfo *ScanRedInfo);
3350
3351 /// Generator for '#omp critical'
3352 ///
3353 /// \param Loc The insert and source location description.
3354 /// \param BodyGenCB Callback that will generate the region body code.
3355 /// \param FiniCB Callback to finalize variable copies.
3356 /// \param CriticalName name of the lock used by the critical directive
3357 /// \param HintInst Hint Instruction for hint clause associated with critical
3358 ///
3359 /// \returns The insertion position *after* the critical.
3360 LLVM_ABI InsertPointOrErrorTy createCritical(const LocationDescription &Loc,
3361 BodyGenCallbackTy BodyGenCB,
3362 FinalizeCallbackTy FiniCB,
3363 StringRef CriticalName,
3364 Value *HintInst);
3365
3366 /// Generator for '#omp ordered depend (source | sink)'
3367 ///
3368 /// \param Loc The insert and source location description.
3369 /// \param AllocaIP The insertion point to be used for alloca instructions.
3370 /// \param NumLoops The number of loops in depend clause.
3371 /// \param StoreValues The value will be stored in vector address.
3372 /// \param Name The name of alloca instruction.
3373 /// \param IsDependSource If true, depend source; otherwise, depend sink.
3374 ///
3375 /// \return The insertion position *after* the ordered.
3377 createOrderedDepend(const LocationDescription &Loc, InsertPointTy AllocaIP,
3378 unsigned NumLoops, ArrayRef<llvm::Value *> StoreValues,
3379 const Twine &Name, bool IsDependSource);
3380
3381 /// Generator for '#omp ordered [threads | simd]'
3382 ///
3383 /// \param Loc The insert and source location description.
3384 /// \param BodyGenCB Callback that will generate the region code.
3385 /// \param FiniCB Callback to finalize variable copies.
3386 /// \param IsThreads If true, with threads clause or without clause;
3387 /// otherwise, with simd clause;
3388 ///
3389 /// \returns The insertion position *after* the ordered.
3391 const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB,
3392 FinalizeCallbackTy FiniCB, bool IsThreads);
3393
3394 /// Generator for '#omp sections'
3395 ///
3396 /// \param Loc The insert and source location description.
3397 /// \param AllocaIP The insertion points to be used for alloca instructions.
3398 /// \param SectionCBs Callbacks that will generate body of each section.
3399 /// \param PrivCB Callback to copy a given variable (think copy constructor).
3400 /// \param FiniCB Callback to finalize variable copies.
3401 /// \param IsCancellable Flag to indicate a cancellable parallel region.
3402 /// \param IsNowait If true, barrier - to ensure all sections are executed
3403 /// before moving forward will not be generated.
3404 /// \returns The insertion position *after* the sections.
3406 createSections(const LocationDescription &Loc, InsertPointTy AllocaIP,
3409 bool IsCancellable, bool IsNowait);
3410
3411 /// Generator for '#omp section'
3412 ///
3413 /// \param Loc The insert and source location description.
3414 /// \param BodyGenCB Callback that will generate the region body code.
3415 /// \param FiniCB Callback to finalize variable copies.
3416 /// \returns The insertion position *after* the section.
3417 LLVM_ABI InsertPointOrErrorTy createSection(const LocationDescription &Loc,
3418 BodyGenCallbackTy BodyGenCB,
3419 FinalizeCallbackTy FiniCB);
3420
3421 /// Generator for `#omp teams`
3422 ///
3423 /// \param Loc The location where the teams construct was encountered.
3424 /// \param BodyGenCB Callback that will generate the region code.
3425 /// \param NumTeamsLower Lower bound on number of teams. If this is nullptr,
3426 /// it is as if lower bound is specified as equal to upperbound. If
3427 /// this is non-null, then upperbound must also be non-null.
3428 /// \param NumTeamsUpper Upper bound on the number of teams.
3429 /// \param ThreadLimit on the number of threads that may participate in a
3430 /// contention group created by each team.
3431 /// \param IfExpr is the integer argument value of the if condition on the
3432 /// teams clause.
3433 LLVM_ABI InsertPointOrErrorTy createTeams(const LocationDescription &Loc,
3434 BodyGenCallbackTy BodyGenCB,
3435 Value *NumTeamsLower = nullptr,
3436 Value *NumTeamsUpper = nullptr,
3437 Value *ThreadLimit = nullptr,
3438 Value *IfExpr = nullptr);
3439
3440 /// Generator for `#omp distribute`
3441 ///
3442 /// \param Loc The location where the distribute construct was encountered.
3443 /// \param AllocaIP The insertion point to be used for allocations.
3444 /// \param DeallocBlocks The insertion blocks to be used for explicit
3445 /// deallocations, if needed.
3446 /// \param BodyGenCB Callback that will generate the region code.
3448 const LocationDescription &Loc, InsertPointTy AllocaIP,
3449 ArrayRef<BasicBlock *> DeallocBlocks, BodyGenCallbackTy BodyGenCB);
3450
3451 /// Generate conditional branch and relevant BasicBlocks through which private
3452 /// threads copy the 'copyin' variables from Master copy to threadprivate
3453 /// copies.
3454 ///
3455 /// \param IP insertion block for copyin conditional
3456 /// \param MasterVarPtr a pointer to the master variable
3457 /// \param PrivateVarPtr a pointer to the threadprivate variable
3458 /// \param IntPtrTy Pointer size type
3459 /// \param BranchtoEnd Create a branch between the copyin.not.master blocks
3460 // and copy.in.end block
3461 ///
3462 /// \returns The insertion point where copying operation to be emitted.
3464 Value *MasterAddr,
3465 Value *PrivateAddr,
3467 bool BranchtoEnd = true);
3468
3469 /// Create a runtime call for kmpc_alloc
3470 ///
3471 /// \param Loc The insert and source location description.
3472 /// \param Size Size of allocated memory space
3473 /// \param Allocator Allocator information instruction
3474 /// \param Name Name of call Instruction for OMP_alloc
3475 ///
3476 /// \returns CallInst to the OMP_Alloc call
3477 LLVM_ABI CallInst *createOMPAlloc(const LocationDescription &Loc, Value *Size,
3478 Value *Allocator, std::string Name = "");
3479
3480 /// Create a runtime call for kmpc_align_alloc
3481 ///
3482 /// \param Loc The insert and source location description.
3483 /// \param Align Align value
3484 /// \param Size Size of allocated memory space
3485 /// \param Allocator Allocator information instruction
3486 /// \param Name Name of call Instruction for OMP_Align_Alloc
3487 ///
3488 /// \returns CallInst to the OMP_Align_Alloc call
3489 LLVM_ABI CallInst *createOMPAlignedAlloc(const LocationDescription &Loc,
3490 Value *Align, Value *Size,
3491 Value *Allocator,
3492 std::string Name = "");
3493
3494 /// Create a runtime call for kmpc_free
3495 ///
3496 /// \param Loc The insert and source location description.
3497 /// \param Addr Address of memory space to be freed
3498 /// \param Allocator Allocator information instruction
3499 /// \param Name Name of call Instruction for OMP_Free
3500 ///
3501 /// \returns CallInst to the OMP_Free call
3502 LLVM_ABI CallInst *createOMPFree(const LocationDescription &Loc, Value *Addr,
3503 Value *Allocator, std::string Name = "");
3504
3505 /// Create a runtime call for kmpc_alloc_shared.
3506 ///
3507 /// \param Loc The insert and source location description.
3508 /// \param Size Size of allocated memory space.
3509 /// \param Name Name of call Instruction.
3510 ///
3511 /// \returns CallInst to the kmpc_alloc_shared call.
3512 LLVM_ABI CallInst *createOMPAllocShared(const LocationDescription &Loc,
3513 Value *Size,
3514 const Twine &Name = Twine(""));
3515
3516 /// Create a runtime call for kmpc_alloc_shared.
3517 ///
3518 /// \param Loc The insert and source location description.
3519 /// \param VarType Type of variable to be allocated.
3520 /// \param Name Name of call Instruction.
3521 ///
3522 /// \returns CallInst to the kmpc_alloc_shared call.
3523 LLVM_ABI CallInst *createOMPAllocShared(const LocationDescription &Loc,
3524 Type *VarType,
3525 const Twine &Name = Twine(""));
3526
3527 /// Create a runtime call for kmpc_free_shared.
3528 ///
3529 /// \param Loc The insert and source location description.
3530 /// \param Addr Value obtained from the corresponding kmpc_alloc_shared call.
3531 /// \param Size Size of allocated memory space.
3532 /// \param Name Name of call Instruction.
3533 ///
3534 /// \returns CallInst to the kmpc_free_shared call.
3535 LLVM_ABI CallInst *createOMPFreeShared(const LocationDescription &Loc,
3536 Value *Addr, Value *Size,
3537 const Twine &Name = Twine(""));
3538
3539 /// Create a runtime call for kmpc_free_shared.
3540 ///
3541 /// \param Loc The insert and source location description.
3542 /// \param Addr Value obtained from the corresponding kmpc_alloc_shared call.
3543 /// \param VarType Type of variable to be freed.
3544 /// \param Name Name of call Instruction.
3545 ///
3546 /// \returns CallInst to the kmpc_free_shared call.
3547 LLVM_ABI CallInst *createOMPFreeShared(const LocationDescription &Loc,
3548 Value *Addr, Type *VarType,
3549 const Twine &Name = Twine(""));
3550
3551 /// Create a runtime call for kmpc_threadprivate_cached
3552 ///
3553 /// \param Loc The insert and source location description.
3554 /// \param Pointer pointer to data to be cached
3555 /// \param Size size of data to be cached
3556 /// \param Name Name of call Instruction for callinst
3557 ///
3558 /// \returns CallInst to the thread private cache call.
3559 LLVM_ABI CallInst *
3560 createCachedThreadPrivate(const LocationDescription &Loc,
3562 const llvm::Twine &Name = Twine(""));
3563
3564 /// Create a runtime call for __tgt_interop_init
3565 ///
3566 /// \param Loc The insert and source location description.
3567 /// \param InteropVar variable to be allocated
3568 /// \param InteropType type of interop operation
3569 /// \param Device devide to which offloading will occur
3570 /// \param NumDependences number of dependence variables
3571 /// \param DependenceAddress pointer to dependence variables
3572 /// \param HaveNowaitClause does nowait clause exist
3573 ///
3574 /// \returns CallInst to the __tgt_interop_init call
3575 LLVM_ABI CallInst *createOMPInteropInit(const LocationDescription &Loc,
3576 Value *InteropVar,
3577 omp::OMPInteropType InteropType,
3578 Value *Device, Value *NumDependences,
3579 Value *DependenceAddress,
3580 bool HaveNowaitClause);
3581
3582 /// Create a runtime call for __tgt_interop_destroy
3583 ///
3584 /// \param Loc The insert and source location description.
3585 /// \param InteropVar variable to be allocated
3586 /// \param Device devide to which offloading will occur
3587 /// \param NumDependences number of dependence variables
3588 /// \param DependenceAddress pointer to dependence variables
3589 /// \param HaveNowaitClause does nowait clause exist
3590 ///
3591 /// \returns CallInst to the __tgt_interop_destroy call
3592 LLVM_ABI CallInst *createOMPInteropDestroy(const LocationDescription &Loc,
3593 Value *InteropVar, Value *Device,
3594 Value *NumDependences,
3595 Value *DependenceAddress,
3596 bool HaveNowaitClause);
3597
3598 /// Create a runtime call for __tgt_interop_use
3599 ///
3600 /// \param Loc The insert and source location description.
3601 /// \param InteropVar variable to be allocated
3602 /// \param Device devide to which offloading will occur
3603 /// \param NumDependences number of dependence variables
3604 /// \param DependenceAddress pointer to dependence variables
3605 /// \param HaveNowaitClause does nowait clause exist
3606 ///
3607 /// \returns CallInst to the __tgt_interop_use call
3608 LLVM_ABI CallInst *createOMPInteropUse(const LocationDescription &Loc,
3609 Value *InteropVar, Value *Device,
3610 Value *NumDependences,
3611 Value *DependenceAddress,
3612 bool HaveNowaitClause);
3613
3614 /// The `omp target` interface
3615 ///
3616 /// For more information about the usage of this interface,
3617 /// \see openmp/device/include/Interface.h
3618 ///
3619 ///{
3620
3621 /// Create (or update) the '<kernel>_kernel_environment' global describing
3622 /// the launch configuration of the kernel at the current insertion point,
3623 ///
3624 /// \param Loc The insert and source location description.
3625 /// \param Attrs Structure containing the default attributes, including
3626 /// numbers of threads and teams to launch the kernel with.
3627 ///
3628 /// \returns the (possibly address-space-cast) kernel environment constant,
3629 /// or nullptr if \p Loc has no valid insertion point.
3631 const LocationDescription &Loc,
3633
3634 /// Create a runtime call for kmpc_target_init
3635 ///
3636 /// \param Loc The insert and source location description.
3637 /// \param Attrs Structure containing the default attributes, including
3638 /// numbers of threads and teams to launch the kernel with.
3640 const LocationDescription &Loc,
3642
3643 /// Create a runtime call for kmpc_target_deinit
3644 ///
3645 /// \param Loc The insert and source location description.
3646 /// \param TeamsReductionDataSize The maximal size of all the reduction data
3647 /// for teams reduction.
3648 LLVM_ABI void createTargetDeinit(const LocationDescription &Loc,
3649 int32_t TeamsReductionDataSize = 0);
3650
3651 ///}
3652
3653 /// Helpers to read/write kernel annotations from the IR.
3654 ///
3655 ///{
3656
3657 /// Read/write a bounds on threads for \p Kernel. Read will return 0 if none
3658 /// is set.
3659 LLVM_ABI static std::pair<int32_t, int32_t>
3660 readThreadBoundsForKernel(const Triple &T, Function &Kernel);
3661 LLVM_ABI static void writeThreadBoundsForKernel(const Triple &T,
3662 Function &Kernel, int32_t LB,
3663 int32_t UB);
3664
3665 /// Read/write a bounds on teams for \p Kernel. Read will return 0 if none
3666 /// is set.
3667 LLVM_ABI static std::pair<int32_t, int32_t>
3668 readTeamBoundsForKernel(const Triple &T, Function &Kernel);
3669 LLVM_ABI static void writeTeamsForKernel(const Triple &T, Function &Kernel,
3670 int32_t LB, int32_t UB);
3671 ///}
3672
3673private:
3674 // Sets the function attributes expected for the outlined function
3675 void setOutlinedTargetRegionFunctionAttributes(Function *OutlinedFn);
3676
3677 // Creates the function ID/Address for the given outlined function.
3678 // In the case of an embedded device function the address of the function is
3679 // used, in the case of a non-offload function a constant is created.
3680 Constant *createOutlinedFunctionID(Function *OutlinedFn,
3681 StringRef EntryFnIDName);
3682
3683 // Creates the region entry address for the outlined function
3684 Constant *createTargetRegionEntryAddr(Function *OutlinedFunction,
3685 StringRef EntryFnName);
3686
3687public:
3688 /// Functions used to generate a function with the given name.
3690 std::function<Expected<Function *>(StringRef FunctionName)>;
3691
3692 /// Create a unique name for the entry function using the source location
3693 /// information of the current target region. The name will be something like:
3694 ///
3695 /// __omp_offloading_DD_FFFF_PP_lBB[_CC]
3696 ///
3697 /// where DD_FFFF is an ID unique to the file (device and file IDs), PP is the
3698 /// mangled name of the function that encloses the target region and BB is the
3699 /// line number of the target region. CC is a count added when more than one
3700 /// region is located at the same location.
3701 ///
3702 /// If this target outline function is not an offload entry, we don't need to
3703 /// register it. This may happen if it is guarded by an if clause that is
3704 /// false at compile time, or no target archs have been specified.
3705 ///
3706 /// The created target region ID is used by the runtime library to identify
3707 /// the current target region, so it only has to be unique and not
3708 /// necessarily point to anything. It could be the pointer to the outlined
3709 /// function that implements the target region, but we aren't using that so
3710 /// that the compiler doesn't need to keep that, and could therefore inline
3711 /// the host function if proven worthwhile during optimization. In the other
3712 /// hand, if emitting code for the device, the ID has to be the function
3713 /// address so that it can retrieved from the offloading entry and launched
3714 /// by the runtime library. We also mark the outlined function to have
3715 /// external linkage in case we are emitting code for the device, because
3716 /// these functions will be entry points to the device.
3717 ///
3718 /// \param InfoManager The info manager keeping track of the offload entries
3719 /// \param EntryInfo The entry information about the function
3720 /// \param GenerateFunctionCallback The callback function to generate the code
3721 /// \param OutlinedFunction Pointer to the outlined function
3722 /// \param EntryFnIDName Name of the ID o be created
3724 TargetRegionEntryInfo &EntryInfo,
3725 FunctionGenCallback &GenerateFunctionCallback, bool IsOffloadEntry,
3726 Function *&OutlinedFn, Constant *&OutlinedFnID);
3727
3728 /// Registers the given function and sets up the attribtues of the function
3729 /// Returns the FunctionID.
3730 ///
3731 /// \param InfoManager The info manager keeping track of the offload entries
3732 /// \param EntryInfo The entry information about the function
3733 /// \param OutlinedFunction Pointer to the outlined function
3734 /// \param EntryFnName Name of the outlined function
3735 /// \param EntryFnIDName Name of the ID o be created
3738 Function *OutlinedFunction,
3739 StringRef EntryFnName, StringRef EntryFnIDName);
3740
3741 /// Type of BodyGen to use for region codegen
3742 ///
3743 /// Priv: If device pointer privatization is required, emit the body of the
3744 /// region here. It will have to be duplicated: with and without
3745 /// privatization.
3746 /// DupNoPriv: If we need device pointer privatization, we need
3747 /// to emit the body of the region with no privatization in the 'else' branch
3748 /// of the conditional.
3749 /// NoPriv: If we don't require privatization of device
3750 /// pointers, we emit the body in between the runtime calls. This avoids
3751 /// duplicating the body code.
3753
3754 /// Callback type for creating the map infos for the kernel parameters.
3755 /// \param CodeGenIP is the insertion point where code should be generated,
3756 /// if any.
3759
3760private:
3761 /// Emit the array initialization or deletion portion for user-defined mapper
3762 /// code generation. First, it evaluates whether an array section is mapped
3763 /// and whether the \a MapType instructs to delete this section. If \a IsInit
3764 /// is true, and \a MapType indicates to not delete this array, array
3765 /// initialization code is generated. If \a IsInit is false, and \a MapType
3766 /// indicates to delete this array, array deletion code is generated.
3767 void emitUDMapperArrayInitOrDel(Function *MapperFn, llvm::Value *MapperHandle,
3768 llvm::Value *Base, llvm::Value *Begin,
3769 llvm::Value *Size, llvm::Value *MapType,
3770 llvm::Value *MapName, TypeSize ElementSize,
3771 llvm::BasicBlock *ExitBB, bool IsInit);
3772
3773public:
3774 /// Emit the user-defined mapper function. The code generation follows the
3775 /// pattern in the example below.
3776 /// \code
3777 /// void .omp_mapper.<type_name>.<mapper_id>.(void *rt_mapper_handle,
3778 /// void *base, void *begin,
3779 /// int64_t size, int64_t type,
3780 /// void *name = nullptr) {
3781 /// // Allocate space for an array section first or add a base/begin for
3782 /// // pointer dereference.
3783 /// if ((size > 1 || (base != begin && maptype.IsPtrAndObj)) &&
3784 /// !maptype.IsDelete)
3785 /// __tgt_push_mapper_component(rt_mapper_handle, base, begin,
3786 /// size*sizeof(Ty), clearToFromMember(type));
3787 /// // Map members.
3788 /// for (unsigned i = 0; i < size; i++) {
3789 /// // For each component specified by this mapper:
3790 /// for (auto c : begin[i]->all_components) {
3791 /// // Map-type-modifying bits (ALWAYS, DELETE, CLOSE) from the outer
3792 /// // map clause are propagated to each component, except ATTACH
3793 /// // entries (ATTACH|ALWAYS is reserved for attach(always), and other
3794 /// // modifier bits have no meaning for ATTACH). PRESENT propagation is
3795 /// // controlled independently for pointee and non-pointee storage.
3796 /// present_bit = (!(c.isAttach() || c.isPtrAndObj()) &&
3797 /// (c.hasAttachPtr() ? PropagatePresentToPointeeStorage
3798 /// :
3799 /// PropagatePresentToNonPointeeStorage))
3800 /// ? PRESENT : 0;
3801 /// imported_modifier_bits = type & (ALWAYS | DELETE | CLOSE |
3802 /// present_bit);
3803 /// effective_type = c.isAttach() ? c.arg_type
3804 /// : c.arg_type | imported_modifier_bits;
3805 /// if (c.hasMapper())
3806 /// (*c.Mapper())(rt_mapper_handle, c.arg_base, c.arg_begin,
3807 /// c.arg_size, effective_type, c.arg_name);
3808 /// else
3809 /// __tgt_push_mapper_component(rt_mapper_handle, c.arg_base,
3810 /// c.arg_begin, c.arg_size,
3811 /// effective_type, c.arg_name);
3812 /// }
3813 /// }
3814 /// // Delete the array section.
3815 /// if (size > 1 && maptype.IsDelete)
3816 /// __tgt_push_mapper_component(rt_mapper_handle, base, begin,
3817 /// size*sizeof(Ty), clearToFromMember(type));
3818 /// }
3819 /// \endcode
3820 ///
3821 /// \param PrivAndGenMapInfoCB Callback that privatizes code and populates the
3822 /// MapInfos and returns.
3823 /// \param ElemTy DeclareMapper element type.
3824 /// \param FuncName Optional param to specify mapper function name.
3825 /// \param CustomMapperCB Optional callback to generate code related to
3826 /// custom mappers.
3827 /// \param PropagatePresentToPointeeStorage If true, the PRESENT map-type
3828 /// modifier from the outer clause is propagated to the pointee entries the
3829 /// mapper inserts, i.e. those with HasAttachPtr. Callers set this only for
3830 /// OpenMP >= 6.0; at earlier versions the present modifier is treated as not
3831 /// applying to the pointee.
3832 /// \param PropagatePresentToNonPointeeStorage If true, the PRESENT map-type
3833 /// modifier from the outer clause is propagated to eligible mapper entries
3834 /// describing non-pointee storage, i.e. those without HasAttachPtr.
3835 /// ATTACH and PTR_AND_OBJ entries are not eligible for PRESENT propagation.
3838 InsertPointTy CodeGenIP, llvm::Value *PtrPHI, llvm::Value *BeginArg)>
3839 PrivAndGenMapInfoCB,
3840 llvm::Type *ElemTy, StringRef FuncName,
3841 CustomMapperCallbackTy CustomMapperCB, bool PreserveMemberOfFlags = false,
3842 bool PropagatePresentToPointeeStorage = false,
3843 bool PropagatePresentToNonPointeeStorage = false);
3844
3845 /// Generator for '#omp target data'
3846 ///
3847 /// \param Loc The location where the target data construct was encountered.
3848 /// \param AllocaIP The insertion points to be used for allocations.
3849 /// \param CodeGenIP The insertion point at which the target directive code
3850 /// should be placed.
3851 /// \param DeallocBlocks The insertion blocks at which explicit deallocations
3852 /// should be placed, if needed.
3853 /// \param IsBegin If true then emits begin mapper call otherwise emits
3854 /// end mapper call.
3855 /// \param DeviceID Stores the DeviceID from the device clause.
3856 /// \param IfCond Value which corresponds to the if clause condition.
3857 /// \param Info Stores all information realted to the Target Data directive.
3858 /// \param GenMapInfoCB Callback that populates the MapInfos and returns.
3859 /// \param CustomMapperCB Callback to generate code related to
3860 /// custom mappers.
3861 /// \param BodyGenCB Optional Callback to generate the region code.
3862 /// \param DeviceAddrCB Optional callback to generate code related to
3863 /// use_device_ptr and use_device_addr.
3865 const LocationDescription &Loc, InsertPointTy AllocaIP,
3866 InsertPointTy CodeGenIP, ArrayRef<BasicBlock *> DeallocBlocks,
3867 Value *DeviceID, Value *IfCond, TargetDataInfo &Info,
3868 GenMapInfoCallbackTy GenMapInfoCB, CustomMapperCallbackTy CustomMapperCB,
3869 omp::RuntimeFunction *MapperFunc = nullptr,
3871 BodyGenTy BodyGenType)>
3872 BodyGenCB = nullptr,
3873 function_ref<void(unsigned int, Value *)> DeviceAddrCB = nullptr,
3874 Value *SrcLocInfo = nullptr);
3875
3877 InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
3878 ArrayRef<BasicBlock *> DeallocBlocks)>;
3879
3881 Argument &Arg, Value *Input, Value *&RetVal, InsertPointTy AllocaIP,
3882 InsertPointTy CodeGenIP, ArrayRef<InsertPointTy> DeallocIPs)>;
3883
3884 /// Generator for '#omp target'
3885 ///
3886 /// \param Loc where the target data construct was encountered.
3887 /// \param IsOffloadEntry whether it is an offload entry.
3888 /// \param CodeGenIP The insertion point where the call to the outlined
3889 /// function should be emitted.
3890 /// \param DeallocBlocks The insertion points at which explicit deallocations
3891 /// should be placed, if needed.
3892 /// \param Info Stores all information realted to the Target directive.
3893 /// \param EntryInfo The entry information about the function.
3894 /// \param DefaultAttrs Structure containing the default attributes, including
3895 /// numbers of threads and teams to launch the kernel with.
3896 /// \param RuntimeAttrs Structure containing the runtime numbers of threads
3897 /// and teams to launch the kernel with.
3898 /// \param IfCond value of the `if` clause.
3899 /// \param Inputs The input values to the region that will be passed.
3900 /// as arguments to the outlined function.
3901 /// \param BodyGenCB Callback that will generate the region code.
3902 /// \param ArgAccessorFuncCB Callback that will generate accessors
3903 /// instructions for passed in target arguments where neccessary
3904 /// \param CustomMapperCB Callback to generate code related to
3905 /// custom mappers.
3906 /// \param Dependencies A vector of DependData objects that carry
3907 /// dependency information as passed in the depend clause
3908 /// \param HasNowait Whether the target construct has a `nowait` clause or
3909 /// not.
3910 /// \param DynCGroupMem The size of the dynamic groupprivate memory for each
3911 /// cgroup.
3912 /// \param DynCGroupMem The fallback mechanism to execute if the requested
3913 /// cgroup memory cannot be provided.
3914 /// \param OutlinedFnLoc Location scoped to the DISubprogram that the caller
3915 /// will attach to the outlined function. \p Loc is scoped to the
3916 /// parent function, so it cannot be used for code emitted inside the
3917 /// outlined function. If this is empty, such code is emitted without a
3918 /// debug location.
3919 /// \param RTLocOverride Optional runtime source-location identifier to report
3920 /// to the offload runtime for the kernel launch. When null, a default
3921 /// source-location identifier is used.
3923 const LocationDescription &Loc, bool IsOffloadEntry,
3926 ArrayRef<BasicBlock *> DeallocBlocks, TargetDataInfo &Info,
3927 TargetRegionEntryInfo &EntryInfo,
3928 const TargetKernelDefaultAttrs &DefaultAttrs,
3929 const TargetKernelRuntimeAttrs &RuntimeAttrs, Value *IfCond,
3930 SmallVectorImpl<Value *> &Inputs, GenMapInfoCallbackTy GenMapInfoCB,
3931 TargetBodyGenCallbackTy BodyGenCB,
3932 TargetGenArgAccessorsCallbackTy ArgAccessorFuncCB,
3933 CustomMapperCallbackTy CustomMapperCB,
3934 const DependenciesInfo &Dependencies = {}, bool HasNowait = false,
3935 Value *DynCGroupMem = nullptr,
3936 omp::OMPDynGroupprivateFallbackType DynCGroupMemFallback =
3938 DebugLoc OutlinedFnLoc = {}, Value *RTLocOverride = nullptr);
3939
3940 /// Returns __kmpc_for_static_init_* runtime function for the specified
3941 /// size \a IVSize and sign \a IVSigned. Will create a distribute call
3942 /// __kmpc_distribute_static_init* if \a IsGPUDistribute is set.
3943 LLVM_ABI FunctionCallee createForStaticInitFunction(unsigned IVSize,
3944 bool IVSigned,
3945 bool IsGPUDistribute);
3946
3947 /// Returns __kmpc_dispatch_init_* runtime function for the specified
3948 /// size \a IVSize and sign \a IVSigned.
3949 LLVM_ABI FunctionCallee createDispatchInitFunction(unsigned IVSize,
3950 bool IVSigned);
3951
3952 /// Returns __kmpc_dispatch_next_* runtime function for the specified
3953 /// size \a IVSize and sign \a IVSigned.
3954 LLVM_ABI FunctionCallee createDispatchNextFunction(unsigned IVSize,
3955 bool IVSigned);
3956
3957 /// Returns __kmpc_dispatch_fini_* runtime function for the specified
3958 /// size \a IVSize and sign \a IVSigned.
3959 LLVM_ABI FunctionCallee createDispatchFiniFunction(unsigned IVSize,
3960 bool IVSigned);
3961
3962 /// Returns __kmpc_dispatch_deinit runtime function.
3963 LLVM_ABI FunctionCallee createDispatchDeinitFunction();
3964
3965 /// Declarations for LLVM-IR types (simple, array, function and structure) are
3966 /// generated below. Their names are defined and used in OpenMPKinds.def. Here
3967 /// we provide the declarations, the initializeTypes function will provide the
3968 /// values.
3969 ///
3970 ///{
3971#define OMP_TYPE(VarName, InitValue) Type *VarName = nullptr;
3972#define OMP_ARRAY_TYPE(VarName, ElemTy, ArraySize) \
3973 ArrayType *VarName##Ty = nullptr; \
3974 PointerType *VarName##PtrTy = nullptr;
3975#define OMP_FUNCTION_TYPE(VarName, IsVarArg, ReturnType, ...) \
3976 FunctionType *VarName = nullptr; \
3977 PointerType *VarName##Ptr = nullptr;
3978#define OMP_STRUCT_TYPE(VarName, StrName, ...) \
3979 StructType *VarName = nullptr; \
3980 PointerType *VarName##Ptr = nullptr;
3981#include "llvm/Frontend/OpenMP/OMPKinds.def"
3982
3983 ///}
3984
3985private:
3986 /// Create all simple and struct types exposed by the runtime and remember
3987 /// the llvm::PointerTypes of them for easy access later.
3988 void initializeTypes(Module &M);
3989
3990 /// Common interface for generating entry calls for OMP Directives.
3991 /// if the directive has a region/body, It will set the insertion
3992 /// point to the body
3993 ///
3994 /// \param OMPD Directive to generate entry blocks for
3995 /// \param EntryCall Call to the entry OMP Runtime Function
3996 /// \param ExitBB block where the region ends.
3997 /// \param Conditional indicate if the entry call result will be used
3998 /// to evaluate a conditional of whether a thread will execute
3999 /// body code or not.
4000 ///
4001 /// \return The insertion position in exit block
4002 InsertPointTy emitCommonDirectiveEntry(omp::Directive OMPD, Value *EntryCall,
4003 BasicBlock *ExitBB,
4004 bool Conditional = false);
4005
4006 /// Common interface to finalize the region
4007 ///
4008 /// \param OMPD Directive to generate exiting code for
4009 /// \param FinIP Insertion point for emitting Finalization code and exit call.
4010 /// This block must not contain any non-finalization code.
4011 /// \param ExitCall Call to the ending OMP Runtime Function
4012 /// \param HasFinalize indicate if the directive will require finalization
4013 /// and has a finalization callback in the stack that
4014 /// should be called.
4015 ///
4016 /// \return The insertion position in exit block
4017 InsertPointOrErrorTy emitCommonDirectiveExit(omp::Directive OMPD,
4018 InsertPointTy FinIP,
4019 Instruction *ExitCall,
4020 bool HasFinalize = true);
4021
4022 /// Common Interface to generate OMP inlined regions
4023 ///
4024 /// \param OMPD Directive to generate inlined region for
4025 /// \param EntryCall Call to the entry OMP Runtime Function
4026 /// \param ExitCall Call to the ending OMP Runtime Function
4027 /// \param BodyGenCB Body code generation callback.
4028 /// \param FiniCB Finalization Callback. Will be called when finalizing region
4029 /// \param Conditional indicate if the entry call result will be used
4030 /// to evaluate a conditional of whether a thread will execute
4031 /// body code or not.
4032 /// \param HasFinalize indicate if the directive will require finalization
4033 /// and has a finalization callback in the stack that
4034 /// should be called.
4035 /// \param IsCancellable if HasFinalize is set to true, indicate if the
4036 /// the directive should be cancellable.
4037 /// \return The insertion point after the region
4039 EmitOMPInlinedRegion(omp::Directive OMPD, Instruction *EntryCall,
4040 Instruction *ExitCall, BodyGenCallbackTy BodyGenCB,
4041 FinalizeCallbackTy FiniCB, bool Conditional = false,
4042 bool HasFinalize = true, bool IsCancellable = false);
4043
4044 /// Get the platform-specific name separator.
4045 /// \param Parts different parts of the final name that needs separation
4046 /// \param FirstSeparator First separator used between the initial two
4047 /// parts of the name.
4048 /// \param Separator separator used between all of the rest consecutive
4049 /// parts of the name
4050 static std::string getNameWithSeparators(ArrayRef<StringRef> Parts,
4051 StringRef FirstSeparator,
4052 StringRef Separator);
4053
4054 /// Returns corresponding lock object for the specified critical region
4055 /// name. If the lock object does not exist it is created, otherwise the
4056 /// reference to the existing copy is returned.
4057 /// \param CriticalName Name of the critical region.
4058 ///
4059 Value *getOMPCriticalRegionLock(StringRef CriticalName);
4060
4061 /// Callback type for Atomic Expression update
4062 /// ex:
4063 /// \code{.cpp}
4064 /// unsigned x = 0;
4065 /// #pragma omp atomic update
4066 /// x = Expr(x_old); //Expr() is any legal operation
4067 /// \endcode
4068 ///
4069 /// \param XOld the value of the atomic memory address to use for update
4070 /// \param IRB reference to the IRBuilder to use
4071 ///
4072 /// \returns Value to update X to.
4073 using AtomicUpdateCallbackTy =
4074 const function_ref<Expected<Value *>(Value *XOld, IRBuilder<> &IRB)>;
4075
4076private:
4077 enum AtomicKind { Read, Write, Update, Capture, Compare };
4078
4079 /// Determine whether to emit flush or not
4080 ///
4081 /// \param Loc The insert and source location description.
4082 /// \param AO The required atomic ordering
4083 /// \param AK The OpenMP atomic operation kind used.
4084 ///
4085 /// \returns wether a flush was emitted or not
4086 bool checkAndEmitFlushAfterAtomic(const LocationDescription &Loc,
4087 AtomicOrdering AO, AtomicKind AK);
4088
4089 /// Emit atomic update for constructs: X = X BinOp Expr ,or X = Expr BinOp X
4090 /// For complex Operations: X = UpdateOp(X) => CmpExch X, old_X, UpdateOp(X)
4091 /// Only Scalar data types.
4092 ///
4093 /// \param AllocaIP The insertion point to be used for alloca
4094 /// instructions.
4095 /// \param X The target atomic pointer to be updated
4096 /// \param XElemTy The element type of the atomic pointer.
4097 /// \param Expr The value to update X with.
4098 /// \param AO Atomic ordering of the generated atomic
4099 /// instructions.
4100 /// \param RMWOp The binary operation used for update. If
4101 /// operation is not supported by atomicRMW,
4102 /// or belong to {FMaximumNum, FMinimumNum, UDecWrap,
4103 /// UIncWrap, USubCond, USubSat, BAD_BINOP}.
4104 /// Then a `cmpExch` based atomic will be generated.
4105 /// \param UpdateOp Code generator for complex expressions that cannot be
4106 /// expressed through atomicrmw instruction.
4107 /// \param VolatileX true if \a X volatile?
4108 /// \param IsXBinopExpr true if \a X is Left H.S. in Right H.S. part of the
4109 /// update expression, false otherwise.
4110 /// (e.g. true for X = X BinOp Expr)
4111 ///
4112 /// \returns A pair of the old value of X before the update, and the value
4113 /// used for the update.
4114 Expected<std::pair<Value *, Value *>>
4115 emitAtomicUpdate(InsertPointTy AllocaIP, Value *X, Type *XElemTy, Value *Expr,
4117 AtomicUpdateCallbackTy &UpdateOp, bool VolatileX,
4118 bool IsXBinopExpr, bool IsIgnoreDenormalMode,
4119 bool IsFineGrainedMemory, bool IsRemoteMemory);
4120
4121 /// Emit the binary op. described by \p RMWOp, using \p Src1 and \p Src2 .
4122 ///
4123 /// \Return The instruction
4124 Value *emitRMWOpAsInstruction(Value *Src1, Value *Src2,
4125 AtomicRMWInst::BinOp RMWOp);
4126
4127 bool IsFinalized;
4128
4129public:
4130 /// a struct to pack relevant information while generating atomic Ops
4132 Value *Var = nullptr;
4133 Type *ElemTy = nullptr;
4134 bool IsSigned = false;
4135 bool IsVolatile = false;
4136 };
4137
4138 /// Emit atomic Read for : V = X --- Only Scalar data types.
4139 ///
4140 /// \param Loc The insert and source location description.
4141 /// \param X The target pointer to be atomically read
4142 /// \param V Memory address where to store atomically read
4143 /// value
4144 /// \param AO Atomic ordering of the generated atomic
4145 /// instructions.
4146 /// \param AllocaIP Insert point for allocas
4147 //
4148 /// \return Insertion point after generated atomic read IR.
4151 AtomicOrdering AO,
4152 InsertPointTy AllocaIP);
4153
4154 /// Emit atomic write for : X = Expr --- Only Scalar data types.
4155 ///
4156 /// \param Loc The insert and source location description.
4157 /// \param X The target pointer to be atomically written to
4158 /// \param Expr The value to store.
4159 /// \param AO Atomic ordering of the generated atomic
4160 /// instructions.
4161 /// \param AllocaIP Insert point for allocas
4162 ///
4163 /// \return Insertion point after generated atomic Write IR.
4165 AtomicOpValue &X, Value *Expr,
4166 AtomicOrdering AO,
4167 InsertPointTy AllocaIP);
4168
4169 /// Emit atomic update for constructs: X = X BinOp Expr ,or X = Expr BinOp X
4170 /// For complex Operations: X = UpdateOp(X) => CmpExch X, old_X, UpdateOp(X)
4171 /// Only Scalar data types.
4172 ///
4173 /// \param Loc The insert and source location description.
4174 /// \param AllocaIP The insertion point to be used for alloca instructions.
4175 /// \param X The target atomic pointer to be updated
4176 /// \param Expr The value to update X with.
4177 /// \param AO Atomic ordering of the generated atomic instructions.
4178 /// \param RMWOp The binary operation used for update. If operation
4179 /// is not supported by atomicRMW, or belong to
4180 /// {FMaximumNum, FMinimumNum, UDecWrap, UIncWrap,
4181 /// USubCond, USubSat, BAD_BINOP}. Then a
4182 /// `cmpExch` based atomic will be generated.
4183 /// \param UpdateOp Code generator for complex expressions that cannot be
4184 /// expressed through atomicrmw instruction.
4185 /// \param IsXBinopExpr true if \a X is Left H.S. in Right H.S. part of the
4186 /// update expression, false otherwise.
4187 /// (e.g. true for X = X BinOp Expr)
4188 ///
4189 /// \return Insertion point after generated atomic update IR.
4192 Value *Expr, AtomicOrdering AO, AtomicRMWInst::BinOp RMWOp,
4193 AtomicUpdateCallbackTy &UpdateOp, bool IsXBinopExpr,
4194 bool IsIgnoreDenormalMode = false, bool IsFineGrainedMemory = false,
4195 bool IsRemoteMemory = false);
4196
4197 /// Emit atomic update for constructs: --- Only Scalar data types
4198 /// V = X; X = X BinOp Expr ,
4199 /// X = X BinOp Expr; V = X,
4200 /// V = X; X = Expr BinOp X,
4201 /// X = Expr BinOp X; V = X,
4202 /// V = X; X = UpdateOp(X),
4203 /// X = UpdateOp(X); V = X,
4204 ///
4205 /// \param Loc The insert and source location description.
4206 /// \param AllocaIP The insertion point to be used for alloca instructions.
4207 /// \param X The target atomic pointer to be updated
4208 /// \param V Memory address where to store captured value
4209 /// \param Expr The value to update X with.
4210 /// \param AO Atomic ordering of the generated atomic instructions
4211 /// \param RMWOp The binary operation used for update. If
4212 /// operation is not supported by atomicRMW, or belong to
4213 /// {FMaximumNum, FMinimumNum, UDecWrap, UIncWrap,
4214 /// USubCond, USubSat, BAD_BINOP}. Then a
4215 /// `cmpExch` based atomic will be generated.
4216 /// \param UpdateOp Code generator for complex expressions that cannot be
4217 /// expressed through atomicrmw instruction.
4218 /// \param UpdateExpr true if X is an in place update of the form
4219 /// X = X BinOp Expr or X = Expr BinOp X
4220 /// \param IsXBinopExpr true if X is Left H.S. in Right H.S. part of the
4221 /// update expression, false otherwise.
4222 /// (e.g. true for X = X BinOp Expr)
4223 /// \param IsPostfixUpdate true if original value of 'x' must be stored in
4224 /// 'v', not an updated one.
4225 ///
4226 /// \return Insertion point after generated atomic capture IR.
4229 AtomicOpValue &V, Value *Expr, AtomicOrdering AO,
4230 AtomicRMWInst::BinOp RMWOp, AtomicUpdateCallbackTy &UpdateOp,
4231 bool UpdateExpr, bool IsPostfixUpdate, bool IsXBinopExpr,
4232 bool IsIgnoreDenormalMode = false, bool IsFineGrainedMemory = false,
4233 bool IsRemoteMemory = false);
4234
4235 /// Emit atomic compare for constructs: --- Only scalar data types
4236 /// cond-expr-stmt:
4237 /// x = x ordop expr ? expr : x;
4238 /// x = expr ordop x ? expr : x;
4239 /// x = x == e ? d : x;
4240 /// x = e == x ? d : x; (this one is not in the spec)
4241 /// cond-update-stmt:
4242 /// if (x ordop expr) { x = expr; }
4243 /// if (expr ordop x) { x = expr; }
4244 /// if (x == e) { x = d; }
4245 /// if (e == x) { x = d; } (this one is not in the spec)
4246 /// conditional-update-capture-atomic:
4247 /// v = x; cond-update-stmt; (IsPostfixUpdate=true, IsFailOnly=false)
4248 /// cond-update-stmt; v = x; (IsPostfixUpdate=false, IsFailOnly=false)
4249 /// if (x == e) { x = d; } else { v = x; } (IsPostfixUpdate=false,
4250 /// IsFailOnly=true)
4251 /// r = x == e; if (r) { x = d; } (IsPostfixUpdate=false, IsFailOnly=false)
4252 /// r = x == e; if (r) { x = d; } else { v = x; } (IsPostfixUpdate=false,
4253 /// IsFailOnly=true)
4254 ///
4255 /// \param Loc The insert and source location description.
4256 /// \param X The target atomic pointer to be updated.
4257 /// \param V Memory address where to store captured value (for
4258 /// compare capture only).
4259 /// \param R Memory address where to store comparison result
4260 /// (for compare capture with '==' only).
4261 /// \param E The expected value ('e') for forms that use an
4262 /// equality comparison or an expression ('expr') for
4263 /// forms that use 'ordop' (logically an atomic maximum or
4264 /// minimum).
4265 /// \param D The desired value for forms that use an equality
4266 /// comparison. If forms that use 'ordop', it should be
4267 /// \p nullptr.
4268 /// \param AO Atomic ordering of the generated atomic instructions.
4269 /// \param Op Atomic compare operation. It can only be ==, <, or >.
4270 /// \param IsXBinopExpr True if the conditional statement is in the form where
4271 /// x is on LHS. It only matters for < or >.
4272 /// \param IsPostfixUpdate True if original value of 'x' must be stored in
4273 /// 'v', not an updated one (for compare capture
4274 /// only).
4275 /// \param IsFailOnly True if the original value of 'x' is stored to 'v'
4276 /// only when the comparison fails. This is only valid for
4277 /// the case the comparison is '=='.
4278 ///
4279 /// \return Insertion point after generated atomic capture IR.
4280 /// Whether to emit special handling for IEEE 754 -0.0 == +0.0 in
4281 /// atomic compare operations on floating-point types.
4282 bool HandleFPNegZero = false;
4283
4284 /// Set whether atomic compare should handle -0.0/+0.0 equivalence.
4285 /// Returns the previous value so callers can save and restore it.
4286 bool setHandleFPNegZero(bool FPNegZero) {
4287 bool Old = HandleFPNegZero;
4288 HandleFPNegZero = FPNegZero;
4289 return Old;
4290 }
4291
4293 const LocationDescription &Loc, AtomicOpValue &X, AtomicOpValue &V,
4294 AtomicOpValue &R, Value *E, Value *D, AtomicOrdering AO,
4295 omp::OMPAtomicCompareOp Op, bool IsXBinopExpr, bool IsPostfixUpdate,
4296 bool IsFailOnly, bool IsWeak = false);
4298 const LocationDescription &Loc, AtomicOpValue &X, AtomicOpValue &V,
4299 AtomicOpValue &R, Value *E, Value *D, AtomicOrdering AO,
4300 omp::OMPAtomicCompareOp Op, bool IsXBinopExpr, bool IsPostfixUpdate,
4301 bool IsFailOnly, AtomicOrdering Failure, bool IsWeak = false);
4302
4303 /// Create the control flow structure of a canonical OpenMP loop.
4304 ///
4305 /// The emitted loop will be disconnected, i.e. no edge to the loop's
4306 /// preheader and no terminator in the AfterBB. The OpenMPIRBuilder's
4307 /// IRBuilder location is not preserved.
4308 ///
4309 /// \param DL DebugLoc used for the instructions in the skeleton.
4310 /// \param TripCount Value to be used for the trip count.
4311 /// \param F Function in which to insert the BasicBlocks.
4312 /// \param PreInsertBefore Where to insert BBs that execute before the body,
4313 /// typically the body itself.
4314 /// \param PostInsertBefore Where to insert BBs that execute after the body.
4315 /// \param Name Base name used to derive BB
4316 /// and instruction names.
4317 /// \param IsCollapsed Whether this is a collapsed loop.
4318 ///
4319 /// \returns The CanonicalLoopInfo that represents the emitted loop.
4322 BasicBlock *PreInsertBefore, BasicBlock *PostInsertBefore,
4323 const Twine &Name = {}, bool IsCollapsed = false);
4324 /// OMP Offload Info Metadata name string
4325 const std::string ompOffloadInfoName = "omp_offload.info";
4326
4327 /// Loads all the offload entries information from the host IR
4328 /// metadata. This function is only meant to be used with device code
4329 /// generation.
4330 ///
4331 /// \param M Module to load Metadata info from. Module passed maybe
4332 /// loaded from bitcode file, i.e, different from OpenMPIRBuilder::M module.
4334
4335 /// Loads all the offload entries information from the host IR
4336 /// metadata read from the file passed in as the HostFilePath argument. This
4337 /// function is only meant to be used with device code generation.
4338 ///
4339 /// \param HostFilePath The path to the host IR file,
4340 /// used to load in offload metadata for the device, allowing host and device
4341 /// to maintain the same metadata mapping.
4343 StringRef HostFilePath);
4344
4345 /// Gets (if variable with the given name already exist) or creates
4346 /// internal global variable with the specified Name. The created variable has
4347 /// linkage CommonLinkage by default and is initialized by null value.
4348 /// \param Ty Type of the global variable. If it is exist already the type
4349 /// must be the same.
4350 /// \param Name Name of the variable.
4353 std::optional<unsigned> AddressSpace = {});
4354
4356 InsertPointTy BodyIP, llvm::Value *LinearIV)>;
4357
4358 /// Create a canonical iterator loop at the current insertion point.
4359 ///
4360 /// This helper splits the current block and builds a canonical loop
4361 /// using createLoopSkeleton(). The resulting control flow looks like:
4362 ///
4363 /// CurBB -> Preheader -> Header -> Body -> Latch -> After -> ContBB
4364 ///
4365 /// The body of the loop is produced by calling \p BodyGen with the insertion
4366 /// point for the loop body and the induction variable.
4367 /// Unlike createCanonicalLoop(), this function is intended for \p BodyGen
4368 /// that may perform region lowering (e.g., translating MLIR regions) and are
4369 /// not guaranteed to preserve the canonical skeleton's body terminator. In
4370 /// particular:
4371 ///
4372 /// - The skeleton’s unconditional branch from the loop body is removed
4373 /// before invoking \p BodyGen.
4374 /// - \p BodyGen may freely emit instructions and introduce control flow
4375 /// within the loop body.
4376 /// - If the body leaves exactly one block without a terminator after
4377 /// \p BodyGen returns, a branch to the latch is inserted there. Otherwise,
4378 /// some block of the body must already branch to the latch.
4379 /// - The body must not branch to blocks that existed before \p BodyGen ran,
4380 /// other than the body block and the latch.
4381 ///
4382 /// \param Loc The location where the iterator modifier was encountered.
4383 /// \param TripCount Number of loop iterations.
4384 /// \param BodyGen Callback to generate the loop body.
4385 /// \param Name Base name used for creating the loop
4386 /// \returns The insertion position *after* the iterator loop
4389 IteratorBodyGenTy BodyGen, llvm::StringRef Name = "iterator");
4390
4391 /// Kind of parameter in a function with 'declare simd' directive.
4400
4401 /// Attribute set of the `declare simd` parameter.
4408
4414
4415 /// Emit x86 vector-function ABI attributes for a `declare simd` function.
4416 ///
4417 /// Generates and attaches `_ZGV*` vector function ABI attributes to \p Fn
4418 /// following the x86 vector ABI used by OpenMP `declare simd`. For each
4419 /// supported ISA (SSE, AVX, AVX2, AVX512) and masking variant, this
4420 /// constructs the appropriate mangled vector-function name and adds it as a
4421 /// function attribute.
4422 ///
4423 /// \param Fn The scalar function to which vector-function attributes
4424 /// are attached.
4425 /// \param NumElements Number of elements used to derive the vector length
4426 /// when
4427 /// \p VLENVal is not specified.
4428 /// \param VLENVal User provided vector length.
4429 /// \param ParamAttrs Array of attribute set of the `declare simd` parameter.
4430 /// \param Branch `undefined`, `inbranch` or `notinbranch` clause.
4432 llvm::Function *Fn, unsigned NumElements, const llvm::APSInt &VLENVal,
4434
4435 /// Emit AArch64 vector-function ABI attributes for a `declare simd` function.
4436 ///
4437 /// Generates and attaches `_ZGV*` vector function ABI attributes to \p Fn
4438 /// following the AArch64 vector-function ABI. The emitted names depend on the
4439 /// selected ISA, user-specified vector length, parameter attribute mangling,
4440 /// and the declare simd branch clause.
4441 ///
4442 /// \param Fn The scalar function to which vector-function
4443 /// attributes are attached.
4444 /// \param VLENVal User provided vector length.
4445 /// \param ParamAttrs Array of attribute set of the `declare simd`
4446 /// parameter.
4447 /// \param Branch `undefined`, `inbranch` or `notinbranch`
4448 /// clause.
4449 /// \param ISA `'n'` for Advanced SIMD or `'s'` for SVE.
4450 /// \param NarrowestDataSize Narrowest data size in bits used to infer the
4451 /// default vector length when \p VLENVal is
4452 /// absent.
4453 /// \param OutputBecomesInput Whether result values are represented as input
4454 /// parameters in the emitted vector-function ABI
4455 /// name.
4457 llvm::Function *Fn, unsigned VLENVal,
4459 char ISA, unsigned NarrowestDataSize, bool OutputBecomesInput);
4460};
4461
4462/// Class to represented the control flow structure of an OpenMP canonical loop.
4463///
4464/// The control-flow structure is standardized for easy consumption by
4465/// directives associated with loops. For instance, the worksharing-loop
4466/// construct may change this control flow such that each loop iteration is
4467/// executed on only one thread. The constraints of a canonical loop in brief
4468/// are:
4469///
4470/// * The number of loop iterations must have been computed before entering the
4471/// loop.
4472///
4473/// * Has an (unsigned) logical induction variable that starts at zero and
4474/// increments by one.
4475///
4476/// * The loop's CFG itself has no side-effects. The OpenMP specification
4477/// itself allows side-effects, but the order in which they happen, including
4478/// how often or whether at all, is unspecified. We expect that the frontend
4479/// will emit those side-effect instructions somewhere (e.g. before the loop)
4480/// such that the CanonicalLoopInfo itself can be side-effect free.
4481///
4482/// Keep in mind that CanonicalLoopInfo is meant to only describe a repeated
4483/// execution of a loop body that satifies these constraints. It does NOT
4484/// represent arbitrary SESE regions that happen to contain a loop. Do not use
4485/// CanonicalLoopInfo for such purposes.
4486///
4487/// The control flow can be described as follows:
4488///
4489/// Preheader
4490/// |
4491/// /-> Header
4492/// | |
4493/// | Cond---\
4494/// | | |
4495/// | Body |
4496/// | | | |
4497/// | <...> |
4498/// | | | |
4499/// \--Latch |
4500/// |
4501/// Exit
4502/// |
4503/// After
4504///
4505/// The loop is thought to start at PreheaderIP (at the Preheader's terminator,
4506/// including) and end at AfterIP (at the After's first instruction, excluding).
4507/// That is, instructions in the Preheader and After blocks (except the
4508/// Preheader's terminator) are out of CanonicalLoopInfo's control and may have
4509/// side-effects. Typically, the Preheader is used to compute the loop's trip
4510/// count. The instructions from BodyIP (at the Body block's first instruction,
4511/// excluding) until the Latch are also considered outside CanonicalLoopInfo's
4512/// control and thus can have side-effects. The body block is the single entry
4513/// point into the loop body, which may contain arbitrary control flow as long
4514/// as all control paths eventually branch to the Latch block.
4515///
4516/// TODO: Consider adding another standardized BasicBlock between Body CFG and
4517/// Latch to guarantee that there is only a single edge to the latch. It would
4518/// make loop transformations easier to not needing to consider multiple
4519/// predecessors of the latch (See redirectAllPredecessorsTo) and would give us
4520/// an equivalant to PreheaderIP, AfterIP and BodyIP for inserting code that
4521/// executes after each body iteration.
4522///
4523/// There must be no loop-carried dependencies through llvm::Values. This is
4524/// equivalant to that the Latch has no PHINode and the Header's only PHINode is
4525/// for the induction variable.
4526///
4527/// All code in Header, Cond, Latch and Exit (plus the terminator of the
4528/// Preheader) are CanonicalLoopInfo's responsibility and their build-up checked
4529/// by assertOK(). They are expected to not be modified unless explicitly
4530/// modifying the CanonicalLoopInfo through a methods that applies a OpenMP
4531/// loop-associated construct such as applyWorkshareLoop, tileLoops, unrollLoop,
4532/// etc. These methods usually invalidate the CanonicalLoopInfo and re-use its
4533/// basic blocks. After invalidation, the CanonicalLoopInfo must not be used
4534/// anymore as its underlying control flow may not exist anymore.
4535/// Loop-transformation methods such as tileLoops, collapseLoops and unrollLoop
4536/// may also return a new CanonicalLoopInfo that can be passed to other
4537/// loop-associated construct implementing methods. These loop-transforming
4538/// methods may either create a new CanonicalLoopInfo usually using
4539/// createLoopSkeleton and invalidate the input CanonicalLoopInfo, or reuse and
4540/// modify one of the input CanonicalLoopInfo and return it as representing the
4541/// modified loop. What is done is an implementation detail of
4542/// transformation-implementing method and callers should always assume that the
4543/// CanonicalLoopInfo passed to it is invalidated and a new object is returned.
4544/// Without Virtual collapse, results have the same guarantees as the one
4545/// created by createCanonicalLoop, such that transforming methods do not have
4546/// to special case where the CanonicalLoopInfo originated from.
4547///
4548/// Generally, methods consuming CanonicalLoopInfo do not need an
4549/// OpenMPIRBuilder::InsertPointTy as argument, but use the locations of the
4550/// CanonicalLoopInfo to insert new or modify existing instructions. Unless
4551/// documented otherwise, methods consuming CanonicalLoopInfo do not invalidate
4552/// any InsertPoint that is outside CanonicalLoopInfo's control. Specifically,
4553/// any InsertPoint in the Preheader, After or Block can still be used after
4554/// calling such a method.
4555///
4556/// TODO: Provide mechanisms for exception handling and cancellation points.
4557///
4558/// Defined outside OpenMPIRBuilder because nested classes cannot be
4559/// forward-declared, e.g. to avoid having to include the entire OMPIRBuilder.h.
4561 friend class OpenMPIRBuilder;
4562
4563private:
4564 /// State retained after Virtual collapse of a loop nest.
4565 struct VirtualCollapseInfo {
4566 /// Copy of the first normalized iteration; scheduling replaces operand
4567 /// zero.
4568 BinaryOperator *Begin = nullptr;
4569 /// Copy of the full count; scheduling replaces operand zero with its count.
4570 /// May wrap for idle scheduler assignments.
4571 BinaryOperator *Count = nullptr;
4572 };
4573 std::optional<VirtualCollapseInfo> VirtualCollapse;
4574
4575 /// Report a fatal error for an unsupported operation on Virtual collapse.
4576 /// Must only be called for a loop with Virtual collapse state.
4577 [[noreturn]] LLVM_ABI void reportUnsupportedVirtualCollapse() const;
4578 /// Return the Virtual range initialization block containing the Begin and
4579 /// Count copies, or nullptr for ordinary canonical loops.
4580 BasicBlock *getVirtualCollapseInit() const;
4581
4582 BasicBlock *Header = nullptr;
4583 BasicBlock *Cond = nullptr;
4584 BasicBlock *Latch = nullptr;
4585 BasicBlock *Exit = nullptr;
4586
4587 // Hold the MLIR value for the `lastiter` of the canonical loop.
4588 Value *LastIter = nullptr;
4589
4590 /// Add the control blocks of this loop to \p BBs.
4591 ///
4592 /// This does not include any block from the body, including the one returned
4593 /// by getBody().
4594 ///
4595 /// FIXME: This currently includes the Preheader and After blocks even though
4596 /// their content is (mostly) not under CanonicalLoopInfo's control.
4597 /// Re-evaluated whether this makes sense.
4598 void collectControlBlocks(SmallVectorImpl<BasicBlock *> &BBs);
4599
4600 /// Sets the number of loop iterations to the given value. This value must be
4601 /// valid in the condition block (i.e., defined in the preheader) and is
4602 /// interpreted as an unsigned integer.
4603 void setTripCount(Value *TripCount);
4604
4605 /// Replace all uses of the canonical induction variable in the loop body with
4606 /// a new one.
4607 ///
4608 /// The intended use case is to update the induction variable for an updated
4609 /// iteration space such that it can stay normalized in the 0...tripcount-1
4610 /// range.
4611 ///
4612 /// The \p Updater is called with the (presumable updated) current normalized
4613 /// induction variable and is expected to return the value that uses of the
4614 /// pre-updated induction values should use instead, typically dependent on
4615 /// the new induction variable. This is a lambda (instead of e.g. just passing
4616 /// the new value) to be able to distinguish the uses of the pre-updated
4617 /// induction variable and uses of the induction varible to compute the
4618 /// updated induction variable value.
4619 void mapIndVar(llvm::function_ref<Value *(Instruction *)> Updater);
4620
4621public:
4622 /// Sets the last iteration variable for this loop.
4623 void setLastIter(Value *IterVar) { LastIter = std::move(IterVar); }
4624
4625 /// Returns the last iteration variable for this loop.
4626 /// Certain use-cases (like translation of linear clause) may access
4627 /// this variable even after a loop transformation. Hence, do not guard
4628 /// this getter function by `isValid`. It is the responsibility of the
4629 /// callee to ensure this functionality is not invoked by a non-outlined
4630 /// CanonicalLoopInfo object (in which case, `setLastIter` will never be
4631 /// invoked and `LastIter` will be by default `nullptr`).
4632 Value *getLastIter() { return LastIter; }
4633
4634 /// Returns whether this object currently represents the IR of a loop. If
4635 /// returning false, it may have been consumed by a loop transformation or not
4636 /// been initialized. Do not use in this case;
4637 bool isValid() const { return Header; }
4638
4639 /// The preheader ensures that there is only a single edge entering the loop.
4640 /// Code that must be execute before any loop iteration can be emitted here,
4641 /// such as computing the loop trip count and begin lifetime markers. Code in
4642 /// the preheader is not considered part of the canonical loop.
4644
4645 /// The header is the entry for each iteration. In the canonical control flow,
4646 /// it only contains the PHINode for the induction variable.
4648 assert(isValid() && "Requires a valid canonical loop");
4649 return Header;
4650 }
4651
4652 /// The condition block computes whether there is another loop iteration. If
4653 /// yes, branches to the body; otherwise to the exit block.
4655 assert(isValid() && "Requires a valid canonical loop");
4656 return Cond;
4657 }
4658
4659 /// The body block is the single entry for a loop iteration and not controlled
4660 /// by CanonicalLoopInfo. It can contain arbitrary control flow but must
4661 /// eventually branch to the \p Latch block.
4662 /// Virtual does not expose a logical loop body.
4664 assert(isValid() && "Requires a valid canonical loop");
4665 if (VirtualCollapse)
4666 reportUnsupportedVirtualCollapse();
4667 return cast<CondBrInst>(Cond->getTerminator())->getSuccessor(0);
4668 }
4669
4670 /// Reaching the latch indicates the end of the loop body code. In the
4671 /// canonical control flow, it only contains the increment of the induction
4672 /// variable.
4674 assert(isValid() && "Requires a valid canonical loop");
4675 return Latch;
4676 }
4677
4678 /// Reaching the exit indicates no more iterations are being executed.
4680 assert(isValid() && "Requires a valid canonical loop");
4681 return Exit;
4682 }
4683
4684 /// The after block is intended for clean-up code such as lifetime end
4685 /// markers. It is separate from the exit block to ensure, analogous to the
4686 /// preheader, it having just a single entry edge and being free from PHI
4687 /// nodes should there be multiple loop exits (such as from break
4688 /// statements/cancellations).
4690 assert(isValid() && "Requires a valid canonical loop");
4691 return Exit->getSingleSuccessor();
4692 }
4693
4694 /// Returns the llvm::Value containing the number of loop iterations. It must
4695 /// be valid in the preheader and always interpreted as an unsigned integer of
4696 /// any bit-width.
4698 assert(isValid() && "Requires a valid canonical loop");
4699 if (VirtualCollapse)
4700 return VirtualCollapse->Count->getOperand(0);
4701 Instruction *CmpI = &Cond->front();
4702 assert(isa<CmpInst>(CmpI) && "First inst must compare IV with TripCount");
4703 return CmpI->getOperand(1);
4704 }
4705
4706 /// Returns the instruction representing the current logical induction
4707 /// variable. Always unsigned, always starting at 0 with an increment of one.
4708 /// Virtual does not expose a logical induction variable.
4710 assert(isValid() && "Requires a valid canonical loop");
4711 if (VirtualCollapse)
4712 reportUnsupportedVirtualCollapse();
4713 Instruction *IndVarPHI = &Header->front();
4714 assert(isa<PHINode>(IndVarPHI) && "First inst must be the IV PHI");
4715 return IndVarPHI;
4716 }
4717
4718 /// Return the type of the induction variable (and the trip count).
4720 assert(isValid() && "Requires a valid canonical loop");
4721 return getTripCount()->getType();
4722 }
4723
4724 /// Return the insertion point for user code before the loop.
4726 assert(isValid() && "Requires a valid canonical loop");
4727 BasicBlock *Preheader = getPreheader();
4728 return std::prev(Preheader->end());
4729 };
4730
4731 /// Return the insertion point for user code in the body.
4733 assert(isValid() && "Requires a valid canonical loop");
4734 BasicBlock *Body = getBody();
4735 return Body->begin();
4736 };
4737
4738 /// Return the insertion point for user code after the loop.
4740 assert(isValid() && "Requires a valid canonical loop");
4741 BasicBlock *After = getAfter();
4742 return After->begin();
4743 };
4744
4746 assert(isValid() && "Requires a valid canonical loop");
4747 return Header->getParent();
4748 }
4749
4750 /// Consistency self-check.
4751 LLVM_ABI void assertOK() const;
4752
4753 /// Invalidate this loop. That is, the underlying IR does not fulfill the
4754 /// requirements of an OpenMP canonical loop anymore.
4755 LLVM_ABI void invalidate();
4756};
4757
4758/// ScanInfo holds the information to assist in lowering of Scan reduction.
4759/// Before lowering, the body of the for loop specifying scan reduction is
4760/// expected to have the following structure
4761///
4762/// Loop Body Entry
4763/// |
4764/// Code before the scan directive
4765/// |
4766/// Scan Directive
4767/// |
4768/// Code after the scan directive
4769/// |
4770/// Loop Body Exit
4771/// When `createCanonicalScanLoops` is executed, the bodyGen callback of it
4772/// transforms the body to:
4773///
4774/// Loop Body Entry
4775/// |
4776/// OMPScanDispatch
4777///
4778/// OMPBeforeScanBlock
4779/// |
4780/// OMPScanLoopExit
4781/// |
4782/// Loop Body Exit
4783///
4784/// The insert point is updated to the first insert point of OMPBeforeScanBlock.
4785/// It dominates the control flow of code generated until
4786/// scan directive is encountered and OMPAfterScanBlock dominates the
4787/// control flow of code generated after scan is encountered. The successor
4788/// of OMPScanDispatch can be OMPBeforeScanBlock or OMPAfterScanBlock based
4789/// on 1.whether it is in Input phase or Scan Phase , 2. whether it is an
4790/// exclusive or inclusive scan. This jump is added when `createScan` is
4791/// executed. If input loop is being generated, if it is inclusive scan,
4792/// `OMPAfterScanBlock` succeeds `OMPScanDispatch` , if exclusive,
4793/// `OMPBeforeScanBlock` succeeds `OMPDispatch` and vice versa for scan loop. At
4794/// the end of the input loop, temporary buffer is populated and at the
4795/// beginning of the scan loop, temporary buffer is read. After scan directive
4796/// is encountered, insertion point is updated to `OMPAfterScanBlock` as it is
4797/// expected to dominate the code after the scan directive. Both Before and
4798/// After scan blocks are succeeded by `OMPScanLoopExit`.
4799/// Temporary buffer allocations are done in `ScanLoopInit` block before the
4800/// lowering of for-loop. The results are copied back to reduction variable in
4801/// `ScanLoopFinish` block.
4803public:
4804 /// Dominates the body of the loop before scan directive
4806
4807 /// Dominates the body of the loop before scan directive
4809
4810 /// Controls the flow to before or after scan blocks
4812
4813 /// Exit block of loop body
4815
4816 /// Block before loop body where scan initializations are done
4818
4819 /// Block after loop body where scan finalizations are done
4821
4822 /// If true, it indicates Input phase is lowered; else it indicates
4823 /// ScanPhase is lowered
4824 bool OMPFirstScanLoop = false;
4825
4826 /// Maps the private reduction variable to the pointer of the temporary
4827 /// buffer
4829
4830 /// Keeps track of value of iteration variable for input/scan loop to be
4831 /// used for Scan directive lowering
4832 llvm::Value *IV = nullptr;
4833
4834 /// Stores the span of canonical loop being lowered to be used for temporary
4835 /// buffer allocation or Finalization.
4836 llvm::Value *Span = nullptr;
4837
4841 ScanInfo(ScanInfo &) = delete;
4842 ScanInfo &operator=(const ScanInfo &) = delete;
4843
4844 ~ScanInfo() { delete (ScanBuffPtrs); }
4845};
4846
4847} // end namespace llvm
4848
4849#endif // LLVM_FRONTEND_OPENMP_OMPIRBUILDER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
arc branch finalize
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the BumpPtrAllocator interface.
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:211
DXIL Finalize Linkage
Hexagon Hardware Loops
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Machine Check Debug Module
#define T
This file defines constans and helpers used when dealing with OpenMP.
Provides definitions for Target specific Grid Values.
SmallVector< MachineOperand, 4 > Cond
RISCVCC::CondCode CC
Basic Register Allocator
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SmallPtrSet< BasicBlock *, 0 > BlockSet
This file implements a set that has insertion order iteration characteristics.
Contains the forward declaration for vfs::FileSystem, as well as the IntrusiveRefCntPtrInfo specializ...
Value * RHS
Value * LHS
The Input class is used to parse a yaml document into in-memory structs and vectors.
An arbitrary precision integer that knows its signedness.
Definition APSInt.h:24
an instruction to allocate memory on the stack
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Align AtomicAlign
Definition Atomic.h:23
bool UseLibcall
Definition Atomic.h:25
IRBuilderBase * Builder
Definition Atomic.h:19
uint64_t AtomicSizeInBits
Definition Atomic.h:21
uint64_t ValueSizeInBits
Definition Atomic.h:22
IRBuilderBase::InsertPoint AllocaIP
Definition Atomic.h:26
Align ValueAlign
Definition Atomic.h:24
BinOp
This enumeration lists the possible modifications atomicrmw can make.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:453
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:440
This class represents a function call, abstracting a target machine's calling convention.
Class to represented the control flow structure of an OpenMP canonical loop.
Value * getTripCount() const
Returns the llvm::Value containing the number of loop iterations.
BasicBlock * getHeader() const
The header is the entry for each iteration.
LLVM_ABI void assertOK() const
Consistency self-check.
Type * getIndVarType() const
Return the type of the induction variable (and the trip count).
BasicBlock * getBody() const
The body block is the single entry for a loop iteration and not controlled by CanonicalLoopInfo.
bool isValid() const
Returns whether this object currently represents the IR of a loop.
void setLastIter(Value *IterVar)
Sets the last iteration variable for this loop.
OpenMPIRBuilder::InsertPointTy getAfterIP() const
Return the insertion point for user code after the loop.
Value * getLastIter()
Returns the last iteration variable for this loop.
OpenMPIRBuilder::InsertPointTy getBodyIP() const
Return the insertion point for user code in the body.
BasicBlock * getAfter() const
The after block is intended for clean-up code such as lifetime end markers.
Function * getFunction() const
LLVM_ABI void invalidate()
Invalidate this loop.
BasicBlock * getLatch() const
Reaching the latch indicates the end of the loop body code.
OpenMPIRBuilder::InsertPointTy getPreheaderIP() const
Return the insertion point for user code before the loop.
BasicBlock * getCond() const
The condition block computes whether there is another loop iteration.
BasicBlock * getExit() const
Reaching the exit indicates no more iterations are being executed.
LLVM_ABI BasicBlock * getPreheader() const
The preheader ensures that there is only a single edge entering the loop.
Instruction * getIndVar() const
Returns the instruction representing the current logical induction variable.
Utility class for extracting code into a new function.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
This is an important base class in LLVM.
Definition Constant.h:44
A debug info location.
Definition DebugLoc.h:126
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition GlobalValue.h:52
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
BasicBlock::iterator InsertPoint
InsertPoint - A saved insertion point.
Definition IRBuilder.h:254
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2987
Class to represent integer types.
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:598
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:39
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
OffloadEntryInfoDeviceGlobalVar(unsigned Order, OMPTargetGlobalVarEntryKind Flags)
OffloadEntryInfoDeviceGlobalVar(unsigned Order, Constant *Addr, int64_t VarSize, OMPTargetGlobalVarEntryKind Flags, GlobalValue::LinkageTypes Linkage, const std::string &VarName)
static bool classof(const OffloadEntryInfo *Info)
OffloadEntryInfoTargetRegion(unsigned Order, Constant *Addr, Constant *ID, OMPTargetRegionEntryKind Flags)
@ OffloadingEntryInfoTargetRegion
Entry is a target region.
@ OffloadingEntryInfoDeviceGlobalVar
Entry is a declare target variable.
OffloadingEntryInfoKinds getKind() const
OffloadEntryInfo(OffloadingEntryInfoKinds Kind)
static bool classof(const OffloadEntryInfo *Info)
OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order, uint32_t Flags)
Class that manages information about offload code regions and data.
function_ref< void(StringRef, const OffloadEntryInfoDeviceGlobalVar &)> OffloadDeviceGlobalVarEntryInfoActTy
Applies action Action on all registered entries.
OMPTargetDeviceClauseKind
Kind of device clause for declare target variables and functions NOTE: Currently not used as a part o...
@ OMPTargetDeviceClauseNoHost
The target is marked for non-host devices.
@ OMPTargetDeviceClauseAny
The target is marked for all devices.
@ OMPTargetDeviceClauseNone
The target is marked as having no clause.
@ OMPTargetDeviceClauseHost
The target is marked for host devices.
LLVM_ABI void registerDeviceGlobalVarEntryInfo(StringRef VarName, Constant *Addr, int64_t VarSize, OMPTargetGlobalVarEntryKind Flags, GlobalValue::LinkageTypes Linkage)
Register device global variable entry.
LLVM_ABI void initializeDeviceGlobalVarEntryInfo(StringRef Name, OMPTargetGlobalVarEntryKind Flags, unsigned Order)
Initialize device global variable entry.
LLVM_ABI void actOnDeviceGlobalVarEntriesInfo(const OffloadDeviceGlobalVarEntryInfoActTy &Action)
OMPTargetRegionEntryKind
Kind of the target registry entry.
@ OMPTargetRegionEntryTargetRegion
Mark the entry as target region.
OffloadEntriesInfoManager(OpenMPIRBuilder *builder)
LLVM_ABI void getTargetRegionEntryFnName(SmallVectorImpl< char > &Name, const TargetRegionEntryInfo &EntryInfo)
LLVM_ABI bool hasTargetRegionEntryInfo(TargetRegionEntryInfo EntryInfo, bool IgnoreAddressId=false) const
Return true if a target region entry with the provided information exists.
LLVM_ABI void registerTargetRegionEntryInfo(TargetRegionEntryInfo EntryInfo, Constant *Addr, Constant *ID, OMPTargetRegionEntryKind Flags)
Register target region entry.
LLVM_ABI void actOnTargetRegionEntriesInfo(const OffloadTargetRegionEntryInfoActTy &Action)
unsigned size() const
Return number of entries defined so far.
LLVM_ABI void initializeTargetRegionEntryInfo(const TargetRegionEntryInfo &EntryInfo, unsigned Order)
Initialize target region entry.
OMPTargetGlobalVarEntryKind
Kind of the global variable entry..
@ OMPTargetGlobalVarEntryEnter
Mark the entry as a declare target enter.
@ OMPTargetGlobalVarEntryNone
Mark the entry as having no declare target entry kind.
@ OMPTargetGlobalRegisterRequires
Mark the entry as a register requires global.
@ OMPTargetGlobalVarEntryIndirect
Mark the entry as a declare target indirect global.
@ OMPTargetGlobalVarEntryLink
Mark the entry as a to declare target link.
@ OMPTargetGlobalVarEntryTo
Mark the entry as a to declare target.
@ OMPTargetGlobalVarEntryIndirectVTable
Mark the entry as a declare target indirect vtable.
function_ref< void(const TargetRegionEntryInfo &EntryInfo, const OffloadEntryInfoTargetRegion &)> OffloadTargetRegionEntryInfoActTy
brief Applies action Action on all registered entries.
bool hasDeviceGlobalVarEntryInfo(StringRef VarName) const
Checks if the variable with the given name has been registered already.
LLVM_ABI bool empty() const
Return true if a there are no entries defined.
Captures attributes that affect generating LLVM-IR using the OpenMPIRBuilder and related classes.
std::optional< bool > NoSignedWrap
Flag for specifying whether the no-signed-wrap (nsw) flag should be added to loop induction variable ...
std::optional< bool > IsTargetDevice
Flag to define whether to generate code for the role of the OpenMP host (if set to false) or device (...
std::optional< bool > IsGPU
Flag for specifying if the compilation is done for an accelerator.
std::optional< StringRef > FirstSeparator
First separator used between the initial two parts of a name.
StringRef separator() const
LLVM_ABI int64_t getRequiresFlags() const
Returns requires directive clauses as flags compatible with those expected by libomptarget.
void setFirstSeparator(StringRef FS)
CollapseIVMapping
Representation of a collapsed iteration space.
@ Virtual
Retain the physical nest and decode each assigned range once.
@ DivMod
Decode source indices from the logical index using division and remainder in each iteration.
void setDefaultTargetAS(unsigned AS)
StringRef firstSeparator() const
std::optional< bool > OpenMPOffloadMandatory
Flag for specifying if offloading is mandatory.
std::optional< bool > EmitLLVMUsedMetaInfo
Flag for specifying if LLVMUsed information should be emitted.
SmallVector< Triple > TargetTriples
When compilation is being done for the OpenMP host (i.e.
LLVM_ABI void setHasRequiresReverseOffload(bool Value)
void setNoSignedWrap(bool Value)
LLVM_ABI bool hasRequiresUnifiedSharedMemory() const
LLVM_ABI void setHasRequiresUnifiedSharedMemory(bool Value)
unsigned getDefaultTargetAS() const
std::optional< StringRef > Separator
Separator used between all of the rest consecutive parts of s name.
LLVM_ABI bool hasRequiresDynamicAllocators() const
bool openMPOffloadMandatory() const
CallingConv::ID getRuntimeCC() const
CollapseIVMapping CollapseMapping
Mapping used for collapsed loops.
LLVM_ABI void setHasRequiresUnifiedAddress(bool Value)
void setOpenMPOffloadMandatory(bool Value)
void setIsTargetDevice(bool Value)
void setSeparator(StringRef S)
void setRuntimeCC(CallingConv::ID CC)
LLVM_ABI void setHasRequiresDynamicAllocators(bool Value)
void setEmitLLVMUsed(bool Value=true)
std::optional< omp::GV > GridValue
LLVM_ABI bool hasRequiresReverseOffload() const
LLVM_ABI bool hasRequiresUnifiedAddress() const
llvm::AllocaInst * CreateAlloca(llvm::Type *Ty, const llvm::Twine &Name) const override
void decorateWithTBAA(llvm::Instruction *I) override
AtomicInfo(IRBuilder<> *Builder, llvm::Type *Ty, uint64_t AtomicSizeInBits, uint64_t ValueSizeInBits, llvm::Align AtomicAlign, llvm::Align ValueAlign, bool UseLibcall, IRBuilderBase::InsertPoint AllocaIP, llvm::Value *AtomicVar)
llvm::Value * getAtomicPointer() const override
Struct that keeps the information that should be kept throughout a 'target data' region.
TargetDataInfo(bool RequiresDevicePointerInfo, bool SeparateBeginEndCalls)
SmallMapVector< const Value *, std::pair< Value *, Value * >, 4 > DevicePtrInfoMap
void clearArrayInfo()
Clear information about the data arrays.
unsigned NumberOfPtrs
The total number of pointers passed to the runtime library.
bool HasNoWait
Whether the target ... data directive has a nowait clause.
bool isValid()
Return true if the current target data information has valid arrays.
bool HasMapper
Indicate whether any user-defined mapper exists.
An interface to create LLVM-IR for OpenMP directives.
LLVM_ABI InsertPointOrErrorTy createOrderedThreadsSimd(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB, bool IsThreads)
Generator for 'omp ordered [threads | simd]'.
LLVM_ABI void emitAArch64DeclareSimdFunction(llvm::Function *Fn, unsigned VLENVal, llvm::ArrayRef< DeclareSimdAttrTy > ParamAttrs, DeclareSimdBranch Branch, char ISA, unsigned NarrowestDataSize, bool OutputBecomesInput)
Emit AArch64 vector-function ABI attributes for a declare simd function.
LLVM_ABI Constant * getOrCreateIdent(Constant *SrcLocStr, uint32_t SrcLocStrSize, omp::IdentFlag Flags=omp::IdentFlag(0), unsigned Reserve2Flags=0)
Return an ident_t* encoding the source location SrcLocStr and Flags.
LLVM_ABI void registerDeclareTargetGlobalReplacement(GlobalValue *Original, GlobalValue *Replacement)
Register a module-scope replacement of a declare target global variable.
LLVM_ABI FunctionCallee getOrCreateRuntimeFunction(Module &M, omp::RuntimeFunction FnID)
Return the function declaration for the runtime function with FnID.
LLVM_ABI InsertPointOrErrorTy createCancel(const LocationDescription &Loc, Value *IfCondition, omp::Directive CanceledDirective)
Generator for 'omp cancel'.
std::function< Expected< Function * >(StringRef FunctionName)> FunctionGenCallback
Functions used to generate a function with the given name.
LLVM_ABI CallInst * createOMPAllocShared(const LocationDescription &Loc, Value *Size, const Twine &Name=Twine(""))
Create a runtime call for kmpc_alloc_shared.
ReductionGenCBKind
Enum class for the RedctionGen CallBack type to be used.
LLVM_ABI CanonicalLoopInfo * collapseLoops(DebugLoc DL, ArrayRef< CanonicalLoopInfo * > Loops, InsertPointTy ComputeIP)
Collapse a loop nest using Config.CollapseMapping.
LLVM_ABI void createTaskyield(const LocationDescription &Loc)
Generator for 'omp taskyield'.
std::function< Error(InsertPointTy CodeGenIP)> FinalizeCallbackTy
Callback type for variable finalization (think destructors).
LLVM_ABI void emitBranch(BasicBlock *Target)
LLVM_ABI Error emitCancelationCheckImpl(Value *CancelFlag, omp::Directive CanceledDirective)
Generate control flow and cleanup for cancellation.
static LLVM_ABI void writeThreadBoundsForKernel(const Triple &T, Function &Kernel, int32_t LB, int32_t UB)
EvalKind
Enum class for reduction evaluation types scalar, complex and aggregate.
LLVM_ABI void emitTaskwaitImpl(const LocationDescription &Loc)
Generate a taskwait runtime call.
LLVM_ABI Constant * registerTargetRegionFunction(TargetRegionEntryInfo &EntryInfo, Function *OutlinedFunction, StringRef EntryFnName, StringRef EntryFnIDName)
Registers the given function and sets up the attribtues of the function Returns the FunctionID.
LLVM_ABI GlobalVariable * emitKernelExecutionMode(StringRef KernelName, omp::OMPTgtExecModeFlags Mode)
Emit the kernel execution mode.
LLVM_ABI void initialize()
Initialize the internal state, this will put structures types and potentially other helpers into the ...
LLVM_ABI InsertPointTy createAtomicCompare(const LocationDescription &Loc, AtomicOpValue &X, AtomicOpValue &V, AtomicOpValue &R, Value *E, Value *D, AtomicOrdering AO, omp::OMPAtomicCompareOp Op, bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly, bool IsWeak=false)
std::function< InsertPointTy(InsertPointTy CodeGenIP, unsigned Index, Value **LHS, Value **RHS, Function *CurFn)> ReductionGenClangCBTy
ReductionGen CallBack for Clang.
LLVM_ABI InsertPointTy createAtomicWrite(const LocationDescription &Loc, AtomicOpValue &X, Value *Expr, AtomicOrdering AO, InsertPointTy AllocaIP)
Emit atomic write for : X = Expr — Only Scalar data types.
LLVM_ABI void loadOffloadInfoMetadata(Module &M)
Loads all the offload entries information from the host IR metadata.
function_ref< MapInfosTy &(InsertPointTy CodeGenIP)> GenMapInfoCallbackTy
Callback type for creating the map infos for the kernel parameters.
LLVM_ABI Error emitOffloadingArrays(InsertPointTy AllocaIP, InsertPointTy CodeGenIP, MapInfosTy &CombinedInfo, TargetDataInfo &Info, CustomMapperCallbackTy CustomMapperCB, bool IsNonContiguous=false, function_ref< void(unsigned int, Value *)> DeviceAddrCB=nullptr)
Emit the arrays used to pass the captures and map information to the offloading runtime library.
LLVM_ABI void unrollLoopFull(DebugLoc DL, CanonicalLoopInfo *Loop)
Fully unroll a loop.
function_ref< Error(InsertPointTy CodeGenIP, Value *IndVar)> LoopBodyGenCallbackTy
Callback type for loop body code generation.
LLVM_ABI InsertPointOrErrorTy emitScanReduction(const LocationDescription &Loc, ArrayRef< llvm::OpenMPIRBuilder::ReductionInfo > ReductionInfos, ScanInfo *ScanRedInfo)
This function performs the scan reduction of the values updated in the input phase.
LLVM_ABI void emitFlush(const LocationDescription &Loc)
Generate a flush runtime call.
LLVM_ABI InsertPointOrErrorTy createScope(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB, bool IsNowait)
Generator for 'omp scope'.
static LLVM_ABI std::pair< int32_t, int32_t > readThreadBoundsForKernel(const Triple &T, Function &Kernel)
}
origPtr *with the address space normalization required by the runtime entry point *The NULL descriptor makes the runtime walk the enclosing taskgroups to *find the matching task_reduction registration for the item The lookups *are emitted at p which must be inside the target task body **The front end specific work(matching each `in_reduction` item to its *mapped storage and binding the generated private pointer back to the *right value) stays with the caller InsertPointT getInsertionPoint)()
Return the insertion point used by the underlying IRBuilder.
SmallVector< bool, 4 > MapHasAttachPtrArrayTy
OpenMPIRBuilderConfig Config
The OpenMPIRBuilder Configuration.
LLVM_ABI CallInst * createOMPInteropDestroy(const LocationDescription &Loc, Value *InteropVar, Value *Device, Value *NumDependences, Value *DependenceAddress, bool HaveNowaitClause)
Create a runtime call for __tgt_interop_destroy.
std::function< InsertPointOrErrorTy( InsertPointTy CodeGenIP, Value *LHS, Value *RHS, Value *&Res)> ReductionGenCBTy
ReductionGen CallBack for MLIR.
LLVM_ABI void emitUsed(StringRef Name, ArrayRef< llvm::WeakTrackingVH > List)
Emit the llvm.used metadata.
void setConfig(OpenMPIRBuilderConfig C)
LLVM_ABI InsertPointOrErrorTy createSingle(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB, bool IsNowait, ArrayRef< llvm::Value * > CPVars={}, ArrayRef< llvm::Function * > CPFuncs={})
Generator for 'omp single'.
LLVM_ABI InsertPointOrErrorTy createTarget(const LocationDescription &Loc, bool IsOffloadEntry, OpenMPIRBuilder::InsertPointTy AllocaIP, OpenMPIRBuilder::InsertPointTy CodeGenIP, ArrayRef< BasicBlock * > DeallocBlocks, TargetDataInfo &Info, TargetRegionEntryInfo &EntryInfo, const TargetKernelDefaultAttrs &DefaultAttrs, const TargetKernelRuntimeAttrs &RuntimeAttrs, Value *IfCond, SmallVectorImpl< Value * > &Inputs, GenMapInfoCallbackTy GenMapInfoCB, TargetBodyGenCallbackTy BodyGenCB, TargetGenArgAccessorsCallbackTy ArgAccessorFuncCB, CustomMapperCallbackTy CustomMapperCB, const DependenciesInfo &Dependencies={}, bool HasNowait=false, Value *DynCGroupMem=nullptr, omp::OMPDynGroupprivateFallbackType DynCGroupMemFallback=omp::OMPDynGroupprivateFallbackType::Abort, DebugLoc OutlinedFnLoc={}, Value *RTLocOverride=nullptr)
Generator for 'omp target'.
LLVM_ABI InsertPointOrErrorTy createTeams(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, Value *NumTeamsLower=nullptr, Value *NumTeamsUpper=nullptr, Value *ThreadLimit=nullptr, Value *IfExpr=nullptr)
Generator for #omp teams
std::forward_list< CanonicalLoopInfo > LoopInfos
Collection of owned canonical loop objects that eventually need to be free'd.
bool setHandleFPNegZero(bool FPNegZero)
Set whether atomic compare should handle -0.0/+0.0 equivalence.
LLVM_ABI llvm::StructType * getKmpTaskAffinityInfoTy()
Return the LLVM struct type matching runtime kmp_task_affinity_info_t.
LLVM_ABI Constant * emitKernelEnvironment(const LocationDescription &Loc, const llvm::OpenMPIRBuilder::TargetKernelDefaultAttrs &Attrs)
The omp target interface.
SmallVector< uint64_t, 4 > MapDimArrayTy
std::function< Error(InsertPointTy AllocaIP, InsertPointTy CodeGenIP, ArrayRef< BasicBlock * > DeallocBlocks)> StorableBodyGenCallbackTy
LLVM_ABI std::string createPlatformSpecificName(ArrayRef< StringRef > Parts) const
Get the create a name using the platform specific separators.
LLVM_ABI FunctionCallee createDispatchNextFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_next_* runtime function for the specified size IVSize and sign IVSigned.
static LLVM_ABI void getKernelArgsVector(TargetKernelArgs &KernelArgs, IRBuilderBase &Builder, SmallVector< Value * > &ArgsVector)
Create the kernel args vector used by emitTargetKernel.
SmallVector< Constant *, 4 > MapNamesArrayTy
LLVM_ABI void unrollLoopHeuristic(DebugLoc DL, CanonicalLoopInfo *Loop)
Fully or partially unroll a loop.
LLVM_ABI omp::OpenMPOffloadMappingFlags getMemberOfFlag(unsigned Position)
Get OMP_MAP_MEMBER_OF flag with extra bits reserved based on the position given.
LLVM_ABI void addAttributes(omp::RuntimeFunction FnID, Function &Fn)
Add attributes known for FnID to Fn.
LLVM_ABI Expected< Function * > emitUserDefinedMapper(function_ref< MapInfosOrErrorTy(InsertPointTy CodeGenIP, llvm::Value *PtrPHI, llvm::Value *BeginArg)> PrivAndGenMapInfoCB, llvm::Type *ElemTy, StringRef FuncName, CustomMapperCallbackTy CustomMapperCB, bool PreserveMemberOfFlags=false, bool PropagatePresentToPointeeStorage=false, bool PropagatePresentToNonPointeeStorage=false)
Emit the user-defined mapper function.
Module & M
The underlying LLVM-IR module.
StringMap< Constant * > SrcLocStrMap
Map to remember source location strings.
LLVM_ABI void createMapperAllocas(const LocationDescription &Loc, InsertPointTy AllocaIP, unsigned NumOperands, struct MapperAllocas &MapperAllocas)
Create the allocas instruction used in call to mapper functions.
SmallVector< DeclareTargetGlobalReplacement, 8 > DeclareTargetGlobalReplacements
Collection of declare target globals to rewrite uses of during device module finalizaiton.
LLVM_ABI Constant * getOrCreateSrcLocStr(StringRef LocStr, uint32_t &SrcLocStrSize)
Return the (LLVM-IR) string describing the source location LocStr.
OpenMPIRBuilderConfig::CollapseIVMapping CollapseIVMapping
Strategy used to derive the original induction variables after collapse.
LLVM_ABI Error emitTargetRegionFunction(TargetRegionEntryInfo &EntryInfo, FunctionGenCallback &GenerateFunctionCallback, bool IsOffloadEntry, Function *&OutlinedFn, Constant *&OutlinedFnID)
Create a unique name for the entry function using the source location information of the current targ...
LLVM_ABI InsertPointOrErrorTy createIteratorLoop(LocationDescription Loc, llvm::Value *TripCount, IteratorBodyGenTy BodyGen, llvm::StringRef Name="iterator")
Create a canonical iterator loop at the current insertion point.
LLVM_ABI Expected< SmallVector< llvm::CanonicalLoopInfo * > > createCanonicalScanLoops(const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB, Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop, InsertPointTy ComputeIP, const Twine &Name, ScanInfo *ScanRedInfo)
Generator for the control flow structure of an OpenMP canonical loops if the parent directive has an ...
LLVM_ABI FunctionCallee createDispatchFiniFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_fini_* runtime function for the specified size IVSize and sign IVSigned.
function_ref< InsertPointOrErrorTy( InsertPointTy AllocaIP, InsertPointTy CodeGenIP, ArrayRef< BasicBlock * > DeallocBlocks)> TargetBodyGenCallbackTy
LLVM_ABI void unrollLoopPartial(DebugLoc DL, CanonicalLoopInfo *Loop, int32_t Factor, CanonicalLoopInfo **UnrolledCLI)
Partially unroll a loop.
function_ref< Error(Value *DeviceID, Value *RTLoc, IRBuilderBase::InsertPoint TargetTaskAllocaIP)> TargetTaskBodyCallbackTy
Callback type for generating the bodies of device directives that require outer target tasks (e....
Expected< MapInfosTy & > MapInfosOrErrorTy
bool HandleFPNegZero
Emit atomic compare for constructs: — Only scalar data types cond-expr-stmt: x = x ordop expr ?
SmallVector< omp::OpenMPOffloadMappingFlags, 4 > MapFlagsArrayTy
LLVM_ABI void emitTaskyieldImpl(const LocationDescription &Loc)
Generate a taskyield runtime call.
LLVM_ABI void emitMapperCall(const LocationDescription &Loc, Function *MapperFunc, Value *SrcLocInfo, Value *MaptypesArg, Value *MapnamesArg, struct MapperAllocas &MapperAllocas, int64_t DeviceID, unsigned NumOperands)
Create the call for the target mapper function.
LLVM_ABI InsertPointOrErrorTy createDistribute(const LocationDescription &Loc, InsertPointTy AllocaIP, ArrayRef< BasicBlock * > DeallocBlocks, BodyGenCallbackTy BodyGenCB)
Generator for #omp distribute
function_ref< Expected< Function * >(unsigned int)> CustomMapperCallbackTy
LLVM_ABI InsertPointTy createOrderedDepend(const LocationDescription &Loc, InsertPointTy AllocaIP, unsigned NumLoops, ArrayRef< llvm::Value * > StoreValues, const Twine &Name, bool IsDependSource)
Generator for 'omp ordered depend (source | sink)'.
LLVM_ABI InsertPointTy createCopyinClauseBlocks(InsertPointTy IP, Value *MasterAddr, Value *PrivateAddr, llvm::IntegerType *IntPtrTy, bool BranchtoEnd=true)
Generate conditional branch and relevant BasicBlocks through which private threads copy the 'copyin' ...
SmallVector< MapValuesArrayTy, 4 > MapNonContiguousArrayTy
function_ref< InsertPointOrErrorTy( InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &Original, Value &Inner, Value *&ReplVal)> PrivatizeCallbackTy
Callback type for variable privatization (think copy & default constructor).
LLVM_ABI bool isFinalized()
Check whether the finalize function has already run.
SmallVector< DeviceInfoTy, 4 > MapDeviceInfoArrayTy
SmallVector< FinalizationInfo, 8 > FinalizationStack
The finalization stack made up of finalize callbacks currently in-flight, wrapped into FinalizationIn...
LLVM_ABI std::vector< CanonicalLoopInfo * > tileLoops(DebugLoc DL, ArrayRef< CanonicalLoopInfo * > Loops, ArrayRef< Value * > TileSizes)
Tile a loop nest.
LLVM_ABI CallInst * createOMPInteropInit(const LocationDescription &Loc, Value *InteropVar, omp::OMPInteropType InteropType, Value *Device, Value *NumDependences, Value *DependenceAddress, bool HaveNowaitClause)
Create a runtime call for __tgt_interop_init.
LLVM_ABI Error emitIfClause(Value *Cond, BodyGenCallbackTy ThenGen, BodyGenCallbackTy ElseGen, InsertPointTy AllocaIP={}, ArrayRef< BasicBlock * > DeallocBlocks={})
Emits code for OpenMP 'if' clause using specified BodyGenCallbackTy Here is the logic: if (Cond) { Th...
LLVM_ABI Function * getOrCreateRuntimeFunctionPtr(omp::RuntimeFunction FnID)
std::function< InsertPointOrErrorTy( InsertPointTy, Value *ByRefVal, Value *&Res)> ReductionGenDataPtrPtrCBTy
void addOutlineInfo(std::unique_ptr< OutlineInfo > &&OI)
Add a new region that will be outlined later.
LLVM_ABI InsertPointTy createTargetInit(const LocationDescription &Loc, const llvm::OpenMPIRBuilder::TargetKernelDefaultAttrs &Attrs)
Create a runtime call for kmpc_target_init.
LLVM_ABI InsertPointOrErrorTy createReductions(const LocationDescription &Loc, InsertPointTy AllocaIP, ArrayRef< ReductionInfo > ReductionInfos, ArrayRef< bool > IsByRef, bool IsNoWait=false, bool IsTeamsReduction=false)
Generator for 'omp reduction'.
const Triple T
The target triple of the underlying module.
DenseMap< std::pair< Constant *, uint64_t >, Constant * > IdentMap
Map to remember existing ident_t*.
LLVM_ABI CallInst * createOMPFree(const LocationDescription &Loc, Value *Addr, Value *Allocator, std::string Name="")
Create a runtime call for kmpc_free.
LLVM_ABI InsertPointOrErrorTy createReductionsGPU(const LocationDescription &Loc, InsertPointTy AllocaIP, InsertPointTy CodeGenIP, ArrayRef< ReductionInfo > ReductionInfos, ArrayRef< bool > IsByRef, bool IsNoWait=false, bool IsTeamsReduction=false, bool IsSPMD=false, ReductionGenCBKind ReductionGenCBKind=ReductionGenCBKind::MLIR, std::optional< omp::GV > GridValue={}, Value *SrcLocInfo=nullptr)
Design of OpenMP reductions on the GPU.
LLVM_ABI FunctionCallee createForStaticInitFunction(unsigned IVSize, bool IVSigned, bool IsGPUDistribute)
Returns __kmpc_for_static_init_* runtime function for the specified size IVSize and sign IVSigned.
LLVM_ABI CallInst * createOMPAlloc(const LocationDescription &Loc, Value *Size, Value *Allocator, std::string Name="")
Create a runtime call for kmpc_alloc.
LLVM_ABI void emitNonContiguousDescriptor(InsertPointTy AllocaIP, InsertPointTy CodeGenIP, MapInfosTy &CombinedInfo, TargetDataInfo &Info)
Emit an array of struct descriptors to be assigned to the offload args.
SmallVector< Value *, 4 > MapValuesArrayTy
LLVM_ABI InsertPointOrErrorTy createSection(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB)
Generator for 'omp section'.
LLVM_ABI InsertPointOrErrorTy createTaskgroup(const LocationDescription &Loc, InsertPointTy AllocaIP, ArrayRef< BasicBlock * > DeallocBlocks, BodyGenCallbackTy BodyGenCB)
Generator for the taskgroup construct.
LLVM_ABI InsertPointOrErrorTy createParallel(const LocationDescription &Loc, InsertPointTy AllocaIP, ArrayRef< BasicBlock * > DeallocBlocks, BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB, FinalizeCallbackTy FiniCB, Value *IfCondition, Value *NumThreads, omp::ProcBindKind ProcBind, bool IsCancellable)
Generator for 'omp parallel'.
function_ref< InsertPointOrErrorTy(InsertPointTy)> EmitFallbackCallbackTy
Callback function type for functions emitting the host fallback code that is executed when the kernel...
static LLVM_ABI TargetRegionEntryInfo getTargetEntryUniqueInfo(FileIdentifierInfoCallbackTy CallBack, vfs::FileSystem &VFS, StringRef ParentName="")
Creates a unique info for a target entry when provided a filename and line number from.
LLVM_ABI void emitTaskDependency(IRBuilderBase &Builder, Value *Entry, const DependData &Dep)
Store one kmp_depend_info entry at the given Entry pointer.
LLVM_ABI void emitBlock(BasicBlock *BB, Function *CurFn, bool IsFinished=false)
LLVM_ABI Value * getOrCreateThreadID(Value *Ident)
Return the current thread ID.
LLVM_ABI InsertPointOrErrorTy createMaster(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB)
Generator for 'omp master'.
void pushFinalizationCB(const FinalizationInfo &FI)
Push a finalization callback on the finalization stack.
LLVM_ABI InsertPointOrErrorTy createTargetData(const LocationDescription &Loc, InsertPointTy AllocaIP, InsertPointTy CodeGenIP, ArrayRef< BasicBlock * > DeallocBlocks, Value *DeviceID, Value *IfCond, TargetDataInfo &Info, GenMapInfoCallbackTy GenMapInfoCB, CustomMapperCallbackTy CustomMapperCB, omp::RuntimeFunction *MapperFunc=nullptr, function_ref< InsertPointOrErrorTy(InsertPointTy CodeGenIP, BodyGenTy BodyGenType)> BodyGenCB=nullptr, function_ref< void(unsigned int, Value *)> DeviceAddrCB=nullptr, Value *SrcLocInfo=nullptr)
Generator for 'omp target data'.
LLVM_ABI CallInst * createRuntimeFunctionCall(FunctionCallee Callee, ArrayRef< Value * > Args, StringRef Name="")
LLVM_ABI InsertPointOrErrorTy emitKernelLaunch(const LocationDescription &Loc, Value *OutlinedFnID, EmitFallbackCallbackTy EmitTargetCallFallbackCB, TargetKernelArgs &Args, Value *DeviceID, Value *RTLoc, InsertPointTy AllocaIP)
Generate a target region entry call and host fallback call.
StringMap< GlobalVariable *, BumpPtrAllocator > InternalVars
An ordered map of auto-generated variables to their unique names.
LLVM_ABI InsertPointOrErrorTy createCancellationPoint(const LocationDescription &Loc, omp::Directive CanceledDirective)
Generator for 'omp cancellation point'.
LLVM_ABI CallInst * createOMPAlignedAlloc(const LocationDescription &Loc, Value *Align, Value *Size, Value *Allocator, std::string Name="")
Create a runtime call for kmpc_align_alloc.
LLVM_ABI FunctionCallee createDispatchInitFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_init_* runtime function for the specified size IVSize and sign IVSigned.
LLVM_ABI InsertPointOrErrorTy createScan(const LocationDescription &Loc, InsertPointTy AllocaIP, ArrayRef< llvm::Value * > ScanVars, ArrayRef< llvm::Type * > ScanVarsType, bool IsInclusive, ScanInfo *ScanRedInfo)
This directive split and directs the control flow to input phase blocks or scan phase blocks based on...
LLVM_ABI CallInst * createOMPFreeShared(const LocationDescription &Loc, Value *Addr, Value *Size, const Twine &Name=Twine(""))
Create a runtime call for kmpc_free_shared.
LLVM_ABI CallInst * createOMPInteropUse(const LocationDescription &Loc, Value *InteropVar, Value *Device, Value *NumDependences, Value *DependenceAddress, bool HaveNowaitClause)
Create a runtime call for __tgt_interop_use.
IRBuilder<>::InsertPoint InsertPointTy
Type used throughout for insertion points.
LLVM_ABI GlobalVariable * getOrCreateInternalVariable(Type *Ty, const StringRef &Name, std::optional< unsigned > AddressSpace={})
Gets (if variable with the given name already exist) or creates internal global variable with the spe...
LLVM_ABI GlobalVariable * createOffloadMapnames(SmallVectorImpl< llvm::Constant * > &Names, std::string VarName)
Create the global variable holding the offload names information.
LLVM_ABI InsertPointOrErrorTy createTask(const LocationDescription &Loc, InsertPointTy AllocaIP, ArrayRef< BasicBlock * > DeallocBlocks, BodyGenCallbackTy BodyGenCB, bool Tied=true, Value *Final=nullptr, Value *IfCondition=nullptr, const DependenciesInfo &Dependencies={}, const AffinityData &Affinities={}, bool Mergeable=false, Value *EventHandle=nullptr, Value *Priority=nullptr, bool FreeAgent=false)
Generator for #omp taskloop
std::forward_list< ScanInfo > ScanInfos
Collection of owned ScanInfo objects that eventually need to be free'd.
static LLVM_ABI void writeTeamsForKernel(const Triple &T, Function &Kernel, int32_t LB, int32_t UB)
std::function< InsertPointOrErrorTy( InsertPointTy, Type *, Value *, Value *)> ReductionGenAtomicCBTy
Functions used to generate atomic reductions.
LLVM_ABI Value * calculateCanonicalLoopTripCount(const LocationDescription &Loc, Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop, const Twine &Name="loop")
Calculate the trip count of a canonical loop.
DeclareSimdKindTy
Kind of parameter in a function with 'declare simd' directive.
LLVM_ABI InsertPointOrErrorTy createBarrier(const LocationDescription &Loc, omp::Directive Kind, bool ForceSimpleCall=false, bool CheckCancelFlag=true)
Emitter methods for OpenMP directives.
LLVM_ABI void setCorrectMemberOfFlag(omp::OpenMPOffloadMappingFlags &Flags, omp::OpenMPOffloadMappingFlags MemberOfFlag)
Given an initial flag set, this function modifies it to contain the passed in MemberOfFlag generated ...
LLVM_ABI Error emitOffloadingArraysAndArgs(InsertPointTy AllocaIP, InsertPointTy CodeGenIP, TargetDataInfo &Info, TargetDataRTArgs &RTArgs, MapInfosTy &CombinedInfo, CustomMapperCallbackTy CustomMapperCB, bool IsNonContiguous=false, bool ForEndCall=false, function_ref< void(unsigned int, Value *)> DeviceAddrCB=nullptr)
Allocates memory for and populates the arrays required for offloading (offload_{baseptrs|ptrs|mappers...
LLVM_ABI Constant * getOrCreateDefaultSrcLocStr(uint32_t &SrcLocStrSize)
Return the (LLVM-IR) string describing the default source location.
LLVM_ABI InsertPointOrErrorTy createCritical(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB, StringRef CriticalName, Value *HintInst)
Generator for 'omp critical'.
LLVM_ABI void createError(const LocationDescription &Loc, bool IsFatal, Value *Message)
Generate a call to the runtime to emit the diagnostic of an OpenMP error directive with at(execution)...
LLVM_ABI void createOffloadEntry(Constant *ID, Constant *Addr, uint64_t Size, int32_t Flags, GlobalValue::LinkageTypes, StringRef Name="")
Creates offloading entry for the provided entry ID ID, address Addr, size Size, and flags Flags.
static LLVM_ABI unsigned getOpenMPDefaultSimdAlign(const Triple &TargetTriple, const StringMap< bool > &Features)
Get the default alignment value for given target.
LLVM_ABI unsigned getFlagMemberOffset()
Get the offset of the OMP_MAP_MEMBER_OF field.
LLVM_ABI InsertPointOrErrorTy createAtomicCapture(const LocationDescription &Loc, InsertPointTy AllocaIP, AtomicOpValue &X, AtomicOpValue &V, Value *Expr, AtomicOrdering AO, AtomicRMWInst::BinOp RMWOp, AtomicUpdateCallbackTy &UpdateOp, bool UpdateExpr, bool IsPostfixUpdate, bool IsXBinopExpr, bool IsIgnoreDenormalMode=false, bool IsFineGrainedMemory=false, bool IsRemoteMemory=false)
Emit atomic update for constructs: — Only Scalar data types V = X; X = X BinOp Expr ,...
LLVM_ABI CanonicalLoopInfo * createLoopSkeleton(DebugLoc DL, Value *TripCount, Function *F, BasicBlock *PreInsertBefore, BasicBlock *PostInsertBefore, const Twine &Name={}, bool IsCollapsed=false)
Create the control flow structure of a canonical OpenMP loop.
LLVM_ABI void createOffloadEntriesAndInfoMetadata(EmitMetadataErrorReportFunctionTy &ErrorReportFunction)
LLVM_ABI void applySimd(CanonicalLoopInfo *Loop, MapVector< Value *, Value * > AlignedVars, Value *IfCond, omp::OrderKind Order, ConstantInt *Simdlen, ConstantInt *Safelen)
Add metadata to simd-ize a loop.
SmallVector< std::unique_ptr< OutlineInfo >, 16 > OutlineInfos
Collection of regions that need to be outlined during finalization.
LLVM_ABI InsertPointOrErrorTy createAtomicUpdate(const LocationDescription &Loc, InsertPointTy AllocaIP, AtomicOpValue &X, Value *Expr, AtomicOrdering AO, AtomicRMWInst::BinOp RMWOp, AtomicUpdateCallbackTy &UpdateOp, bool IsXBinopExpr, bool IsIgnoreDenormalMode=false, bool IsFineGrainedMemory=false, bool IsRemoteMemory=false)
Emit atomic update for constructs: X = X BinOp Expr ,or X = Expr BinOp X For complex Operations: X = ...
std::function< std::tuple< std::string, uint64_t >()> FileIdentifierInfoCallbackTy
bool isLastFinalizationInfoCancellable(omp::Directive DK)
Return true if the last entry in the finalization stack is of kind DK and cancellable.
LLVM_ABI InsertPointTy emitTargetKernel(const LocationDescription &Loc, InsertPointTy AllocaIP, Value *&Return, Value *Ident, Value *DeviceID, Value *NumTeams, Value *NumThreads, Value *HostPtr, ArrayRef< Value * > KernelArgs)
Generate a target region entry call.
LLVM_ABI GlobalVariable * createOffloadMaptypes(SmallVectorImpl< uint64_t > &Mappings, std::string VarName)
Create the global variable holding the offload mappings information.
LLVM_ABI CallInst * createCachedThreadPrivate(const LocationDescription &Loc, llvm::Value *Pointer, llvm::ConstantInt *Size, const llvm::Twine &Name=Twine(""))
Create a runtime call for kmpc_threadprivate_cached.
IRBuilder Builder
The LLVM-IR Builder used to create IR.
LLVM_ABI GlobalValue * createGlobalFlag(unsigned Value, StringRef Name)
Create a hidden global flag Name in the module with initial value Value.
LLVM_ABI void emitOffloadingArraysArgument(IRBuilderBase &Builder, OpenMPIRBuilder::TargetDataRTArgs &RTArgs, OpenMPIRBuilder::TargetDataInfo &Info, bool ForEndCall=false)
Emit the arguments to be passed to the runtime library based on the arrays of base pointers,...
LLVM_ABI InsertPointOrErrorTy createMasked(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB, Value *Filter)
Generator for 'omp masked'.
LLVM_ABI Expected< CanonicalLoopInfo * > createCanonicalLoop(const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB, Value *TripCount, const Twine &Name="loop")
Generator for the control flow structure of an OpenMP canonical loop.
function_ref< Expected< InsertPointTy >( InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value *DestPtr, Value *SrcPtr)> TaskDupCallbackTy
Callback type for task duplication function code generation.
LLVM_ABI Value * getSizeInBytes(Value *BasePtr)
Computes the size of type in bytes.
llvm::function_ref< llvm::Error( InsertPointTy BodyIP, llvm::Value *LinearIV)> IteratorBodyGenTy
OpenMPIRBuilder(Module &M)
Create a new OpenMPIRBuilder operating on the given module M.
LLVM_ABI FunctionCallee createDispatchDeinitFunction()
Returns __kmpc_dispatch_deinit runtime function.
LLVM_ABI void registerTargetGlobalVariable(OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind CaptureClause, OffloadEntriesInfoManager::OMPTargetDeviceClauseKind DeviceClause, bool IsDeclaration, bool IsExternallyVisible, TargetRegionEntryInfo EntryInfo, StringRef MangledName, std::vector< GlobalVariable * > &GeneratedRefs, bool OpenMPSIMD, std::vector< Triple > TargetTriple, std::function< Constant *()> GlobalInitializer, std::function< GlobalValue::LinkageTypes()> VariableLinkage, Type *LlvmPtrTy, Constant *Addr)
Registers a target variable for device or host.
LLVM_ABI void createTargetDeinit(const LocationDescription &Loc, int32_t TeamsReductionDataSize=0)
Create a runtime call for kmpc_target_deinit.
BodyGenTy
Type of BodyGen to use for region codegen.
LLVM_ABI CanonicalLoopInfo * fuseLoops(DebugLoc DL, ArrayRef< CanonicalLoopInfo * > Loops)
Fuse a sequence of loops.
LLVM_ABI void emitX86DeclareSimdFunction(llvm::Function *Fn, unsigned NumElements, const llvm::APSInt &VLENVal, llvm::ArrayRef< DeclareSimdAttrTy > ParamAttrs, DeclareSimdBranch Branch)
Emit x86 vector-function ABI attributes for a declare simd function.
SmallVector< llvm::Function *, 16 > ConstantAllocaRaiseCandidates
A collection of candidate target functions that's constant allocas will attempt to be raised on a cal...
OffloadEntriesInfoManager OffloadInfoManager
Info manager to keep track of target regions.
static LLVM_ABI std::pair< int32_t, int32_t > readTeamBoundsForKernel(const Triple &T, Function &Kernel)
Read/write a bounds on teams for Kernel.
const std::string ompOffloadInfoName
OMP Offload Info Metadata name string.
LLVM_ABI InsertPointOrErrorTy applyWorkshareLoop(DebugLoc DL, CanonicalLoopInfo *CLI, InsertPointTy AllocaIP, bool NeedsBarrier, llvm::omp::ScheduleKind SchedKind=llvm::omp::OMP_SCHEDULE_Default, Value *ChunkSize=nullptr, bool HasSimdModifier=false, bool HasMonotonicModifier=false, bool HasNonmonotonicModifier=false, bool HasOrderedClause=false, omp::WorksharingLoopType LoopType=omp::WorksharingLoopType::ForStaticLoop, bool NoLoop=false, bool HasDistSchedule=false, Value *DistScheduleChunkSize=nullptr, bool NeedsLastIter=false)
Modifies the canonical loop to be a workshare loop.
Expected< InsertPointTy > InsertPointOrErrorTy
Type used to represent an insertion point or an error value.
LLVM_ABI InsertPointTy createCopyPrivate(const LocationDescription &Loc, llvm::Value *BufSize, llvm::Value *CpyBuf, llvm::Value *CpyFn, llvm::Value *DidIt)
Generator for __kmpc_copyprivate.
void popFinalizationCB()
Pop the last finalization callback from the finalization stack.
LLVM_ABI InsertPointOrErrorTy createSections(const LocationDescription &Loc, InsertPointTy AllocaIP, ArrayRef< StorableBodyGenCallbackTy > SectionCBs, PrivatizeCallbackTy PrivCB, FinalizeCallbackTy FiniCB, bool IsCancellable, bool IsNowait)
Generator for 'omp sections'.
std::function< void(EmitMetadataErrorKind, TargetRegionEntryInfo)> EmitMetadataErrorReportFunctionTy
Callback function type.
function_ref< InsertPointOrErrorTy( Argument &Arg, Value *Input, Value *&RetVal, InsertPointTy AllocaIP, InsertPointTy CodeGenIP, ArrayRef< InsertPointTy > DeallocIPs)> TargetGenArgAccessorsCallbackTy
LLVM_ABI Expected< ScanInfo * > scanInfoInitialize()
Creates a ScanInfo object, allocates and returns the pointer.
LLVM_ABI InsertPointOrErrorTy emitTargetTask(TargetTaskBodyCallbackTy TaskBodyCB, Value *DeviceID, Value *RTLoc, OpenMPIRBuilder::InsertPointTy AllocaIP, const DependenciesInfo &Dependencies, const TargetDataRTArgs &RTArgs, bool HasNoWait)
Generate a target-task for the target construct.
LLVM_ABI InsertPointTy createAtomicRead(const LocationDescription &Loc, AtomicOpValue &X, AtomicOpValue &V, AtomicOrdering AO, InsertPointTy AllocaIP)
Emit atomic Read for : V = X — Only Scalar data types.
function_ref< Error(InsertPointTy AllocaIP, InsertPointTy CodeGenIP, ArrayRef< BasicBlock * > DeallocBlocks)> BodyGenCallbackTy
Callback type for body (=inner region) code generation.
bool updateToLocation(const LocationDescription &Loc)
Update the internal location to Loc.
LLVM_ABI void createFlush(const LocationDescription &Loc)
Generator for 'omp flush'.
LLVM_ABI Constant * getAddrOfDeclareTargetVar(OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind CaptureClause, OffloadEntriesInfoManager::OMPTargetDeviceClauseKind DeviceClause, bool IsDeclaration, bool IsExternallyVisible, TargetRegionEntryInfo EntryInfo, StringRef MangledName, std::vector< GlobalVariable * > &GeneratedRefs, bool OpenMPSIMD, std::vector< Triple > TargetTriple, Type *LlvmPtrTy, std::function< Constant *()> GlobalInitializer, std::function< GlobalValue::LinkageTypes()> VariableLinkage)
Retrieve (or create if non-existent) the address of a declare target variable, used in conjunction wi...
LLVM_ABI void createTaskwait(const LocationDescription &Loc, DependenciesInfo Dependencies={}, bool IsNowait=false)
Generator for 'omp taskwait'.
origPtr *with the address space normalization required by the runtime entry point *The NULL descriptor makes the runtime walk the enclosing taskgroups to *find the matching task_reduction registration for the item The lookups *are emitted at p Loc
EmitMetadataErrorKind
The kind of errors that can occur when emitting the offload entries and metadata.
ScanInfo holds the information to assist in lowering of Scan reduction.
llvm::SmallDenseMap< llvm::Value *, llvm::Value * > * ScanBuffPtrs
Maps the private reduction variable to the pointer of the temporary buffer.
llvm::BasicBlock * OMPScanLoopExit
Exit block of loop body.
llvm::Value * IV
Keeps track of value of iteration variable for input/scan loop to be used for Scan directive lowering...
llvm::BasicBlock * OMPAfterScanBlock
Dominates the body of the loop before scan directive.
llvm::BasicBlock * OMPScanInit
Block before loop body where scan initializations are done.
llvm::BasicBlock * OMPBeforeScanBlock
Dominates the body of the loop before scan directive.
llvm::BasicBlock * OMPScanFinish
Block after loop body where scan finalizations are done.
ScanInfo & operator=(const ScanInfo &)=delete
llvm::Value * Span
Stores the span of canonical loop being lowered to be used for temporary buffer allocation or Finaliz...
bool OMPFirstScanLoop
If true, it indicates Input phase is lowered; else it indicates ScanPhase is lowered.
ScanInfo(ScanInfo &)=delete
llvm::BasicBlock * OMPScanDispatch
Controls the flow to before or after scan blocks.
A vector that has set insertion semantics.
Definition SetVector.h:57
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Class to represent struct types.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Value * getOperand(unsigned i) const
Definition User.h:207
See the file comment.
Definition ValueMap.h:84
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:389
Value handle that is nullable, but tries to track the Value.
An efficient, type-erasing, non-owning reference to a callable.
The virtual file system interface.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
OpenMPOffloadMappingFlags
Values for bit flags used to specify the mapping type for offloading.
IdentFlag
IDs for all omp runtime library ident_t flag encodings (see their defintion in openmp/runtime/src/kmp...
RTLDependenceKindTy
Dependence kind for RTL.
RuntimeFunction
IDs for all omp runtime library (RTL) functions.
OMPDynGroupprivateFallbackType
The fallback types for the dyn_groupprivate clause.
WorksharingLoopType
A type of worksharing loop construct.
OMPAtomicCompareOp
Atomic compare operations. Currently OpenMP only supports ==, >, and <.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI BasicBlock * splitBBWithSuffix(IRBuilderBase &Builder, bool CreateBranch, llvm::Twine Suffix=".split")
Like splitBB, but reuses the current block's name for the new name.
@ Offset
Definition DWP.cpp:577
LLVM_ABI BasicBlock * splitBB(IRBuilderBase::InsertPoint IP, bool CreateBranch, DebugLoc DL, llvm::Twine Name={})
Split a BasicBlock at an InsertPoint, even if the block is degenerate (missing the terminator).
auto cast_or_null(const Y &Val)
Definition Casting.h:714
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
AtomicOrdering
Atomic ordering for LLVM's memory model.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
IntPtrTy
Definition InstrProf.h:82
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
LLVM_ABI void spliceBB(IRBuilderBase::InsertPoint IP, BasicBlock *New, bool CreateBranch, DebugLoc DL)
Move the instruction after an InsertPoint to the beginning of another BasicBlock.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:879
Physical handles captured before the source descriptors are invalidated.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
A struct to pack the relevant information for an OpenMP affinity clause.
a struct to pack relevant information while generating atomic Ops
Attribute set of the declare simd parameter.
Describes a declare target global variable replacement to be applied during finalization.
DependData(omp::RTLDependenceKindTy DepKind, Type *DepValueType, Value *DepVal)
omp::RTLDependenceKindTy DepKind
A struct to pack static and dynamic dependency information for a task.
DependenciesInfo(SmallVector< DependData > D)
const omp::Directive DK
The directive kind of the innermost directive that has an associated region which might require final...
const bool IsCancellable
Flag to indicate if the directive is cancellable.
LLVM_ABI Error mergeFiniBB(IRBuilderBase &Builder, BasicBlock *ExistingFiniBB)
For cases where there is an unavoidable existing finalization block (e.g.
FinalizationInfo(FinalizeCallbackTy FiniCB, omp::Directive DK, bool IsCancellable)
LLVM_ABI Expected< BasicBlock * > getFiniBB(IRBuilderBase &Builder)
The basic block to which control should be transferred to implement the FiniCB.
Description of a LLVM-IR insertion point (IP) and a debug/source location (filename,...
LocationDescription(const InsertPointTy &IP, const DebugLoc &DL)
LocationDescription(const IRBuilderBase &IRB)
This structure contains combined information generated for mappable clauses, including base pointers,...
void append(MapInfosTy &CurInfo)
Append arrays in CurInfo.
MapDeviceInfoArrayTy DevicePointers
MapHasAttachPtrArrayTy HasAttachPtr
True for entries that have an attach ptr, and thus an accompanying ATTACH entry linking that ptr to i...
StructNonContiguousInfo NonContigInfo
Helper that contains information about regions we need to outline during finalization.
void collectBlocks(SmallPtrSetImpl< BasicBlock * > &BlockSet, SmallVectorImpl< BasicBlock * > &BlockVector)
Collect all blocks in between EntryBB and ExitBB in both the given vector and set.
Function * getFunction() const
Return the function that contains the region to be outlined.
SmallVector< Value *, 2 > ExcludeArgsFromAggregate
virtual std::unique_ptr< CodeExtractor > createCodeExtractor(ArrayRef< BasicBlock * > Blocks, bool ArgsInZeroAddressSpace, Twine Suffix=Twine(""))
Create a CodeExtractor instance based on the information stored in this structure,...
std::function< void(Function &)> PostOutlineCBTy
SmallVector< BasicBlock * > OuterDeallocBBs
EvalKind EvaluationKind
Reduction evaluation kind - scalar, complex or aggregate.
ReductionInfo(Type *ElementType, Value *Variable, Value *PrivateVariable, EvalKind EvaluationKind, ReductionGenCBTy ReductionGen, ReductionGenClangCBTy ReductionGenClang, ReductionGenAtomicCBTy AtomicReductionGen, ReductionGenDataPtrPtrCBTy DataPtrPtrGen, Type *ByRefAllocatedType=nullptr, Type *ByRefElementType=nullptr)
ReductionGenAtomicCBTy AtomicReductionGen
Callback for generating the atomic reduction body, may be null.
ReductionGenCBTy ReductionGen
Callback for generating the reduction body.
ReductionInfo(Value *PrivateVariable)
Type * ByRefAllocatedType
For by-ref reductions, we need to keep track of 2 extra types that are potentially different:
Value * Variable
Reduction variable of pointer type.
Value * PrivateVariable
Thread-private partial reduction variable.
ReductionGenClangCBTy ReductionGenClang
Clang callback for generating the reduction body.
Type * ElementType
Reduction element type, must match pointee type of variable.
ReductionGenDataPtrPtrCBTy DataPtrPtrGen
Container for the arguments used to pass data to the runtime library.
Value * SizesArray
The array of sizes passed to the runtime library.
TargetDataRTArgs(Value *BasePointersArray, Value *PointersArray, Value *SizesArray, Value *MapTypesArray, Value *MapTypesArrayEnd, Value *MappersArray, Value *MapNamesArray)
Value * PointersArray
The array of section pointers passed to the runtime library.
Value * MappersArray
The array of user-defined mappers passed to the runtime library.
Value * MapTypesArrayEnd
The array of map types passed to the runtime library for the end of the region, or nullptr if there a...
Value * BasePointersArray
The array of base pointer passed to the runtime library.
Value * MapTypesArray
The array of map types passed to the runtime library for the beginning of the region or for the entir...
Value * MapNamesArray
The array of original declaration names of mapped pointers sent to the runtime library for debugging.
Data structure that contains the needed information to construct the kernel args vector.
bool StrictBlocks
True if the kernel strictly requires the number of blocks and threads above to run.
ArrayRef< Value * > NumThreads
The number of threads.
TargetDataRTArgs RTArgs
Arguments passed to the runtime library.
TargetKernelArgs(unsigned NumTargetItems, TargetDataRTArgs RTArgs, Value *NumIterations, ArrayRef< Value * > NumTeams, ArrayRef< Value * > NumThreads, Value *DynCGroupMem, bool HasNoWait, bool StrictBlocks, bool StrictThreads, omp::OMPDynGroupprivateFallbackType DynCGroupMemFallback)
Value * NumIterations
The number of iterations.
Value * DynCGroupMem
The size of the dynamic shared memory.
unsigned NumTargetItems
Number of arguments passed to the runtime library.
bool HasNoWait
True if the kernel has 'no wait' clause.
ArrayRef< Value * > NumTeams
The number of teams.
omp::OMPDynGroupprivateFallbackType DynCGroupMemFallback
The fallback mechanism for the shared memory.
Container to pass the default attributes with which a kernel must be launched, used to set kernel att...
Container to pass LLVM IR runtime values or constants related to the number of teams and threads with...
Value * DeviceID
Device ID value used in the kernel launch.
Value * LoopTripCount
Total number of iterations of the SPMD or Generic-SPMD kernel or null if it is a generic kernel.
SmallVector< Value * > MaxThreads
'parallel' construct 'num_threads' clause value, if present and it is an SPMD kernel.
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:344
Data structure to contain the information needed to uniquely identify a target entry.
static LLVM_ABI void getTargetRegionEntryFnName(SmallVectorImpl< char > &Name, StringRef ParentName, unsigned DeviceID, unsigned FileID, unsigned Line, unsigned Count)
static constexpr const char * KernelNamePrefix
The prefix used for kernel names.
bool operator<(const TargetRegionEntryInfo &RHS) const
TargetRegionEntryInfo(StringRef ParentName, unsigned DeviceID, unsigned FileID, unsigned Line, unsigned Count=0)
Defines various target-specific GPU grid values that must be consistent between host RTL (plugin),...