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