]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / Frontend / OpenMP / OMPIRBuilder.h
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/IR/DebugLoc.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/Frontend/OpenMP/OMPConstants.h"
20
21 namespace llvm {
22
23 /// An interface to create LLVM-IR for OpenMP directives.
24 ///
25 /// Each OpenMP directive has a corresponding public generator method.
26 class OpenMPIRBuilder {
27 public:
28   /// Create a new OpenMPIRBuilder operating on the given module \p M. This will
29   /// not have an effect on \p M (see initialize).
30   OpenMPIRBuilder(Module &M) : M(M), Builder(M.getContext()) {}
31
32   /// Initialize the internal state, this will put structures types and
33   /// potentially other helpers into the underlying module. Must be called
34   /// before any other method and only once!
35   void initialize();
36
37   /// Add attributes known for \p FnID to \p Fn.
38   void addAttributes(omp::RuntimeFunction FnID, Function &Fn);
39
40   /// Type used throughout for insertion points.
41   using InsertPointTy = IRBuilder<>::InsertPoint;
42
43   /// Callback type for variable finalization (think destructors).
44   ///
45   /// \param CodeGenIP is the insertion point at which the finalization code
46   ///                  should be placed.
47   ///
48   /// A finalize callback knows about all objects that need finalization, e.g.
49   /// destruction, when the scope of the currently generated construct is left
50   /// at the time, and location, the callback is invoked.
51   using FinalizeCallbackTy = std::function<void(InsertPointTy CodeGenIP)>;
52
53   struct FinalizationInfo {
54     /// The finalization callback provided by the last in-flight invocation of
55     /// CreateXXXX for the directive of kind DK.
56     FinalizeCallbackTy FiniCB;
57
58     /// The directive kind of the innermost directive that has an associated
59     /// region which might require finalization when it is left.
60     omp::Directive DK;
61
62     /// Flag to indicate if the directive is cancellable.
63     bool IsCancellable;
64   };
65
66   /// Push a finalization callback on the finalization stack.
67   ///
68   /// NOTE: Temporary solution until Clang CG is gone.
69   void pushFinalizationCB(const FinalizationInfo &FI) {
70     FinalizationStack.push_back(FI);
71   }
72
73   /// Pop the last finalization callback from the finalization stack.
74   ///
75   /// NOTE: Temporary solution until Clang CG is gone.
76   void popFinalizationCB() { FinalizationStack.pop_back(); }
77
78   /// Callback type for body (=inner region) code generation
79   ///
80   /// The callback takes code locations as arguments, each describing a
81   /// location at which code might need to be generated or a location that is
82   /// the target of control transfer.
83   ///
84   /// \param AllocaIP is the insertion point at which new alloca instructions
85   ///                 should be placed.
86   /// \param CodeGenIP is the insertion point at which the body code should be
87   ///                  placed.
88   /// \param ContinuationBB is the basic block target to leave the body.
89   ///
90   /// Note that all blocks pointed to by the arguments have terminators.
91   using BodyGenCallbackTy =
92       function_ref<void(InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
93                         BasicBlock &ContinuationBB)>;
94
95   /// Callback type for variable privatization (think copy & default
96   /// constructor).
97   ///
98   /// \param AllocaIP is the insertion point at which new alloca instructions
99   ///                 should be placed.
100   /// \param CodeGenIP is the insertion point at which the privatization code
101   ///                  should be placed.
102   /// \param Val The value beeing copied/created.
103   /// \param ReplVal The replacement value, thus a copy or new created version
104   ///                of \p Val.
105   ///
106   /// \returns The new insertion point where code generation continues and
107   ///          \p ReplVal the replacement of \p Val.
108   using PrivatizeCallbackTy = function_ref<InsertPointTy(
109       InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &Val,
110       Value *&ReplVal)>;
111
112   /// Description of a LLVM-IR insertion point (IP) and a debug/source location
113   /// (filename, line, column, ...).
114   struct LocationDescription {
115     template <typename T, typename U>
116     LocationDescription(const IRBuilder<T, U> &IRB)
117         : IP(IRB.saveIP()), DL(IRB.getCurrentDebugLocation()) {}
118     LocationDescription(const InsertPointTy &IP) : IP(IP) {}
119     LocationDescription(const InsertPointTy &IP, const DebugLoc &DL)
120         : IP(IP), DL(DL) {}
121     InsertPointTy IP;
122     DebugLoc DL;
123   };
124
125   /// Emitter methods for OpenMP directives.
126   ///
127   ///{
128
129   /// Generator for '#omp barrier'
130   ///
131   /// \param Loc The location where the barrier directive was encountered.
132   /// \param DK The kind of directive that caused the barrier.
133   /// \param ForceSimpleCall Flag to force a simple (=non-cancellation) barrier.
134   /// \param CheckCancelFlag Flag to indicate a cancel barrier return value
135   ///                        should be checked and acted upon.
136   ///
137   /// \returns The insertion point after the barrier.
138   InsertPointTy CreateBarrier(const LocationDescription &Loc, omp::Directive DK,
139                               bool ForceSimpleCall = false,
140                               bool CheckCancelFlag = true);
141
142   /// Generator for '#omp cancel'
143   ///
144   /// \param Loc The location where the directive was encountered.
145   /// \param IfCondition The evaluated 'if' clause expression, if any.
146   /// \param CanceledDirective The kind of directive that is cancled.
147   ///
148   /// \returns The insertion point after the barrier.
149   InsertPointTy CreateCancel(const LocationDescription &Loc,
150                               Value *IfCondition,
151                               omp::Directive CanceledDirective);
152
153   /// Generator for '#omp parallel'
154   ///
155   /// \param Loc The insert and source location description.
156   /// \param BodyGenCB Callback that will generate the region code.
157   /// \param PrivCB Callback to copy a given variable (think copy constructor).
158   /// \param FiniCB Callback to finalize variable copies.
159   /// \param IfCondition The evaluated 'if' clause expression, if any.
160   /// \param NumThreads The evaluated 'num_threads' clause expression, if any.
161   /// \param ProcBind The value of the 'proc_bind' clause (see ProcBindKind).
162   /// \param IsCancellable Flag to indicate a cancellable parallel region.
163   ///
164   /// \returns The insertion position *after* the parallel.
165   IRBuilder<>::InsertPoint
166   CreateParallel(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB,
167                  PrivatizeCallbackTy PrivCB, FinalizeCallbackTy FiniCB,
168                  Value *IfCondition, Value *NumThreads,
169                  omp::ProcBindKind ProcBind, bool IsCancellable);
170
171   ///}
172
173 private:
174   /// Update the internal location to \p Loc.
175   bool updateToLocation(const LocationDescription &Loc) {
176     Builder.restoreIP(Loc.IP);
177     Builder.SetCurrentDebugLocation(Loc.DL);
178     return Loc.IP.getBlock() != nullptr;
179   }
180
181   /// Return the function declaration for the runtime function with \p FnID.
182   Function *getOrCreateRuntimeFunction(omp::RuntimeFunction FnID);
183
184   /// Return the (LLVM-IR) string describing the source location \p LocStr.
185   Constant *getOrCreateSrcLocStr(StringRef LocStr);
186
187   /// Return the (LLVM-IR) string describing the default source location.
188   Constant *getOrCreateDefaultSrcLocStr();
189
190   /// Return the (LLVM-IR) string describing the source location \p Loc.
191   Constant *getOrCreateSrcLocStr(const LocationDescription &Loc);
192
193   /// Return an ident_t* encoding the source location \p SrcLocStr and \p Flags.
194   Value *getOrCreateIdent(Constant *SrcLocStr,
195                           omp::IdentFlag Flags = omp::IdentFlag(0));
196
197   /// Generate control flow and cleanup for cancellation.
198   ///
199   /// \param CancelFlag Flag indicating if the cancellation is performed.
200   /// \param CanceledDirective The kind of directive that is cancled.
201   void emitCancelationCheckImpl(Value *CancelFlag,
202                                 omp::Directive CanceledDirective);
203
204   /// Generate a barrier runtime call.
205   ///
206   /// \param Loc The location at which the request originated and is fulfilled.
207   /// \param DK The directive which caused the barrier
208   /// \param ForceSimpleCall Flag to force a simple (=non-cancellation) barrier.
209   /// \param CheckCancelFlag Flag to indicate a cancel barrier return value
210   ///                        should be checked and acted upon.
211   ///
212   /// \returns The insertion point after the barrier.
213   InsertPointTy emitBarrierImpl(const LocationDescription &Loc,
214                                 omp::Directive DK, bool ForceSimpleCall,
215                                 bool CheckCancelFlag);
216
217   /// The finalization stack made up of finalize callbacks currently in-flight,
218   /// wrapped into FinalizationInfo objects that reference also the finalization
219   /// target block and the kind of cancellable directive.
220   SmallVector<FinalizationInfo, 8> FinalizationStack;
221
222   /// Return true if the last entry in the finalization stack is of kind \p DK
223   /// and cancellable.
224   bool isLastFinalizationInfoCancellable(omp::Directive DK) {
225     return !FinalizationStack.empty() &&
226            FinalizationStack.back().IsCancellable &&
227            FinalizationStack.back().DK == DK;
228   }
229
230   /// Return the current thread ID.
231   ///
232   /// \param Ident The ident (ident_t*) describing the query origin.
233   Value *getOrCreateThreadID(Value *Ident);
234
235   /// The underlying LLVM-IR module
236   Module &M;
237
238   /// The LLVM-IR Builder used to create IR.
239   IRBuilder<> Builder;
240
241   /// Map to remember source location strings
242   StringMap<Constant *> SrcLocStrMap;
243
244   /// Map to remember existing ident_t*.
245   DenseMap<std::pair<Constant *, uint64_t>, GlobalVariable *> IdentMap;
246 };
247
248 } // end namespace llvm
249
250 #endif // LLVM_IR_IRBUILDER_H