1 //===- IR/OpenMPIRBuilder.h - OpenMP encoding builder for LLVM IR - C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the OpenMPIRBuilder class and helpers used as a convenient
10 // way to create LLVM instructions for OpenMP directives.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_OPENMP_IR_IRBUILDER_H
15 #define LLVM_OPENMP_IR_IRBUILDER_H
17 #include "llvm/IR/DebugLoc.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/Frontend/OpenMP/OMPConstants.h"
23 /// An interface to create LLVM-IR for OpenMP directives.
25 /// Each OpenMP directive has a corresponding public generator method.
26 class OpenMPIRBuilder {
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()) {}
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!
37 /// Add attributes known for \p FnID to \p Fn.
38 void addAttributes(omp::RuntimeFunction FnID, Function &Fn);
40 /// Type used throughout for insertion points.
41 using InsertPointTy = IRBuilder<>::InsertPoint;
43 /// Callback type for variable finalization (think destructors).
45 /// \param CodeGenIP is the insertion point at which the finalization code
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)>;
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;
58 /// The directive kind of the innermost directive that has an associated
59 /// region which might require finalization when it is left.
62 /// Flag to indicate if the directive is cancellable.
66 /// Push a finalization callback on the finalization stack.
68 /// NOTE: Temporary solution until Clang CG is gone.
69 void pushFinalizationCB(const FinalizationInfo &FI) {
70 FinalizationStack.push_back(FI);
73 /// Pop the last finalization callback from the finalization stack.
75 /// NOTE: Temporary solution until Clang CG is gone.
76 void popFinalizationCB() { FinalizationStack.pop_back(); }
78 /// Callback type for body (=inner region) code generation
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.
84 /// \param AllocaIP is the insertion point at which new alloca instructions
86 /// \param CodeGenIP is the insertion point at which the body code should be
88 /// \param ContinuationBB is the basic block target to leave the body.
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)>;
95 /// Callback type for variable privatization (think copy & default
98 /// \param AllocaIP is the insertion point at which new alloca instructions
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
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,
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)
125 /// Emitter methods for OpenMP directives.
129 /// Generator for '#omp barrier'
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.
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);
142 /// Generator for '#omp cancel'
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.
148 /// \returns The insertion point after the barrier.
149 InsertPointTy CreateCancel(const LocationDescription &Loc,
151 omp::Directive CanceledDirective);
153 /// Generator for '#omp parallel'
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.
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);
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;
181 /// Return the function declaration for the runtime function with \p FnID.
182 Function *getOrCreateRuntimeFunction(omp::RuntimeFunction FnID);
184 /// Return the (LLVM-IR) string describing the source location \p LocStr.
185 Constant *getOrCreateSrcLocStr(StringRef LocStr);
187 /// Return the (LLVM-IR) string describing the default source location.
188 Constant *getOrCreateDefaultSrcLocStr();
190 /// Return the (LLVM-IR) string describing the source location \p Loc.
191 Constant *getOrCreateSrcLocStr(const LocationDescription &Loc);
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));
197 /// Generate control flow and cleanup for cancellation.
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);
204 /// Generate a barrier runtime call.
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.
212 /// \returns The insertion point after the barrier.
213 InsertPointTy emitBarrierImpl(const LocationDescription &Loc,
214 omp::Directive DK, bool ForceSimpleCall,
215 bool CheckCancelFlag);
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;
222 /// Return true if the last entry in the finalization stack is of kind \p DK
224 bool isLastFinalizationInfoCancellable(omp::Directive DK) {
225 return !FinalizationStack.empty() &&
226 FinalizationStack.back().IsCancellable &&
227 FinalizationStack.back().DK == DK;
230 /// Return the current thread ID.
232 /// \param Ident The ident (ident_t*) describing the query origin.
233 Value *getOrCreateThreadID(Value *Ident);
235 /// The underlying LLVM-IR module
238 /// The LLVM-IR Builder used to create IR.
241 /// Map to remember source location strings
242 StringMap<Constant *> SrcLocStrMap;
244 /// Map to remember existing ident_t*.
245 DenseMap<std::pair<Constant *, uint64_t>, GlobalVariable *> IdentMap;
248 } // end namespace llvm
250 #endif // LLVM_IR_IRBUILDER_H