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   /// \brief Kinds of OpenMP regions used in codegen.
35   enum CGOpenMPRegionKind {
36     /// \brief Region with outlined function for standalone 'parallel'
37     /// directive.
38     ParallelOutlinedRegion,
39     /// \brief Region with outlined function for standalone 'task' directive.
40     TaskOutlinedRegion,
41     /// \brief Region for constructs that do not require function outlining,
42     /// like 'for', 'sections', 'atomic' etc. directives.
43     InlinedRegion,
44   };
45 
46   CGOpenMPRegionInfo(const CapturedStmt &CS,
47                      const CGOpenMPRegionKind RegionKind,
48                      const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind)
49       : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind),
50         CodeGen(CodeGen), Kind(Kind) {}
51 
52   CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind,
53                      const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind)
54       : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
55         Kind(Kind) {}
56 
57   /// \brief Get a variable or parameter for storing global thread id
58   /// inside OpenMP construct.
59   virtual const VarDecl *getThreadIDVariable() const = 0;
60 
61   /// \brief Emit the captured statement body.
62   virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) override;
63 
64   /// \brief Get an LValue for the current ThreadID variable.
65   /// \return LValue for thread id variable. This LValue always has type int32*.
66   virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF);
67 
68   CGOpenMPRegionKind getRegionKind() const { return RegionKind; }
69 
70   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
71 
72   static bool classof(const CGCapturedStmtInfo *Info) {
73     return Info->getKind() == CR_OpenMP;
74   }
75 
76 protected:
77   CGOpenMPRegionKind RegionKind;
78   const RegionCodeGenTy &CodeGen;
79   OpenMPDirectiveKind Kind;
80 };
81 
82 /// \brief API for captured statement code generation in OpenMP constructs.
83 class CGOpenMPOutlinedRegionInfo : public CGOpenMPRegionInfo {
84 public:
85   CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
86                              const RegionCodeGenTy &CodeGen,
87                              OpenMPDirectiveKind Kind)
88       : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind),
89         ThreadIDVar(ThreadIDVar) {
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   const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
95 
96   /// \brief Get the name of the capture helper.
97   StringRef getHelperName() const override { return ".omp_outlined."; }
98 
99   static bool classof(const CGCapturedStmtInfo *Info) {
100     return CGOpenMPRegionInfo::classof(Info) &&
101            cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
102                ParallelOutlinedRegion;
103   }
104 
105 private:
106   /// \brief A variable or parameter storing global thread id for OpenMP
107   /// constructs.
108   const VarDecl *ThreadIDVar;
109 };
110 
111 /// \brief API for captured statement code generation in OpenMP constructs.
112 class CGOpenMPTaskOutlinedRegionInfo : public CGOpenMPRegionInfo {
113 public:
114   CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS,
115                                  const VarDecl *ThreadIDVar,
116                                  const RegionCodeGenTy &CodeGen,
117                                  OpenMPDirectiveKind Kind)
118       : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind),
119         ThreadIDVar(ThreadIDVar) {
120     assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
121   }
122   /// \brief Get a variable or parameter for storing global thread id
123   /// inside OpenMP construct.
124   const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
125 
126   /// \brief Get an LValue for the current ThreadID variable.
127   LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override;
128 
129   /// \brief Get the name of the capture helper.
130   StringRef getHelperName() const override { return ".omp_outlined."; }
131 
132   static bool classof(const CGCapturedStmtInfo *Info) {
133     return CGOpenMPRegionInfo::classof(Info) &&
134            cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
135                TaskOutlinedRegion;
136   }
137 
138 private:
139   /// \brief A variable or parameter storing global thread id for OpenMP
140   /// constructs.
141   const VarDecl *ThreadIDVar;
142 };
143 
144 /// \brief API for inlined captured statement code generation in OpenMP
145 /// constructs.
146 class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
147 public:
148   CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI,
149                             const RegionCodeGenTy &CodeGen,
150                             OpenMPDirectiveKind Kind)
151       : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind), OldCSI(OldCSI),
152         OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
153   // \brief Retrieve the value of the context parameter.
154   llvm::Value *getContextValue() const override {
155     if (OuterRegionInfo)
156       return OuterRegionInfo->getContextValue();
157     llvm_unreachable("No context value for inlined OpenMP region");
158   }
159   virtual void setContextValue(llvm::Value *V) override {
160     if (OuterRegionInfo) {
161       OuterRegionInfo->setContextValue(V);
162       return;
163     }
164     llvm_unreachable("No context value for inlined OpenMP region");
165   }
166   /// \brief Lookup the captured field decl for a variable.
167   const FieldDecl *lookup(const VarDecl *VD) const override {
168     if (OuterRegionInfo)
169       return OuterRegionInfo->lookup(VD);
170     // If there is no outer outlined region,no need to lookup in a list of
171     // captured variables, we can use the original one.
172     return nullptr;
173   }
174   FieldDecl *getThisFieldDecl() const override {
175     if (OuterRegionInfo)
176       return OuterRegionInfo->getThisFieldDecl();
177     return nullptr;
178   }
179   /// \brief Get a variable or parameter for storing global thread id
180   /// inside OpenMP construct.
181   const VarDecl *getThreadIDVariable() const override {
182     if (OuterRegionInfo)
183       return OuterRegionInfo->getThreadIDVariable();
184     return nullptr;
185   }
186 
187   /// \brief Get the name of the capture helper.
188   StringRef getHelperName() const override {
189     if (auto *OuterRegionInfo = getOldCSI())
190       return OuterRegionInfo->getHelperName();
191     llvm_unreachable("No helper name for inlined OpenMP construct");
192   }
193 
194   CodeGenFunction::CGCapturedStmtInfo *getOldCSI() const { return OldCSI; }
195 
196   static bool classof(const CGCapturedStmtInfo *Info) {
197     return CGOpenMPRegionInfo::classof(Info) &&
198            cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
199   }
200 
201 private:
202   /// \brief CodeGen info about outer OpenMP region.
203   CodeGenFunction::CGCapturedStmtInfo *OldCSI;
204   CGOpenMPRegionInfo *OuterRegionInfo;
205 };
206 
207 /// \brief RAII for emitting code of OpenMP constructs.
208 class InlinedOpenMPRegionRAII {
209   CodeGenFunction &CGF;
210 
211 public:
212   /// \brief Constructs region for combined constructs.
213   /// \param CodeGen Code generation sequence for combined directives. Includes
214   /// a list of functions used for code generation of implicitly inlined
215   /// regions.
216   InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen,
217                           OpenMPDirectiveKind Kind)
218       : CGF(CGF) {
219     // Start emission for the construct.
220     CGF.CapturedStmtInfo =
221         new CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, CodeGen, Kind);
222   }
223   ~InlinedOpenMPRegionRAII() {
224     // Restore original CapturedStmtInfo only if we're done with code emission.
225     auto *OldCSI =
226         cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI();
227     delete CGF.CapturedStmtInfo;
228     CGF.CapturedStmtInfo = OldCSI;
229   }
230 };
231 
232 } // namespace
233 
234 LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
235   return CGF.MakeNaturalAlignAddrLValue(
236       CGF.Builder.CreateAlignedLoad(
237           CGF.GetAddrOfLocalVar(getThreadIDVariable()),
238           CGF.PointerAlignInBytes),
239       getThreadIDVariable()
240           ->getType()
241           ->castAs<PointerType>()
242           ->getPointeeType());
243 }
244 
245 void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) {
246   // 1.2.2 OpenMP Language Terminology
247   // Structured block - An executable statement with a single entry at the
248   // top and a single exit at the bottom.
249   // The point of exit cannot be a branch out of the structured block.
250   // longjmp() and throw() must not violate the entry/exit criteria.
251   CGF.EHStack.pushTerminate();
252   {
253     CodeGenFunction::RunCleanupsScope Scope(CGF);
254     CodeGen(CGF);
255   }
256   CGF.EHStack.popTerminate();
257 }
258 
259 LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
260     CodeGenFunction &CGF) {
261   return CGF.MakeNaturalAlignAddrLValue(
262       CGF.GetAddrOfLocalVar(getThreadIDVariable()),
263       getThreadIDVariable()->getType());
264 }
265 
266 CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
267     : CGM(CGM), DefaultOpenMPPSource(nullptr), KmpRoutineEntryPtrTy(nullptr) {
268   IdentTy = llvm::StructType::create(
269       "ident_t", CGM.Int32Ty /* reserved_1 */, CGM.Int32Ty /* flags */,
270       CGM.Int32Ty /* reserved_2 */, CGM.Int32Ty /* reserved_3 */,
271       CGM.Int8PtrTy /* psource */, nullptr);
272   // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
273   llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
274                                llvm::PointerType::getUnqual(CGM.Int32Ty)};
275   Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
276   KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
277 }
278 
279 void CGOpenMPRuntime::clear() {
280   InternalVars.clear();
281 }
282 
283 llvm::Value *CGOpenMPRuntime::emitParallelOutlinedFunction(
284     const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
285     OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
286   assert(ThreadIDVar->getType()->isPointerType() &&
287          "thread id variable must be of type kmp_int32 *");
288   const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt());
289   CodeGenFunction CGF(CGM, true);
290   CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind);
291   CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
292   return CGF.GenerateCapturedStmtFunction(*CS);
293 }
294 
295 llvm::Value *CGOpenMPRuntime::emitTaskOutlinedFunction(
296     const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
297     OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
298   assert(!ThreadIDVar->getType()->isPointerType() &&
299          "thread id variable must be of type kmp_int32 for tasks");
300   auto *CS = cast<CapturedStmt>(D.getAssociatedStmt());
301   CodeGenFunction CGF(CGM, true);
302   CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
303                                         InnermostKind);
304   CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
305   return CGF.GenerateCapturedStmtFunction(*CS);
306 }
307 
308 llvm::Value *
309 CGOpenMPRuntime::getOrCreateDefaultLocation(OpenMPLocationFlags Flags) {
310   llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags);
311   if (!Entry) {
312     if (!DefaultOpenMPPSource) {
313       // Initialize default location for psource field of ident_t structure of
314       // all ident_t objects. Format is ";file;function;line;column;;".
315       // Taken from
316       // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp_str.c
317       DefaultOpenMPPSource =
318           CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;");
319       DefaultOpenMPPSource =
320           llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
321     }
322     auto DefaultOpenMPLocation = new llvm::GlobalVariable(
323         CGM.getModule(), IdentTy, /*isConstant*/ true,
324         llvm::GlobalValue::PrivateLinkage, /*Initializer*/ nullptr);
325     DefaultOpenMPLocation->setUnnamedAddr(true);
326 
327     llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true);
328     llvm::Constant *Values[] = {Zero,
329                                 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
330                                 Zero, Zero, DefaultOpenMPPSource};
331     llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values);
332     DefaultOpenMPLocation->setInitializer(Init);
333     OpenMPDefaultLocMap[Flags] = DefaultOpenMPLocation;
334     return DefaultOpenMPLocation;
335   }
336   return Entry;
337 }
338 
339 llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
340                                                  SourceLocation Loc,
341                                                  OpenMPLocationFlags Flags) {
342   // If no debug info is generated - return global default location.
343   if (CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::NoDebugInfo ||
344       Loc.isInvalid())
345     return getOrCreateDefaultLocation(Flags);
346 
347   assert(CGF.CurFn && "No function in current CodeGenFunction.");
348 
349   llvm::Value *LocValue = nullptr;
350   auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
351   if (I != OpenMPLocThreadIDMap.end())
352     LocValue = I->second.DebugLoc;
353   // OpenMPLocThreadIDMap may have null DebugLoc and non-null ThreadID, if
354   // GetOpenMPThreadID was called before this routine.
355   if (LocValue == nullptr) {
356     // Generate "ident_t .kmpc_loc.addr;"
357     llvm::AllocaInst *AI = CGF.CreateTempAlloca(IdentTy, ".kmpc_loc.addr");
358     AI->setAlignment(CGM.getDataLayout().getPrefTypeAlignment(IdentTy));
359     auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
360     Elem.second.DebugLoc = AI;
361     LocValue = AI;
362 
363     CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
364     CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
365     CGF.Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags),
366                              llvm::ConstantExpr::getSizeOf(IdentTy),
367                              CGM.PointerAlignInBytes);
368   }
369 
370   // char **psource = &.kmpc_loc_<flags>.addr.psource;
371   auto *PSource = CGF.Builder.CreateConstInBoundsGEP2_32(IdentTy, LocValue, 0,
372                                                          IdentField_PSource);
373 
374   auto OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
375   if (OMPDebugLoc == nullptr) {
376     SmallString<128> Buffer2;
377     llvm::raw_svector_ostream OS2(Buffer2);
378     // Build debug location
379     PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
380     OS2 << ";" << PLoc.getFilename() << ";";
381     if (const FunctionDecl *FD =
382             dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) {
383       OS2 << FD->getQualifiedNameAsString();
384     }
385     OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
386     OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
387     OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
388   }
389   // *psource = ";<File>;<Function>;<Line>;<Column>;;";
390   CGF.Builder.CreateStore(OMPDebugLoc, PSource);
391 
392   return LocValue;
393 }
394 
395 llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
396                                           SourceLocation Loc) {
397   assert(CGF.CurFn && "No function in current CodeGenFunction.");
398 
399   llvm::Value *ThreadID = nullptr;
400   // Check whether we've already cached a load of the thread id in this
401   // function.
402   auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
403   if (I != OpenMPLocThreadIDMap.end()) {
404     ThreadID = I->second.ThreadID;
405     if (ThreadID != nullptr)
406       return ThreadID;
407   }
408   if (auto OMPRegionInfo =
409           dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
410     if (OMPRegionInfo->getThreadIDVariable()) {
411       // Check if this an outlined function with thread id passed as argument.
412       auto LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
413       ThreadID = CGF.EmitLoadOfLValue(LVal, Loc).getScalarVal();
414       // If value loaded in entry block, cache it and use it everywhere in
415       // function.
416       if (CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) {
417         auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
418         Elem.second.ThreadID = ThreadID;
419       }
420       return ThreadID;
421     }
422   }
423 
424   // This is not an outlined function region - need to call __kmpc_int32
425   // kmpc_global_thread_num(ident_t *loc).
426   // Generate thread id value and cache this value for use across the
427   // function.
428   CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
429   CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
430   ThreadID =
431       CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
432                           emitUpdateLocation(CGF, Loc));
433   auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
434   Elem.second.ThreadID = ThreadID;
435   return ThreadID;
436 }
437 
438 void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) {
439   assert(CGF.CurFn && "No function in current CodeGenFunction.");
440   if (OpenMPLocThreadIDMap.count(CGF.CurFn))
441     OpenMPLocThreadIDMap.erase(CGF.CurFn);
442 }
443 
444 llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
445   return llvm::PointerType::getUnqual(IdentTy);
446 }
447 
448 llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
449   return llvm::PointerType::getUnqual(Kmpc_MicroTy);
450 }
451 
452 llvm::Constant *
453 CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {
454   llvm::Constant *RTLFn = nullptr;
455   switch (Function) {
456   case OMPRTL__kmpc_fork_call: {
457     // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
458     // microtask, ...);
459     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
460                                 getKmpc_MicroPointerTy()};
461     llvm::FunctionType *FnTy =
462         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
463     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
464     break;
465   }
466   case OMPRTL__kmpc_global_thread_num: {
467     // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
468     llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
469     llvm::FunctionType *FnTy =
470         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
471     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
472     break;
473   }
474   case OMPRTL__kmpc_threadprivate_cached: {
475     // Build void *__kmpc_threadprivate_cached(ident_t *loc,
476     // kmp_int32 global_tid, void *data, size_t size, void ***cache);
477     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
478                                 CGM.VoidPtrTy, CGM.SizeTy,
479                                 CGM.VoidPtrTy->getPointerTo()->getPointerTo()};
480     llvm::FunctionType *FnTy =
481         llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg*/ false);
482     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_cached");
483     break;
484   }
485   case OMPRTL__kmpc_critical: {
486     // Build void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
487     // kmp_critical_name *crit);
488     llvm::Type *TypeParams[] = {
489         getIdentTyPointerTy(), CGM.Int32Ty,
490         llvm::PointerType::getUnqual(KmpCriticalNameTy)};
491     llvm::FunctionType *FnTy =
492         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
493     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical");
494     break;
495   }
496   case OMPRTL__kmpc_threadprivate_register: {
497     // Build void __kmpc_threadprivate_register(ident_t *, void *data,
498     // kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
499     // typedef void *(*kmpc_ctor)(void *);
500     auto KmpcCtorTy =
501         llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
502                                 /*isVarArg*/ false)->getPointerTo();
503     // typedef void *(*kmpc_cctor)(void *, void *);
504     llvm::Type *KmpcCopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
505     auto KmpcCopyCtorTy =
506         llvm::FunctionType::get(CGM.VoidPtrTy, KmpcCopyCtorTyArgs,
507                                 /*isVarArg*/ false)->getPointerTo();
508     // typedef void (*kmpc_dtor)(void *);
509     auto KmpcDtorTy =
510         llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy, /*isVarArg*/ false)
511             ->getPointerTo();
512     llvm::Type *FnTyArgs[] = {getIdentTyPointerTy(), CGM.VoidPtrTy, KmpcCtorTy,
513                               KmpcCopyCtorTy, KmpcDtorTy};
514     auto FnTy = llvm::FunctionType::get(CGM.VoidTy, FnTyArgs,
515                                         /*isVarArg*/ false);
516     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_register");
517     break;
518   }
519   case OMPRTL__kmpc_end_critical: {
520     // Build void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
521     // kmp_critical_name *crit);
522     llvm::Type *TypeParams[] = {
523         getIdentTyPointerTy(), CGM.Int32Ty,
524         llvm::PointerType::getUnqual(KmpCriticalNameTy)};
525     llvm::FunctionType *FnTy =
526         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
527     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical");
528     break;
529   }
530   case OMPRTL__kmpc_cancel_barrier: {
531     // Build kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
532     // global_tid);
533     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
534     llvm::FunctionType *FnTy =
535         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
536     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier");
537     break;
538   }
539   case OMPRTL__kmpc_barrier: {
540     // Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
541     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
542     llvm::FunctionType *FnTy =
543         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
544     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier");
545     break;
546   }
547   case OMPRTL__kmpc_for_static_fini: {
548     // Build void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
549     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
550     llvm::FunctionType *FnTy =
551         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
552     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_fini");
553     break;
554   }
555   case OMPRTL__kmpc_push_num_threads: {
556     // Build void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
557     // kmp_int32 num_threads)
558     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
559                                 CGM.Int32Ty};
560     llvm::FunctionType *FnTy =
561         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
562     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_threads");
563     break;
564   }
565   case OMPRTL__kmpc_serialized_parallel: {
566     // Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
567     // global_tid);
568     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
569     llvm::FunctionType *FnTy =
570         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
571     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel");
572     break;
573   }
574   case OMPRTL__kmpc_end_serialized_parallel: {
575     // Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
576     // global_tid);
577     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
578     llvm::FunctionType *FnTy =
579         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
580     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel");
581     break;
582   }
583   case OMPRTL__kmpc_flush: {
584     // Build void __kmpc_flush(ident_t *loc);
585     llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
586     llvm::FunctionType *FnTy =
587         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
588     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_flush");
589     break;
590   }
591   case OMPRTL__kmpc_master: {
592     // Build kmp_int32 __kmpc_master(ident_t *loc, kmp_int32 global_tid);
593     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
594     llvm::FunctionType *FnTy =
595         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
596     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_master");
597     break;
598   }
599   case OMPRTL__kmpc_end_master: {
600     // Build void __kmpc_end_master(ident_t *loc, kmp_int32 global_tid);
601     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
602     llvm::FunctionType *FnTy =
603         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
604     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_master");
605     break;
606   }
607   case OMPRTL__kmpc_omp_taskyield: {
608     // Build kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
609     // int end_part);
610     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
611     llvm::FunctionType *FnTy =
612         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
613     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_taskyield");
614     break;
615   }
616   case OMPRTL__kmpc_single: {
617     // Build kmp_int32 __kmpc_single(ident_t *loc, kmp_int32 global_tid);
618     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
619     llvm::FunctionType *FnTy =
620         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
621     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_single");
622     break;
623   }
624   case OMPRTL__kmpc_end_single: {
625     // Build void __kmpc_end_single(ident_t *loc, kmp_int32 global_tid);
626     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
627     llvm::FunctionType *FnTy =
628         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
629     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_single");
630     break;
631   }
632   case OMPRTL__kmpc_omp_task_alloc: {
633     // Build kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
634     // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
635     // kmp_routine_entry_t *task_entry);
636     assert(KmpRoutineEntryPtrTy != nullptr &&
637            "Type kmp_routine_entry_t must be created.");
638     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
639                                 CGM.SizeTy, CGM.SizeTy, KmpRoutineEntryPtrTy};
640     // Return void * and then cast to particular kmp_task_t type.
641     llvm::FunctionType *FnTy =
642         llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
643     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_alloc");
644     break;
645   }
646   case OMPRTL__kmpc_omp_task: {
647     // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
648     // *new_task);
649     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
650                                 CGM.VoidPtrTy};
651     llvm::FunctionType *FnTy =
652         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
653     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task");
654     break;
655   }
656   case OMPRTL__kmpc_copyprivate: {
657     // Build void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
658     // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
659     // kmp_int32 didit);
660     llvm::Type *CpyTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
661     auto *CpyFnTy =
662         llvm::FunctionType::get(CGM.VoidTy, CpyTypeParams, /*isVarArg=*/false);
663     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.SizeTy,
664                                 CGM.VoidPtrTy, CpyFnTy->getPointerTo(),
665                                 CGM.Int32Ty};
666     llvm::FunctionType *FnTy =
667         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
668     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_copyprivate");
669     break;
670   }
671   case OMPRTL__kmpc_reduce: {
672     // Build kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
673     // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
674     // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
675     llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
676     auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
677                                                /*isVarArg=*/false);
678     llvm::Type *TypeParams[] = {
679         getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
680         CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
681         llvm::PointerType::getUnqual(KmpCriticalNameTy)};
682     llvm::FunctionType *FnTy =
683         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
684     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce");
685     break;
686   }
687   case OMPRTL__kmpc_reduce_nowait: {
688     // Build kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
689     // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
690     // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
691     // *lck);
692     llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
693     auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
694                                                /*isVarArg=*/false);
695     llvm::Type *TypeParams[] = {
696         getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
697         CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
698         llvm::PointerType::getUnqual(KmpCriticalNameTy)};
699     llvm::FunctionType *FnTy =
700         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
701     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce_nowait");
702     break;
703   }
704   case OMPRTL__kmpc_end_reduce: {
705     // Build void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
706     // kmp_critical_name *lck);
707     llvm::Type *TypeParams[] = {
708         getIdentTyPointerTy(), CGM.Int32Ty,
709         llvm::PointerType::getUnqual(KmpCriticalNameTy)};
710     llvm::FunctionType *FnTy =
711         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
712     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce");
713     break;
714   }
715   case OMPRTL__kmpc_end_reduce_nowait: {
716     // Build __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
717     // kmp_critical_name *lck);
718     llvm::Type *TypeParams[] = {
719         getIdentTyPointerTy(), CGM.Int32Ty,
720         llvm::PointerType::getUnqual(KmpCriticalNameTy)};
721     llvm::FunctionType *FnTy =
722         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
723     RTLFn =
724         CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce_nowait");
725     break;
726   }
727   case OMPRTL__kmpc_omp_task_begin_if0: {
728     // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
729     // *new_task);
730     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
731                                 CGM.VoidPtrTy};
732     llvm::FunctionType *FnTy =
733         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
734     RTLFn =
735         CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_begin_if0");
736     break;
737   }
738   case OMPRTL__kmpc_omp_task_complete_if0: {
739     // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
740     // *new_task);
741     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
742                                 CGM.VoidPtrTy};
743     llvm::FunctionType *FnTy =
744         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
745     RTLFn = CGM.CreateRuntimeFunction(FnTy,
746                                       /*Name=*/"__kmpc_omp_task_complete_if0");
747     break;
748   }
749   case OMPRTL__kmpc_ordered: {
750     // Build void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
751     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
752     llvm::FunctionType *FnTy =
753         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
754     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_ordered");
755     break;
756   }
757   case OMPRTL__kmpc_end_ordered: {
758     // Build void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
759     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
760     llvm::FunctionType *FnTy =
761         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
762     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_ordered");
763     break;
764   }
765   case OMPRTL__kmpc_omp_taskwait: {
766     // Build kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 global_tid);
767     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
768     llvm::FunctionType *FnTy =
769         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
770     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_omp_taskwait");
771     break;
772   }
773   case OMPRTL__kmpc_taskgroup: {
774     // Build void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
775     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
776     llvm::FunctionType *FnTy =
777         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
778     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_taskgroup");
779     break;
780   }
781   case OMPRTL__kmpc_end_taskgroup: {
782     // Build void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
783     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
784     llvm::FunctionType *FnTy =
785         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
786     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_taskgroup");
787     break;
788   }
789   case OMPRTL__kmpc_push_proc_bind: {
790     // Build void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
791     // int proc_bind)
792     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
793     llvm::FunctionType *FnTy =
794         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
795     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_proc_bind");
796     break;
797   }
798   case OMPRTL__kmpc_omp_task_with_deps: {
799     // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
800     // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
801     // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
802     llvm::Type *TypeParams[] = {
803         getIdentTyPointerTy(), CGM.Int32Ty, CGM.VoidPtrTy, CGM.Int32Ty,
804         CGM.VoidPtrTy,         CGM.Int32Ty, CGM.VoidPtrTy};
805     llvm::FunctionType *FnTy =
806         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
807     RTLFn =
808         CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_with_deps");
809     break;
810   }
811   case OMPRTL__kmpc_omp_wait_deps: {
812     // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
813     // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias,
814     // kmp_depend_info_t *noalias_dep_list);
815     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
816                                 CGM.Int32Ty,           CGM.VoidPtrTy,
817                                 CGM.Int32Ty,           CGM.VoidPtrTy};
818     llvm::FunctionType *FnTy =
819         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
820     RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_wait_deps");
821     break;
822   }
823   case OMPRTL__kmpc_cancellationpoint: {
824     // Build kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
825     // global_tid, kmp_int32 cncl_kind)
826     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
827     llvm::FunctionType *FnTy =
828         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
829     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint");
830     break;
831   }
832   case OMPRTL__kmpc_cancel: {
833     // Build kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
834     // kmp_int32 cncl_kind)
835     llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
836     llvm::FunctionType *FnTy =
837         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
838     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancel");
839     break;
840   }
841   }
842   return RTLFn;
843 }
844 
845 llvm::Constant *CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize,
846                                                              bool IVSigned) {
847   assert((IVSize == 32 || IVSize == 64) &&
848          "IV size is not compatible with the omp runtime");
849   auto Name = IVSize == 32 ? (IVSigned ? "__kmpc_for_static_init_4"
850                                        : "__kmpc_for_static_init_4u")
851                            : (IVSigned ? "__kmpc_for_static_init_8"
852                                        : "__kmpc_for_static_init_8u");
853   auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
854   auto PtrTy = llvm::PointerType::getUnqual(ITy);
855   llvm::Type *TypeParams[] = {
856     getIdentTyPointerTy(),                     // loc
857     CGM.Int32Ty,                               // tid
858     CGM.Int32Ty,                               // schedtype
859     llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
860     PtrTy,                                     // p_lower
861     PtrTy,                                     // p_upper
862     PtrTy,                                     // p_stride
863     ITy,                                       // incr
864     ITy                                        // chunk
865   };
866   llvm::FunctionType *FnTy =
867       llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
868   return CGM.CreateRuntimeFunction(FnTy, Name);
869 }
870 
871 llvm::Constant *CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize,
872                                                             bool IVSigned) {
873   assert((IVSize == 32 || IVSize == 64) &&
874          "IV size is not compatible with the omp runtime");
875   auto Name =
876       IVSize == 32
877           ? (IVSigned ? "__kmpc_dispatch_init_4" : "__kmpc_dispatch_init_4u")
878           : (IVSigned ? "__kmpc_dispatch_init_8" : "__kmpc_dispatch_init_8u");
879   auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
880   llvm::Type *TypeParams[] = { getIdentTyPointerTy(), // loc
881                                CGM.Int32Ty,           // tid
882                                CGM.Int32Ty,           // schedtype
883                                ITy,                   // lower
884                                ITy,                   // upper
885                                ITy,                   // stride
886                                ITy                    // chunk
887   };
888   llvm::FunctionType *FnTy =
889       llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
890   return CGM.CreateRuntimeFunction(FnTy, Name);
891 }
892 
893 llvm::Constant *CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize,
894                                                             bool IVSigned) {
895   assert((IVSize == 32 || IVSize == 64) &&
896          "IV size is not compatible with the omp runtime");
897   auto Name =
898       IVSize == 32
899           ? (IVSigned ? "__kmpc_dispatch_fini_4" : "__kmpc_dispatch_fini_4u")
900           : (IVSigned ? "__kmpc_dispatch_fini_8" : "__kmpc_dispatch_fini_8u");
901   llvm::Type *TypeParams[] = {
902       getIdentTyPointerTy(), // loc
903       CGM.Int32Ty,           // tid
904   };
905   llvm::FunctionType *FnTy =
906       llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
907   return CGM.CreateRuntimeFunction(FnTy, Name);
908 }
909 
910 llvm::Constant *CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize,
911                                                             bool IVSigned) {
912   assert((IVSize == 32 || IVSize == 64) &&
913          "IV size is not compatible with the omp runtime");
914   auto Name =
915       IVSize == 32
916           ? (IVSigned ? "__kmpc_dispatch_next_4" : "__kmpc_dispatch_next_4u")
917           : (IVSigned ? "__kmpc_dispatch_next_8" : "__kmpc_dispatch_next_8u");
918   auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
919   auto PtrTy = llvm::PointerType::getUnqual(ITy);
920   llvm::Type *TypeParams[] = {
921     getIdentTyPointerTy(),                     // loc
922     CGM.Int32Ty,                               // tid
923     llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
924     PtrTy,                                     // p_lower
925     PtrTy,                                     // p_upper
926     PtrTy                                      // p_stride
927   };
928   llvm::FunctionType *FnTy =
929       llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
930   return CGM.CreateRuntimeFunction(FnTy, Name);
931 }
932 
933 llvm::Constant *
934 CGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
935   // Lookup the entry, lazily creating it if necessary.
936   return getOrCreateInternalVariable(CGM.Int8PtrPtrTy,
937                                      Twine(CGM.getMangledName(VD)) + ".cache.");
938 }
939 
940 llvm::Value *CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
941                                                      const VarDecl *VD,
942                                                      llvm::Value *VDAddr,
943                                                      SourceLocation Loc) {
944   auto VarTy = VDAddr->getType()->getPointerElementType();
945   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
946                          CGF.Builder.CreatePointerCast(VDAddr, CGM.Int8PtrTy),
947                          CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)),
948                          getOrCreateThreadPrivateCache(VD)};
949   return CGF.EmitRuntimeCall(
950       createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args);
951 }
952 
953 void CGOpenMPRuntime::emitThreadPrivateVarInit(
954     CodeGenFunction &CGF, llvm::Value *VDAddr, llvm::Value *Ctor,
955     llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc) {
956   // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime
957   // library.
958   auto OMPLoc = emitUpdateLocation(CGF, Loc);
959   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
960                       OMPLoc);
961   // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor)
962   // to register constructor/destructor for variable.
963   llvm::Value *Args[] = {OMPLoc,
964                          CGF.Builder.CreatePointerCast(VDAddr, CGM.VoidPtrTy),
965                          Ctor, CopyCtor, Dtor};
966   CGF.EmitRuntimeCall(
967       createRuntimeFunction(OMPRTL__kmpc_threadprivate_register), Args);
968 }
969 
970 llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
971     const VarDecl *VD, llvm::Value *VDAddr, SourceLocation Loc,
972     bool PerformInit, CodeGenFunction *CGF) {
973   VD = VD->getDefinition(CGM.getContext());
974   if (VD && ThreadPrivateWithDefinition.count(VD) == 0) {
975     ThreadPrivateWithDefinition.insert(VD);
976     QualType ASTTy = VD->getType();
977 
978     llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr;
979     auto Init = VD->getAnyInitializer();
980     if (CGM.getLangOpts().CPlusPlus && PerformInit) {
981       // Generate function that re-emits the declaration's initializer into the
982       // threadprivate copy of the variable VD
983       CodeGenFunction CtorCGF(CGM);
984       FunctionArgList Args;
985       ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, SourceLocation(),
986                             /*Id=*/nullptr, CGM.getContext().VoidPtrTy);
987       Args.push_back(&Dst);
988 
989       auto &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
990           CGM.getContext().VoidPtrTy, Args, FunctionType::ExtInfo(),
991           /*isVariadic=*/false);
992       auto FTy = CGM.getTypes().GetFunctionType(FI);
993       auto Fn = CGM.CreateGlobalInitOrDestructFunction(
994           FTy, ".__kmpc_global_ctor_.", Loc);
995       CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI,
996                             Args, SourceLocation());
997       auto ArgVal = CtorCGF.EmitLoadOfScalar(
998           CtorCGF.GetAddrOfLocalVar(&Dst),
999           /*Volatile=*/false, CGM.PointerAlignInBytes,
1000           CGM.getContext().VoidPtrTy, Dst.getLocation());
1001       auto Arg = CtorCGF.Builder.CreatePointerCast(
1002           ArgVal,
1003           CtorCGF.ConvertTypeForMem(CGM.getContext().getPointerType(ASTTy)));
1004       CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
1005                                /*IsInitializer=*/true);
1006       ArgVal = CtorCGF.EmitLoadOfScalar(
1007           CtorCGF.GetAddrOfLocalVar(&Dst),
1008           /*Volatile=*/false, CGM.PointerAlignInBytes,
1009           CGM.getContext().VoidPtrTy, Dst.getLocation());
1010       CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue);
1011       CtorCGF.FinishFunction();
1012       Ctor = Fn;
1013     }
1014     if (VD->getType().isDestructedType() != QualType::DK_none) {
1015       // Generate function that emits destructor call for the threadprivate copy
1016       // of the variable VD
1017       CodeGenFunction DtorCGF(CGM);
1018       FunctionArgList Args;
1019       ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, SourceLocation(),
1020                             /*Id=*/nullptr, CGM.getContext().VoidPtrTy);
1021       Args.push_back(&Dst);
1022 
1023       auto &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
1024           CGM.getContext().VoidTy, Args, FunctionType::ExtInfo(),
1025           /*isVariadic=*/false);
1026       auto FTy = CGM.getTypes().GetFunctionType(FI);
1027       auto Fn = CGM.CreateGlobalInitOrDestructFunction(
1028           FTy, ".__kmpc_global_dtor_.", Loc);
1029       DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, Args,
1030                             SourceLocation());
1031       auto ArgVal = DtorCGF.EmitLoadOfScalar(
1032           DtorCGF.GetAddrOfLocalVar(&Dst),
1033           /*Volatile=*/false, CGM.PointerAlignInBytes,
1034           CGM.getContext().VoidPtrTy, Dst.getLocation());
1035       DtorCGF.emitDestroy(ArgVal, ASTTy,
1036                           DtorCGF.getDestroyer(ASTTy.isDestructedType()),
1037                           DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
1038       DtorCGF.FinishFunction();
1039       Dtor = Fn;
1040     }
1041     // Do not emit init function if it is not required.
1042     if (!Ctor && !Dtor)
1043       return nullptr;
1044 
1045     llvm::Type *CopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1046     auto CopyCtorTy =
1047         llvm::FunctionType::get(CGM.VoidPtrTy, CopyCtorTyArgs,
1048                                 /*isVarArg=*/false)->getPointerTo();
1049     // Copying constructor for the threadprivate variable.
1050     // Must be NULL - reserved by runtime, but currently it requires that this
1051     // parameter is always NULL. Otherwise it fires assertion.
1052     CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
1053     if (Ctor == nullptr) {
1054       auto CtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
1055                                             /*isVarArg=*/false)->getPointerTo();
1056       Ctor = llvm::Constant::getNullValue(CtorTy);
1057     }
1058     if (Dtor == nullptr) {
1059       auto DtorTy = llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy,
1060                                             /*isVarArg=*/false)->getPointerTo();
1061       Dtor = llvm::Constant::getNullValue(DtorTy);
1062     }
1063     if (!CGF) {
1064       auto InitFunctionTy =
1065           llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false);
1066       auto InitFunction = CGM.CreateGlobalInitOrDestructFunction(
1067           InitFunctionTy, ".__omp_threadprivate_init_.");
1068       CodeGenFunction InitCGF(CGM);
1069       FunctionArgList ArgList;
1070       InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, InitFunction,
1071                             CGM.getTypes().arrangeNullaryFunction(), ArgList,
1072                             Loc);
1073       emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
1074       InitCGF.FinishFunction();
1075       return InitFunction;
1076     }
1077     emitThreadPrivateVarInit(*CGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
1078   }
1079   return nullptr;
1080 }
1081 
1082 /// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
1083 /// function. Here is the logic:
1084 /// if (Cond) {
1085 ///   ThenGen();
1086 /// } else {
1087 ///   ElseGen();
1088 /// }
1089 static void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
1090                             const RegionCodeGenTy &ThenGen,
1091                             const RegionCodeGenTy &ElseGen) {
1092   CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
1093 
1094   // If the condition constant folds and can be elided, try to avoid emitting
1095   // the condition and the dead arm of the if/else.
1096   bool CondConstant;
1097   if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
1098     CodeGenFunction::RunCleanupsScope Scope(CGF);
1099     if (CondConstant) {
1100       ThenGen(CGF);
1101     } else {
1102       ElseGen(CGF);
1103     }
1104     return;
1105   }
1106 
1107   // Otherwise, the condition did not fold, or we couldn't elide it.  Just
1108   // emit the conditional branch.
1109   auto ThenBlock = CGF.createBasicBlock("omp_if.then");
1110   auto ElseBlock = CGF.createBasicBlock("omp_if.else");
1111   auto ContBlock = CGF.createBasicBlock("omp_if.end");
1112   CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount=*/0);
1113 
1114   // Emit the 'then' code.
1115   CGF.EmitBlock(ThenBlock);
1116   {
1117     CodeGenFunction::RunCleanupsScope ThenScope(CGF);
1118     ThenGen(CGF);
1119   }
1120   CGF.EmitBranch(ContBlock);
1121   // Emit the 'else' code if present.
1122   {
1123     // There is no need to emit line number for unconditional branch.
1124     auto NL = ApplyDebugLocation::CreateEmpty(CGF);
1125     CGF.EmitBlock(ElseBlock);
1126   }
1127   {
1128     CodeGenFunction::RunCleanupsScope ThenScope(CGF);
1129     ElseGen(CGF);
1130   }
1131   {
1132     // There is no need to emit line number for unconditional branch.
1133     auto NL = ApplyDebugLocation::CreateEmpty(CGF);
1134     CGF.EmitBranch(ContBlock);
1135   }
1136   // Emit the continuation block for code after the if.
1137   CGF.EmitBlock(ContBlock, /*IsFinished=*/true);
1138 }
1139 
1140 void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
1141                                        llvm::Value *OutlinedFn,
1142                                        llvm::Value *CapturedStruct,
1143                                        const Expr *IfCond) {
1144   auto *RTLoc = emitUpdateLocation(CGF, Loc);
1145   auto &&ThenGen =
1146       [this, OutlinedFn, CapturedStruct, RTLoc](CodeGenFunction &CGF) {
1147         // Build call __kmpc_fork_call(loc, 1, microtask,
1148         // captured_struct/*context*/)
1149         llvm::Value *Args[] = {
1150             RTLoc,
1151             CGF.Builder.getInt32(
1152                 1), // Number of arguments after 'microtask' argument
1153             // (there is only one additional argument - 'context')
1154             CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy()),
1155             CGF.EmitCastToVoidPtr(CapturedStruct)};
1156         auto RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_call);
1157         CGF.EmitRuntimeCall(RTLFn, Args);
1158       };
1159   auto &&ElseGen = [this, OutlinedFn, CapturedStruct, RTLoc, Loc](
1160       CodeGenFunction &CGF) {
1161     auto ThreadID = getThreadID(CGF, Loc);
1162     // Build calls:
1163     // __kmpc_serialized_parallel(&Loc, GTid);
1164     llvm::Value *Args[] = {RTLoc, ThreadID};
1165     CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_serialized_parallel),
1166                         Args);
1167 
1168     // OutlinedFn(&GTid, &zero, CapturedStruct);
1169     auto ThreadIDAddr = emitThreadIDAddress(CGF, Loc);
1170     auto Int32Ty = CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32,
1171                                                           /*Signed*/ true);
1172     auto ZeroAddr = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".zero.addr");
1173     CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C*/ 0));
1174     llvm::Value *OutlinedFnArgs[] = {ThreadIDAddr, ZeroAddr, CapturedStruct};
1175     CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
1176 
1177     // __kmpc_end_serialized_parallel(&Loc, GTid);
1178     llvm::Value *EndArgs[] = {emitUpdateLocation(CGF, Loc), ThreadID};
1179     CGF.EmitRuntimeCall(
1180         createRuntimeFunction(OMPRTL__kmpc_end_serialized_parallel), EndArgs);
1181   };
1182   if (IfCond) {
1183     emitOMPIfClause(CGF, IfCond, ThenGen, ElseGen);
1184   } else {
1185     CodeGenFunction::RunCleanupsScope Scope(CGF);
1186     ThenGen(CGF);
1187   }
1188 }
1189 
1190 // If we're inside an (outlined) parallel region, use the region info's
1191 // thread-ID variable (it is passed in a first argument of the outlined function
1192 // as "kmp_int32 *gtid"). Otherwise, if we're not inside parallel region, but in
1193 // regular serial code region, get thread ID by calling kmp_int32
1194 // kmpc_global_thread_num(ident_t *loc), stash this thread ID in a temporary and
1195 // return the address of that temp.
1196 llvm::Value *CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
1197                                                   SourceLocation Loc) {
1198   if (auto OMPRegionInfo =
1199           dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
1200     if (OMPRegionInfo->getThreadIDVariable())
1201       return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
1202 
1203   auto ThreadID = getThreadID(CGF, Loc);
1204   auto Int32Ty =
1205       CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true);
1206   auto ThreadIDTemp = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".threadid_temp.");
1207   CGF.EmitStoreOfScalar(ThreadID,
1208                         CGF.MakeNaturalAlignAddrLValue(ThreadIDTemp, Int32Ty));
1209 
1210   return ThreadIDTemp;
1211 }
1212 
1213 llvm::Constant *
1214 CGOpenMPRuntime::getOrCreateInternalVariable(llvm::Type *Ty,
1215                                              const llvm::Twine &Name) {
1216   SmallString<256> Buffer;
1217   llvm::raw_svector_ostream Out(Buffer);
1218   Out << Name;
1219   auto RuntimeName = Out.str();
1220   auto &Elem = *InternalVars.insert(std::make_pair(RuntimeName, nullptr)).first;
1221   if (Elem.second) {
1222     assert(Elem.second->getType()->getPointerElementType() == Ty &&
1223            "OMP internal variable has different type than requested");
1224     return &*Elem.second;
1225   }
1226 
1227   return Elem.second = new llvm::GlobalVariable(
1228              CGM.getModule(), Ty, /*IsConstant*/ false,
1229              llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
1230              Elem.first());
1231 }
1232 
1233 llvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
1234   llvm::Twine Name(".gomp_critical_user_", CriticalName);
1235   return getOrCreateInternalVariable(KmpCriticalNameTy, Name.concat(".var"));
1236 }
1237 
1238 namespace {
1239 template <size_t N> class CallEndCleanup : public EHScopeStack::Cleanup {
1240   llvm::Value *Callee;
1241   llvm::Value *Args[N];
1242 
1243 public:
1244   CallEndCleanup(llvm::Value *Callee, ArrayRef<llvm::Value *> CleanupArgs)
1245       : Callee(Callee) {
1246     assert(CleanupArgs.size() == N);
1247     std::copy(CleanupArgs.begin(), CleanupArgs.end(), std::begin(Args));
1248   }
1249   void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
1250     CGF.EmitRuntimeCall(Callee, Args);
1251   }
1252 };
1253 } // namespace
1254 
1255 void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
1256                                          StringRef CriticalName,
1257                                          const RegionCodeGenTy &CriticalOpGen,
1258                                          SourceLocation Loc) {
1259   // __kmpc_critical(ident_t *, gtid, Lock);
1260   // CriticalOpGen();
1261   // __kmpc_end_critical(ident_t *, gtid, Lock);
1262   // Prepare arguments and build a call to __kmpc_critical
1263   {
1264     CodeGenFunction::RunCleanupsScope Scope(CGF);
1265     llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
1266                            getCriticalRegionLock(CriticalName)};
1267     CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_critical), Args);
1268     // Build a call to __kmpc_end_critical
1269     CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
1270         NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_critical),
1271         llvm::makeArrayRef(Args));
1272     emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
1273   }
1274 }
1275 
1276 static void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond,
1277                        OpenMPDirectiveKind Kind,
1278                        const RegionCodeGenTy &BodyOpGen) {
1279   llvm::Value *CallBool = CGF.EmitScalarConversion(
1280       IfCond,
1281       CGF.getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true),
1282       CGF.getContext().BoolTy);
1283 
1284   auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
1285   auto *ContBlock = CGF.createBasicBlock("omp_if.end");
1286   // Generate the branch (If-stmt)
1287   CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
1288   CGF.EmitBlock(ThenBlock);
1289   CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, Kind, BodyOpGen);
1290   // Emit the rest of bblocks/branches
1291   CGF.EmitBranch(ContBlock);
1292   CGF.EmitBlock(ContBlock, true);
1293 }
1294 
1295 void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF,
1296                                        const RegionCodeGenTy &MasterOpGen,
1297                                        SourceLocation Loc) {
1298   // if(__kmpc_master(ident_t *, gtid)) {
1299   //   MasterOpGen();
1300   //   __kmpc_end_master(ident_t *, gtid);
1301   // }
1302   // Prepare arguments and build a call to __kmpc_master
1303   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
1304   auto *IsMaster =
1305       CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_master), Args);
1306   typedef CallEndCleanup<std::extent<decltype(Args)>::value>
1307       MasterCallEndCleanup;
1308   emitIfStmt(CGF, IsMaster, OMPD_master, [&](CodeGenFunction &CGF) -> void {
1309     CodeGenFunction::RunCleanupsScope Scope(CGF);
1310     CGF.EHStack.pushCleanup<MasterCallEndCleanup>(
1311         NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_master),
1312         llvm::makeArrayRef(Args));
1313     MasterOpGen(CGF);
1314   });
1315 }
1316 
1317 void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
1318                                         SourceLocation Loc) {
1319   // Build call __kmpc_omp_taskyield(loc, thread_id, 0);
1320   llvm::Value *Args[] = {
1321       emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
1322       llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)};
1323   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), Args);
1324 }
1325 
1326 void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF,
1327                                           const RegionCodeGenTy &TaskgroupOpGen,
1328                                           SourceLocation Loc) {
1329   // __kmpc_taskgroup(ident_t *, gtid);
1330   // TaskgroupOpGen();
1331   // __kmpc_end_taskgroup(ident_t *, gtid);
1332   // Prepare arguments and build a call to __kmpc_taskgroup
1333   {
1334     CodeGenFunction::RunCleanupsScope Scope(CGF);
1335     llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
1336     CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_taskgroup), Args);
1337     // Build a call to __kmpc_end_taskgroup
1338     CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
1339         NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_taskgroup),
1340         llvm::makeArrayRef(Args));
1341     emitInlinedDirective(CGF, OMPD_taskgroup, TaskgroupOpGen);
1342   }
1343 }
1344 
1345 static llvm::Value *emitCopyprivateCopyFunction(
1346     CodeGenModule &CGM, llvm::Type *ArgsType,
1347     ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
1348     ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps) {
1349   auto &C = CGM.getContext();
1350   // void copy_func(void *LHSArg, void *RHSArg);
1351   FunctionArgList Args;
1352   ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr,
1353                            C.VoidPtrTy);
1354   ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr,
1355                            C.VoidPtrTy);
1356   Args.push_back(&LHSArg);
1357   Args.push_back(&RHSArg);
1358   FunctionType::ExtInfo EI;
1359   auto &CGFI = CGM.getTypes().arrangeFreeFunctionDeclaration(
1360       C.VoidTy, Args, EI, /*isVariadic=*/false);
1361   auto *Fn = llvm::Function::Create(
1362       CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
1363       ".omp.copyprivate.copy_func", &CGM.getModule());
1364   CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, CGFI, Fn);
1365   CodeGenFunction CGF(CGM);
1366   CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args);
1367   // Dest = (void*[n])(LHSArg);
1368   // Src = (void*[n])(RHSArg);
1369   auto *LHS = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1370       CGF.Builder.CreateAlignedLoad(CGF.GetAddrOfLocalVar(&LHSArg),
1371                                     CGF.PointerAlignInBytes),
1372       ArgsType);
1373   auto *RHS = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1374       CGF.Builder.CreateAlignedLoad(CGF.GetAddrOfLocalVar(&RHSArg),
1375                                     CGF.PointerAlignInBytes),
1376       ArgsType);
1377   // *(Type0*)Dst[0] = *(Type0*)Src[0];
1378   // *(Type1*)Dst[1] = *(Type1*)Src[1];
1379   // ...
1380   // *(Typen*)Dst[n] = *(Typen*)Src[n];
1381   for (unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
1382     auto *DestAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1383         CGF.Builder.CreateAlignedLoad(
1384             CGF.Builder.CreateStructGEP(nullptr, LHS, I),
1385             CGM.PointerAlignInBytes),
1386         CGF.ConvertTypeForMem(C.getPointerType(SrcExprs[I]->getType())));
1387     auto *SrcAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1388         CGF.Builder.CreateAlignedLoad(
1389             CGF.Builder.CreateStructGEP(nullptr, RHS, I),
1390             CGM.PointerAlignInBytes),
1391         CGF.ConvertTypeForMem(C.getPointerType(SrcExprs[I]->getType())));
1392     auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
1393     QualType Type = VD->getType();
1394     CGF.EmitOMPCopy(CGF, Type, DestAddr, SrcAddr,
1395                     cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl()),
1396                     cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl()),
1397                     AssignmentOps[I]);
1398   }
1399   CGF.FinishFunction();
1400   return Fn;
1401 }
1402 
1403 void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
1404                                        const RegionCodeGenTy &SingleOpGen,
1405                                        SourceLocation Loc,
1406                                        ArrayRef<const Expr *> CopyprivateVars,
1407                                        ArrayRef<const Expr *> SrcExprs,
1408                                        ArrayRef<const Expr *> DstExprs,
1409                                        ArrayRef<const Expr *> AssignmentOps) {
1410   assert(CopyprivateVars.size() == SrcExprs.size() &&
1411          CopyprivateVars.size() == DstExprs.size() &&
1412          CopyprivateVars.size() == AssignmentOps.size());
1413   auto &C = CGM.getContext();
1414   // int32 did_it = 0;
1415   // if(__kmpc_single(ident_t *, gtid)) {
1416   //   SingleOpGen();
1417   //   __kmpc_end_single(ident_t *, gtid);
1418   //   did_it = 1;
1419   // }
1420   // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
1421   // <copy_func>, did_it);
1422 
1423   llvm::AllocaInst *DidIt = nullptr;
1424   if (!CopyprivateVars.empty()) {
1425     // int32 did_it = 0;
1426     auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
1427     DidIt = CGF.CreateMemTemp(KmpInt32Ty, ".omp.copyprivate.did_it");
1428     CGF.Builder.CreateAlignedStore(CGF.Builder.getInt32(0), DidIt,
1429                                    DidIt->getAlignment());
1430   }
1431   // Prepare arguments and build a call to __kmpc_single
1432   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
1433   auto *IsSingle =
1434       CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_single), Args);
1435   typedef CallEndCleanup<std::extent<decltype(Args)>::value>
1436       SingleCallEndCleanup;
1437   emitIfStmt(CGF, IsSingle, OMPD_single, [&](CodeGenFunction &CGF) -> void {
1438     CodeGenFunction::RunCleanupsScope Scope(CGF);
1439     CGF.EHStack.pushCleanup<SingleCallEndCleanup>(
1440         NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_single),
1441         llvm::makeArrayRef(Args));
1442     SingleOpGen(CGF);
1443     if (DidIt) {
1444       // did_it = 1;
1445       CGF.Builder.CreateAlignedStore(CGF.Builder.getInt32(1), DidIt,
1446                                      DidIt->getAlignment());
1447     }
1448   });
1449   // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
1450   // <copy_func>, did_it);
1451   if (DidIt) {
1452     llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size());
1453     auto CopyprivateArrayTy =
1454         C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
1455                                /*IndexTypeQuals=*/0);
1456     // Create a list of all private variables for copyprivate.
1457     auto *CopyprivateList =
1458         CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list");
1459     for (unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
1460       auto *Elem = CGF.Builder.CreateStructGEP(
1461           CopyprivateList->getAllocatedType(), CopyprivateList, I);
1462       CGF.Builder.CreateAlignedStore(
1463           CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1464               CGF.EmitLValue(CopyprivateVars[I]).getAddress(), CGF.VoidPtrTy),
1465           Elem, CGM.PointerAlignInBytes);
1466     }
1467     // Build function that copies private values from single region to all other
1468     // threads in the corresponding parallel region.
1469     auto *CpyFn = emitCopyprivateCopyFunction(
1470         CGM, CGF.ConvertTypeForMem(CopyprivateArrayTy)->getPointerTo(),
1471         CopyprivateVars, SrcExprs, DstExprs, AssignmentOps);
1472     auto *BufSize = llvm::ConstantInt::get(
1473         CGM.SizeTy, C.getTypeSizeInChars(CopyprivateArrayTy).getQuantity());
1474     auto *CL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList,
1475                                                                CGF.VoidPtrTy);
1476     auto *DidItVal =
1477         CGF.Builder.CreateAlignedLoad(DidIt, CGF.PointerAlignInBytes);
1478     llvm::Value *Args[] = {
1479         emitUpdateLocation(CGF, Loc), // ident_t *<loc>
1480         getThreadID(CGF, Loc),        // i32 <gtid>
1481         BufSize,                      // size_t <buf_size>
1482         CL,                           // void *<copyprivate list>
1483         CpyFn,                        // void (*) (void *, void *) <copy_func>
1484         DidItVal                      // i32 did_it
1485     };
1486     CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_copyprivate), Args);
1487   }
1488 }
1489 
1490 void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF,
1491                                         const RegionCodeGenTy &OrderedOpGen,
1492                                         SourceLocation Loc) {
1493   // __kmpc_ordered(ident_t *, gtid);
1494   // OrderedOpGen();
1495   // __kmpc_end_ordered(ident_t *, gtid);
1496   // Prepare arguments and build a call to __kmpc_ordered
1497   {
1498     CodeGenFunction::RunCleanupsScope Scope(CGF);
1499     llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
1500     CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_ordered), Args);
1501     // Build a call to __kmpc_end_ordered
1502     CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
1503         NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_ordered),
1504         llvm::makeArrayRef(Args));
1505     emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
1506   }
1507 }
1508 
1509 void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
1510                                       OpenMPDirectiveKind Kind,
1511                                       bool CheckForCancel) {
1512   // Build call __kmpc_cancel_barrier(loc, thread_id);
1513   // Build call __kmpc_barrier(loc, thread_id);
1514   OpenMPLocationFlags Flags = OMP_IDENT_KMPC;
1515   if (Kind == OMPD_for) {
1516     Flags =
1517         static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_IMPL_FOR);
1518   } else if (Kind == OMPD_sections) {
1519     Flags = static_cast<OpenMPLocationFlags>(Flags |
1520                                              OMP_IDENT_BARRIER_IMPL_SECTIONS);
1521   } else if (Kind == OMPD_single) {
1522     Flags =
1523         static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_IMPL_SINGLE);
1524   } else if (Kind == OMPD_barrier) {
1525     Flags = static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_EXPL);
1526   } else {
1527     Flags = static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_IMPL);
1528   }
1529   // Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
1530   // thread_id);
1531   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
1532                          getThreadID(CGF, Loc)};
1533   if (auto *OMPRegionInfo =
1534           dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
1535     auto CancelDestination =
1536         CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
1537     if (CancelDestination.isValid()) {
1538       auto *Result = CGF.EmitRuntimeCall(
1539           createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
1540       if (CheckForCancel) {
1541         // if (__kmpc_cancel_barrier()) {
1542         //   exit from construct;
1543         // }
1544         auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
1545         auto *ContBB = CGF.createBasicBlock(".cancel.continue");
1546         auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
1547         CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
1548         CGF.EmitBlock(ExitBB);
1549         //   exit from construct;
1550         CGF.EmitBranchThroughCleanup(CancelDestination);
1551         CGF.EmitBlock(ContBB, /*IsFinished=*/true);
1552       }
1553       return;
1554     }
1555   }
1556   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_barrier), Args);
1557 }
1558 
1559 /// \brief Schedule types for 'omp for' loops (these enumerators are taken from
1560 /// the enum sched_type in kmp.h).
1561 enum OpenMPSchedType {
1562   /// \brief Lower bound for default (unordered) versions.
1563   OMP_sch_lower = 32,
1564   OMP_sch_static_chunked = 33,
1565   OMP_sch_static = 34,
1566   OMP_sch_dynamic_chunked = 35,
1567   OMP_sch_guided_chunked = 36,
1568   OMP_sch_runtime = 37,
1569   OMP_sch_auto = 38,
1570   /// \brief Lower bound for 'ordered' versions.
1571   OMP_ord_lower = 64,
1572   OMP_ord_static_chunked = 65,
1573   OMP_ord_static = 66,
1574   OMP_ord_dynamic_chunked = 67,
1575   OMP_ord_guided_chunked = 68,
1576   OMP_ord_runtime = 69,
1577   OMP_ord_auto = 70,
1578   OMP_sch_default = OMP_sch_static,
1579 };
1580 
1581 /// \brief Map the OpenMP loop schedule to the runtime enumeration.
1582 static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
1583                                           bool Chunked, bool Ordered) {
1584   switch (ScheduleKind) {
1585   case OMPC_SCHEDULE_static:
1586     return Chunked ? (Ordered ? OMP_ord_static_chunked : OMP_sch_static_chunked)
1587                    : (Ordered ? OMP_ord_static : OMP_sch_static);
1588   case OMPC_SCHEDULE_dynamic:
1589     return Ordered ? OMP_ord_dynamic_chunked : OMP_sch_dynamic_chunked;
1590   case OMPC_SCHEDULE_guided:
1591     return Ordered ? OMP_ord_guided_chunked : OMP_sch_guided_chunked;
1592   case OMPC_SCHEDULE_runtime:
1593     return Ordered ? OMP_ord_runtime : OMP_sch_runtime;
1594   case OMPC_SCHEDULE_auto:
1595     return Ordered ? OMP_ord_auto : OMP_sch_auto;
1596   case OMPC_SCHEDULE_unknown:
1597     assert(!Chunked && "chunk was specified but schedule kind not known");
1598     return Ordered ? OMP_ord_static : OMP_sch_static;
1599   }
1600   llvm_unreachable("Unexpected runtime schedule");
1601 }
1602 
1603 bool CGOpenMPRuntime::isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
1604                                          bool Chunked) const {
1605   auto Schedule = getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
1606   return Schedule == OMP_sch_static;
1607 }
1608 
1609 bool CGOpenMPRuntime::isDynamic(OpenMPScheduleClauseKind ScheduleKind) const {
1610   auto Schedule =
1611       getRuntimeSchedule(ScheduleKind, /*Chunked=*/false, /*Ordered=*/false);
1612   assert(Schedule != OMP_sch_static_chunked && "cannot be chunked here");
1613   return Schedule != OMP_sch_static;
1614 }
1615 
1616 void CGOpenMPRuntime::emitForInit(CodeGenFunction &CGF, SourceLocation Loc,
1617                                   OpenMPScheduleClauseKind ScheduleKind,
1618                                   unsigned IVSize, bool IVSigned, bool Ordered,
1619                                   llvm::Value *IL, llvm::Value *LB,
1620                                   llvm::Value *UB, llvm::Value *ST,
1621                                   llvm::Value *Chunk) {
1622   OpenMPSchedType Schedule =
1623       getRuntimeSchedule(ScheduleKind, Chunk != nullptr, Ordered);
1624   if (Ordered ||
1625       (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked &&
1626        Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked)) {
1627     // Call __kmpc_dispatch_init(
1628     //          ident_t *loc, kmp_int32 tid, kmp_int32 schedule,
1629     //          kmp_int[32|64] lower, kmp_int[32|64] upper,
1630     //          kmp_int[32|64] stride, kmp_int[32|64] chunk);
1631 
1632     // If the Chunk was not specified in the clause - use default value 1.
1633     if (Chunk == nullptr)
1634       Chunk = CGF.Builder.getIntN(IVSize, 1);
1635     llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC),
1636                             getThreadID(CGF, Loc),
1637                             CGF.Builder.getInt32(Schedule), // Schedule type
1638                             CGF.Builder.getIntN(IVSize, 0), // Lower
1639                             UB,                             // Upper
1640                             CGF.Builder.getIntN(IVSize, 1), // Stride
1641                             Chunk                           // Chunk
1642     };
1643     CGF.EmitRuntimeCall(createDispatchInitFunction(IVSize, IVSigned), Args);
1644   } else {
1645     // Call __kmpc_for_static_init(
1646     //          ident_t *loc, kmp_int32 tid, kmp_int32 schedtype,
1647     //          kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower,
1648     //          kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride,
1649     //          kmp_int[32|64] incr, kmp_int[32|64] chunk);
1650     if (Chunk == nullptr) {
1651       assert((Schedule == OMP_sch_static || Schedule == OMP_ord_static) &&
1652              "expected static non-chunked schedule");
1653       // If the Chunk was not specified in the clause - use default value 1.
1654       Chunk = CGF.Builder.getIntN(IVSize, 1);
1655     } else
1656       assert((Schedule == OMP_sch_static_chunked ||
1657               Schedule == OMP_ord_static_chunked) &&
1658              "expected static chunked schedule");
1659     llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC),
1660                             getThreadID(CGF, Loc),
1661                             CGF.Builder.getInt32(Schedule), // Schedule type
1662                             IL,                             // &isLastIter
1663                             LB,                             // &LB
1664                             UB,                             // &UB
1665                             ST,                             // &Stride
1666                             CGF.Builder.getIntN(IVSize, 1), // Incr
1667                             Chunk                           // Chunk
1668     };
1669     CGF.EmitRuntimeCall(createForStaticInitFunction(IVSize, IVSigned), Args);
1670   }
1671 }
1672 
1673 void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF,
1674                                           SourceLocation Loc) {
1675   // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid);
1676   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC),
1677                          getThreadID(CGF, Loc)};
1678   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini),
1679                       Args);
1680 }
1681 
1682 void CGOpenMPRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
1683                                                  SourceLocation Loc,
1684                                                  unsigned IVSize,
1685                                                  bool IVSigned) {
1686   // Call __kmpc_for_dynamic_fini_(4|8)[u](ident_t *loc, kmp_int32 tid);
1687   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC),
1688                          getThreadID(CGF, Loc)};
1689   CGF.EmitRuntimeCall(createDispatchFiniFunction(IVSize, IVSigned), Args);
1690 }
1691 
1692 llvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF,
1693                                           SourceLocation Loc, unsigned IVSize,
1694                                           bool IVSigned, llvm::Value *IL,
1695                                           llvm::Value *LB, llvm::Value *UB,
1696                                           llvm::Value *ST) {
1697   // Call __kmpc_dispatch_next(
1698   //          ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
1699   //          kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
1700   //          kmp_int[32|64] *p_stride);
1701   llvm::Value *Args[] = {
1702       emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC), getThreadID(CGF, Loc),
1703       IL, // &isLastIter
1704       LB, // &Lower
1705       UB, // &Upper
1706       ST  // &Stride
1707   };
1708   llvm::Value *Call =
1709       CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args);
1710   return CGF.EmitScalarConversion(
1711       Call, CGF.getContext().getIntTypeForBitwidth(32, /* Signed */ true),
1712       CGF.getContext().BoolTy);
1713 }
1714 
1715 void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
1716                                            llvm::Value *NumThreads,
1717                                            SourceLocation Loc) {
1718   // Build call __kmpc_push_num_threads(&loc, global_tid, num_threads)
1719   llvm::Value *Args[] = {
1720       emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
1721       CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)};
1722   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_threads),
1723                       Args);
1724 }
1725 
1726 void CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF,
1727                                          OpenMPProcBindClauseKind ProcBind,
1728                                          SourceLocation Loc) {
1729   // Constants for proc bind value accepted by the runtime.
1730   enum ProcBindTy {
1731     ProcBindFalse = 0,
1732     ProcBindTrue,
1733     ProcBindMaster,
1734     ProcBindClose,
1735     ProcBindSpread,
1736     ProcBindIntel,
1737     ProcBindDefault
1738   } RuntimeProcBind;
1739   switch (ProcBind) {
1740   case OMPC_PROC_BIND_master:
1741     RuntimeProcBind = ProcBindMaster;
1742     break;
1743   case OMPC_PROC_BIND_close:
1744     RuntimeProcBind = ProcBindClose;
1745     break;
1746   case OMPC_PROC_BIND_spread:
1747     RuntimeProcBind = ProcBindSpread;
1748     break;
1749   case OMPC_PROC_BIND_unknown:
1750     llvm_unreachable("Unsupported proc_bind value.");
1751   }
1752   // Build call __kmpc_push_proc_bind(&loc, global_tid, proc_bind)
1753   llvm::Value *Args[] = {
1754       emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
1755       llvm::ConstantInt::get(CGM.IntTy, RuntimeProcBind, /*isSigned=*/true)};
1756   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_proc_bind), Args);
1757 }
1758 
1759 void CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>,
1760                                 SourceLocation Loc) {
1761   // Build call void __kmpc_flush(ident_t *loc)
1762   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_flush),
1763                       emitUpdateLocation(CGF, Loc));
1764 }
1765 
1766 namespace {
1767 /// \brief Indexes of fields for type kmp_task_t.
1768 enum KmpTaskTFields {
1769   /// \brief List of shared variables.
1770   KmpTaskTShareds,
1771   /// \brief Task routine.
1772   KmpTaskTRoutine,
1773   /// \brief Partition id for the untied tasks.
1774   KmpTaskTPartId,
1775   /// \brief Function with call of destructors for private variables.
1776   KmpTaskTDestructors,
1777 };
1778 } // namespace
1779 
1780 void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) {
1781   if (!KmpRoutineEntryPtrTy) {
1782     // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type.
1783     auto &C = CGM.getContext();
1784     QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
1785     FunctionProtoType::ExtProtoInfo EPI;
1786     KmpRoutineEntryPtrQTy = C.getPointerType(
1787         C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
1788     KmpRoutineEntryPtrTy = CGM.getTypes().ConvertType(KmpRoutineEntryPtrQTy);
1789   }
1790 }
1791 
1792 static void addFieldToRecordDecl(ASTContext &C, DeclContext *DC,
1793                                  QualType FieldTy) {
1794   auto *Field = FieldDecl::Create(
1795       C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy,
1796       C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()),
1797       /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
1798   Field->setAccess(AS_public);
1799   DC->addDecl(Field);
1800 }
1801 
1802 namespace {
1803 struct PrivateHelpersTy {
1804   PrivateHelpersTy(const VarDecl *Original, const VarDecl *PrivateCopy,
1805                    const VarDecl *PrivateElemInit)
1806       : Original(Original), PrivateCopy(PrivateCopy),
1807         PrivateElemInit(PrivateElemInit) {}
1808   const VarDecl *Original;
1809   const VarDecl *PrivateCopy;
1810   const VarDecl *PrivateElemInit;
1811 };
1812 typedef std::pair<CharUnits /*Align*/, PrivateHelpersTy> PrivateDataTy;
1813 } // namespace
1814 
1815 static RecordDecl *
1816 createPrivatesRecordDecl(CodeGenModule &CGM,
1817                          const ArrayRef<PrivateDataTy> Privates) {
1818   if (!Privates.empty()) {
1819     auto &C = CGM.getContext();
1820     // Build struct .kmp_privates_t. {
1821     //         /*  private vars  */
1822     //       };
1823     auto *RD = C.buildImplicitRecord(".kmp_privates.t");
1824     RD->startDefinition();
1825     for (auto &&Pair : Privates) {
1826       auto Type = Pair.second.Original->getType();
1827       Type = Type.getNonReferenceType();
1828       addFieldToRecordDecl(C, RD, Type);
1829     }
1830     RD->completeDefinition();
1831     return RD;
1832   }
1833   return nullptr;
1834 }
1835 
1836 static RecordDecl *
1837 createKmpTaskTRecordDecl(CodeGenModule &CGM, QualType KmpInt32Ty,
1838                          QualType KmpRoutineEntryPointerQTy) {
1839   auto &C = CGM.getContext();
1840   // Build struct kmp_task_t {
1841   //         void *              shareds;
1842   //         kmp_routine_entry_t routine;
1843   //         kmp_int32           part_id;
1844   //         kmp_routine_entry_t destructors;
1845   //       };
1846   auto *RD = C.buildImplicitRecord("kmp_task_t");
1847   RD->startDefinition();
1848   addFieldToRecordDecl(C, RD, C.VoidPtrTy);
1849   addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
1850   addFieldToRecordDecl(C, RD, KmpInt32Ty);
1851   addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
1852   RD->completeDefinition();
1853   return RD;
1854 }
1855 
1856 static RecordDecl *
1857 createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
1858                                      const ArrayRef<PrivateDataTy> Privates) {
1859   auto &C = CGM.getContext();
1860   // Build struct kmp_task_t_with_privates {
1861   //         kmp_task_t task_data;
1862   //         .kmp_privates_t. privates;
1863   //       };
1864   auto *RD = C.buildImplicitRecord("kmp_task_t_with_privates");
1865   RD->startDefinition();
1866   addFieldToRecordDecl(C, RD, KmpTaskTQTy);
1867   if (auto *PrivateRD = createPrivatesRecordDecl(CGM, Privates)) {
1868     addFieldToRecordDecl(C, RD, C.getRecordType(PrivateRD));
1869   }
1870   RD->completeDefinition();
1871   return RD;
1872 }
1873 
1874 /// \brief Emit a proxy function which accepts kmp_task_t as the second
1875 /// argument.
1876 /// \code
1877 /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
1878 ///   TaskFunction(gtid, tt->part_id, &tt->privates, task_privates_map,
1879 ///   tt->shareds);
1880 ///   return 0;
1881 /// }
1882 /// \endcode
1883 static llvm::Value *
1884 emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
1885                       QualType KmpInt32Ty, QualType KmpTaskTWithPrivatesPtrQTy,
1886                       QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy,
1887                       QualType SharedsPtrTy, llvm::Value *TaskFunction,
1888                       llvm::Value *TaskPrivatesMap) {
1889   auto &C = CGM.getContext();
1890   FunctionArgList Args;
1891   ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty);
1892   ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc,
1893                                 /*Id=*/nullptr, KmpTaskTWithPrivatesPtrQTy);
1894   Args.push_back(&GtidArg);
1895   Args.push_back(&TaskTypeArg);
1896   FunctionType::ExtInfo Info;
1897   auto &TaskEntryFnInfo =
1898       CGM.getTypes().arrangeFreeFunctionDeclaration(KmpInt32Ty, Args, Info,
1899                                                     /*isVariadic=*/false);
1900   auto *TaskEntryTy = CGM.getTypes().GetFunctionType(TaskEntryFnInfo);
1901   auto *TaskEntry =
1902       llvm::Function::Create(TaskEntryTy, llvm::GlobalValue::InternalLinkage,
1903                              ".omp_task_entry.", &CGM.getModule());
1904   CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, TaskEntryFnInfo, TaskEntry);
1905   CodeGenFunction CGF(CGM);
1906   CGF.disableDebugInfo();
1907   CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args);
1908 
1909   // TaskFunction(gtid, tt->task_data.part_id, &tt->privates, task_privates_map,
1910   // tt->task_data.shareds);
1911   auto *GtidParam = CGF.EmitLoadOfScalar(
1912       CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false,
1913       C.getTypeAlignInChars(KmpInt32Ty).getQuantity(), KmpInt32Ty, Loc);
1914   auto *TaskTypeArgAddr = CGF.Builder.CreateAlignedLoad(
1915       CGF.GetAddrOfLocalVar(&TaskTypeArg), CGM.PointerAlignInBytes);
1916   LValue TDBase =
1917       CGF.MakeNaturalAlignAddrLValue(TaskTypeArgAddr, KmpTaskTWithPrivatesQTy);
1918   auto *KmpTaskTWithPrivatesQTyRD =
1919       cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
1920   LValue Base =
1921       CGF.EmitLValueForField(TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
1922   auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
1923   auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
1924   auto PartIdLVal = CGF.EmitLValueForField(Base, *PartIdFI);
1925   auto *PartidParam = CGF.EmitLoadOfLValue(PartIdLVal, Loc).getScalarVal();
1926 
1927   auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
1928   auto SharedsLVal = CGF.EmitLValueForField(Base, *SharedsFI);
1929   auto *SharedsParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1930       CGF.EmitLoadOfLValue(SharedsLVal, Loc).getScalarVal(),
1931       CGF.ConvertTypeForMem(SharedsPtrTy));
1932 
1933   auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
1934   llvm::Value *PrivatesParam;
1935   if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
1936     auto PrivatesLVal = CGF.EmitLValueForField(TDBase, *PrivatesFI);
1937     PrivatesParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1938         PrivatesLVal.getAddress(), CGF.VoidPtrTy);
1939   } else {
1940     PrivatesParam = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
1941   }
1942 
1943   llvm::Value *CallArgs[] = {GtidParam, PartidParam, PrivatesParam,
1944                              TaskPrivatesMap, SharedsParam};
1945   CGF.EmitCallOrInvoke(TaskFunction, CallArgs);
1946   CGF.EmitStoreThroughLValue(
1947       RValue::get(CGF.Builder.getInt32(/*C=*/0)),
1948       CGF.MakeNaturalAlignAddrLValue(CGF.ReturnValue, KmpInt32Ty));
1949   CGF.FinishFunction();
1950   return TaskEntry;
1951 }
1952 
1953 static llvm::Value *emitDestructorsFunction(CodeGenModule &CGM,
1954                                             SourceLocation Loc,
1955                                             QualType KmpInt32Ty,
1956                                             QualType KmpTaskTWithPrivatesPtrQTy,
1957                                             QualType KmpTaskTWithPrivatesQTy) {
1958   auto &C = CGM.getContext();
1959   FunctionArgList Args;
1960   ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty);
1961   ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc,
1962                                 /*Id=*/nullptr, KmpTaskTWithPrivatesPtrQTy);
1963   Args.push_back(&GtidArg);
1964   Args.push_back(&TaskTypeArg);
1965   FunctionType::ExtInfo Info;
1966   auto &DestructorFnInfo =
1967       CGM.getTypes().arrangeFreeFunctionDeclaration(KmpInt32Ty, Args, Info,
1968                                                     /*isVariadic=*/false);
1969   auto *DestructorFnTy = CGM.getTypes().GetFunctionType(DestructorFnInfo);
1970   auto *DestructorFn =
1971       llvm::Function::Create(DestructorFnTy, llvm::GlobalValue::InternalLinkage,
1972                              ".omp_task_destructor.", &CGM.getModule());
1973   CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, DestructorFnInfo, DestructorFn);
1974   CodeGenFunction CGF(CGM);
1975   CGF.disableDebugInfo();
1976   CGF.StartFunction(GlobalDecl(), KmpInt32Ty, DestructorFn, DestructorFnInfo,
1977                     Args);
1978 
1979   auto *TaskTypeArgAddr = CGF.Builder.CreateAlignedLoad(
1980       CGF.GetAddrOfLocalVar(&TaskTypeArg), CGM.PointerAlignInBytes);
1981   LValue Base =
1982       CGF.MakeNaturalAlignAddrLValue(TaskTypeArgAddr, KmpTaskTWithPrivatesQTy);
1983   auto *KmpTaskTWithPrivatesQTyRD =
1984       cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
1985   auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
1986   Base = CGF.EmitLValueForField(Base, *FI);
1987   for (auto *Field :
1988        cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
1989     if (auto DtorKind = Field->getType().isDestructedType()) {
1990       auto FieldLValue = CGF.EmitLValueForField(Base, Field);
1991       CGF.pushDestroy(DtorKind, FieldLValue.getAddress(), Field->getType());
1992     }
1993   }
1994   CGF.FinishFunction();
1995   return DestructorFn;
1996 }
1997 
1998 /// \brief Emit a privates mapping function for correct handling of private and
1999 /// firstprivate variables.
2000 /// \code
2001 /// void .omp_task_privates_map.(const .privates. *noalias privs, <ty1>
2002 /// **noalias priv1,...,  <tyn> **noalias privn) {
2003 ///   *priv1 = &.privates.priv1;
2004 ///   ...;
2005 ///   *privn = &.privates.privn;
2006 /// }
2007 /// \endcode
2008 static llvm::Value *
2009 emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc,
2010                                const ArrayRef<const Expr *> PrivateVars,
2011                                const ArrayRef<const Expr *> FirstprivateVars,
2012                                QualType PrivatesQTy,
2013                                const ArrayRef<PrivateDataTy> Privates) {
2014   auto &C = CGM.getContext();
2015   FunctionArgList Args;
2016   ImplicitParamDecl TaskPrivatesArg(
2017       C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
2018       C.getPointerType(PrivatesQTy).withConst().withRestrict());
2019   Args.push_back(&TaskPrivatesArg);
2020   llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
2021   unsigned Counter = 1;
2022   for (auto *E: PrivateVars) {
2023     Args.push_back(ImplicitParamDecl::Create(
2024         C, /*DC=*/nullptr, Loc,
2025         /*Id=*/nullptr, C.getPointerType(C.getPointerType(E->getType()))
2026                             .withConst()
2027                             .withRestrict()));
2028     auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2029     PrivateVarsPos[VD] = Counter;
2030     ++Counter;
2031   }
2032   for (auto *E : FirstprivateVars) {
2033     Args.push_back(ImplicitParamDecl::Create(
2034         C, /*DC=*/nullptr, Loc,
2035         /*Id=*/nullptr, C.getPointerType(C.getPointerType(E->getType()))
2036                             .withConst()
2037                             .withRestrict()));
2038     auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2039     PrivateVarsPos[VD] = Counter;
2040     ++Counter;
2041   }
2042   FunctionType::ExtInfo Info;
2043   auto &TaskPrivatesMapFnInfo =
2044       CGM.getTypes().arrangeFreeFunctionDeclaration(C.VoidTy, Args, Info,
2045                                                     /*isVariadic=*/false);
2046   auto *TaskPrivatesMapTy =
2047       CGM.getTypes().GetFunctionType(TaskPrivatesMapFnInfo);
2048   auto *TaskPrivatesMap = llvm::Function::Create(
2049       TaskPrivatesMapTy, llvm::GlobalValue::InternalLinkage,
2050       ".omp_task_privates_map.", &CGM.getModule());
2051   CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, TaskPrivatesMapFnInfo,
2052                                 TaskPrivatesMap);
2053   TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
2054   CodeGenFunction CGF(CGM);
2055   CGF.disableDebugInfo();
2056   CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskPrivatesMap,
2057                     TaskPrivatesMapFnInfo, Args);
2058 
2059   // *privi = &.privates.privi;
2060   auto *TaskPrivatesArgAddr = CGF.Builder.CreateAlignedLoad(
2061       CGF.GetAddrOfLocalVar(&TaskPrivatesArg), CGM.PointerAlignInBytes);
2062   LValue Base =
2063       CGF.MakeNaturalAlignAddrLValue(TaskPrivatesArgAddr, PrivatesQTy);
2064   auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->getAsTagDecl());
2065   Counter = 0;
2066   for (auto *Field : PrivatesQTyRD->fields()) {
2067     auto FieldLVal = CGF.EmitLValueForField(Base, Field);
2068     auto *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
2069     auto RefLVal = CGF.MakeNaturalAlignAddrLValue(CGF.GetAddrOfLocalVar(VD),
2070                                                   VD->getType());
2071     auto RefLoadRVal = CGF.EmitLoadOfLValue(RefLVal, Loc);
2072     CGF.EmitStoreOfScalar(
2073         FieldLVal.getAddress(),
2074         CGF.MakeNaturalAlignAddrLValue(RefLoadRVal.getScalarVal(),
2075                                        RefLVal.getType()->getPointeeType()));
2076     ++Counter;
2077   }
2078   CGF.FinishFunction();
2079   return TaskPrivatesMap;
2080 }
2081 
2082 static int array_pod_sort_comparator(const PrivateDataTy *P1,
2083                                      const PrivateDataTy *P2) {
2084   return P1->first < P2->first ? 1 : (P2->first < P1->first ? -1 : 0);
2085 }
2086 
2087 void CGOpenMPRuntime::emitTaskCall(
2088     CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D,
2089     bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
2090     llvm::Value *TaskFunction, QualType SharedsTy, llvm::Value *Shareds,
2091     const Expr *IfCond, ArrayRef<const Expr *> PrivateVars,
2092     ArrayRef<const Expr *> PrivateCopies,
2093     ArrayRef<const Expr *> FirstprivateVars,
2094     ArrayRef<const Expr *> FirstprivateCopies,
2095     ArrayRef<const Expr *> FirstprivateInits,
2096     ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependences) {
2097   auto &C = CGM.getContext();
2098   llvm::SmallVector<PrivateDataTy, 8> Privates;
2099   // Aggregate privates and sort them by the alignment.
2100   auto I = PrivateCopies.begin();
2101   for (auto *E : PrivateVars) {
2102     auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2103     Privates.push_back(std::make_pair(
2104         C.getTypeAlignInChars(VD->getType()),
2105         PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
2106                          /*PrivateElemInit=*/nullptr)));
2107     ++I;
2108   }
2109   I = FirstprivateCopies.begin();
2110   auto IElemInitRef = FirstprivateInits.begin();
2111   for (auto *E : FirstprivateVars) {
2112     auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2113     Privates.push_back(std::make_pair(
2114         C.getTypeAlignInChars(VD->getType()),
2115         PrivateHelpersTy(
2116             VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
2117             cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl()))));
2118     ++I, ++IElemInitRef;
2119   }
2120   llvm::array_pod_sort(Privates.begin(), Privates.end(),
2121                        array_pod_sort_comparator);
2122   auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2123   // Build type kmp_routine_entry_t (if not built yet).
2124   emitKmpRoutineEntryT(KmpInt32Ty);
2125   // Build type kmp_task_t (if not built yet).
2126   if (KmpTaskTQTy.isNull()) {
2127     KmpTaskTQTy = C.getRecordType(
2128         createKmpTaskTRecordDecl(CGM, KmpInt32Ty, KmpRoutineEntryPtrQTy));
2129   }
2130   auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
2131   // Build particular struct kmp_task_t for the given task.
2132   auto *KmpTaskTWithPrivatesQTyRD =
2133       createKmpTaskTWithPrivatesRecordDecl(CGM, KmpTaskTQTy, Privates);
2134   auto KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
2135   QualType KmpTaskTWithPrivatesPtrQTy =
2136       C.getPointerType(KmpTaskTWithPrivatesQTy);
2137   auto *KmpTaskTWithPrivatesTy = CGF.ConvertType(KmpTaskTWithPrivatesQTy);
2138   auto *KmpTaskTWithPrivatesPtrTy = KmpTaskTWithPrivatesTy->getPointerTo();
2139   auto KmpTaskTWithPrivatesTySize =
2140       CGM.getSize(C.getTypeSizeInChars(KmpTaskTWithPrivatesQTy));
2141   QualType SharedsPtrTy = C.getPointerType(SharedsTy);
2142 
2143   // Emit initial values for private copies (if any).
2144   llvm::Value *TaskPrivatesMap = nullptr;
2145   auto *TaskPrivatesMapTy =
2146       std::next(cast<llvm::Function>(TaskFunction)->getArgumentList().begin(),
2147                 3)
2148           ->getType();
2149   if (!Privates.empty()) {
2150     auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
2151     TaskPrivatesMap = emitTaskPrivateMappingFunction(
2152         CGM, Loc, PrivateVars, FirstprivateVars, FI->getType(), Privates);
2153     TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2154         TaskPrivatesMap, TaskPrivatesMapTy);
2155   } else {
2156     TaskPrivatesMap = llvm::ConstantPointerNull::get(
2157         cast<llvm::PointerType>(TaskPrivatesMapTy));
2158   }
2159   // Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid,
2160   // kmp_task_t *tt);
2161   auto *TaskEntry = emitProxyTaskFunction(
2162       CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTy,
2163       KmpTaskTQTy, SharedsPtrTy, TaskFunction, TaskPrivatesMap);
2164 
2165   // Build call kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
2166   // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
2167   // kmp_routine_entry_t *task_entry);
2168   // Task flags. Format is taken from
2169   // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h,
2170   // description of kmp_tasking_flags struct.
2171   const unsigned TiedFlag = 0x1;
2172   const unsigned FinalFlag = 0x2;
2173   unsigned Flags = Tied ? TiedFlag : 0;
2174   auto *TaskFlags =
2175       Final.getPointer()
2176           ? CGF.Builder.CreateSelect(Final.getPointer(),
2177                                      CGF.Builder.getInt32(FinalFlag),
2178                                      CGF.Builder.getInt32(/*C=*/0))
2179           : CGF.Builder.getInt32(Final.getInt() ? FinalFlag : 0);
2180   TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
2181   auto SharedsSize = C.getTypeSizeInChars(SharedsTy);
2182   llvm::Value *AllocArgs[] = {
2183       emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), TaskFlags,
2184       KmpTaskTWithPrivatesTySize, CGM.getSize(SharedsSize),
2185       CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TaskEntry,
2186                                                       KmpRoutineEntryPtrTy)};
2187   auto *NewTask = CGF.EmitRuntimeCall(
2188       createRuntimeFunction(OMPRTL__kmpc_omp_task_alloc), AllocArgs);
2189   auto *NewTaskNewTaskTTy = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2190       NewTask, KmpTaskTWithPrivatesPtrTy);
2191   LValue Base = CGF.MakeNaturalAlignAddrLValue(NewTaskNewTaskTTy,
2192                                                KmpTaskTWithPrivatesQTy);
2193   LValue TDBase =
2194       CGF.EmitLValueForField(Base, *KmpTaskTWithPrivatesQTyRD->field_begin());
2195   // Fill the data in the resulting kmp_task_t record.
2196   // Copy shareds if there are any.
2197   llvm::Value *KmpTaskSharedsPtr = nullptr;
2198   if (!SharedsTy->getAsStructureType()->getDecl()->field_empty()) {
2199     KmpTaskSharedsPtr = CGF.EmitLoadOfScalar(
2200         CGF.EmitLValueForField(
2201             TDBase, *std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds)),
2202         Loc);
2203     CGF.EmitAggregateCopy(KmpTaskSharedsPtr, Shareds, SharedsTy);
2204   }
2205   // Emit initial values for private copies (if any).
2206   bool NeedsCleanup = false;
2207   if (!Privates.empty()) {
2208     auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
2209     auto PrivatesBase = CGF.EmitLValueForField(Base, *FI);
2210     FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
2211     LValue SharedsBase;
2212     if (!FirstprivateVars.empty()) {
2213       SharedsBase = CGF.MakeNaturalAlignAddrLValue(
2214           CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2215               KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)),
2216           SharedsTy);
2217     }
2218     CodeGenFunction::CGCapturedStmtInfo CapturesInfo(
2219         cast<CapturedStmt>(*D.getAssociatedStmt()));
2220     for (auto &&Pair : Privates) {
2221       auto *VD = Pair.second.PrivateCopy;
2222       auto *Init = VD->getAnyInitializer();
2223       LValue PrivateLValue = CGF.EmitLValueForField(PrivatesBase, *FI);
2224       if (Init) {
2225         if (auto *Elem = Pair.second.PrivateElemInit) {
2226           auto *OriginalVD = Pair.second.Original;
2227           auto *SharedField = CapturesInfo.lookup(OriginalVD);
2228           auto SharedRefLValue =
2229               CGF.EmitLValueForField(SharedsBase, SharedField);
2230           QualType Type = OriginalVD->getType();
2231           if (Type->isArrayType()) {
2232             // Initialize firstprivate array.
2233             if (!isa<CXXConstructExpr>(Init) ||
2234                 CGF.isTrivialInitializer(Init)) {
2235               // Perform simple memcpy.
2236               CGF.EmitAggregateAssign(PrivateLValue.getAddress(),
2237                                       SharedRefLValue.getAddress(), Type);
2238             } else {
2239               // Initialize firstprivate array using element-by-element
2240               // intialization.
2241               CGF.EmitOMPAggregateAssign(
2242                   PrivateLValue.getAddress(), SharedRefLValue.getAddress(),
2243                   Type, [&CGF, Elem, Init, &CapturesInfo](
2244                             llvm::Value *DestElement, llvm::Value *SrcElement) {
2245                     // Clean up any temporaries needed by the initialization.
2246                     CodeGenFunction::OMPPrivateScope InitScope(CGF);
2247                     InitScope.addPrivate(Elem, [SrcElement]() -> llvm::Value *{
2248                       return SrcElement;
2249                     });
2250                     (void)InitScope.Privatize();
2251                     // Emit initialization for single element.
2252                     CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(
2253                         CGF, &CapturesInfo);
2254                     CGF.EmitAnyExprToMem(Init, DestElement,
2255                                          Init->getType().getQualifiers(),
2256                                          /*IsInitializer=*/false);
2257                   });
2258             }
2259           } else {
2260             CodeGenFunction::OMPPrivateScope InitScope(CGF);
2261             InitScope.addPrivate(Elem, [SharedRefLValue]() -> llvm::Value *{
2262               return SharedRefLValue.getAddress();
2263             });
2264             (void)InitScope.Privatize();
2265             CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CapturesInfo);
2266             CGF.EmitExprAsInit(Init, VD, PrivateLValue,
2267                                /*capturedByInit=*/false);
2268           }
2269         } else {
2270           CGF.EmitExprAsInit(Init, VD, PrivateLValue, /*capturedByInit=*/false);
2271         }
2272       }
2273       NeedsCleanup = NeedsCleanup || FI->getType().isDestructedType();
2274       ++FI;
2275     }
2276   }
2277   // Provide pointer to function with destructors for privates.
2278   llvm::Value *DestructorFn =
2279       NeedsCleanup ? emitDestructorsFunction(CGM, Loc, KmpInt32Ty,
2280                                              KmpTaskTWithPrivatesPtrQTy,
2281                                              KmpTaskTWithPrivatesQTy)
2282                    : llvm::ConstantPointerNull::get(
2283                          cast<llvm::PointerType>(KmpRoutineEntryPtrTy));
2284   LValue Destructor = CGF.EmitLValueForField(
2285       TDBase, *std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTDestructors));
2286   CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2287                             DestructorFn, KmpRoutineEntryPtrTy),
2288                         Destructor);
2289 
2290   // Process list of dependences.
2291   llvm::Value *DependInfo = nullptr;
2292   unsigned DependencesNumber = Dependences.size();
2293   if (!Dependences.empty()) {
2294     // Dependence kind for RTL.
2295     enum RTLDependenceKindTy { DepIn = 1, DepOut = 2, DepInOut = 3 };
2296     enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
2297     RecordDecl *KmpDependInfoRD;
2298     QualType FlagsTy = C.getIntTypeForBitwidth(
2299         C.toBits(C.getTypeSizeInChars(C.BoolTy)), /*Signed=*/false);
2300     llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
2301     if (KmpDependInfoTy.isNull()) {
2302       KmpDependInfoRD = C.buildImplicitRecord("kmp_depend_info");
2303       KmpDependInfoRD->startDefinition();
2304       addFieldToRecordDecl(C, KmpDependInfoRD, C.getIntPtrType());
2305       addFieldToRecordDecl(C, KmpDependInfoRD, C.getSizeType());
2306       addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
2307       KmpDependInfoRD->completeDefinition();
2308       KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
2309     } else {
2310       KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
2311     }
2312     // Define type kmp_depend_info[<Dependences.size()>];
2313     QualType KmpDependInfoArrayTy = C.getConstantArrayType(
2314         KmpDependInfoTy, llvm::APInt(/*numBits=*/64, Dependences.size()),
2315         ArrayType::Normal, /*IndexTypeQuals=*/0);
2316     // kmp_depend_info[<Dependences.size()>] deps;
2317     DependInfo = CGF.CreateMemTemp(KmpDependInfoArrayTy);
2318     for (unsigned i = 0; i < DependencesNumber; ++i) {
2319       auto Addr = CGF.EmitLValue(Dependences[i].second);
2320       auto *Size = llvm::ConstantInt::get(
2321           CGF.SizeTy,
2322           C.getTypeSizeInChars(Dependences[i].second->getType()).getQuantity());
2323       auto Base = CGF.MakeNaturalAlignAddrLValue(
2324           CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, DependInfo, i),
2325           KmpDependInfoTy);
2326       // deps[i].base_addr = &<Dependences[i].second>;
2327       auto BaseAddrLVal = CGF.EmitLValueForField(
2328           Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
2329       CGF.EmitStoreOfScalar(
2330           CGF.Builder.CreatePtrToInt(Addr.getAddress(), CGF.IntPtrTy),
2331           BaseAddrLVal);
2332       // deps[i].len = sizeof(<Dependences[i].second>);
2333       auto LenLVal = CGF.EmitLValueForField(
2334           Base, *std::next(KmpDependInfoRD->field_begin(), Len));
2335       CGF.EmitStoreOfScalar(Size, LenLVal);
2336       // deps[i].flags = <Dependences[i].first>;
2337       RTLDependenceKindTy DepKind;
2338       switch (Dependences[i].first) {
2339       case OMPC_DEPEND_in:
2340         DepKind = DepIn;
2341         break;
2342       case OMPC_DEPEND_out:
2343         DepKind = DepOut;
2344         break;
2345       case OMPC_DEPEND_inout:
2346         DepKind = DepInOut;
2347         break;
2348       case OMPC_DEPEND_unknown:
2349         llvm_unreachable("Unknown task dependence type");
2350       }
2351       auto FlagsLVal = CGF.EmitLValueForField(
2352           Base, *std::next(KmpDependInfoRD->field_begin(), Flags));
2353       CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
2354                             FlagsLVal);
2355     }
2356     DependInfo = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2357         CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, DependInfo, 0),
2358         CGF.VoidPtrTy);
2359   }
2360 
2361   // NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc()
2362   // libcall.
2363   // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
2364   // *new_task);
2365   // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
2366   // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
2367   // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list) if dependence
2368   // list is not empty
2369   auto *ThreadID = getThreadID(CGF, Loc);
2370   auto *UpLoc = emitUpdateLocation(CGF, Loc);
2371   llvm::Value *TaskArgs[] = {UpLoc, ThreadID, NewTask};
2372   llvm::Value *DepTaskArgs[] = {
2373       UpLoc,
2374       ThreadID,
2375       NewTask,
2376       DependInfo ? CGF.Builder.getInt32(DependencesNumber) : nullptr,
2377       DependInfo,
2378       DependInfo ? CGF.Builder.getInt32(0) : nullptr,
2379       DependInfo ? llvm::ConstantPointerNull::get(CGF.VoidPtrTy) : nullptr};
2380   auto &&ThenCodeGen = [this, DependInfo, &TaskArgs,
2381                         &DepTaskArgs](CodeGenFunction &CGF) {
2382     // TODO: add check for untied tasks.
2383     CGF.EmitRuntimeCall(
2384         createRuntimeFunction(DependInfo ? OMPRTL__kmpc_omp_task_with_deps
2385                                          : OMPRTL__kmpc_omp_task),
2386         DependInfo ? makeArrayRef(DepTaskArgs) : makeArrayRef(TaskArgs));
2387   };
2388   typedef CallEndCleanup<std::extent<decltype(TaskArgs)>::value>
2389       IfCallEndCleanup;
2390   llvm::Value *DepWaitTaskArgs[] = {
2391       UpLoc,
2392       ThreadID,
2393       DependInfo ? CGF.Builder.getInt32(DependencesNumber) : nullptr,
2394       DependInfo,
2395       DependInfo ? CGF.Builder.getInt32(0) : nullptr,
2396       DependInfo ? llvm::ConstantPointerNull::get(CGF.VoidPtrTy) : nullptr};
2397   auto &&ElseCodeGen = [this, &TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
2398                         DependInfo, &DepWaitTaskArgs](CodeGenFunction &CGF) {
2399     CodeGenFunction::RunCleanupsScope LocalScope(CGF);
2400     // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
2401     // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
2402     // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info
2403     // is specified.
2404     if (DependInfo)
2405       CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_wait_deps),
2406                           DepWaitTaskArgs);
2407     // Build void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
2408     // kmp_task_t *new_task);
2409     CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task_begin_if0),
2410                         TaskArgs);
2411     // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
2412     // kmp_task_t *new_task);
2413     CGF.EHStack.pushCleanup<IfCallEndCleanup>(
2414         NormalAndEHCleanup,
2415         createRuntimeFunction(OMPRTL__kmpc_omp_task_complete_if0),
2416         llvm::makeArrayRef(TaskArgs));
2417 
2418     // Call proxy_task_entry(gtid, new_task);
2419     llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
2420     CGF.EmitCallOrInvoke(TaskEntry, OutlinedFnArgs);
2421   };
2422   if (IfCond) {
2423     emitOMPIfClause(CGF, IfCond, ThenCodeGen, ElseCodeGen);
2424   } else {
2425     CodeGenFunction::RunCleanupsScope Scope(CGF);
2426     ThenCodeGen(CGF);
2427   }
2428 }
2429 
2430 static llvm::Value *emitReductionFunction(CodeGenModule &CGM,
2431                                           llvm::Type *ArgsType,
2432                                           ArrayRef<const Expr *> LHSExprs,
2433                                           ArrayRef<const Expr *> RHSExprs,
2434                                           ArrayRef<const Expr *> ReductionOps) {
2435   auto &C = CGM.getContext();
2436 
2437   // void reduction_func(void *LHSArg, void *RHSArg);
2438   FunctionArgList Args;
2439   ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr,
2440                            C.VoidPtrTy);
2441   ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr,
2442                            C.VoidPtrTy);
2443   Args.push_back(&LHSArg);
2444   Args.push_back(&RHSArg);
2445   FunctionType::ExtInfo EI;
2446   auto &CGFI = CGM.getTypes().arrangeFreeFunctionDeclaration(
2447       C.VoidTy, Args, EI, /*isVariadic=*/false);
2448   auto *Fn = llvm::Function::Create(
2449       CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
2450       ".omp.reduction.reduction_func", &CGM.getModule());
2451   CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, CGFI, Fn);
2452   CodeGenFunction CGF(CGM);
2453   CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args);
2454 
2455   // Dst = (void*[n])(LHSArg);
2456   // Src = (void*[n])(RHSArg);
2457   auto *LHS = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2458       CGF.Builder.CreateAlignedLoad(CGF.GetAddrOfLocalVar(&LHSArg),
2459                                     CGF.PointerAlignInBytes),
2460       ArgsType);
2461   auto *RHS = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2462       CGF.Builder.CreateAlignedLoad(CGF.GetAddrOfLocalVar(&RHSArg),
2463                                     CGF.PointerAlignInBytes),
2464       ArgsType);
2465 
2466   //  ...
2467   //  *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
2468   //  ...
2469   CodeGenFunction::OMPPrivateScope Scope(CGF);
2470   for (unsigned I = 0, E = ReductionOps.size(); I < E; ++I) {
2471     Scope.addPrivate(
2472         cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl()),
2473         [&]() -> llvm::Value *{
2474           return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2475               CGF.Builder.CreateAlignedLoad(
2476                   CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, RHS, I),
2477                   CGM.PointerAlignInBytes),
2478               CGF.ConvertTypeForMem(C.getPointerType(RHSExprs[I]->getType())));
2479         });
2480     Scope.addPrivate(
2481         cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl()),
2482         [&]() -> llvm::Value *{
2483           return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2484               CGF.Builder.CreateAlignedLoad(
2485                   CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, LHS, I),
2486                   CGM.PointerAlignInBytes),
2487               CGF.ConvertTypeForMem(C.getPointerType(LHSExprs[I]->getType())));
2488         });
2489   }
2490   Scope.Privatize();
2491   for (auto *E : ReductionOps) {
2492     CGF.EmitIgnoredExpr(E);
2493   }
2494   Scope.ForceCleanup();
2495   CGF.FinishFunction();
2496   return Fn;
2497 }
2498 
2499 void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
2500                                     ArrayRef<const Expr *> LHSExprs,
2501                                     ArrayRef<const Expr *> RHSExprs,
2502                                     ArrayRef<const Expr *> ReductionOps,
2503                                     bool WithNowait, bool SimpleReduction) {
2504   // Next code should be emitted for reduction:
2505   //
2506   // static kmp_critical_name lock = { 0 };
2507   //
2508   // void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
2509   //  *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
2510   //  ...
2511   //  *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
2512   //  *(Type<n>-1*)rhs[<n>-1]);
2513   // }
2514   //
2515   // ...
2516   // void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
2517   // switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
2518   // RedList, reduce_func, &<lock>)) {
2519   // case 1:
2520   //  ...
2521   //  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
2522   //  ...
2523   // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
2524   // break;
2525   // case 2:
2526   //  ...
2527   //  Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
2528   //  ...
2529   // [__kmpc_end_reduce(<loc>, <gtid>, &<lock>);]
2530   // break;
2531   // default:;
2532   // }
2533   //
2534   // if SimpleReduction is true, only the next code is generated:
2535   //  ...
2536   //  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
2537   //  ...
2538 
2539   auto &C = CGM.getContext();
2540 
2541   if (SimpleReduction) {
2542     CodeGenFunction::RunCleanupsScope Scope(CGF);
2543     for (auto *E : ReductionOps) {
2544       CGF.EmitIgnoredExpr(E);
2545     }
2546     return;
2547   }
2548 
2549   // 1. Build a list of reduction variables.
2550   // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
2551   llvm::APInt ArraySize(/*unsigned int numBits=*/32, RHSExprs.size());
2552   QualType ReductionArrayTy =
2553       C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
2554                              /*IndexTypeQuals=*/0);
2555   auto *ReductionList =
2556       CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
2557   for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I) {
2558     auto *Elem = CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, ReductionList, I);
2559     CGF.Builder.CreateAlignedStore(
2560         CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2561             CGF.EmitLValue(RHSExprs[I]).getAddress(), CGF.VoidPtrTy),
2562         Elem, CGM.PointerAlignInBytes);
2563   }
2564 
2565   // 2. Emit reduce_func().
2566   auto *ReductionFn = emitReductionFunction(
2567       CGM, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), LHSExprs,
2568       RHSExprs, ReductionOps);
2569 
2570   // 3. Create static kmp_critical_name lock = { 0 };
2571   auto *Lock = getCriticalRegionLock(".reduction");
2572 
2573   // 4. Build res = __kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
2574   // RedList, reduce_func, &<lock>);
2575   auto *IdentTLoc = emitUpdateLocation(
2576       CGF, Loc,
2577       static_cast<OpenMPLocationFlags>(OMP_IDENT_KMPC | OMP_ATOMIC_REDUCE));
2578   auto *ThreadId = getThreadID(CGF, Loc);
2579   auto *ReductionArrayTySize = llvm::ConstantInt::get(
2580       CGM.SizeTy, C.getTypeSizeInChars(ReductionArrayTy).getQuantity());
2581   auto *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(ReductionList,
2582                                                              CGF.VoidPtrTy);
2583   llvm::Value *Args[] = {
2584       IdentTLoc,                             // ident_t *<loc>
2585       ThreadId,                              // i32 <gtid>
2586       CGF.Builder.getInt32(RHSExprs.size()), // i32 <n>
2587       ReductionArrayTySize,                  // size_type sizeof(RedList)
2588       RL,                                    // void *RedList
2589       ReductionFn, // void (*) (void *, void *) <reduce_func>
2590       Lock         // kmp_critical_name *&<lock>
2591   };
2592   auto Res = CGF.EmitRuntimeCall(
2593       createRuntimeFunction(WithNowait ? OMPRTL__kmpc_reduce_nowait
2594                                        : OMPRTL__kmpc_reduce),
2595       Args);
2596 
2597   // 5. Build switch(res)
2598   auto *DefaultBB = CGF.createBasicBlock(".omp.reduction.default");
2599   auto *SwInst = CGF.Builder.CreateSwitch(Res, DefaultBB, /*NumCases=*/2);
2600 
2601   // 6. Build case 1:
2602   //  ...
2603   //  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
2604   //  ...
2605   // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
2606   // break;
2607   auto *Case1BB = CGF.createBasicBlock(".omp.reduction.case1");
2608   SwInst->addCase(CGF.Builder.getInt32(1), Case1BB);
2609   CGF.EmitBlock(Case1BB);
2610 
2611   {
2612     CodeGenFunction::RunCleanupsScope Scope(CGF);
2613     // Add emission of __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
2614     llvm::Value *EndArgs[] = {
2615         IdentTLoc, // ident_t *<loc>
2616         ThreadId,  // i32 <gtid>
2617         Lock       // kmp_critical_name *&<lock>
2618     };
2619     CGF.EHStack
2620         .pushCleanup<CallEndCleanup<std::extent<decltype(EndArgs)>::value>>(
2621             NormalAndEHCleanup,
2622             createRuntimeFunction(WithNowait ? OMPRTL__kmpc_end_reduce_nowait
2623                                              : OMPRTL__kmpc_end_reduce),
2624             llvm::makeArrayRef(EndArgs));
2625     for (auto *E : ReductionOps) {
2626       CGF.EmitIgnoredExpr(E);
2627     }
2628   }
2629 
2630   CGF.EmitBranch(DefaultBB);
2631 
2632   // 7. Build case 2:
2633   //  ...
2634   //  Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
2635   //  ...
2636   // break;
2637   auto *Case2BB = CGF.createBasicBlock(".omp.reduction.case2");
2638   SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
2639   CGF.EmitBlock(Case2BB);
2640 
2641   {
2642     CodeGenFunction::RunCleanupsScope Scope(CGF);
2643     if (!WithNowait) {
2644       // Add emission of __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
2645       llvm::Value *EndArgs[] = {
2646           IdentTLoc, // ident_t *<loc>
2647           ThreadId,  // i32 <gtid>
2648           Lock       // kmp_critical_name *&<lock>
2649       };
2650       CGF.EHStack
2651           .pushCleanup<CallEndCleanup<std::extent<decltype(EndArgs)>::value>>(
2652               NormalAndEHCleanup,
2653               createRuntimeFunction(OMPRTL__kmpc_end_reduce),
2654               llvm::makeArrayRef(EndArgs));
2655     }
2656     auto I = LHSExprs.begin();
2657     for (auto *E : ReductionOps) {
2658       const Expr *XExpr = nullptr;
2659       const Expr *EExpr = nullptr;
2660       const Expr *UpExpr = nullptr;
2661       BinaryOperatorKind BO = BO_Comma;
2662       if (auto *BO = dyn_cast<BinaryOperator>(E)) {
2663         if (BO->getOpcode() == BO_Assign) {
2664           XExpr = BO->getLHS();
2665           UpExpr = BO->getRHS();
2666         }
2667       }
2668       // Try to emit update expression as a simple atomic.
2669       auto *RHSExpr = UpExpr;
2670       if (RHSExpr) {
2671         // Analyze RHS part of the whole expression.
2672         if (auto *ACO = dyn_cast<AbstractConditionalOperator>(
2673                 RHSExpr->IgnoreParenImpCasts())) {
2674           // If this is a conditional operator, analyze its condition for
2675           // min/max reduction operator.
2676           RHSExpr = ACO->getCond();
2677         }
2678         if (auto *BORHS =
2679                 dyn_cast<BinaryOperator>(RHSExpr->IgnoreParenImpCasts())) {
2680           EExpr = BORHS->getRHS();
2681           BO = BORHS->getOpcode();
2682         }
2683       }
2684       if (XExpr) {
2685         auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
2686         LValue X = CGF.EmitLValue(XExpr);
2687         RValue E;
2688         if (EExpr)
2689           E = CGF.EmitAnyExpr(EExpr);
2690         CGF.EmitOMPAtomicSimpleUpdateExpr(
2691             X, E, BO, /*IsXLHSInRHSPart=*/true, llvm::Monotonic, Loc,
2692             [&CGF, UpExpr, VD](RValue XRValue) {
2693               CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
2694               PrivateScope.addPrivate(
2695                   VD, [&CGF, VD, XRValue]() -> llvm::Value *{
2696                     auto *LHSTemp = CGF.CreateMemTemp(VD->getType());
2697                     CGF.EmitStoreThroughLValue(
2698                         XRValue,
2699                         CGF.MakeNaturalAlignAddrLValue(LHSTemp, VD->getType()));
2700                     return LHSTemp;
2701                   });
2702               (void)PrivateScope.Privatize();
2703               return CGF.EmitAnyExpr(UpExpr);
2704             });
2705       } else {
2706         // Emit as a critical region.
2707         emitCriticalRegion(CGF, ".atomic_reduction", [E](CodeGenFunction &CGF) {
2708           CGF.EmitIgnoredExpr(E);
2709         }, Loc);
2710       }
2711       ++I;
2712     }
2713   }
2714 
2715   CGF.EmitBranch(DefaultBB);
2716   CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
2717 }
2718 
2719 void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
2720                                        SourceLocation Loc) {
2721   // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
2722   // global_tid);
2723   llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
2724   // Ignore return result until untied tasks are supported.
2725   CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskwait), Args);
2726 }
2727 
2728 void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
2729                                            OpenMPDirectiveKind InnerKind,
2730                                            const RegionCodeGenTy &CodeGen) {
2731   InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind);
2732   CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
2733 }
2734 
2735 namespace {
2736 enum RTCancelKind {
2737   CancelNoreq = 0,
2738   CancelParallel = 1,
2739   CancelLoop = 2,
2740   CancelSections = 3,
2741   CancelTaskgroup = 4
2742 };
2743 }
2744 
2745 static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion) {
2746   RTCancelKind CancelKind = CancelNoreq;
2747   if (CancelRegion == OMPD_parallel)
2748     CancelKind = CancelParallel;
2749   else if (CancelRegion == OMPD_for)
2750     CancelKind = CancelLoop;
2751   else if (CancelRegion == OMPD_sections)
2752     CancelKind = CancelSections;
2753   else {
2754     assert(CancelRegion == OMPD_taskgroup);
2755     CancelKind = CancelTaskgroup;
2756   }
2757   return CancelKind;
2758 }
2759 
2760 void CGOpenMPRuntime::emitCancellationPointCall(
2761     CodeGenFunction &CGF, SourceLocation Loc,
2762     OpenMPDirectiveKind CancelRegion) {
2763   // Build call kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
2764   // global_tid, kmp_int32 cncl_kind);
2765   if (auto *OMPRegionInfo =
2766           dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
2767     auto CancelDest =
2768         CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
2769     if (CancelDest.isValid()) {
2770       llvm::Value *Args[] = {
2771           emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2772           CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
2773       // Ignore return result until untied tasks are supported.
2774       auto *Result = CGF.EmitRuntimeCall(
2775           createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
2776       // if (__kmpc_cancellationpoint()) {
2777       //  __kmpc_cancel_barrier();
2778       //   exit from construct;
2779       // }
2780       auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
2781       auto *ContBB = CGF.createBasicBlock(".cancel.continue");
2782       auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
2783       CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
2784       CGF.EmitBlock(ExitBB);
2785       // __kmpc_cancel_barrier();
2786       emitBarrierCall(CGF, Loc, OMPD_unknown, /*CheckForCancel=*/false);
2787       // exit from construct;
2788       CGF.EmitBranchThroughCleanup(CancelDest);
2789       CGF.EmitBlock(ContBB, /*IsFinished=*/true);
2790     }
2791   }
2792 }
2793 
2794 void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
2795                                      OpenMPDirectiveKind CancelRegion) {
2796   // Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
2797   // kmp_int32 cncl_kind);
2798   if (auto *OMPRegionInfo =
2799           dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
2800     auto CancelDest =
2801         CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
2802     if (CancelDest.isValid()) {
2803       llvm::Value *Args[] = {
2804           emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2805           CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
2806       // Ignore return result until untied tasks are supported.
2807       auto *Result =
2808           CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
2809       // if (__kmpc_cancel()) {
2810       //  __kmpc_cancel_barrier();
2811       //   exit from construct;
2812       // }
2813       auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
2814       auto *ContBB = CGF.createBasicBlock(".cancel.continue");
2815       auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
2816       CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
2817       CGF.EmitBlock(ExitBB);
2818       // __kmpc_cancel_barrier();
2819       emitBarrierCall(CGF, Loc, OMPD_unknown, /*CheckForCancel=*/false);
2820       // exit from construct;
2821       CGF.EmitBranchThroughCleanup(CancelDest);
2822       CGF.EmitBlock(ContBB, /*IsFinished=*/true);
2823     }
2824   }
2825 }
2826 
2827