1 //===----- CGOpenMPRuntime.cpp - Interface to OpenMP Runtimes -------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This provides a class for OpenMP runtime code generation.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "CGOpenMPRuntime.h"
15 #include "CodeGenFunction.h"
16 #include "CGCleanup.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/StmtOpenMP.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/IR/CallSite.h"
21 #include "llvm/IR/DerivedTypes.h"
22 #include "llvm/IR/GlobalValue.h"
23 #include "llvm/IR/Value.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include <cassert>
26 
27 using namespace clang;
28 using namespace CodeGen;
29 
30 namespace {
31 /// \brief Base class for handling code generation inside OpenMP regions.
32 class CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
33 public:
34   CGOpenMPRegionInfo(const OMPExecutableDirective &D, const CapturedStmt &CS)
35       : CGCapturedStmtInfo(CS, CR_OpenMP), Directive(D) {}
36 
37   CGOpenMPRegionInfo(const OMPExecutableDirective &D)
38       : CGCapturedStmtInfo(CR_OpenMP), Directive(D) {}
39 
40   /// \brief Get a variable or parameter for storing global thread id
41   /// inside OpenMP construct.
42   virtual const VarDecl *getThreadIDVariable() const = 0;
43 
44   /// \brief Get an LValue for the current ThreadID variable.
45   /// \return LValue for thread id variable. This LValue always has type int32*.
46   virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF);
47 
48     /// \brief Emit the captured statement body.
49   virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) override;
50 
51   static bool classof(const CGCapturedStmtInfo *Info) {
52     return Info->getKind() == CR_OpenMP;
53   }
54 protected:
55   /// \brief OpenMP executable directive associated with the region.
56   const OMPExecutableDirective &Directive;
57 };
58 
59 /// \brief API for captured statement code generation in OpenMP constructs.
60 class CGOpenMPOutlinedRegionInfo : public CGOpenMPRegionInfo {
61 public:
62   CGOpenMPOutlinedRegionInfo(const OMPExecutableDirective &D,
63                              const CapturedStmt &CS, const VarDecl *ThreadIDVar)
64       : CGOpenMPRegionInfo(D, CS), ThreadIDVar(ThreadIDVar) {
65     assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
66   }
67   /// \brief Get a variable or parameter for storing global thread id
68   /// inside OpenMP construct.
69   virtual const VarDecl *getThreadIDVariable() const override {
70     return ThreadIDVar;
71   }
72   /// \brief Get the name of the capture helper.
73   StringRef getHelperName() const override { return ".omp_outlined."; }
74 
75 private:
76   /// \brief A variable or parameter storing global thread id for OpenMP
77   /// constructs.
78   const VarDecl *ThreadIDVar;
79 };
80 
81 /// \brief API for captured statement code generation in OpenMP constructs.
82 class CGOpenMPTaskOutlinedRegionInfo : public CGOpenMPRegionInfo {
83 public:
84   CGOpenMPTaskOutlinedRegionInfo(const OMPExecutableDirective &D,
85                                  const CapturedStmt &CS,
86                                  const VarDecl *ThreadIDVar,
87                                  const VarDecl *PartIDVar)
88       : CGOpenMPRegionInfo(D, CS), ThreadIDVar(ThreadIDVar),
89         PartIDVar(PartIDVar) {
90     assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
91   }
92   /// \brief Get a variable or parameter for storing global thread id
93   /// inside OpenMP construct.
94   virtual const VarDecl *getThreadIDVariable() const override {
95     return ThreadIDVar;
96   }
97 
98   /// \brief Get an LValue for the current ThreadID variable.
99   virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override;
100 
101   /// \brief Emit the captured statement body.
102   virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) override;
103 
104   /// \brief Get the name of the capture helper.
105   StringRef getHelperName() const override { return ".omp_outlined."; }
106 
107 private:
108   /// \brief A variable or parameter storing global thread id for OpenMP
109   /// constructs.
110   const VarDecl *ThreadIDVar;
111   /// \brief A variable or parameter storing part id for OpenMP tasking
112   /// constructs.
113   const VarDecl *PartIDVar;
114 };
115 
116 /// \brief API for inlined captured statement code generation in OpenMP
117 /// constructs.
118 class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
119 public:
120   CGOpenMPInlinedRegionInfo(const OMPExecutableDirective &D,
121                             CodeGenFunction::CGCapturedStmtInfo *OldCSI)
122       : CGOpenMPRegionInfo(D), OldCSI(OldCSI),
123         OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
124   // \brief Retrieve the value of the context parameter.
125   virtual llvm::Value *getContextValue() const override {
126     if (OuterRegionInfo)
127       return OuterRegionInfo->getContextValue();
128     llvm_unreachable("No context value for inlined OpenMP region");
129   }
130   /// \brief Lookup the captured field decl for a variable.
131   virtual const FieldDecl *lookup(const VarDecl *VD) const override {
132     if (OuterRegionInfo)
133       return OuterRegionInfo->lookup(VD);
134     llvm_unreachable("Trying to reference VarDecl that is neither local nor "
135                      "captured in outer OpenMP region");
136   }
137   virtual FieldDecl *getThisFieldDecl() const override {
138     if (OuterRegionInfo)
139       return OuterRegionInfo->getThisFieldDecl();
140     return nullptr;
141   }
142   /// \brief Get a variable or parameter for storing global thread id
143   /// inside OpenMP construct.
144   virtual const VarDecl *getThreadIDVariable() const override {
145     if (OuterRegionInfo)
146       return OuterRegionInfo->getThreadIDVariable();
147     return nullptr;
148   }
149 
150   /// \brief Get the name of the capture helper.
151   virtual StringRef getHelperName() const override {
152     llvm_unreachable("No helper name for inlined OpenMP construct");
153   }
154 
155   CodeGenFunction::CGCapturedStmtInfo *getOldCSI() const { return OldCSI; }
156 
157 private:
158   /// \brief CodeGen info about outer OpenMP region.
159   CodeGenFunction::CGCapturedStmtInfo *OldCSI;
160   CGOpenMPRegionInfo *OuterRegionInfo;
161 };
162 } // namespace
163 
164 LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
165   return CGF.MakeNaturalAlignAddrLValue(
166       CGF.Builder.CreateAlignedLoad(
167           CGF.GetAddrOfLocalVar(getThreadIDVariable()),
168           CGF.PointerAlignInBytes),
169       getThreadIDVariable()
170           ->getType()
171           ->castAs<PointerType>()
172           ->getPointeeType());
173 }
174 
175 void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt *S) {
176   CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
177   CGF.EmitOMPPrivateClause(Directive, PrivateScope);
178   CGF.EmitOMPFirstprivateClause(Directive, PrivateScope);
179   if (PrivateScope.Privatize())
180     // Emit implicit barrier to synchronize threads and avoid data races.
181     CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, Directive.getLocStart(),
182                                                /*IsExplicit=*/false);
183   CGCapturedStmtInfo::EmitBody(CGF, S);
184 }
185 
186 LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
187     CodeGenFunction &CGF) {
188   return CGF.MakeNaturalAlignAddrLValue(
189       CGF.GetAddrOfLocalVar(getThreadIDVariable()),
190       getThreadIDVariable()->getType());
191 }
192 
193 void CGOpenMPTaskOutlinedRegionInfo::EmitBody(CodeGenFunction &CGF,
194                                               const Stmt *S) {
195   if (PartIDVar) {
196     // TODO: emit code for untied tasks.
197   }
198   CGCapturedStmtInfo::EmitBody(CGF, S);
199 }
200 
201 CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
202     : CGM(CGM), DefaultOpenMPPSource(nullptr), KmpRoutineEntryPtrTy(nullptr) {
203   IdentTy = llvm::StructType::create(
204       "ident_t", CGM.Int32Ty /* reserved_1 */, CGM.Int32Ty /* flags */,
205       CGM.Int32Ty /* reserved_2 */, CGM.Int32Ty /* reserved_3 */,
206       CGM.Int8PtrTy /* psource */, nullptr);
207   // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
208   llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
209                                llvm::PointerType::getUnqual(CGM.Int32Ty)};
210   Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
211   KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
212 }
213 
214 llvm::Value *
215 CGOpenMPRuntime::emitOutlinedFunction(const OMPExecutableDirective &D,
216                                       const VarDecl *ThreadIDVar) {
217   assert(ThreadIDVar->getType()->isPointerType() &&
218          "thread id variable must be of type kmp_int32 *");
219   const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt());
220   CodeGenFunction CGF(CGM, true);
221   CGOpenMPOutlinedRegionInfo CGInfo(D, *CS, ThreadIDVar);
222   CGF.CapturedStmtInfo = &CGInfo;
223   return CGF.GenerateCapturedStmtFunction(*CS);
224 }
225 
226 llvm::Value *
227 CGOpenMPRuntime::emitTaskOutlinedFunction(const OMPExecutableDirective &D,
228                                           const VarDecl *ThreadIDVar,
229                                           const VarDecl *PartIDVar) {
230   assert(!ThreadIDVar->getType()->isPointerType() &&
231          "thread id variable must be of type kmp_int32 for tasks");
232   auto *CS = cast<CapturedStmt>(D.getAssociatedStmt());
233   CodeGenFunction CGF(CGM, true);
234   CGOpenMPTaskOutlinedRegionInfo CGInfo(D, *CS, ThreadIDVar, PartIDVar);
235   CGF.CapturedStmtInfo = &CGInfo;
236   return CGF.GenerateCapturedStmtFunction(*CS);
237 }
238 
239 llvm::Value *
240 CGOpenMPRuntime::getOrCreateDefaultLocation(OpenMPLocationFlags Flags) {
241   llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags);
242   if (!Entry) {
243     if (!DefaultOpenMPPSource) {
244       // Initialize default location for psource field of ident_t structure of
245       // all ident_t objects. Format is ";file;function;line;column;;".
246       // Taken from
247       // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp_str.c
248       DefaultOpenMPPSource =
249           CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;");
250       DefaultOpenMPPSource =
251           llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
252     }
253     auto DefaultOpenMPLocation = new llvm::GlobalVariable(
254         CGM.getModule(), IdentTy, /*isConstant*/ true,
255         llvm::GlobalValue::PrivateLinkage, /*Initializer*/ nullptr);
256     DefaultOpenMPLocation->setUnnamedAddr(true);
257 
258     llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true);
259     llvm::Constant *Values[] = {Zero,
260                                 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
261                                 Zero, Zero, DefaultOpenMPPSource};
262     llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values);
263     DefaultOpenMPLocation->setInitializer(Init);
264     OpenMPDefaultLocMap[Flags] = DefaultOpenMPLocation;
265     return DefaultOpenMPLocation;
266   }
267   return Entry;
268 }
269 
270 llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
271                                                  SourceLocation Loc,
272                                                  OpenMPLocationFlags Flags) {
273   // If no debug info is generated - return global default location.
274   if (CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::NoDebugInfo ||
275       Loc.isInvalid())
276     return getOrCreateDefaultLocation(Flags);
277 
278   assert(CGF.CurFn && "No function in current CodeGenFunction.");
279 
280   llvm::Value *LocValue = nullptr;
281   auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
282   if (I != OpenMPLocThreadIDMap.end())
283     LocValue = I->second.DebugLoc;
284   // OpenMPLocThreadIDMap may have null DebugLoc and non-null ThreadID, if
285   // GetOpenMPThreadID was called before this routine.
286   if (LocValue == nullptr) {
287     // Generate "ident_t .kmpc_loc.addr;"
288     llvm::AllocaInst *AI = CGF.CreateTempAlloca(IdentTy, ".kmpc_loc.addr");
289     AI->setAlignment(CGM.getDataLayout().getPrefTypeAlignment(IdentTy));
290     auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
291     Elem.second.DebugLoc = AI;
292     LocValue = AI;
293 
294     CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
295     CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
296     CGF.Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags),
297                              llvm::ConstantExpr::getSizeOf(IdentTy),
298                              CGM.PointerAlignInBytes);
299   }
300 
301   // char **psource = &.kmpc_loc_<flags>.addr.psource;
302   auto *PSource =
303       CGF.Builder.CreateConstInBoundsGEP2_32(LocValue, 0, IdentField_PSource);
304 
305   auto OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
306   if (OMPDebugLoc == nullptr) {
307     SmallString<128> Buffer2;
308     llvm::raw_svector_ostream OS2(Buffer2);
309     // Build debug location
310     PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
311     OS2 << ";" << PLoc.getFilename() << ";";
312     if (const FunctionDecl *FD =
313             dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) {
314       OS2 << FD->getQualifiedNameAsString();
315     }
316     OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
317     OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
318     OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
319   }
320   // *psource = ";<File>;<Function>;<Line>;<Column>;;";
321   CGF.Builder.CreateStore(OMPDebugLoc, PSource);
322 
323   return LocValue;
324 }
325 
326 llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
327                                           SourceLocation Loc) {
328   assert(CGF.CurFn && "No function in current CodeGenFunction.");
329 
330   llvm::Value *ThreadID = nullptr;
331   // Check whether we've already cached a load of the thread id in this
332   // function.
333   auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
334   if (I != OpenMPLocThreadIDMap.end()) {
335     ThreadID = I->second.ThreadID;
336     if (ThreadID != nullptr)
337       return ThreadID;
338   }
339   if (auto OMPRegionInfo =
340           dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
341     if (OMPRegionInfo->getThreadIDVariable()) {
342       // Check if this an outlined function with thread id passed as argument.
343       auto LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
344       ThreadID = CGF.EmitLoadOfLValue(LVal, Loc).getScalarVal();
345       // If value loaded in entry block, cache it and use it everywhere in
346       // function.
347       if (CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) {
348         auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
349         Elem.second.ThreadID = ThreadID;
350       }
351       return ThreadID;
352     }
353   }
354 
355   // This is not an outlined function region - need to call __kmpc_int32
356   // kmpc_global_thread_num(ident_t *loc).
357   // Generate thread id value and cache this value for use across the
358   // function.
359   CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
360   CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
361   ThreadID =
362       CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
363                           emitUpdateLocation(CGF, Loc));
364   auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
365   Elem.second.ThreadID = ThreadID;
366   return ThreadID;
367 }
368 
369 void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) {
370   assert(CGF.CurFn && "No function in current CodeGenFunction.");
371   if (OpenMPLocThreadIDMap.count(CGF.CurFn))
372     OpenMPLocThreadIDMap.erase(CGF.CurFn);
373 }
374 
375 llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
376   return llvm::PointerType::getUnqual(IdentTy);
377 }
378 
379 llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
380   return llvm::PointerType::getUnqual(Kmpc_MicroTy);
381 }
382 
383 llvm::Constant *
384 CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {
385   llvm::Constant *RTLFn = nullptr;
386   switch (Function) {
387   case OMPRTL__kmpc_fork_call: {
388     // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
389     // microtask, ...);
390     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
391                                 getKmpc_MicroPointerTy()};
392     llvm::FunctionType *FnTy =
393         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
394     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
395     break;
396   }
397   case OMPRTL__kmpc_global_thread_num: {
398     // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
399     llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
400     llvm::FunctionType *FnTy =
401         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
402     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
403     break;
404   }
405   case OMPRTL__kmpc_threadprivate_cached: {
406     // Build void *__kmpc_threadprivate_cached(ident_t *loc,
407     // kmp_int32 global_tid, void *data, size_t size, void ***cache);
408     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
409                                 CGM.VoidPtrTy, CGM.SizeTy,
410                                 CGM.VoidPtrTy->getPointerTo()->getPointerTo()};
411     llvm::FunctionType *FnTy =
412         llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg*/ false);
413     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_cached");
414     break;
415   }
416   case OMPRTL__kmpc_critical: {
417     // Build void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
418     // kmp_critical_name *crit);
419     llvm::Type *TypeParams[] = {
420         getIdentTyPointerTy(), CGM.Int32Ty,
421         llvm::PointerType::getUnqual(KmpCriticalNameTy)};
422     llvm::FunctionType *FnTy =
423         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
424     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical");
425     break;
426   }
427   case OMPRTL__kmpc_threadprivate_register: {
428     // Build void __kmpc_threadprivate_register(ident_t *, void *data,
429     // kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
430     // typedef void *(*kmpc_ctor)(void *);
431     auto KmpcCtorTy =
432         llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
433                                 /*isVarArg*/ false)->getPointerTo();
434     // typedef void *(*kmpc_cctor)(void *, void *);
435     llvm::Type *KmpcCopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
436     auto KmpcCopyCtorTy =
437         llvm::FunctionType::get(CGM.VoidPtrTy, KmpcCopyCtorTyArgs,
438                                 /*isVarArg*/ false)->getPointerTo();
439     // typedef void (*kmpc_dtor)(void *);
440     auto KmpcDtorTy =
441         llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy, /*isVarArg*/ false)
442             ->getPointerTo();
443     llvm::Type *FnTyArgs[] = {getIdentTyPointerTy(), CGM.VoidPtrTy, KmpcCtorTy,
444                               KmpcCopyCtorTy, KmpcDtorTy};
445     auto FnTy = llvm::FunctionType::get(CGM.VoidTy, FnTyArgs,
446                                         /*isVarArg*/ false);
447     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_register");
448     break;
449   }
450   case OMPRTL__kmpc_end_critical: {
451     // Build void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
452     // kmp_critical_name *crit);
453     llvm::Type *TypeParams[] = {
454         getIdentTyPointerTy(), CGM.Int32Ty,
455         llvm::PointerType::getUnqual(KmpCriticalNameTy)};
456     llvm::FunctionType *FnTy =
457         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
458     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical");
459     break;
460   }
461   case OMPRTL__kmpc_cancel_barrier: {
462     // Build kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
463     // global_tid);
464     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
465     llvm::FunctionType *FnTy =
466         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
467     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier");
468     break;
469   }
470   // Build __kmpc_for_static_init*(
471   //               ident_t *loc, kmp_int32 tid, kmp_int32 schedtype,
472   //               kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower,
473   //               kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride,
474   //               kmp_int[32|64] incr, kmp_int[32|64] chunk);
475   case OMPRTL__kmpc_for_static_init_4: {
476     auto ITy = CGM.Int32Ty;
477     auto PtrTy = llvm::PointerType::getUnqual(ITy);
478     llvm::Type *TypeParams[] = {
479         getIdentTyPointerTy(),                     // loc
480         CGM.Int32Ty,                               // tid
481         CGM.Int32Ty,                               // schedtype
482         llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
483         PtrTy,                                     // p_lower
484         PtrTy,                                     // p_upper
485         PtrTy,                                     // p_stride
486         ITy,                                       // incr
487         ITy                                        // chunk
488     };
489     llvm::FunctionType *FnTy =
490         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
491     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_init_4");
492     break;
493   }
494   case OMPRTL__kmpc_for_static_init_4u: {
495     auto ITy = CGM.Int32Ty;
496     auto PtrTy = llvm::PointerType::getUnqual(ITy);
497     llvm::Type *TypeParams[] = {
498         getIdentTyPointerTy(),                     // loc
499         CGM.Int32Ty,                               // tid
500         CGM.Int32Ty,                               // schedtype
501         llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
502         PtrTy,                                     // p_lower
503         PtrTy,                                     // p_upper
504         PtrTy,                                     // p_stride
505         ITy,                                       // incr
506         ITy                                        // chunk
507     };
508     llvm::FunctionType *FnTy =
509         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
510     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_init_4u");
511     break;
512   }
513   case OMPRTL__kmpc_for_static_init_8: {
514     auto ITy = CGM.Int64Ty;
515     auto PtrTy = llvm::PointerType::getUnqual(ITy);
516     llvm::Type *TypeParams[] = {
517         getIdentTyPointerTy(),                     // loc
518         CGM.Int32Ty,                               // tid
519         CGM.Int32Ty,                               // schedtype
520         llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
521         PtrTy,                                     // p_lower
522         PtrTy,                                     // p_upper
523         PtrTy,                                     // p_stride
524         ITy,                                       // incr
525         ITy                                        // chunk
526     };
527     llvm::FunctionType *FnTy =
528         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
529     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_init_8");
530     break;
531   }
532   case OMPRTL__kmpc_for_static_init_8u: {
533     auto ITy = CGM.Int64Ty;
534     auto PtrTy = llvm::PointerType::getUnqual(ITy);
535     llvm::Type *TypeParams[] = {
536         getIdentTyPointerTy(),                     // loc
537         CGM.Int32Ty,                               // tid
538         CGM.Int32Ty,                               // schedtype
539         llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
540         PtrTy,                                     // p_lower
541         PtrTy,                                     // p_upper
542         PtrTy,                                     // p_stride
543         ITy,                                       // incr
544         ITy                                        // chunk
545     };
546     llvm::FunctionType *FnTy =
547         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
548     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_init_8u");
549     break;
550   }
551   case OMPRTL__kmpc_for_static_fini: {
552     // Build void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
553     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
554     llvm::FunctionType *FnTy =
555         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
556     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_fini");
557     break;
558   }
559   case OMPRTL__kmpc_push_num_threads: {
560     // Build void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
561     // kmp_int32 num_threads)
562     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
563                                 CGM.Int32Ty};
564     llvm::FunctionType *FnTy =
565         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
566     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_threads");
567     break;
568   }
569   case OMPRTL__kmpc_serialized_parallel: {
570     // Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
571     // global_tid);
572     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
573     llvm::FunctionType *FnTy =
574         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
575     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel");
576     break;
577   }
578   case OMPRTL__kmpc_end_serialized_parallel: {
579     // Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
580     // global_tid);
581     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
582     llvm::FunctionType *FnTy =
583         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
584     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel");
585     break;
586   }
587   case OMPRTL__kmpc_flush: {
588     // Build void __kmpc_flush(ident_t *loc);
589     llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
590     llvm::FunctionType *FnTy =
591         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
592     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_flush");
593     break;
594   }
595   case OMPRTL__kmpc_master: {
596     // Build kmp_int32 __kmpc_master(ident_t *loc, kmp_int32 global_tid);
597     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
598     llvm::FunctionType *FnTy =
599         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
600     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_master");
601     break;
602   }
603   case OMPRTL__kmpc_end_master: {
604     // Build void __kmpc_end_master(ident_t *loc, kmp_int32 global_tid);
605     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
606     llvm::FunctionType *FnTy =
607         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
608     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_master");
609     break;
610   }
611   case OMPRTL__kmpc_omp_taskyield: {
612     // Build kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
613     // int end_part);
614     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
615     llvm::FunctionType *FnTy =
616         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
617     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_taskyield");
618     break;
619   }
620   case OMPRTL__kmpc_single: {
621     // Build kmp_int32 __kmpc_single(ident_t *loc, kmp_int32 global_tid);
622     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
623     llvm::FunctionType *FnTy =
624         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
625     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_single");
626     break;
627   }
628   case OMPRTL__kmpc_end_single: {
629     // Build void __kmpc_end_single(ident_t *loc, kmp_int32 global_tid);
630     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
631     llvm::FunctionType *FnTy =
632         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
633     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_single");
634     break;
635   }
636   case OMPRTL__kmpc_omp_task_alloc: {
637     // Build kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
638     // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
639     // kmp_routine_entry_t *task_entry);
640     assert(KmpRoutineEntryPtrTy != nullptr &&
641            "Type kmp_routine_entry_t must be created.");
642     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
643                                 CGM.SizeTy, CGM.SizeTy, KmpRoutineEntryPtrTy};
644     // Return void * and then cast to particular kmp_task_t type.
645     llvm::FunctionType *FnTy =
646         llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
647     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_alloc");
648     break;
649   }
650   case OMPRTL__kmpc_omp_task: {
651     // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
652     // *new_task);
653     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
654                                 CGM.VoidPtrTy};
655     llvm::FunctionType *FnTy =
656         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
657     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task");
658     break;
659   }
660   }
661   return RTLFn;
662 }
663 
664 llvm::Constant *
665 CGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
666   // Lookup the entry, lazily creating it if necessary.
667   return getOrCreateInternalVariable(CGM.Int8PtrPtrTy,
668                                      Twine(CGM.getMangledName(VD)) + ".cache.");
669 }
670 
671 llvm::Value *CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
672                                                      const VarDecl *VD,
673                                                      llvm::Value *VDAddr,
674                                                      SourceLocation Loc) {
675   auto VarTy = VDAddr->getType()->getPointerElementType();
676   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
677                          CGF.Builder.CreatePointerCast(VDAddr, CGM.Int8PtrTy),
678                          CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)),
679                          getOrCreateThreadPrivateCache(VD)};
680   return CGF.EmitRuntimeCall(
681       createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args);
682 }
683 
684 void CGOpenMPRuntime::emitThreadPrivateVarInit(
685     CodeGenFunction &CGF, llvm::Value *VDAddr, llvm::Value *Ctor,
686     llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc) {
687   // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime
688   // library.
689   auto OMPLoc = emitUpdateLocation(CGF, Loc);
690   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
691                       OMPLoc);
692   // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor)
693   // to register constructor/destructor for variable.
694   llvm::Value *Args[] = {OMPLoc,
695                          CGF.Builder.CreatePointerCast(VDAddr, CGM.VoidPtrTy),
696                          Ctor, CopyCtor, Dtor};
697   CGF.EmitRuntimeCall(
698       createRuntimeFunction(OMPRTL__kmpc_threadprivate_register), Args);
699 }
700 
701 llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
702     const VarDecl *VD, llvm::Value *VDAddr, SourceLocation Loc,
703     bool PerformInit, CodeGenFunction *CGF) {
704   VD = VD->getDefinition(CGM.getContext());
705   if (VD && ThreadPrivateWithDefinition.count(VD) == 0) {
706     ThreadPrivateWithDefinition.insert(VD);
707     QualType ASTTy = VD->getType();
708 
709     llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr;
710     auto Init = VD->getAnyInitializer();
711     if (CGM.getLangOpts().CPlusPlus && PerformInit) {
712       // Generate function that re-emits the declaration's initializer into the
713       // threadprivate copy of the variable VD
714       CodeGenFunction CtorCGF(CGM);
715       FunctionArgList Args;
716       ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, SourceLocation(),
717                             /*Id=*/nullptr, CGM.getContext().VoidPtrTy);
718       Args.push_back(&Dst);
719 
720       auto &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
721           CGM.getContext().VoidPtrTy, Args, FunctionType::ExtInfo(),
722           /*isVariadic=*/false);
723       auto FTy = CGM.getTypes().GetFunctionType(FI);
724       auto Fn = CGM.CreateGlobalInitOrDestructFunction(
725           FTy, ".__kmpc_global_ctor_.", Loc);
726       CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI,
727                             Args, SourceLocation());
728       auto ArgVal = CtorCGF.EmitLoadOfScalar(
729           CtorCGF.GetAddrOfLocalVar(&Dst),
730           /*Volatile=*/false, CGM.PointerAlignInBytes,
731           CGM.getContext().VoidPtrTy, Dst.getLocation());
732       auto Arg = CtorCGF.Builder.CreatePointerCast(
733           ArgVal,
734           CtorCGF.ConvertTypeForMem(CGM.getContext().getPointerType(ASTTy)));
735       CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
736                                /*IsInitializer=*/true);
737       ArgVal = CtorCGF.EmitLoadOfScalar(
738           CtorCGF.GetAddrOfLocalVar(&Dst),
739           /*Volatile=*/false, CGM.PointerAlignInBytes,
740           CGM.getContext().VoidPtrTy, Dst.getLocation());
741       CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue);
742       CtorCGF.FinishFunction();
743       Ctor = Fn;
744     }
745     if (VD->getType().isDestructedType() != QualType::DK_none) {
746       // Generate function that emits destructor call for the threadprivate copy
747       // of the variable VD
748       CodeGenFunction DtorCGF(CGM);
749       FunctionArgList Args;
750       ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, SourceLocation(),
751                             /*Id=*/nullptr, CGM.getContext().VoidPtrTy);
752       Args.push_back(&Dst);
753 
754       auto &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
755           CGM.getContext().VoidTy, Args, FunctionType::ExtInfo(),
756           /*isVariadic=*/false);
757       auto FTy = CGM.getTypes().GetFunctionType(FI);
758       auto Fn = CGM.CreateGlobalInitOrDestructFunction(
759           FTy, ".__kmpc_global_dtor_.", Loc);
760       DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, Args,
761                             SourceLocation());
762       auto ArgVal = DtorCGF.EmitLoadOfScalar(
763           DtorCGF.GetAddrOfLocalVar(&Dst),
764           /*Volatile=*/false, CGM.PointerAlignInBytes,
765           CGM.getContext().VoidPtrTy, Dst.getLocation());
766       DtorCGF.emitDestroy(ArgVal, ASTTy,
767                           DtorCGF.getDestroyer(ASTTy.isDestructedType()),
768                           DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
769       DtorCGF.FinishFunction();
770       Dtor = Fn;
771     }
772     // Do not emit init function if it is not required.
773     if (!Ctor && !Dtor)
774       return nullptr;
775 
776     llvm::Type *CopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
777     auto CopyCtorTy =
778         llvm::FunctionType::get(CGM.VoidPtrTy, CopyCtorTyArgs,
779                                 /*isVarArg=*/false)->getPointerTo();
780     // Copying constructor for the threadprivate variable.
781     // Must be NULL - reserved by runtime, but currently it requires that this
782     // parameter is always NULL. Otherwise it fires assertion.
783     CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
784     if (Ctor == nullptr) {
785       auto CtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
786                                             /*isVarArg=*/false)->getPointerTo();
787       Ctor = llvm::Constant::getNullValue(CtorTy);
788     }
789     if (Dtor == nullptr) {
790       auto DtorTy = llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy,
791                                             /*isVarArg=*/false)->getPointerTo();
792       Dtor = llvm::Constant::getNullValue(DtorTy);
793     }
794     if (!CGF) {
795       auto InitFunctionTy =
796           llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false);
797       auto InitFunction = CGM.CreateGlobalInitOrDestructFunction(
798           InitFunctionTy, ".__omp_threadprivate_init_.");
799       CodeGenFunction InitCGF(CGM);
800       FunctionArgList ArgList;
801       InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, InitFunction,
802                             CGM.getTypes().arrangeNullaryFunction(), ArgList,
803                             Loc);
804       emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
805       InitCGF.FinishFunction();
806       return InitFunction;
807     }
808     emitThreadPrivateVarInit(*CGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
809   }
810   return nullptr;
811 }
812 
813 void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
814                                        llvm::Value *OutlinedFn,
815                                        llvm::Value *CapturedStruct) {
816   // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
817   llvm::Value *Args[] = {
818       emitUpdateLocation(CGF, Loc),
819       CGF.Builder.getInt32(1), // Number of arguments after 'microtask' argument
820       // (there is only one additional argument - 'context')
821       CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy()),
822       CGF.EmitCastToVoidPtr(CapturedStruct)};
823   auto RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_call);
824   CGF.EmitRuntimeCall(RTLFn, Args);
825 }
826 
827 void CGOpenMPRuntime::emitSerialCall(CodeGenFunction &CGF, SourceLocation Loc,
828                                      llvm::Value *OutlinedFn,
829                                      llvm::Value *CapturedStruct) {
830   auto ThreadID = getThreadID(CGF, Loc);
831   // Build calls:
832   // __kmpc_serialized_parallel(&Loc, GTid);
833   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), ThreadID};
834   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_serialized_parallel),
835                       Args);
836 
837   // OutlinedFn(&GTid, &zero, CapturedStruct);
838   auto ThreadIDAddr = emitThreadIDAddress(CGF, Loc);
839   auto Int32Ty =
840       CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true);
841   auto ZeroAddr = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".zero.addr");
842   CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C*/ 0));
843   llvm::Value *OutlinedFnArgs[] = {ThreadIDAddr, ZeroAddr, CapturedStruct};
844   CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
845 
846   // __kmpc_end_serialized_parallel(&Loc, GTid);
847   llvm::Value *EndArgs[] = {emitUpdateLocation(CGF, Loc), ThreadID};
848   CGF.EmitRuntimeCall(
849       createRuntimeFunction(OMPRTL__kmpc_end_serialized_parallel), EndArgs);
850 }
851 
852 // If we're inside an (outlined) parallel region, use the region info's
853 // thread-ID variable (it is passed in a first argument of the outlined function
854 // as "kmp_int32 *gtid"). Otherwise, if we're not inside parallel region, but in
855 // regular serial code region, get thread ID by calling kmp_int32
856 // kmpc_global_thread_num(ident_t *loc), stash this thread ID in a temporary and
857 // return the address of that temp.
858 llvm::Value *CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
859                                                   SourceLocation Loc) {
860   if (auto OMPRegionInfo =
861           dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
862     if (OMPRegionInfo->getThreadIDVariable())
863       return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
864 
865   auto ThreadID = getThreadID(CGF, Loc);
866   auto Int32Ty =
867       CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true);
868   auto ThreadIDTemp = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".threadid_temp.");
869   CGF.EmitStoreOfScalar(ThreadID,
870                         CGF.MakeNaturalAlignAddrLValue(ThreadIDTemp, Int32Ty));
871 
872   return ThreadIDTemp;
873 }
874 
875 llvm::Constant *
876 CGOpenMPRuntime::getOrCreateInternalVariable(llvm::Type *Ty,
877                                              const llvm::Twine &Name) {
878   SmallString<256> Buffer;
879   llvm::raw_svector_ostream Out(Buffer);
880   Out << Name;
881   auto RuntimeName = Out.str();
882   auto &Elem = *InternalVars.insert(std::make_pair(RuntimeName, nullptr)).first;
883   if (Elem.second) {
884     assert(Elem.second->getType()->getPointerElementType() == Ty &&
885            "OMP internal variable has different type than requested");
886     return &*Elem.second;
887   }
888 
889   return Elem.second = new llvm::GlobalVariable(
890              CGM.getModule(), Ty, /*IsConstant*/ false,
891              llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
892              Elem.first());
893 }
894 
895 llvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
896   llvm::Twine Name(".gomp_critical_user_", CriticalName);
897   return getOrCreateInternalVariable(KmpCriticalNameTy, Name.concat(".var"));
898 }
899 
900 void CGOpenMPRuntime::emitCriticalRegion(
901     CodeGenFunction &CGF, StringRef CriticalName,
902     const std::function<void()> &CriticalOpGen, SourceLocation Loc) {
903   auto RegionLock = getCriticalRegionLock(CriticalName);
904   // __kmpc_critical(ident_t *, gtid, Lock);
905   // CriticalOpGen();
906   // __kmpc_end_critical(ident_t *, gtid, Lock);
907   // Prepare arguments and build a call to __kmpc_critical
908   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
909                          RegionLock};
910   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_critical), Args);
911   CriticalOpGen();
912   // Build a call to __kmpc_end_critical
913   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_end_critical), Args);
914 }
915 
916 static void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond,
917                        const std::function<void()> &BodyOpGen) {
918   llvm::Value *CallBool = CGF.EmitScalarConversion(
919       IfCond,
920       CGF.getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true),
921       CGF.getContext().BoolTy);
922 
923   auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
924   auto *ContBlock = CGF.createBasicBlock("omp_if.end");
925   // Generate the branch (If-stmt)
926   CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
927   CGF.EmitBlock(ThenBlock);
928   BodyOpGen();
929   // Emit the rest of bblocks/branches
930   CGF.EmitBranch(ContBlock);
931   CGF.EmitBlock(ContBlock, true);
932 }
933 
934 void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF,
935                                        const std::function<void()> &MasterOpGen,
936                                        SourceLocation Loc) {
937   // if(__kmpc_master(ident_t *, gtid)) {
938   //   MasterOpGen();
939   //   __kmpc_end_master(ident_t *, gtid);
940   // }
941   // Prepare arguments and build a call to __kmpc_master
942   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
943   auto *IsMaster =
944       CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_master), Args);
945   emitIfStmt(CGF, IsMaster, [&]() -> void {
946     MasterOpGen();
947     // Build a call to __kmpc_end_master.
948     // OpenMP [1.2.2 OpenMP Language Terminology]
949     // For C/C++, an executable statement, possibly compound, with a single
950     // entry at the top and a single exit at the bottom, or an OpenMP construct.
951     // * Access to the structured block must not be the result of a branch.
952     // * The point of exit cannot be a branch out of the structured block.
953     // * The point of entry must not be a call to setjmp().
954     // * longjmp() and throw() must not violate the entry/exit criteria.
955     // * An expression statement, iteration statement, selection statement, or
956     // try block is considered to be a structured block if the corresponding
957     // compound statement obtained by enclosing it in { and } would be a
958     // structured block.
959     // It is analyzed in Sema, so we can just call __kmpc_end_master() on
960     // fallthrough rather than pushing a normal cleanup for it.
961     CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_end_master), Args);
962   });
963 }
964 
965 void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
966                                         SourceLocation Loc) {
967   // Build call __kmpc_omp_taskyield(loc, thread_id, 0);
968   llvm::Value *Args[] = {
969       emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
970       llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)};
971   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), Args);
972 }
973 
974 void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
975                                        const std::function<void()> &SingleOpGen,
976                                        SourceLocation Loc) {
977   // if(__kmpc_single(ident_t *, gtid)) {
978   //   SingleOpGen();
979   //   __kmpc_end_single(ident_t *, gtid);
980   // }
981   // Prepare arguments and build a call to __kmpc_single
982   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
983   auto *IsSingle =
984       CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_single), Args);
985   emitIfStmt(CGF, IsSingle, [&]() -> void {
986     SingleOpGen();
987     // Build a call to __kmpc_end_single.
988     // OpenMP [1.2.2 OpenMP Language Terminology]
989     // For C/C++, an executable statement, possibly compound, with a single
990     // entry at the top and a single exit at the bottom, or an OpenMP construct.
991     // * Access to the structured block must not be the result of a branch.
992     // * The point of exit cannot be a branch out of the structured block.
993     // * The point of entry must not be a call to setjmp().
994     // * longjmp() and throw() must not violate the entry/exit criteria.
995     // * An expression statement, iteration statement, selection statement, or
996     // try block is considered to be a structured block if the corresponding
997     // compound statement obtained by enclosing it in { and } would be a
998     // structured block.
999     // It is analyzed in Sema, so we can just call __kmpc_end_single() on
1000     // fallthrough rather than pushing a normal cleanup for it.
1001     CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_end_single), Args);
1002   });
1003 }
1004 
1005 void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
1006                                       bool IsExplicit) {
1007   // Build call __kmpc_cancel_barrier(loc, thread_id);
1008   auto Flags = static_cast<OpenMPLocationFlags>(
1009       OMP_IDENT_KMPC |
1010       (IsExplicit ? OMP_IDENT_BARRIER_EXPL : OMP_IDENT_BARRIER_IMPL));
1011   // Build call __kmpc_cancel_barrier(loc, thread_id);
1012   // Replace __kmpc_barrier() function by __kmpc_cancel_barrier() because this
1013   // one provides the same functionality and adds initial support for
1014   // cancellation constructs introduced in OpenMP 4.0. __kmpc_cancel_barrier()
1015   // is provided default by the runtime library so it safe to make such
1016   // replacement.
1017   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
1018                          getThreadID(CGF, Loc)};
1019   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
1020 }
1021 
1022 /// \brief Schedule types for 'omp for' loops (these enumerators are taken from
1023 /// the enum sched_type in kmp.h).
1024 enum OpenMPSchedType {
1025   /// \brief Lower bound for default (unordered) versions.
1026   OMP_sch_lower = 32,
1027   OMP_sch_static_chunked = 33,
1028   OMP_sch_static = 34,
1029   OMP_sch_dynamic_chunked = 35,
1030   OMP_sch_guided_chunked = 36,
1031   OMP_sch_runtime = 37,
1032   OMP_sch_auto = 38,
1033   /// \brief Lower bound for 'ordered' versions.
1034   OMP_ord_lower = 64,
1035   /// \brief Lower bound for 'nomerge' versions.
1036   OMP_nm_lower = 160,
1037 };
1038 
1039 /// \brief Map the OpenMP loop schedule to the runtime enumeration.
1040 static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
1041                                           bool Chunked) {
1042   switch (ScheduleKind) {
1043   case OMPC_SCHEDULE_static:
1044     return Chunked ? OMP_sch_static_chunked : OMP_sch_static;
1045   case OMPC_SCHEDULE_dynamic:
1046     return OMP_sch_dynamic_chunked;
1047   case OMPC_SCHEDULE_guided:
1048     return OMP_sch_guided_chunked;
1049   case OMPC_SCHEDULE_auto:
1050     return OMP_sch_auto;
1051   case OMPC_SCHEDULE_runtime:
1052     return OMP_sch_runtime;
1053   case OMPC_SCHEDULE_unknown:
1054     assert(!Chunked && "chunk was specified but schedule kind not known");
1055     return OMP_sch_static;
1056   }
1057   llvm_unreachable("Unexpected runtime schedule");
1058 }
1059 
1060 bool CGOpenMPRuntime::isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
1061                                          bool Chunked) const {
1062   auto Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
1063   return Schedule == OMP_sch_static;
1064 }
1065 
1066 bool CGOpenMPRuntime::isDynamic(OpenMPScheduleClauseKind ScheduleKind) const {
1067   auto Schedule = getRuntimeSchedule(ScheduleKind, /* Chunked */ false);
1068   assert(Schedule != OMP_sch_static_chunked && "cannot be chunked here");
1069   return Schedule != OMP_sch_static;
1070 }
1071 
1072 void CGOpenMPRuntime::emitForInit(CodeGenFunction &CGF, SourceLocation Loc,
1073                                   OpenMPScheduleClauseKind ScheduleKind,
1074                                   unsigned IVSize, bool IVSigned,
1075                                   llvm::Value *IL, llvm::Value *LB,
1076                                   llvm::Value *UB, llvm::Value *ST,
1077                                   llvm::Value *Chunk) {
1078   OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunk != nullptr);
1079   // Call __kmpc_for_static_init(
1080   //          ident_t *loc, kmp_int32 tid, kmp_int32 schedtype,
1081   //          kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower,
1082   //          kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride,
1083   //          kmp_int[32|64] incr, kmp_int[32|64] chunk);
1084   // TODO: Implement dynamic schedule.
1085 
1086   // If the Chunk was not specified in the clause - use default value 1.
1087   if (Chunk == nullptr)
1088     Chunk = CGF.Builder.getIntN(IVSize, /*C*/ 1);
1089 
1090   llvm::Value *Args[] = {
1091       emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC), getThreadID(CGF, Loc),
1092       CGF.Builder.getInt32(Schedule), // Schedule type
1093       IL,                             // &isLastIter
1094       LB,                             // &LB
1095       UB,                             // &UB
1096       ST,                             // &Stride
1097       CGF.Builder.getIntN(IVSize, 1), // Incr
1098       Chunk                           // Chunk
1099   };
1100   assert((IVSize == 32 || IVSize == 64) &&
1101          "Index size is not compatible with the omp runtime");
1102   auto F = IVSize == 32 ? (IVSigned ? OMPRTL__kmpc_for_static_init_4
1103                                     : OMPRTL__kmpc_for_static_init_4u)
1104                         : (IVSigned ? OMPRTL__kmpc_for_static_init_8
1105                                     : OMPRTL__kmpc_for_static_init_8u);
1106   CGF.EmitRuntimeCall(createRuntimeFunction(F), Args);
1107 }
1108 
1109 void CGOpenMPRuntime::emitForFinish(CodeGenFunction &CGF, SourceLocation Loc,
1110                                     OpenMPScheduleClauseKind ScheduleKind) {
1111   assert((ScheduleKind == OMPC_SCHEDULE_static ||
1112           ScheduleKind == OMPC_SCHEDULE_unknown) &&
1113          "Non-static schedule kinds are not yet implemented");
1114   // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid);
1115   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC),
1116                          getThreadID(CGF, Loc)};
1117   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini),
1118                       Args);
1119 }
1120 
1121 void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
1122                                            llvm::Value *NumThreads,
1123                                            SourceLocation Loc) {
1124   // Build call __kmpc_push_num_threads(&loc, global_tid, num_threads)
1125   llvm::Value *Args[] = {
1126       emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
1127       CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)};
1128   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_threads),
1129                       Args);
1130 }
1131 
1132 void CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>,
1133                                 SourceLocation Loc) {
1134   // Build call void __kmpc_flush(ident_t *loc)
1135   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_flush),
1136                       emitUpdateLocation(CGF, Loc));
1137 }
1138 
1139 namespace {
1140 /// \brief Indexes of fields for type kmp_task_t.
1141 enum KmpTaskTFields {
1142   /// \brief List of shared variables.
1143   KmpTaskTShareds,
1144   /// \brief Task routine.
1145   KmpTaskTRoutine,
1146   /// \brief Partition id for the untied tasks.
1147   KmpTaskTPartId,
1148   /// \brief Function with call of destructors for private variables.
1149   KmpTaskTDestructors,
1150 };
1151 } // namespace
1152 
1153 void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) {
1154   if (!KmpRoutineEntryPtrTy) {
1155     // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type.
1156     auto &C = CGM.getContext();
1157     QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
1158     FunctionProtoType::ExtProtoInfo EPI;
1159     KmpRoutineEntryPtrQTy = C.getPointerType(
1160         C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
1161     KmpRoutineEntryPtrTy = CGM.getTypes().ConvertType(KmpRoutineEntryPtrQTy);
1162   }
1163 }
1164 
1165 static void addFieldToRecordDecl(ASTContext &C, DeclContext *DC,
1166                                  QualType FieldTy) {
1167   auto *Field = FieldDecl::Create(
1168       C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy,
1169       C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()),
1170       /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
1171   Field->setAccess(AS_public);
1172   DC->addDecl(Field);
1173 }
1174 
1175 static QualType createKmpTaskTRecordDecl(CodeGenModule &CGM,
1176                                          QualType KmpInt32Ty,
1177                                          QualType KmpRoutineEntryPointerQTy) {
1178   auto &C = CGM.getContext();
1179   // Build struct kmp_task_t {
1180   //         void *              shareds;
1181   //         kmp_routine_entry_t routine;
1182   //         kmp_int32           part_id;
1183   //         kmp_routine_entry_t destructors;
1184   //         /*  private vars  */
1185   //       };
1186   auto *RD = C.buildImplicitRecord("kmp_task_t");
1187   RD->startDefinition();
1188   addFieldToRecordDecl(C, RD, C.VoidPtrTy);
1189   addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
1190   addFieldToRecordDecl(C, RD, KmpInt32Ty);
1191   addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
1192   // TODO: add private fields.
1193   RD->completeDefinition();
1194   return C.getRecordType(RD);
1195 }
1196 
1197 /// \brief Emit a proxy function which accepts kmp_task_t as the second
1198 /// argument.
1199 /// \code
1200 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
1201 ///   TaskFunction(gtid, tt->part_id, tt->shareds);
1202 ///   return 0;
1203 /// }
1204 /// \endcode
1205 static llvm::Value *
1206 emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
1207                       QualType KmpInt32Ty, QualType KmpTaskTPtrQTy,
1208                       QualType SharedsPtrTy, llvm::Value *TaskFunction) {
1209   auto &C = CGM.getContext();
1210   FunctionArgList Args;
1211   ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty);
1212   ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc,
1213                                 /*Id=*/nullptr, KmpTaskTPtrQTy);
1214   Args.push_back(&GtidArg);
1215   Args.push_back(&TaskTypeArg);
1216   FunctionType::ExtInfo Info;
1217   auto &TaskEntryFnInfo =
1218       CGM.getTypes().arrangeFreeFunctionDeclaration(KmpInt32Ty, Args, Info,
1219                                                     /*isVariadic=*/false);
1220   auto *TaskEntryTy = CGM.getTypes().GetFunctionType(TaskEntryFnInfo);
1221   auto *TaskEntry =
1222       llvm::Function::Create(TaskEntryTy, llvm::GlobalValue::InternalLinkage,
1223                              ".omp_task_entry.", &CGM.getModule());
1224   CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, TaskEntryFnInfo, TaskEntry);
1225   CodeGenFunction CGF(CGM);
1226   CGF.disableDebugInfo();
1227   CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args);
1228 
1229   // TaskFunction(gtid, tt->part_id, tt->shareds);
1230   auto *GtidParam = CGF.EmitLoadOfScalar(
1231       CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false,
1232       C.getTypeAlignInChars(KmpInt32Ty).getQuantity(), KmpInt32Ty, Loc);
1233   auto TaskTypeArgAddr = CGF.EmitLoadOfScalar(
1234       CGF.GetAddrOfLocalVar(&TaskTypeArg), /*Volatile=*/false,
1235       CGM.PointerAlignInBytes, KmpTaskTPtrQTy, Loc);
1236   auto *PartidPtr = CGF.Builder.CreateStructGEP(TaskTypeArgAddr,
1237                                                 /*Idx=*/KmpTaskTPartId);
1238   auto *PartidParam = CGF.EmitLoadOfScalar(
1239       PartidPtr, /*Volatile=*/false,
1240       C.getTypeAlignInChars(KmpInt32Ty).getQuantity(), KmpInt32Ty, Loc);
1241   auto *SharedsPtr = CGF.Builder.CreateStructGEP(TaskTypeArgAddr,
1242                                                  /*Idx=*/KmpTaskTShareds);
1243   auto *SharedsParam =
1244       CGF.EmitLoadOfScalar(SharedsPtr, /*Volatile=*/false,
1245                            CGM.PointerAlignInBytes, C.VoidPtrTy, Loc);
1246   llvm::Value *CallArgs[] = {
1247       GtidParam, PartidParam,
1248       CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1249           SharedsParam, CGF.ConvertTypeForMem(SharedsPtrTy))};
1250   CGF.EmitCallOrInvoke(TaskFunction, CallArgs);
1251   CGF.EmitStoreThroughLValue(
1252       RValue::get(CGF.Builder.getInt32(/*C=*/0)),
1253       CGF.MakeNaturalAlignAddrLValue(CGF.ReturnValue, KmpInt32Ty));
1254   CGF.FinishFunction();
1255   return TaskEntry;
1256 }
1257 
1258 void CGOpenMPRuntime::emitTaskCall(
1259     CodeGenFunction &CGF, SourceLocation Loc, bool Tied,
1260     llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
1261     llvm::Value *TaskFunction, QualType SharedsTy, llvm::Value *Shareds) {
1262   auto &C = CGM.getContext();
1263   auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
1264   // Build type kmp_routine_entry_t (if not built yet).
1265   emitKmpRoutineEntryT(KmpInt32Ty);
1266   // Build particular struct kmp_task_t for the given task.
1267   auto KmpTaskQTy =
1268       createKmpTaskTRecordDecl(CGM, KmpInt32Ty, KmpRoutineEntryPtrQTy);
1269   QualType KmpTaskTPtrQTy = C.getPointerType(KmpTaskQTy);
1270   auto KmpTaskTPtrTy = CGF.ConvertType(KmpTaskQTy)->getPointerTo();
1271   auto KmpTaskTySize = CGM.getSize(C.getTypeSizeInChars(KmpTaskQTy));
1272   QualType SharedsPtrTy = C.getPointerType(SharedsTy);
1273 
1274   // Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid,
1275   // kmp_task_t *tt);
1276   auto *TaskEntry = emitProxyTaskFunction(CGM, Loc, KmpInt32Ty, KmpTaskTPtrQTy,
1277                                           SharedsPtrTy, TaskFunction);
1278 
1279   // Build call kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
1280   // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1281   // kmp_routine_entry_t *task_entry);
1282   // Task flags. Format is taken from
1283   // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h,
1284   // description of kmp_tasking_flags struct.
1285   const unsigned TiedFlag = 0x1;
1286   const unsigned FinalFlag = 0x2;
1287   unsigned Flags = Tied ? TiedFlag : 0;
1288   auto *TaskFlags =
1289       Final.getPointer()
1290           ? CGF.Builder.CreateSelect(Final.getPointer(),
1291                                      CGF.Builder.getInt32(FinalFlag),
1292                                      CGF.Builder.getInt32(/*C=*/0))
1293           : CGF.Builder.getInt32(Final.getInt() ? FinalFlag : 0);
1294   TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
1295   auto SharedsSize = C.getTypeSizeInChars(SharedsTy);
1296   llvm::Value *AllocArgs[] = {emitUpdateLocation(CGF, Loc),
1297                               getThreadID(CGF, Loc), TaskFlags, KmpTaskTySize,
1298                               CGM.getSize(SharedsSize),
1299                               CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1300                                   TaskEntry, KmpRoutineEntryPtrTy)};
1301   auto *NewTask = CGF.EmitRuntimeCall(
1302       createRuntimeFunction(OMPRTL__kmpc_omp_task_alloc), AllocArgs);
1303   auto *NewTaskNewTaskTTy =
1304       CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(NewTask, KmpTaskTPtrTy);
1305   // Fill the data in the resulting kmp_task_t record.
1306   // Copy shareds if there are any.
1307   if (!SharedsTy->getAsStructureType()->getDecl()->field_empty())
1308     CGF.EmitAggregateCopy(
1309         CGF.EmitLoadOfScalar(
1310             CGF.Builder.CreateStructGEP(NewTaskNewTaskTTy,
1311                                         /*Idx=*/KmpTaskTShareds),
1312             /*Volatile=*/false, CGM.PointerAlignInBytes, SharedsPtrTy, Loc),
1313         Shareds, SharedsTy);
1314   // TODO: generate function with destructors for privates.
1315   // Provide pointer to function with destructors for privates.
1316   CGF.Builder.CreateAlignedStore(
1317       llvm::ConstantPointerNull::get(
1318           cast<llvm::PointerType>(KmpRoutineEntryPtrTy)),
1319       CGF.Builder.CreateStructGEP(NewTaskNewTaskTTy,
1320                                   /*Idx=*/KmpTaskTDestructors),
1321       CGM.PointerAlignInBytes);
1322 
1323   // NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc()
1324   // libcall.
1325   // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
1326   // *new_task);
1327   llvm::Value *TaskArgs[] = {emitUpdateLocation(CGF, Loc),
1328                              getThreadID(CGF, Loc), NewTask};
1329   // TODO: add check for untied tasks.
1330   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task), TaskArgs);
1331 }
1332 
1333 InlinedOpenMPRegionRAII::InlinedOpenMPRegionRAII(
1334     CodeGenFunction &CGF, const OMPExecutableDirective &D)
1335     : CGF(CGF) {
1336   CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo(D, CGF.CapturedStmtInfo);
1337   // 1.2.2 OpenMP Language Terminology
1338   // Structured block - An executable statement with a single entry at the
1339   // top and a single exit at the bottom.
1340   // The point of exit cannot be a branch out of the structured block.
1341   // longjmp() and throw() must not violate the entry/exit criteria.
1342   CGF.EHStack.pushTerminate();
1343 }
1344 
1345 InlinedOpenMPRegionRAII::~InlinedOpenMPRegionRAII() {
1346   CGF.EHStack.popTerminate();
1347   auto *OldCSI =
1348       cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI();
1349   delete CGF.CapturedStmtInfo;
1350   CGF.CapturedStmtInfo = OldCSI;
1351 }
1352 
1353