16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----- CGOpenMPRuntime.cpp - Interface to OpenMP Runtimes -------------===// 26bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 36bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// The LLVM Compiler Infrastructure 46bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 56bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This file is distributed under the University of Illinois Open Source 66bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// License. See LICENSE.TXT for details. 76bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 86bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===// 96bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This provides a class for OpenMP runtime code generation. 116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===// 136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "CGOpenMPRuntime.h" 156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "CodeGenFunction.h" 163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar#include "CGCleanup.h" 176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/AST/Decl.h" 180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#include "clang/AST/StmtOpenMP.h" 196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/ArrayRef.h" 20176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#include "llvm/IR/CallSite.h" 216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/DerivedTypes.h" 226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/GlobalValue.h" 236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/Value.h" 246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/Support/raw_ostream.h" 25c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#include <cassert> 266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace clang; 286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace CodeGen; 296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 30176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace { 310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief Base class for handling code generation inside OpenMP regions. 32176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo { 33176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic: 3433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// \brief Kinds of OpenMP regions used in codegen. 3533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar enum CGOpenMPRegionKind { 3633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// \brief Region with outlined function for standalone 'parallel' 3733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// directive. 3833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ParallelOutlinedRegion, 3933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// \brief Region with outlined function for standalone 'task' directive. 4033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar TaskOutlinedRegion, 4133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// \brief Region for constructs that do not require function outlining, 4233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// like 'for', 'sections', 'atomic' etc. directives. 4333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar InlinedRegion, 4433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar }; 4533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 4633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPRegionInfo(const CapturedStmt &CS, 4733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const CGOpenMPRegionKind RegionKind, 4833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen) 4933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind), 5033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGen(CodeGen) {} 510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 5233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind, 5333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen) 5433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), 5533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGen(CodeGen) {} 56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Get a variable or parameter for storing global thread id 58176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// inside OpenMP construct. 590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines virtual const VarDecl *getThreadIDVariable() const = 0; 60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 6133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// \brief Emit the captured statement body. 6233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) override; 6333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Get an LValue for the current ThreadID variable. 653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \return LValue for thread id variable. This LValue always has type int32*. 663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF); 67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 6833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPRegionKind getRegionKind() const { return RegionKind; } 690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 70176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines static bool classof(const CGCapturedStmtInfo *Info) { 71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return Info->getKind() == CR_OpenMP; 72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 7333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 740e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesprotected: 7533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPRegionKind RegionKind; 7633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen; 770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}; 78176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief API for captured statement code generation in OpenMP constructs. 800e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass CGOpenMPOutlinedRegionInfo : public CGOpenMPRegionInfo { 810e2c34f92f00628d48968dfea096d36381f494cbStephen Hinespublic: 8233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar, 8333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen) 8433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen), 8533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ThreadIDVar(ThreadIDVar) { 860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region."); 870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Get a variable or parameter for storing global thread id 890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// inside OpenMP construct. 9033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; } 9133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 92176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// \brief Get the name of the capture helper. 93176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StringRef getHelperName() const override { return ".omp_outlined."; } 94176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 9533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar static bool classof(const CGCapturedStmtInfo *Info) { 9633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return CGOpenMPRegionInfo::classof(Info) && 9733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == 9833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ParallelOutlinedRegion; 9933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 10033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 101176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesprivate: 102176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// \brief A variable or parameter storing global thread id for OpenMP 103176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// constructs. 104176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const VarDecl *ThreadIDVar; 1050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}; 1060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 1073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \brief API for captured statement code generation in OpenMP constructs. 1083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarclass CGOpenMPTaskOutlinedRegionInfo : public CGOpenMPRegionInfo { 1093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarpublic: 11033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS, 1113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const VarDecl *ThreadIDVar, 11233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen) 11333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen), 11433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ThreadIDVar(ThreadIDVar) { 1153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region."); 1163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 1173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \brief Get a variable or parameter for storing global thread id 1183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// inside OpenMP construct. 11933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; } 1203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \brief Get an LValue for the current ThreadID variable. 12233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override; 1233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \brief Get the name of the capture helper. 1253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar StringRef getHelperName() const override { return ".omp_outlined."; } 1263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 12733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar static bool classof(const CGCapturedStmtInfo *Info) { 12833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return CGOpenMPRegionInfo::classof(Info) && 12933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == 13033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar TaskOutlinedRegion; 13133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 13233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 1333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarprivate: 1343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \brief A variable or parameter storing global thread id for OpenMP 1353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// constructs. 1363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const VarDecl *ThreadIDVar; 1373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}; 1383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief API for inlined captured statement code generation in OpenMP 1400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// constructs. 1410e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo { 1420e2c34f92f00628d48968dfea096d36381f494cbStephen Hinespublic: 14333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI, 14433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen) 14533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : CGOpenMPRegionInfo(InlinedRegion, CodeGen), OldCSI(OldCSI), 1460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {} 1470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // \brief Retrieve the value of the context parameter. 14833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Value *getContextValue() const override { 1490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (OuterRegionInfo) 1500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OuterRegionInfo->getContextValue(); 1510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm_unreachable("No context value for inlined OpenMP region"); 1520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 15333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar virtual void setContextValue(llvm::Value *V) override { 15433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (OuterRegionInfo) { 15533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar OuterRegionInfo->setContextValue(V); 15633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return; 15733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 15833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm_unreachable("No context value for inlined OpenMP region"); 15933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 1600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Lookup the captured field decl for a variable. 16133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const FieldDecl *lookup(const VarDecl *VD) const override { 1620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (OuterRegionInfo) 1630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OuterRegionInfo->lookup(VD); 16433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // If there is no outer outlined region,no need to lookup in a list of 16533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // captured variables, we can use the original one. 16633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return nullptr; 1670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 16833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar FieldDecl *getThisFieldDecl() const override { 1690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (OuterRegionInfo) 1700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OuterRegionInfo->getThisFieldDecl(); 1710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return nullptr; 1720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 1730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Get a variable or parameter for storing global thread id 1740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// inside OpenMP construct. 17533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const VarDecl *getThreadIDVariable() const override { 1760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (OuterRegionInfo) 1770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OuterRegionInfo->getThreadIDVariable(); 1780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return nullptr; 1790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 1803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Get the name of the capture helper. 18233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar StringRef getHelperName() const override { 18333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (auto *OuterRegionInfo = getOldCSI()) 18433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return OuterRegionInfo->getHelperName(); 1850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm_unreachable("No helper name for inlined OpenMP construct"); 1860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 1870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 1880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CodeGenFunction::CGCapturedStmtInfo *getOldCSI() const { return OldCSI; } 1890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 19033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar static bool classof(const CGCapturedStmtInfo *Info) { 19133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return CGOpenMPRegionInfo::classof(Info) && 19233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion; 19333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 19433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 1950e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesprivate: 1960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief CodeGen info about outer OpenMP region. 1970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CodeGenFunction::CGCapturedStmtInfo *OldCSI; 1980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGOpenMPRegionInfo *OuterRegionInfo; 199176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}; 20033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 20133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar/// \brief RAII for emitting code of OpenMP constructs. 20233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarclass InlinedOpenMPRegionRAII { 20333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction &CGF; 20433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 20533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarpublic: 20633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// \brief Constructs region for combined constructs. 20733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// \param CodeGen Code generation sequence for combined directives. Includes 20833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// a list of functions used for code generation of implicitly inlined 20933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /// regions. 21033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen) 21133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : CGF(CGF) { 21233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Start emission for the construct. 21333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.CapturedStmtInfo = 21433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar new CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, CodeGen); 21533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 21633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ~InlinedOpenMPRegionRAII() { 21733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Restore original CapturedStmtInfo only if we're done with code emission. 21833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *OldCSI = 21933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI(); 22033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar delete CGF.CapturedStmtInfo; 22133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.CapturedStmtInfo = OldCSI; 22233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 22333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar}; 22433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 225176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} // namespace 226176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 227176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesLValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) { 228176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return CGF.MakeNaturalAlignAddrLValue( 2293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad( 2303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.GetAddrOfLocalVar(getThreadIDVariable()), 2313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.PointerAlignInBytes), 2323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getThreadIDVariable() 2333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ->getType() 2343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ->castAs<PointerType>() 2353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ->getPointeeType()); 236176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 237176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 23833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) { 23933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 1.2.2 OpenMP Language Terminology 24033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Structured block - An executable statement with a single entry at the 24133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // top and a single exit at the bottom. 24233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // The point of exit cannot be a branch out of the structured block. 24333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // longjmp() and throw() must not violate the entry/exit criteria. 24433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EHStack.pushTerminate(); 24533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar { 24633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction::RunCleanupsScope Scope(CGF); 24733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGen(CGF); 24833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 24933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EHStack.popTerminate(); 250176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 251176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarLValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue( 2533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CodeGenFunction &CGF) { 2543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGF.MakeNaturalAlignAddrLValue( 2553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.GetAddrOfLocalVar(getThreadIDVariable()), 2563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getThreadIDVariable()->getType()); 2573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 2583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 2596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesCGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM) 2603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar : CGM(CGM), DefaultOpenMPPSource(nullptr), KmpRoutineEntryPtrTy(nullptr) { 2616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IdentTy = llvm::StructType::create( 2626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines "ident_t", CGM.Int32Ty /* reserved_1 */, CGM.Int32Ty /* flags */, 2636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGM.Int32Ty /* reserved_2 */, CGM.Int32Ty /* reserved_3 */, 264176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.Int8PtrTy /* psource */, nullptr); 2656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...) 266c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty), 267c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::PointerType::getUnqual(CGM.Int32Ty)}; 2686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true); 269176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8); 270176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 271176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarvoid CGOpenMPRuntime::clear() { 2733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar InternalVars.clear(); 2743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 2753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 276176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesllvm::Value * 27733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga NainarCGOpenMPRuntime::emitParallelOutlinedFunction(const OMPExecutableDirective &D, 27833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const VarDecl *ThreadIDVar, 27933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen) { 2803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(ThreadIDVar->getType()->isPointerType() && 2813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar "thread id variable must be of type kmp_int32 *"); 282176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt()); 283176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGenFunction CGF(CGM, true); 28433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen); 285176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.CapturedStmtInfo = &CGInfo; 286176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return CGF.GenerateCapturedStmtFunction(*CS); 2876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 2886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Value * 2903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarCGOpenMPRuntime::emitTaskOutlinedFunction(const OMPExecutableDirective &D, 2913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const VarDecl *ThreadIDVar, 29233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen) { 2933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(!ThreadIDVar->getType()->isPointerType() && 2943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar "thread id variable must be of type kmp_int32 for tasks"); 2953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *CS = cast<CapturedStmt>(D.getAssociatedStmt()); 2963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CodeGenFunction CGF(CGM, true); 29733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen); 2983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.CapturedStmtInfo = &CGInfo; 2993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGF.GenerateCapturedStmtFunction(*CS); 3003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 3013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 3023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Value * 3030e2c34f92f00628d48968dfea096d36381f494cbStephen HinesCGOpenMPRuntime::getOrCreateDefaultLocation(OpenMPLocationFlags Flags) { 3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags); 3056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Entry) { 3066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!DefaultOpenMPPSource) { 3076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Initialize default location for psource field of ident_t structure of 3086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // all ident_t objects. Format is ";file;function;line;column;;". 3096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Taken from 3106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp_str.c 3116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DefaultOpenMPPSource = 3126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;"); 3136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DefaultOpenMPPSource = 3146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy); 3156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 316176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto DefaultOpenMPLocation = new llvm::GlobalVariable( 317176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getModule(), IdentTy, /*isConstant*/ true, 318176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::GlobalValue::PrivateLinkage, /*Initializer*/ nullptr); 3196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DefaultOpenMPLocation->setUnnamedAddr(true); 3206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true); 322c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *Values[] = {Zero, 323c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::ConstantInt::get(CGM.Int32Ty, Flags), 324c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Zero, Zero, DefaultOpenMPPSource}; 3256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values); 3266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DefaultOpenMPLocation->setInitializer(Init); 327176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines OpenMPDefaultLocMap[Flags] = DefaultOpenMPLocation; 3286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return DefaultOpenMPLocation; 3296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Entry; 3316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 3326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3330e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF, 3340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SourceLocation Loc, 3350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OpenMPLocationFlags Flags) { 3366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If no debug info is generated - return global default location. 3376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::NoDebugInfo || 3386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Loc.isInvalid()) 3390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return getOrCreateDefaultLocation(Flags); 3406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(CGF.CurFn && "No function in current CodeGenFunction."); 3426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Value *LocValue = nullptr; 3440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto I = OpenMPLocThreadIDMap.find(CGF.CurFn); 3450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (I != OpenMPLocThreadIDMap.end()) 346176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines LocValue = I->second.DebugLoc; 3470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // OpenMPLocThreadIDMap may have null DebugLoc and non-null ThreadID, if 3480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // GetOpenMPThreadID was called before this routine. 3490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (LocValue == nullptr) { 3506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Generate "ident_t .kmpc_loc.addr;" 3516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::AllocaInst *AI = CGF.CreateTempAlloca(IdentTy, ".kmpc_loc.addr"); 3526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AI->setAlignment(CGM.getDataLayout().getPrefTypeAlignment(IdentTy)); 353176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn); 354176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Elem.second.DebugLoc = AI; 3556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocValue = AI; 3566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGBuilderTy::InsertPointGuard IPG(CGF.Builder); 3586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt); 3590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags), 3606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::ConstantExpr::getSizeOf(IdentTy), 3616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGM.PointerAlignInBytes); 3626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // char **psource = &.kmpc_loc_<flags>.addr.psource; 36533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *PSource = CGF.Builder.CreateConstInBoundsGEP2_32(IdentTy, LocValue, 0, 36633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar IdentField_PSource); 3676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 368c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines auto OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding()); 369c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (OMPDebugLoc == nullptr) { 370c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines SmallString<128> Buffer2; 371c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::raw_svector_ostream OS2(Buffer2); 372c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Build debug location 373c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc); 374c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OS2 << ";" << PLoc.getFilename() << ";"; 375c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const FunctionDecl *FD = 376c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) { 377c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OS2 << FD->getQualifiedNameAsString(); 378c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 379c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;"; 380c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str()); 381c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc; 3826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // *psource = ";<File>;<Function>;<Line>;<Column>;;"; 384c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.Builder.CreateStore(OMPDebugLoc, PSource); 385c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return LocValue; 3876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 3886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3890e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF, 3900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SourceLocation Loc) { 3916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(CGF.CurFn && "No function in current CodeGenFunction."); 3926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 393176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *ThreadID = nullptr; 394176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Check whether we've already cached a load of the thread id in this 395176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // function. 3960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto I = OpenMPLocThreadIDMap.find(CGF.CurFn); 397176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (I != OpenMPLocThreadIDMap.end()) { 398176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ThreadID = I->second.ThreadID; 399176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (ThreadID != nullptr) 400176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ThreadID; 401176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 402176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (auto OMPRegionInfo = 4030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { 4043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (OMPRegionInfo->getThreadIDVariable()) { 4050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Check if this an outlined function with thread id passed as argument. 4060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF); 4070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ThreadID = CGF.EmitLoadOfLValue(LVal, Loc).getScalarVal(); 4080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // If value loaded in entry block, cache it and use it everywhere in 4090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // function. 4100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) { 4110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn); 4120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Elem.second.ThreadID = ThreadID; 4130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 4140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return ThreadID; 415176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 4166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 4180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // This is not an outlined function region - need to call __kmpc_int32 4190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // kmpc_global_thread_num(ident_t *loc). 4200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Generate thread id value and cache this value for use across the 4210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // function. 4220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGBuilderTy::InsertPointGuard IPG(CGF.Builder); 4230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt); 4240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ThreadID = 4250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num), 4260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines emitUpdateLocation(CGF, Loc)); 4270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn); 4280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Elem.second.ThreadID = ThreadID; 429176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ThreadID; 4306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4320e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) { 4336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(CGF.CurFn && "No function in current CodeGenFunction."); 434176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (OpenMPLocThreadIDMap.count(CGF.CurFn)) 435176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines OpenMPLocThreadIDMap.erase(CGF.CurFn); 4366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() { 4396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return llvm::PointerType::getUnqual(IdentTy); 4406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() { 4436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return llvm::PointerType::getUnqual(Kmpc_MicroTy); 4446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Constant * 4470e2c34f92f00628d48968dfea096d36381f494cbStephen HinesCGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) { 4486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Constant *RTLFn = nullptr; 4496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (Function) { 4506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case OMPRTL__kmpc_fork_call: { 4516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro 4526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // microtask, ...); 453c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, 454c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getKmpc_MicroPointerTy()}; 4556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::FunctionType *FnTy = 456176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true); 4576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call"); 4586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 4596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case OMPRTL__kmpc_global_thread_num: { 4616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc); 462c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy()}; 4636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::FunctionType *FnTy = 464176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false); 4656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num"); 4666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 4676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 468176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMPRTL__kmpc_threadprivate_cached: { 469176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build void *__kmpc_threadprivate_cached(ident_t *loc, 470176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // kmp_int32 global_tid, void *data, size_t size, void ***cache); 471176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, 472176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.VoidPtrTy, CGM.SizeTy, 473176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.VoidPtrTy->getPointerTo()->getPointerTo()}; 474176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FnTy = 475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg*/ false); 476176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_cached"); 477176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 478176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 479176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMPRTL__kmpc_critical: { 480176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build void __kmpc_critical(ident_t *loc, kmp_int32 global_tid, 481176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // kmp_critical_name *crit); 482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *TypeParams[] = { 483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getIdentTyPointerTy(), CGM.Int32Ty, 484176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::PointerType::getUnqual(KmpCriticalNameTy)}; 485176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FnTy = 486176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 487176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical"); 488176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 489176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 490176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMPRTL__kmpc_threadprivate_register: { 491176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build void __kmpc_threadprivate_register(ident_t *, void *data, 492176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor); 493176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // typedef void *(*kmpc_ctor)(void *); 494176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto KmpcCtorTy = 495176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy, 496176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*isVarArg*/ false)->getPointerTo(); 497176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // typedef void *(*kmpc_cctor)(void *, void *); 498176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *KmpcCopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy}; 499176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto KmpcCopyCtorTy = 500176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidPtrTy, KmpcCopyCtorTyArgs, 501176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*isVarArg*/ false)->getPointerTo(); 502176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // typedef void (*kmpc_dtor)(void *); 503176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto KmpcDtorTy = 504176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy, /*isVarArg*/ false) 505176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ->getPointerTo(); 506176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *FnTyArgs[] = {getIdentTyPointerTy(), CGM.VoidPtrTy, KmpcCtorTy, 507176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines KmpcCopyCtorTy, KmpcDtorTy}; 508176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto FnTy = llvm::FunctionType::get(CGM.VoidTy, FnTyArgs, 509176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*isVarArg*/ false); 510176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_register"); 511176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 512176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 513176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMPRTL__kmpc_end_critical: { 514176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid, 515176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // kmp_critical_name *crit); 516176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *TypeParams[] = { 517176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getIdentTyPointerTy(), CGM.Int32Ty, 518176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::PointerType::getUnqual(KmpCriticalNameTy)}; 519176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FnTy = 520176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 521176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical"); 522176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 523176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 5240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPRTL__kmpc_cancel_barrier: { 5250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32 5260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // global_tid); 5270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; 5280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType *FnTy = 5290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false); 5300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier"); 5310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines break; 5320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 5330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPRTL__kmpc_for_static_fini: { 5340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid); 535176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; 536176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FnTy = 537176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 5380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_fini"); 539176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 540176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 541176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMPRTL__kmpc_push_num_threads: { 542176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, 543176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // kmp_int32 num_threads) 544176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, 545176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.Int32Ty}; 546176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FnTy = 547176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 548176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_threads"); 549176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 550176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 551176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMPRTL__kmpc_serialized_parallel: { 552176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32 553176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // global_tid); 554176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; 555176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FnTy = 556176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 557176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel"); 558176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 559176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 560176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMPRTL__kmpc_end_serialized_parallel: { 561176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32 562176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // global_tid); 563176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; 564176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FnTy = 565176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 566176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel"); 567176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 568176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 569176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMPRTL__kmpc_flush: { 5700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build void __kmpc_flush(ident_t *loc); 571176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy()}; 572176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FnTy = 5730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 574176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_flush"); 575176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 576176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 5770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPRTL__kmpc_master: { 5780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build kmp_int32 __kmpc_master(ident_t *loc, kmp_int32 global_tid); 5790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; 5800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType *FnTy = 5810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false); 5820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_master"); 5830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines break; 5840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 5850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPRTL__kmpc_end_master: { 5860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build void __kmpc_end_master(ident_t *loc, kmp_int32 global_tid); 5870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; 5880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType *FnTy = 5890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false); 5900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_master"); 5910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines break; 5920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 5930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPRTL__kmpc_omp_taskyield: { 5940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid, 5950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // int end_part); 5960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy}; 5970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType *FnTy = 5980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false); 5990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_taskyield"); 6000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines break; 6010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 6020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPRTL__kmpc_single: { 6030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build kmp_int32 __kmpc_single(ident_t *loc, kmp_int32 global_tid); 6040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; 6050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType *FnTy = 6060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false); 6070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_single"); 6080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines break; 6090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 6100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPRTL__kmpc_end_single: { 6110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build void __kmpc_end_single(ident_t *loc, kmp_int32 global_tid); 6120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; 6130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType *FnTy = 6140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false); 6150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_single"); 6160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines break; 6170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 6183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case OMPRTL__kmpc_omp_task_alloc: { 6193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid, 6203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, 6213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_routine_entry_t *task_entry); 6223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(KmpRoutineEntryPtrTy != nullptr && 6233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar "Type kmp_routine_entry_t must be created."); 6243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, 6253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.SizeTy, CGM.SizeTy, KmpRoutineEntryPtrTy}; 6263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Return void * and then cast to particular kmp_task_t type. 6273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FnTy = 6283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false); 6293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_alloc"); 6303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar break; 6313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 6323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case OMPRTL__kmpc_omp_task: { 6333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t 6343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // *new_task); 6353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, 6363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.VoidPtrTy}; 6373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FnTy = 6383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false); 6393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task"); 6403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar break; 6413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 6423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case OMPRTL__kmpc_copyprivate: { 6433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid, 6443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int32 cpy_size, void *cpy_data, void(*cpy_func)(void *, void *), 6453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int32 didit); 6463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *CpyTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy}; 6473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *CpyFnTy = 6483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, CpyTypeParams, /*isVarArg=*/false); 6493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, 6503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.VoidPtrTy, CpyFnTy->getPointerTo(), 6513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.Int32Ty}; 6523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FnTy = 6533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false); 6543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_copyprivate"); 6553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar break; 6563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 65733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar case OMPRTL__kmpc_reduce: { 65833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Build kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid, 65933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void 66033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck); 66133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy}; 66233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams, 66333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /*isVarArg=*/false); 66433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Type *TypeParams[] = { 66533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy, 66633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.VoidPtrTy, ReduceFnTy->getPointerTo(), 66733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::PointerType::getUnqual(KmpCriticalNameTy)}; 66833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::FunctionType *FnTy = 66933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false); 67033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce"); 67133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar break; 67233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 67333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar case OMPRTL__kmpc_reduce_nowait: { 67433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Build kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32 67533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data, 67633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name 67733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // *lck); 67833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy}; 67933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams, 68033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /*isVarArg=*/false); 68133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Type *TypeParams[] = { 68233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy, 68333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.VoidPtrTy, ReduceFnTy->getPointerTo(), 68433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::PointerType::getUnqual(KmpCriticalNameTy)}; 68533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::FunctionType *FnTy = 68633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false); 68733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce_nowait"); 68833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar break; 68933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 69033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar case OMPRTL__kmpc_end_reduce: { 69133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Build void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid, 69233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // kmp_critical_name *lck); 69333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Type *TypeParams[] = { 69433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar getIdentTyPointerTy(), CGM.Int32Ty, 69533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::PointerType::getUnqual(KmpCriticalNameTy)}; 69633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::FunctionType *FnTy = 69733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false); 69833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce"); 69933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar break; 70033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 70133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar case OMPRTL__kmpc_end_reduce_nowait: { 70233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Build __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid, 70333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // kmp_critical_name *lck); 70433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Type *TypeParams[] = { 70533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar getIdentTyPointerTy(), CGM.Int32Ty, 70633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::PointerType::getUnqual(KmpCriticalNameTy)}; 70733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::FunctionType *FnTy = 70833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false); 70933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar RTLFn = 71033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce_nowait"); 71133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar break; 71233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 7136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return RTLFn; 7156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 716176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 7173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Constant *CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize, 7183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar bool IVSigned) { 7193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert((IVSize == 32 || IVSize == 64) && 7203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar "IV size is not compatible with the omp runtime"); 7213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto Name = IVSize == 32 ? (IVSigned ? "__kmpc_for_static_init_4" 7223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar : "__kmpc_for_static_init_4u") 7233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar : (IVSigned ? "__kmpc_for_static_init_8" 7243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar : "__kmpc_for_static_init_8u"); 7253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty; 7263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto PtrTy = llvm::PointerType::getUnqual(ITy); 7273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *TypeParams[] = { 7283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getIdentTyPointerTy(), // loc 7293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.Int32Ty, // tid 7303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.Int32Ty, // schedtype 7313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter 7323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar PtrTy, // p_lower 7333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar PtrTy, // p_upper 7343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar PtrTy, // p_stride 7353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ITy, // incr 7363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ITy // chunk 7373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }; 7383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FnTy = 7393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 7403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGM.CreateRuntimeFunction(FnTy, Name); 7413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 7423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 7433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Constant *CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize, 7443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar bool IVSigned) { 7453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert((IVSize == 32 || IVSize == 64) && 7463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar "IV size is not compatible with the omp runtime"); 7473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto Name = 7483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar IVSize == 32 7493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ? (IVSigned ? "__kmpc_dispatch_init_4" : "__kmpc_dispatch_init_4u") 7503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar : (IVSigned ? "__kmpc_dispatch_init_8" : "__kmpc_dispatch_init_8u"); 7513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty; 7523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *TypeParams[] = { getIdentTyPointerTy(), // loc 7533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.Int32Ty, // tid 7543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.Int32Ty, // schedtype 7553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ITy, // lower 7563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ITy, // upper 7573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ITy, // stride 7583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ITy // chunk 7593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }; 7603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FnTy = 7613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); 7623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGM.CreateRuntimeFunction(FnTy, Name); 7633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 7643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 7653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Constant *CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize, 7663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar bool IVSigned) { 7673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert((IVSize == 32 || IVSize == 64) && 7683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar "IV size is not compatible with the omp runtime"); 7693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto Name = 7703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar IVSize == 32 7713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ? (IVSigned ? "__kmpc_dispatch_next_4" : "__kmpc_dispatch_next_4u") 7723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar : (IVSigned ? "__kmpc_dispatch_next_8" : "__kmpc_dispatch_next_8u"); 7733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty; 7743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto PtrTy = llvm::PointerType::getUnqual(ITy); 7753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *TypeParams[] = { 7763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getIdentTyPointerTy(), // loc 7773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.Int32Ty, // tid 7783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter 7793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar PtrTy, // p_lower 7803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar PtrTy, // p_upper 7813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar PtrTy // p_stride 7823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }; 7833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FnTy = 7843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false); 7853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGM.CreateRuntimeFunction(FnTy, Name); 7863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 7873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 788176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesllvm::Constant * 789176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesCGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) { 790176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Lookup the entry, lazily creating it if necessary. 7910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return getOrCreateInternalVariable(CGM.Int8PtrPtrTy, 792176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Twine(CGM.getMangledName(VD)) + ".cache."); 793176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 794176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 7950e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF, 7960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines const VarDecl *VD, 7970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *VDAddr, 7980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SourceLocation Loc) { 799176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto VarTy = VDAddr->getType()->getPointerElementType(); 8000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), 801176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.Builder.CreatePointerCast(VDAddr, CGM.Int8PtrTy), 802176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)), 803176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getOrCreateThreadPrivateCache(VD)}; 804176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return CGF.EmitRuntimeCall( 8050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args); 806176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 807176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 8080e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitThreadPrivateVarInit( 809176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGenFunction &CGF, llvm::Value *VDAddr, llvm::Value *Ctor, 810176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc) { 811176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime 812176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // library. 8130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto OMPLoc = emitUpdateLocation(CGF, Loc); 8140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num), 815176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines OMPLoc); 816176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor) 817176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // to register constructor/destructor for variable. 818176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *Args[] = {OMPLoc, 819176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.Builder.CreatePointerCast(VDAddr, CGM.VoidPtrTy), 820176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Ctor, CopyCtor, Dtor}; 8210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall( 8220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines createRuntimeFunction(OMPRTL__kmpc_threadprivate_register), Args); 823176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 824176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 8250e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition( 826176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const VarDecl *VD, llvm::Value *VDAddr, SourceLocation Loc, 827176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool PerformInit, CodeGenFunction *CGF) { 828176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VD = VD->getDefinition(CGM.getContext()); 829176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (VD && ThreadPrivateWithDefinition.count(VD) == 0) { 830176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ThreadPrivateWithDefinition.insert(VD); 831176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines QualType ASTTy = VD->getType(); 832176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 833176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr; 834176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto Init = VD->getAnyInitializer(); 835176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CGM.getLangOpts().CPlusPlus && PerformInit) { 836176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Generate function that re-emits the declaration's initializer into the 837176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // threadprivate copy of the variable VD 838176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGenFunction CtorCGF(CGM); 839176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines FunctionArgList Args; 840176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, SourceLocation(), 841176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*Id=*/nullptr, CGM.getContext().VoidPtrTy); 842176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Args.push_back(&Dst); 843176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 844176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( 845176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getContext().VoidPtrTy, Args, FunctionType::ExtInfo(), 846176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*isVariadic=*/false); 847176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto FTy = CGM.getTypes().GetFunctionType(FI); 848176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto Fn = CGM.CreateGlobalInitOrDestructFunction( 849176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines FTy, ".__kmpc_global_ctor_.", Loc); 850176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI, 851176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Args, SourceLocation()); 852176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto ArgVal = CtorCGF.EmitLoadOfScalar( 853176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CtorCGF.GetAddrOfLocalVar(&Dst), 854176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*Volatile=*/false, CGM.PointerAlignInBytes, 855176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getContext().VoidPtrTy, Dst.getLocation()); 856176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto Arg = CtorCGF.Builder.CreatePointerCast( 857176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ArgVal, 858176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CtorCGF.ConvertTypeForMem(CGM.getContext().getPointerType(ASTTy))); 859176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(), 860176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*IsInitializer=*/true); 861176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ArgVal = CtorCGF.EmitLoadOfScalar( 862176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CtorCGF.GetAddrOfLocalVar(&Dst), 863176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*Volatile=*/false, CGM.PointerAlignInBytes, 864176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getContext().VoidPtrTy, Dst.getLocation()); 865176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue); 866176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CtorCGF.FinishFunction(); 867176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Ctor = Fn; 868176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 869176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (VD->getType().isDestructedType() != QualType::DK_none) { 870176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Generate function that emits destructor call for the threadprivate copy 871176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // of the variable VD 872176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGenFunction DtorCGF(CGM); 873176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines FunctionArgList Args; 874176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, SourceLocation(), 875176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*Id=*/nullptr, CGM.getContext().VoidPtrTy); 876176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Args.push_back(&Dst); 877176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 878176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( 879176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getContext().VoidTy, Args, FunctionType::ExtInfo(), 880176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*isVariadic=*/false); 881176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto FTy = CGM.getTypes().GetFunctionType(FI); 882176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto Fn = CGM.CreateGlobalInitOrDestructFunction( 883176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines FTy, ".__kmpc_global_dtor_.", Loc); 884176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, Args, 885176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SourceLocation()); 886176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto ArgVal = DtorCGF.EmitLoadOfScalar( 887176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DtorCGF.GetAddrOfLocalVar(&Dst), 888176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*Volatile=*/false, CGM.PointerAlignInBytes, 889176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getContext().VoidPtrTy, Dst.getLocation()); 890176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DtorCGF.emitDestroy(ArgVal, ASTTy, 891176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DtorCGF.getDestroyer(ASTTy.isDestructedType()), 892176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DtorCGF.needsEHCleanup(ASTTy.isDestructedType())); 893176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DtorCGF.FinishFunction(); 894176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Dtor = Fn; 895176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 896176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Do not emit init function if it is not required. 897176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!Ctor && !Dtor) 898176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return nullptr; 899176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 900176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *CopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy}; 901176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto CopyCtorTy = 902176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidPtrTy, CopyCtorTyArgs, 903176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*isVarArg=*/false)->getPointerTo(); 904176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Copying constructor for the threadprivate variable. 905176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Must be NULL - reserved by runtime, but currently it requires that this 906176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // parameter is always NULL. Otherwise it fires assertion. 907176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CopyCtor = llvm::Constant::getNullValue(CopyCtorTy); 908176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Ctor == nullptr) { 909176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto CtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy, 910176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*isVarArg=*/false)->getPointerTo(); 911176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Ctor = llvm::Constant::getNullValue(CtorTy); 912176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 913176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Dtor == nullptr) { 914176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto DtorTy = llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy, 915176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*isVarArg=*/false)->getPointerTo(); 916176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Dtor = llvm::Constant::getNullValue(DtorTy); 917176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 918176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!CGF) { 919176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto InitFunctionTy = 920176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false); 921176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto InitFunction = CGM.CreateGlobalInitOrDestructFunction( 922176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InitFunctionTy, ".__omp_threadprivate_init_."); 923176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGenFunction InitCGF(CGM); 924176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines FunctionArgList ArgList; 925176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, InitFunction, 926176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getTypes().arrangeNullaryFunction(), ArgList, 927176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Loc); 9280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc); 929176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InitCGF.FinishFunction(); 930176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return InitFunction; 931176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 9320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines emitThreadPrivateVarInit(*CGF, VDAddr, Ctor, CopyCtor, Dtor, Loc); 933176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 934176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return nullptr; 935176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 936176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 9370e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, 9380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *OutlinedFn, 9390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *CapturedStruct) { 940176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/) 941176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *Args[] = { 9420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines emitUpdateLocation(CGF, Loc), 943176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.Builder.getInt32(1), // Number of arguments after 'microtask' argument 944176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // (there is only one additional argument - 'context') 945176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy()), 946176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.EmitCastToVoidPtr(CapturedStruct)}; 9470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_call); 948176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.EmitRuntimeCall(RTLFn, Args); 949176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 950176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 9510e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitSerialCall(CodeGenFunction &CGF, SourceLocation Loc, 9520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *OutlinedFn, 9530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *CapturedStruct) { 9540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto ThreadID = getThreadID(CGF, Loc); 955176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build calls: 956176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // __kmpc_serialized_parallel(&Loc, GTid); 9570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), ThreadID}; 9580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_serialized_parallel), 9590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Args); 960176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 961176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // OutlinedFn(>id, &zero, CapturedStruct); 9620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto ThreadIDAddr = emitThreadIDAddress(CGF, Loc); 963176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto Int32Ty = 964176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true); 965176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto ZeroAddr = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".zero.addr"); 966176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C*/ 0)); 967176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *OutlinedFnArgs[] = {ThreadIDAddr, ZeroAddr, CapturedStruct}; 968176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs); 969176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 970176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // __kmpc_end_serialized_parallel(&Loc, GTid); 9710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *EndArgs[] = {emitUpdateLocation(CGF, Loc), ThreadID}; 9720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall( 9730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines createRuntimeFunction(OMPRTL__kmpc_end_serialized_parallel), EndArgs); 974176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 975176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 976176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// If we're inside an (outlined) parallel region, use the region info's 977176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// thread-ID variable (it is passed in a first argument of the outlined function 978176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// as "kmp_int32 *gtid"). Otherwise, if we're not inside parallel region, but in 979176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// regular serial code region, get thread ID by calling kmp_int32 980176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// kmpc_global_thread_num(ident_t *loc), stash this thread ID in a temporary and 981176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// return the address of that temp. 9820e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF, 983176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SourceLocation Loc) { 984176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (auto OMPRegionInfo = 985176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) 9860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (OMPRegionInfo->getThreadIDVariable()) 9873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress(); 9880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 9890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto ThreadID = getThreadID(CGF, Loc); 990176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto Int32Ty = 991176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true); 992176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto ThreadIDTemp = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".threadid_temp."); 993176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.EmitStoreOfScalar(ThreadID, 994176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.MakeNaturalAlignAddrLValue(ThreadIDTemp, Int32Ty)); 995176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 996176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ThreadIDTemp; 997176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 998176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 999176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesllvm::Constant * 10000e2c34f92f00628d48968dfea096d36381f494cbStephen HinesCGOpenMPRuntime::getOrCreateInternalVariable(llvm::Type *Ty, 1001176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const llvm::Twine &Name) { 1002176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SmallString<256> Buffer; 1003176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::raw_svector_ostream Out(Buffer); 1004176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Out << Name; 1005176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto RuntimeName = Out.str(); 1006176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto &Elem = *InternalVars.insert(std::make_pair(RuntimeName, nullptr)).first; 1007176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Elem.second) { 1008176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(Elem.second->getType()->getPointerElementType() == Ty && 1009176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "OMP internal variable has different type than requested"); 1010176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return &*Elem.second; 1011176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1012176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1013176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return Elem.second = new llvm::GlobalVariable( 1014176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getModule(), Ty, /*IsConstant*/ false, 1015176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty), 1016176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Elem.first()); 1017176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 1018176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 10190e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) { 1020176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Twine Name(".gomp_critical_user_", CriticalName); 10210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return getOrCreateInternalVariable(KmpCriticalNameTy, Name.concat(".var")); 1022176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 1023176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 102433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarnamespace { 102533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarclass CallEndCleanup : public EHScopeStack::Cleanup { 102633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarpublic: 102733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar typedef ArrayRef<llvm::Value *> CleanupValuesTy; 102833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarprivate: 102933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Value *Callee; 103033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::SmallVector<llvm::Value *, 8> Args; 103133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 103233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarpublic: 103333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CallEndCleanup(llvm::Value *Callee, CleanupValuesTy Args) 103433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : Callee(Callee), Args(Args.begin(), Args.end()) {} 103533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar void Emit(CodeGenFunction &CGF, Flags /*flags*/) override { 103633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitRuntimeCall(Callee, Args); 103733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 103833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar}; 103933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar} // namespace 104033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 104133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF, 104233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar StringRef CriticalName, 104333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CriticalOpGen, 104433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar SourceLocation Loc) { 10450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // __kmpc_critical(ident_t *, gtid, Lock); 10460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // CriticalOpGen(); 10470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // __kmpc_end_critical(ident_t *, gtid, Lock); 10480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Prepare arguments and build a call to __kmpc_critical 104933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar { 105033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction::RunCleanupsScope Scope(CGF); 105133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), 105233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar getCriticalRegionLock(CriticalName)}; 105333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_critical), Args); 105433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Build a call to __kmpc_end_critical 105533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EHStack.pushCleanup<CallEndCleanup>( 105633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_critical), 105733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::makeArrayRef(Args)); 105833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar emitInlinedDirective(CGF, CriticalOpGen); 105933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 1060176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 1061176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 10620e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstatic void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond, 106333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &BodyOpGen) { 10640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *CallBool = CGF.EmitScalarConversion( 10650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines IfCond, 10660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true), 10670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.getContext().BoolTy); 10680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 10690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto *ThenBlock = CGF.createBasicBlock("omp_if.then"); 10700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto *ContBlock = CGF.createBasicBlock("omp_if.end"); 10710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Generate the branch (If-stmt) 10720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock); 10730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitBlock(ThenBlock); 107433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, BodyOpGen); 10750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Emit the rest of bblocks/branches 10760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitBranch(ContBlock); 10770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitBlock(ContBlock, true); 1078176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 1079176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 10800e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF, 108133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &MasterOpGen, 10820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SourceLocation Loc) { 10830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // if(__kmpc_master(ident_t *, gtid)) { 10840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // MasterOpGen(); 10850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // __kmpc_end_master(ident_t *, gtid); 10860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // } 10870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Prepare arguments and build a call to __kmpc_master 10880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; 10890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto *IsMaster = 10900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_master), Args); 109133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar emitIfStmt(CGF, IsMaster, [&](CodeGenFunction &CGF) -> void { 109233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction::RunCleanupsScope Scope(CGF); 109333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EHStack.pushCleanup<CallEndCleanup>( 109433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_master), 109533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::makeArrayRef(Args)); 109633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar MasterOpGen(CGF); 10970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines }); 1098176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 1099176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 11000e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF, 11010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SourceLocation Loc) { 11020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build call __kmpc_omp_taskyield(loc, thread_id, 0); 11030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *Args[] = { 11040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), 11050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)}; 11060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), Args); 11070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 11080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 11093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Value *emitCopyprivateCopyFunction( 111033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenModule &CGM, llvm::Type *ArgsType, 111133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs, 111233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps) { 11133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto &C = CGM.getContext(); 11143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // void copy_func(void *LHSArg, void *RHSArg); 11153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar FunctionArgList Args; 11163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr, 11173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.VoidPtrTy); 11183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr, 11193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.VoidPtrTy); 11203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Args.push_back(&LHSArg); 11213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Args.push_back(&RHSArg); 11223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar FunctionType::ExtInfo EI; 11233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto &CGFI = CGM.getTypes().arrangeFreeFunctionDeclaration( 11243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.VoidTy, Args, EI, /*isVariadic=*/false); 11253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *Fn = llvm::Function::Create( 11263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, 11273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ".omp.copyprivate.copy_func", &CGM.getModule()); 11283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, CGFI, Fn); 11293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CodeGenFunction CGF(CGM); 11303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args); 113133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Dest = (void*[n])(LHSArg); 11323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Src = (void*[n])(RHSArg); 11333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *LHS = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 11343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(CGF.GetAddrOfLocalVar(&LHSArg), 11353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.PointerAlignInBytes), 11363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ArgsType); 11373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *RHS = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 11383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(CGF.GetAddrOfLocalVar(&RHSArg), 11393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.PointerAlignInBytes), 11403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ArgsType); 11413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // *(Type0*)Dst[0] = *(Type0*)Src[0]; 11423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // *(Type1*)Dst[1] = *(Type1*)Src[1]; 11433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // ... 11443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // *(Typen*)Dst[n] = *(Typen*)Src[n]; 11453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar for (unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) { 114633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *DestAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 114733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad( 114833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateStructGEP(nullptr, LHS, I), 114933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.PointerAlignInBytes), 115033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.ConvertTypeForMem(C.getPointerType(SrcExprs[I]->getType()))); 115133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *SrcAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 115233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad( 115333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateStructGEP(nullptr, RHS, I), 115433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.PointerAlignInBytes), 115533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.ConvertTypeForMem(C.getPointerType(SrcExprs[I]->getType()))); 115633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitOMPCopy(CGF, CopyprivateVars[I]->getType(), DestAddr, SrcAddr, 115733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl()), 115833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl()), 115933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar AssignmentOps[I]); 11603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 11613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.FinishFunction(); 11623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return Fn; 11633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 11643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 11650e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF, 116633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &SingleOpGen, 11673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar SourceLocation Loc, 11683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ArrayRef<const Expr *> CopyprivateVars, 11693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ArrayRef<const Expr *> SrcExprs, 11703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ArrayRef<const Expr *> DstExprs, 11713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ArrayRef<const Expr *> AssignmentOps) { 11723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(CopyprivateVars.size() == SrcExprs.size() && 11733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CopyprivateVars.size() == DstExprs.size() && 11743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CopyprivateVars.size() == AssignmentOps.size()); 11753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto &C = CGM.getContext(); 11763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // int32 did_it = 0; 11770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // if(__kmpc_single(ident_t *, gtid)) { 11780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // SingleOpGen(); 11790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // __kmpc_end_single(ident_t *, gtid); 11803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // did_it = 1; 11810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // } 11823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>, 11833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // <copy_func>, did_it); 11843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 11853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::AllocaInst *DidIt = nullptr; 11863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!CopyprivateVars.empty()) { 11873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // int32 did_it = 0; 11883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 11893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar DidIt = CGF.CreateMemTemp(KmpInt32Ty, ".omp.copyprivate.did_it"); 11903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.InitTempAlloca(DidIt, CGF.Builder.getInt32(0)); 11913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 11920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Prepare arguments and build a call to __kmpc_single 11930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; 11940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto *IsSingle = 11950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_single), Args); 119633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar emitIfStmt(CGF, IsSingle, [&](CodeGenFunction &CGF) -> void { 119733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction::RunCleanupsScope Scope(CGF); 119833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EHStack.pushCleanup<CallEndCleanup>( 119933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_single), 120033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::makeArrayRef(Args)); 120133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar SingleOpGen(CGF); 12023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (DidIt) { 12033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // did_it = 1; 12043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateAlignedStore(CGF.Builder.getInt32(1), DidIt, 12053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar DidIt->getAlignment()); 12063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 12070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines }); 12083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>, 12093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // <copy_func>, did_it); 12103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (DidIt) { 12113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size()); 12123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto CopyprivateArrayTy = 12133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal, 12143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*IndexTypeQuals=*/0); 12153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Create a list of all private variables for copyprivate. 12163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *CopyprivateList = 12173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list"); 12183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar for (unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) { 121933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *Elem = CGF.Builder.CreateStructGEP( 122033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CopyprivateList->getAllocatedType(), CopyprivateList, I); 12213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateAlignedStore( 12223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 12233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitLValue(CopyprivateVars[I]).getAddress(), CGF.VoidPtrTy), 12243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Elem, CGM.PointerAlignInBytes); 12253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 12263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build function that copies private values from single region to all other 12273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // threads in the corresponding parallel region. 12283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *CpyFn = emitCopyprivateCopyFunction( 12293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM, CGF.ConvertTypeForMem(CopyprivateArrayTy)->getPointerTo(), 123033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CopyprivateVars, SrcExprs, DstExprs, AssignmentOps); 12313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *BufSize = CGF.Builder.getInt32( 12323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.getTypeSizeInChars(CopyprivateArrayTy).getQuantity()); 12333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *CL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList, 12343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.VoidPtrTy); 12353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *DidItVal = 12363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(DidIt, CGF.PointerAlignInBytes); 12373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Args[] = { 12383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar emitUpdateLocation(CGF, Loc), // ident_t *<loc> 12393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getThreadID(CGF, Loc), // i32 <gtid> 12403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar BufSize, // i32 <buf_size> 12413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CL, // void *<copyprivate list> 12423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CpyFn, // void (*) (void *, void *) <copy_func> 12433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar DidItVal // i32 did_it 12443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }; 12453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_copyprivate), Args); 12463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 12470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 12480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 12490e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, 125033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar OpenMPDirectiveKind Kind) { 12510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build call __kmpc_cancel_barrier(loc, thread_id); 125233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar OpenMPLocationFlags Flags = OMP_IDENT_KMPC; 125333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (Kind == OMPD_for) { 125433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Flags = 125533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_IMPL_FOR); 125633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } else if (Kind == OMPD_sections) { 125733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Flags = static_cast<OpenMPLocationFlags>(Flags | 125833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar OMP_IDENT_BARRIER_IMPL_SECTIONS); 125933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } else if (Kind == OMPD_single) { 126033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Flags = 126133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_IMPL_SINGLE); 126233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } else if (Kind == OMPD_barrier) { 126333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Flags = static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_EXPL); 126433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } else { 126533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Flags = static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_IMPL); 126633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 12670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build call __kmpc_cancel_barrier(loc, thread_id); 12680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Replace __kmpc_barrier() function by __kmpc_cancel_barrier() because this 12690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // one provides the same functionality and adds initial support for 12700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // cancellation constructs introduced in OpenMP 4.0. __kmpc_cancel_barrier() 12710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // is provided default by the runtime library so it safe to make such 12720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // replacement. 12730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags), 12740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines getThreadID(CGF, Loc)}; 12750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args); 12760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 12770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 12780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief Schedule types for 'omp for' loops (these enumerators are taken from 12790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// the enum sched_type in kmp.h). 12800e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesenum OpenMPSchedType { 12810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Lower bound for default (unordered) versions. 12820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_sch_lower = 32, 12830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_sch_static_chunked = 33, 12840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_sch_static = 34, 12850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_sch_dynamic_chunked = 35, 12860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_sch_guided_chunked = 36, 12870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_sch_runtime = 37, 12880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_sch_auto = 38, 12890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Lower bound for 'ordered' versions. 12900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_ord_lower = 64, 12910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief Lower bound for 'nomerge' versions. 12920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OMP_nm_lower = 160, 12930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}; 12940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 12950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief Map the OpenMP loop schedule to the runtime enumeration. 12960e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstatic OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind, 12970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines bool Chunked) { 12980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines switch (ScheduleKind) { 12990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPC_SCHEDULE_static: 13000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Chunked ? OMP_sch_static_chunked : OMP_sch_static; 13010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPC_SCHEDULE_dynamic: 13020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OMP_sch_dynamic_chunked; 13030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPC_SCHEDULE_guided: 13040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OMP_sch_guided_chunked; 13050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPC_SCHEDULE_auto: 13060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OMP_sch_auto; 13070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPC_SCHEDULE_runtime: 13080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OMP_sch_runtime; 13090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case OMPC_SCHEDULE_unknown: 13100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines assert(!Chunked && "chunk was specified but schedule kind not known"); 13110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return OMP_sch_static; 13120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 13130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm_unreachable("Unexpected runtime schedule"); 13140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 13150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 13160e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool CGOpenMPRuntime::isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind, 13170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines bool Chunked) const { 13180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto Schedule = getRuntimeSchedule(ScheduleKind, Chunked); 13190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Schedule == OMP_sch_static; 13200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 13210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 13220e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool CGOpenMPRuntime::isDynamic(OpenMPScheduleClauseKind ScheduleKind) const { 13230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto Schedule = getRuntimeSchedule(ScheduleKind, /* Chunked */ false); 13240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines assert(Schedule != OMP_sch_static_chunked && "cannot be chunked here"); 13250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Schedule != OMP_sch_static; 13260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 13270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 13280e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitForInit(CodeGenFunction &CGF, SourceLocation Loc, 13290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OpenMPScheduleClauseKind ScheduleKind, 13300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines unsigned IVSize, bool IVSigned, 13310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *IL, llvm::Value *LB, 13320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *UB, llvm::Value *ST, 13330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *Chunk) { 13340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunk != nullptr); 13353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked) { 13363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Call __kmpc_dispatch_init( 13373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // ident_t *loc, kmp_int32 tid, kmp_int32 schedule, 13383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int[32|64] lower, kmp_int[32|64] upper, 13393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int[32|64] stride, kmp_int[32|64] chunk); 13403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 13413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // If the Chunk was not specified in the clause - use default value 1. 13423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (Chunk == nullptr) 13433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Chunk = CGF.Builder.getIntN(IVSize, 1); 13443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC), 13453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getThreadID(CGF, Loc), 13463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.getInt32(Schedule), // Schedule type 13473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.getIntN(IVSize, 0), // Lower 13483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar UB, // Upper 13493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.getIntN(IVSize, 1), // Stride 13503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Chunk // Chunk 13513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }; 13523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitRuntimeCall(createDispatchInitFunction(IVSize, IVSigned), Args); 13533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } else { 13543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Call __kmpc_for_static_init( 13553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // ident_t *loc, kmp_int32 tid, kmp_int32 schedtype, 13563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower, 13573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride, 13583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int[32|64] incr, kmp_int[32|64] chunk); 13593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (Chunk == nullptr) { 13603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(Schedule == OMP_sch_static && 13613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar "expected static non-chunked schedule"); 13623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // If the Chunk was not specified in the clause - use default value 1. 13633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Chunk = CGF.Builder.getIntN(IVSize, 1); 13643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } else 13653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(Schedule == OMP_sch_static_chunked && 13663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar "expected static chunked schedule"); 13673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC), 13683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getThreadID(CGF, Loc), 13693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.getInt32(Schedule), // Schedule type 13703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar IL, // &isLastIter 13713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar LB, // &LB 13723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar UB, // &UB 13733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ST, // &Stride 13743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.getIntN(IVSize, 1), // Incr 13753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Chunk // Chunk 13763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }; 13773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitRuntimeCall(createForStaticInitFunction(IVSize, IVSigned), Args); 13783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 13790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 13800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 13810e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitForFinish(CodeGenFunction &CGF, SourceLocation Loc, 13820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OpenMPScheduleClauseKind ScheduleKind) { 13830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines assert((ScheduleKind == OMPC_SCHEDULE_static || 13840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ScheduleKind == OMPC_SCHEDULE_unknown) && 13850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines "Non-static schedule kinds are not yet implemented"); 138633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar (void)ScheduleKind; 13870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid); 13880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC), 13890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines getThreadID(CGF, Loc)}; 13900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini), 13910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Args); 13920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 13930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 13943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF, 13953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar SourceLocation Loc, unsigned IVSize, 13963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar bool IVSigned, llvm::Value *IL, 13973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *LB, llvm::Value *UB, 13983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *ST) { 13993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Call __kmpc_dispatch_next( 14003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, 14013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper, 14023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int[32|64] *p_stride); 14033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Args[] = { 14043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar emitUpdateLocation(CGF, Loc, OMP_IDENT_KMPC), getThreadID(CGF, Loc), 14053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar IL, // &isLastIter 14063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar LB, // &Lower 14073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar UB, // &Upper 14083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ST // &Stride 14093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }; 14103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Call = 14113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args); 14123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGF.EmitScalarConversion( 14133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Call, CGF.getContext().getIntTypeForBitwidth(32, /* Signed */ true), 14143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.getContext().BoolTy); 14153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 14163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 14170e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF, 14180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Value *NumThreads, 14190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SourceLocation Loc) { 1420176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Build call __kmpc_push_num_threads(&loc, global_tid, num_threads) 1421176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *Args[] = { 14220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), 1423176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)}; 14240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_threads), 14250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Args); 1426176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 1427176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 14280e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>, 14290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SourceLocation Loc) { 14300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Build call void __kmpc_flush(ident_t *loc) 14310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_flush), 14320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines emitUpdateLocation(CGF, Loc)); 14330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 14340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 14353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarnamespace { 14363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \brief Indexes of fields for type kmp_task_t. 14373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarenum KmpTaskTFields { 14383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \brief List of shared variables. 14393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar KmpTaskTShareds, 14403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \brief Task routine. 14413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar KmpTaskTRoutine, 14423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \brief Partition id for the untied tasks. 14433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar KmpTaskTPartId, 14443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// \brief Function with call of destructors for private variables. 14453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar KmpTaskTDestructors, 14463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}; 14473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} // namespace 14483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 14493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) { 14503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!KmpRoutineEntryPtrTy) { 14513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type. 14523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto &C = CGM.getContext(); 14533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy}; 14543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar FunctionProtoType::ExtProtoInfo EPI; 14553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar KmpRoutineEntryPtrQTy = C.getPointerType( 14563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI)); 14573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar KmpRoutineEntryPtrTy = CGM.getTypes().ConvertType(KmpRoutineEntryPtrQTy); 14583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 14593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 14603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 14613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic void addFieldToRecordDecl(ASTContext &C, DeclContext *DC, 14623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType FieldTy) { 14633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *Field = FieldDecl::Create( 14643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy, 14653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()), 14663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit); 14673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Field->setAccess(AS_public); 14683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar DC->addDecl(Field); 14693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 14703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 14713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic QualType createKmpTaskTRecordDecl(CodeGenModule &CGM, 14723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType KmpInt32Ty, 14733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType KmpRoutineEntryPointerQTy) { 14743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto &C = CGM.getContext(); 14753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build struct kmp_task_t { 14763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // void * shareds; 14773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_routine_entry_t routine; 14783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int32 part_id; 14793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_routine_entry_t destructors; 14803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // /* private vars */ 14813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // }; 14823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *RD = C.buildImplicitRecord("kmp_task_t"); 14833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar RD->startDefinition(); 14843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar addFieldToRecordDecl(C, RD, C.VoidPtrTy); 14853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy); 14863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar addFieldToRecordDecl(C, RD, KmpInt32Ty); 14873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy); 14883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // TODO: add private fields. 14893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar RD->completeDefinition(); 14903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return C.getRecordType(RD); 14913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 14923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 14933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \brief Emit a proxy function which accepts kmp_task_t as the second 14943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// argument. 14953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \code 14963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) { 14973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// TaskFunction(gtid, tt->part_id, tt->shareds); 14983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// return 0; 14993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// } 15003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \endcode 15013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Value * 15023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainaremitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc, 15033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType KmpInt32Ty, QualType KmpTaskTPtrQTy, 150433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar QualType SharedsPtrTy, llvm::Value *TaskFunction, 150533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Type *KmpTaskTTy) { 15063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto &C = CGM.getContext(); 15073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar FunctionArgList Args; 15083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty); 15093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, 15103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*Id=*/nullptr, KmpTaskTPtrQTy); 15113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Args.push_back(&GtidArg); 15123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Args.push_back(&TaskTypeArg); 15133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar FunctionType::ExtInfo Info; 15143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto &TaskEntryFnInfo = 15153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.getTypes().arrangeFreeFunctionDeclaration(KmpInt32Ty, Args, Info, 15163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*isVariadic=*/false); 15173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *TaskEntryTy = CGM.getTypes().GetFunctionType(TaskEntryFnInfo); 15183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *TaskEntry = 15193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Function::Create(TaskEntryTy, llvm::GlobalValue::InternalLinkage, 15203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ".omp_task_entry.", &CGM.getModule()); 15213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, TaskEntryFnInfo, TaskEntry); 15223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CodeGenFunction CGF(CGM); 15233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.disableDebugInfo(); 15243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args); 15253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 15263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // TaskFunction(gtid, tt->part_id, tt->shareds); 15273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *GtidParam = CGF.EmitLoadOfScalar( 15283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false, 15293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.getTypeAlignInChars(KmpInt32Ty).getQuantity(), KmpInt32Ty, Loc); 15303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto TaskTypeArgAddr = CGF.EmitLoadOfScalar( 15313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.GetAddrOfLocalVar(&TaskTypeArg), /*Volatile=*/false, 15323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.PointerAlignInBytes, KmpTaskTPtrQTy, Loc); 153333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *PartidPtr = CGF.Builder.CreateStructGEP(KmpTaskTTy, TaskTypeArgAddr, 15343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*Idx=*/KmpTaskTPartId); 15353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *PartidParam = CGF.EmitLoadOfScalar( 15363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar PartidPtr, /*Volatile=*/false, 15373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar C.getTypeAlignInChars(KmpInt32Ty).getQuantity(), KmpInt32Ty, Loc); 153833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *SharedsPtr = CGF.Builder.CreateStructGEP(KmpTaskTTy, TaskTypeArgAddr, 15393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*Idx=*/KmpTaskTShareds); 15403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *SharedsParam = 15413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitLoadOfScalar(SharedsPtr, /*Volatile=*/false, 15423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.PointerAlignInBytes, C.VoidPtrTy, Loc); 15433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *CallArgs[] = { 15443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar GtidParam, PartidParam, 15453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 15463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar SharedsParam, CGF.ConvertTypeForMem(SharedsPtrTy))}; 15473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitCallOrInvoke(TaskFunction, CallArgs); 15483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitStoreThroughLValue( 15493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar RValue::get(CGF.Builder.getInt32(/*C=*/0)), 15503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.MakeNaturalAlignAddrLValue(CGF.ReturnValue, KmpInt32Ty)); 15513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.FinishFunction(); 15523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return TaskEntry; 15533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 15543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 15553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitTaskCall( 15563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CodeGenFunction &CGF, SourceLocation Loc, bool Tied, 15573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::PointerIntPair<llvm::Value *, 1, bool> Final, 15583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *TaskFunction, QualType SharedsTy, llvm::Value *Shareds) { 15593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto &C = CGM.getContext(); 15603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 15613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build type kmp_routine_entry_t (if not built yet). 15623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar emitKmpRoutineEntryT(KmpInt32Ty); 15633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build particular struct kmp_task_t for the given task. 15643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto KmpTaskQTy = 15653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar createKmpTaskTRecordDecl(CGM, KmpInt32Ty, KmpRoutineEntryPtrQTy); 15663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType KmpTaskTPtrQTy = C.getPointerType(KmpTaskQTy); 156733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *KmpTaskTTy = CGF.ConvertType(KmpTaskQTy); 156833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *KmpTaskTPtrTy = KmpTaskTTy->getPointerTo(); 15693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto KmpTaskTySize = CGM.getSize(C.getTypeSizeInChars(KmpTaskQTy)); 15703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType SharedsPtrTy = C.getPointerType(SharedsTy); 15713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 15723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid, 15733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_task_t *tt); 157433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *TaskEntry = 157533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar emitProxyTaskFunction(CGM, Loc, KmpInt32Ty, KmpTaskTPtrQTy, SharedsPtrTy, 157633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar TaskFunction, KmpTaskTTy); 15773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 15783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build call kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid, 15793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, 15803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // kmp_routine_entry_t *task_entry); 15813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Task flags. Format is taken from 15823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h, 15833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // description of kmp_tasking_flags struct. 15843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const unsigned TiedFlag = 0x1; 15853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const unsigned FinalFlag = 0x2; 15863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar unsigned Flags = Tied ? TiedFlag : 0; 15873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *TaskFlags = 15883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Final.getPointer() 15893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ? CGF.Builder.CreateSelect(Final.getPointer(), 15903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.getInt32(FinalFlag), 15913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.getInt32(/*C=*/0)) 15923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar : CGF.Builder.getInt32(Final.getInt() ? FinalFlag : 0); 15933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags)); 15943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto SharedsSize = C.getTypeSizeInChars(SharedsTy); 15953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *AllocArgs[] = {emitUpdateLocation(CGF, Loc), 15963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getThreadID(CGF, Loc), TaskFlags, KmpTaskTySize, 15973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.getSize(SharedsSize), 15983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 15993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar TaskEntry, KmpRoutineEntryPtrTy)}; 16003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *NewTask = CGF.EmitRuntimeCall( 16013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar createRuntimeFunction(OMPRTL__kmpc_omp_task_alloc), AllocArgs); 16023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto *NewTaskNewTaskTTy = 16033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(NewTask, KmpTaskTPtrTy); 16043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Fill the data in the resulting kmp_task_t record. 16053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Copy shareds if there are any. 16063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!SharedsTy->getAsStructureType()->getDecl()->field_empty()) 16073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitAggregateCopy( 16083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitLoadOfScalar( 160933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateStructGEP(KmpTaskTTy, NewTaskNewTaskTTy, 16103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*Idx=*/KmpTaskTShareds), 16113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*Volatile=*/false, CGM.PointerAlignInBytes, SharedsPtrTy, Loc), 16123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Shareds, SharedsTy); 16133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // TODO: generate function with destructors for privates. 16143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Provide pointer to function with destructors for privates. 16153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateAlignedStore( 16163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::ConstantPointerNull::get( 16173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar cast<llvm::PointerType>(KmpRoutineEntryPtrTy)), 161833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateStructGEP(KmpTaskTTy, NewTaskNewTaskTTy, 16193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*Idx=*/KmpTaskTDestructors), 16203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.PointerAlignInBytes); 16213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 16223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc() 16233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // libcall. 16243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t 16253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // *new_task); 16263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *TaskArgs[] = {emitUpdateLocation(CGF, Loc), 16273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getThreadID(CGF, Loc), NewTask}; 16283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // TODO: add check for untied tasks. 16293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task), TaskArgs); 16303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 16313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 163233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarstatic llvm::Value *emitReductionFunction(CodeGenModule &CGM, 163333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Type *ArgsType, 163433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArrayRef<const Expr *> LHSExprs, 163533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArrayRef<const Expr *> RHSExprs, 163633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArrayRef<const Expr *> ReductionOps) { 163733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto &C = CGM.getContext(); 163833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 163933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // void reduction_func(void *LHSArg, void *RHSArg); 164033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar FunctionArgList Args; 164133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr, 164233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar C.VoidPtrTy); 164333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr, 164433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar C.VoidPtrTy); 164533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Args.push_back(&LHSArg); 164633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Args.push_back(&RHSArg); 164733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar FunctionType::ExtInfo EI; 164833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto &CGFI = CGM.getTypes().arrangeFreeFunctionDeclaration( 164933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar C.VoidTy, Args, EI, /*isVariadic=*/false); 165033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *Fn = llvm::Function::Create( 165133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage, 165233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ".omp.reduction.reduction_func", &CGM.getModule()); 165333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, CGFI, Fn); 165433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction CGF(CGM); 165533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args); 165633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 165733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Dst = (void*[n])(LHSArg); 165833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Src = (void*[n])(RHSArg); 165933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *LHS = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 166033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(CGF.GetAddrOfLocalVar(&LHSArg), 166133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.PointerAlignInBytes), 166233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArgsType); 166333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *RHS = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 166433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(CGF.GetAddrOfLocalVar(&RHSArg), 166533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.PointerAlignInBytes), 166633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArgsType); 166733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 166833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 166933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]); 167033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 167133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction::OMPPrivateScope Scope(CGF); 167233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar for (unsigned I = 0, E = ReductionOps.size(); I < E; ++I) { 167333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Scope.addPrivate( 167433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl()), 167533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar [&]() -> llvm::Value *{ 167633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 167733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad( 167833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, RHS, I), 167933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.PointerAlignInBytes), 168033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.ConvertTypeForMem(C.getPointerType(RHSExprs[I]->getType()))); 168133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar }); 168233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Scope.addPrivate( 168333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl()), 168433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar [&]() -> llvm::Value *{ 168533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 168633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateAlignedLoad( 168733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, LHS, I), 168833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.PointerAlignInBytes), 168933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.ConvertTypeForMem(C.getPointerType(LHSExprs[I]->getType()))); 169033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar }); 169133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 169233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Scope.Privatize(); 169333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar for (auto *E : ReductionOps) { 169433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitIgnoredExpr(E); 169533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 169633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Scope.ForceCleanup(); 169733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.FinishFunction(); 169833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return Fn; 1699176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 17000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 170133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, 170233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArrayRef<const Expr *> LHSExprs, 170333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArrayRef<const Expr *> RHSExprs, 170433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ArrayRef<const Expr *> ReductionOps, 170533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar bool WithNowait) { 170633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Next code should be emitted for reduction: 170733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 170833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // static kmp_critical_name lock = { 0 }; 170933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 171033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // void reduce_func(void *lhs[<n>], void *rhs[<n>]) { 171133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); 171233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 171333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], 171433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // *(Type<n>-1*)rhs[<n>-1]); 171533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // } 171633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 171733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 171833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]}; 171933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), 172033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // RedList, reduce_func, &<lock>)) { 172133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // case 1: 172233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 172333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]); 172433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 172533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>); 172633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // break; 172733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // case 2: 172833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 172933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i])); 173033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 173133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // break; 173233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // default:; 173333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // } 173433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 173533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto &C = CGM.getContext(); 173633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 173733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 1. Build a list of reduction variables. 173833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; 173933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::APInt ArraySize(/*unsigned int numBits=*/32, RHSExprs.size()); 174033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar QualType ReductionArrayTy = 174133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal, 174233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar /*IndexTypeQuals=*/0); 174333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *ReductionList = 174433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list"); 174533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I) { 174633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *Elem = CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, ReductionList, I); 174733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreateAlignedStore( 174833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 174933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitLValue(RHSExprs[I]).getAddress(), CGF.VoidPtrTy), 175033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Elem, CGM.PointerAlignInBytes); 175133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 175233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 175333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 2. Emit reduce_func(). 175433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *ReductionFn = emitReductionFunction( 175533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), LHSExprs, 175633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar RHSExprs, ReductionOps); 175733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 175833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 3. Create static kmp_critical_name lock = { 0 }; 175933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *Lock = getCriticalRegionLock(".reduction"); 176033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 176133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 4. Build res = __kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), 176233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // RedList, reduce_func, &<lock>); 176333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *IdentTLoc = emitUpdateLocation( 176433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF, Loc, 176533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar static_cast<OpenMPLocationFlags>(OMP_IDENT_KMPC | OMP_ATOMIC_REDUCE)); 176633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *ThreadId = getThreadID(CGF, Loc); 176733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *ReductionArrayTySize = llvm::ConstantInt::get( 176833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGM.SizeTy, C.getTypeSizeInChars(ReductionArrayTy).getQuantity()); 176933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(ReductionList, 177033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.VoidPtrTy); 177133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Value *Args[] = { 177233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar IdentTLoc, // ident_t *<loc> 177333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ThreadId, // i32 <gtid> 177433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.Builder.getInt32(RHSExprs.size()), // i32 <n> 177533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ReductionArrayTySize, // size_type sizeof(RedList) 177633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar RL, // void *RedList 177733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ReductionFn, // void (*) (void *, void *) <reduce_func> 177833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Lock // kmp_critical_name *&<lock> 177933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar }; 178033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto Res = CGF.EmitRuntimeCall( 178133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar createRuntimeFunction(WithNowait ? OMPRTL__kmpc_reduce_nowait 178233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : OMPRTL__kmpc_reduce), 178333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Args); 178433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 178533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 5. Build switch(res) 178633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *DefaultBB = CGF.createBasicBlock(".omp.reduction.default"); 178733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *SwInst = CGF.Builder.CreateSwitch(Res, DefaultBB, /*NumCases=*/2); 178833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 178933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 6. Build case 1: 179033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 179133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]); 179233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 179333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>); 179433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // break; 179533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *Case1BB = CGF.createBasicBlock(".omp.reduction.case1"); 179633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar SwInst->addCase(CGF.Builder.getInt32(1), Case1BB); 179733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitBlock(Case1BB); 179833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 179933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar { 180033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction::RunCleanupsScope Scope(CGF); 180133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Add emission of __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>); 180233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::Value *EndArgs[] = { 180333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar IdentTLoc, // ident_t *<loc> 180433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ThreadId, // i32 <gtid> 180533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Lock // kmp_critical_name *&<lock> 180633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar }; 180733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EHStack.pushCleanup<CallEndCleanup>( 180833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar NormalAndEHCleanup, 180933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar createRuntimeFunction(WithNowait ? OMPRTL__kmpc_end_reduce_nowait 181033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar : OMPRTL__kmpc_end_reduce), 181133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar llvm::makeArrayRef(EndArgs)); 181233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar for (auto *E : ReductionOps) { 181333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitIgnoredExpr(E); 181433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 181533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 181633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 181733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitBranch(DefaultBB); 181833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 181933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // 7. Build case 2: 182033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 182133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i])); 182233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // ... 182333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // break; 182433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *Case2BB = CGF.createBasicBlock(".omp.reduction.case2"); 182533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar SwInst->addCase(CGF.Builder.getInt32(2), Case2BB); 182633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitBlock(Case2BB); 182733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 182833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar { 182933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction::RunCleanupsScope Scope(CGF); 183033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto I = LHSExprs.begin(); 183133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar for (auto *E : ReductionOps) { 183233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const Expr *XExpr = nullptr; 183333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const Expr *EExpr = nullptr; 183433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const Expr *UpExpr = nullptr; 183533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar BinaryOperatorKind BO = BO_Comma; 183633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Try to emit update expression as a simple atomic. 183733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (auto *ACO = dyn_cast<AbstractConditionalOperator>(E)) { 183833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // If this is a conditional operator, analyze it's condition for 183933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // min/max reduction operator. 184033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar E = ACO->getCond(); 184133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 184233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (auto *BO = dyn_cast<BinaryOperator>(E)) { 184333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (BO->getOpcode() == BO_Assign) { 184433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar XExpr = BO->getLHS(); 184533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar UpExpr = BO->getRHS(); 184633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 184733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 184833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Analyze RHS part of the whole expression. 184933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (UpExpr) { 185033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (auto *BORHS = 185133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar dyn_cast<BinaryOperator>(UpExpr->IgnoreParenImpCasts())) { 185233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar EExpr = BORHS->getRHS(); 185333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar BO = BORHS->getOpcode(); 185433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 185533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 185633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (XExpr) { 185733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()); 185833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar LValue X = CGF.EmitLValue(XExpr); 185933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar RValue E; 186033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (EExpr) 186133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar E = CGF.EmitAnyExpr(EExpr); 186233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitOMPAtomicSimpleUpdateExpr( 186333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar X, E, BO, /*IsXLHSInRHSPart=*/true, llvm::Monotonic, Loc, 186433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar [&CGF, UpExpr, VD](RValue XRValue) { 186533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CodeGenFunction::OMPPrivateScope PrivateScope(CGF); 186633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar PrivateScope.addPrivate( 186733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar VD, [&CGF, VD, XRValue]() -> llvm::Value *{ 186833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar auto *LHSTemp = CGF.CreateMemTemp(VD->getType()); 186933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitStoreThroughLValue( 187033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar XRValue, 187133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.MakeNaturalAlignAddrLValue(LHSTemp, VD->getType())); 187233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return LHSTemp; 187333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar }); 187433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar (void)PrivateScope.Privatize(); 187533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return CGF.EmitAnyExpr(UpExpr); 187633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar }); 187733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } else { 187833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Emit as a critical region. 187933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar emitCriticalRegion(CGF, ".atomic_reduction", [E](CodeGenFunction &CGF) { 188033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitIgnoredExpr(E); 188133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar }, Loc); 188233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 188333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ++I; 188433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 188533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 188633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 188733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitBranch(DefaultBB); 188833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.EmitBlock(DefaultBB, /*IsFinished=*/true); 188933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar} 189033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 189133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF, 189233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar const RegionCodeGenTy &CodeGen) { 189333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar InlinedOpenMPRegionRAII Region(CGF, CodeGen); 189433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr); 18950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 18960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 1897