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
144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "CGCXXABI.h"
154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "CGCleanup.h"
166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "CGOpenMPRuntime.h"
176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "CodeGenFunction.h"
186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/AST/Decl.h"
190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#include "clang/AST/StmtOpenMP.h"
206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/ArrayRef.h"
214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Bitcode/ReaderWriter.h"
22176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#include "llvm/IR/CallSite.h"
236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/DerivedTypes.h"
246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/GlobalValue.h"
256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/Value.h"
264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Support/Format.h"
276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/Support/raw_ostream.h"
28c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#include <cassert>
296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace clang;
316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace CodeGen;
326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
33176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace {
340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief Base class for handling code generation inside OpenMP regions.
35176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
36176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic:
3758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  /// \brief Kinds of OpenMP regions used in codegen.
3858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  enum CGOpenMPRegionKind {
3958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    /// \brief Region with outlined function for standalone 'parallel'
4058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    /// directive.
4158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    ParallelOutlinedRegion,
4258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    /// \brief Region with outlined function for standalone 'task' directive.
4358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    TaskOutlinedRegion,
4458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    /// \brief Region for constructs that do not require function outlining,
4558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    /// like 'for', 'sections', 'atomic' etc. directives.
4658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    InlinedRegion,
4787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    /// \brief Region with outlined function for standalone 'target' directive.
4887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    TargetRegion,
4958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  };
5058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
5158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGOpenMPRegionInfo(const CapturedStmt &CS,
5258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                     const CGOpenMPRegionKind RegionKind,
5387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                     const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
5487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                     bool HasCancel)
5558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind),
5687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
5858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind,
5987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                     const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
6087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                     bool HasCancel)
6187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
6287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        Kind(Kind), HasCancel(HasCancel) {}
63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// \brief Get a variable or parameter for storing global thread id
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// inside OpenMP construct.
660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  virtual const VarDecl *getThreadIDVariable() const = 0;
67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
6858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  /// \brief Emit the captured statement body.
6987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void EmitBody(CodeGenFunction &CGF, const Stmt *S) override;
7058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// \brief Get an LValue for the current ThreadID variable.
723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \return LValue for thread id variable. This LValue always has type int32*.
733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF);
74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  virtual void emitUntiedSwitch(CodeGenFunction & /*CGF*/) {}
764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
7758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGOpenMPRegionKind getRegionKind() const { return RegionKind; }
780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
7987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
8087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
8187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  bool hasCancel() const { return HasCancel; }
8287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static bool classof(const CGCapturedStmtInfo *Info) {
84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return Info->getKind() == CR_OpenMP;
85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
8658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ~CGOpenMPRegionInfo() override = default;
884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
890e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesprotected:
9058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGOpenMPRegionKind RegionKind;
914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RegionCodeGenTy CodeGen;
9287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  OpenMPDirectiveKind Kind;
9387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  bool HasCancel;
940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
95176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief API for captured statement code generation in OpenMP constructs.
974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass CGOpenMPOutlinedRegionInfo final : public CGOpenMPRegionInfo {
980e2c34f92f00628d48968dfea096d36381f494cbStephen Hinespublic:
9958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
10087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                             const RegionCodeGenTy &CodeGen,
10187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                             OpenMPDirectiveKind Kind, bool HasCancel)
10287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
10387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                           HasCancel),
10458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        ThreadIDVar(ThreadIDVar) {
1050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
1060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
1074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// \brief Get a variable or parameter for storing global thread id
1090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// inside OpenMP construct.
11058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
11158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Get the name of the capture helper.
113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StringRef getHelperName() const override { return ".omp_outlined."; }
114176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
11558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  static bool classof(const CGCapturedStmtInfo *Info) {
11658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    return CGOpenMPRegionInfo::classof(Info) &&
11758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar           cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
11858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar               ParallelOutlinedRegion;
11958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
12058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesprivate:
122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief A variable or parameter storing global thread id for OpenMP
123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// constructs.
124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const VarDecl *ThreadIDVar;
1250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
1260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \brief API for captured statement code generation in OpenMP constructs.
1284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass CGOpenMPTaskOutlinedRegionInfo final : public CGOpenMPRegionInfo {
1293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarpublic:
1304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  class UntiedTaskActionTy final : public PrePostActionTy {
1314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool Untied;
1324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const VarDecl *PartIDVar;
1334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const RegionCodeGenTy UntiedCodeGen;
1344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::SwitchInst *UntiedSwitch = nullptr;
1354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  public:
1374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    UntiedTaskActionTy(bool Tied, const VarDecl *PartIDVar,
1384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                       const RegionCodeGenTy &UntiedCodeGen)
1394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        : Untied(!Tied), PartIDVar(PartIDVar), UntiedCodeGen(UntiedCodeGen) {}
1404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    void Enter(CodeGenFunction &CGF) override {
1414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (Untied) {
1424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // Emit task switching point.
1434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto PartIdLVal = CGF.EmitLoadOfPointerLValue(
1444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            CGF.GetAddrOfLocalVar(PartIDVar),
1454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            PartIDVar->getType()->castAs<PointerType>());
1464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *Res = CGF.EmitLoadOfScalar(PartIdLVal, SourceLocation());
1474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *DoneBB = CGF.createBasicBlock(".untied.done.");
1484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        UntiedSwitch = CGF.Builder.CreateSwitch(Res, DoneBB);
1494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitBlock(DoneBB);
1504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
1514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
1524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        UntiedSwitch->addCase(CGF.Builder.getInt32(0),
1534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              CGF.Builder.GetInsertBlock());
1544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        emitUntiedSwitch(CGF);
1554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
1564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
1574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    void emitUntiedSwitch(CodeGenFunction &CGF) const {
1584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (Untied) {
1594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto PartIdLVal = CGF.EmitLoadOfPointerLValue(
1604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            CGF.GetAddrOfLocalVar(PartIDVar),
1614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            PartIDVar->getType()->castAs<PointerType>());
1624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitStoreOfScalar(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
1634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              PartIdLVal);
1644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        UntiedCodeGen(CGF);
1654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CodeGenFunction::JumpDest CurPoint =
1664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            CGF.getJumpDestInCurrentScope(".untied.next.");
1674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
1684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
1694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        UntiedSwitch->addCase(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
1704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              CGF.Builder.GetInsertBlock());
1714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitBranchThroughCleanup(CurPoint);
1724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitBlock(CurPoint.getBlock());
1734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
1744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
1754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned getNumberOfParts() const { return UntiedSwitch->getNumCases(); }
1764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
17758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS,
1783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                 const VarDecl *ThreadIDVar,
17987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                 const RegionCodeGenTy &CodeGen,
1804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 OpenMPDirectiveKind Kind, bool HasCancel,
1814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 const UntiedTaskActionTy &Action)
18287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
1834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ThreadIDVar(ThreadIDVar), Action(Action) {
1843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
1853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
1864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \brief Get a variable or parameter for storing global thread id
1883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// inside OpenMP construct.
18958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
1903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
1913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \brief Get an LValue for the current ThreadID variable.
19258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override;
1933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
1943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \brief Get the name of the capture helper.
1953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  StringRef getHelperName() const override { return ".omp_outlined."; }
1963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
1974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void emitUntiedSwitch(CodeGenFunction &CGF) override {
1984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Action.emitUntiedSwitch(CGF);
1994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
20158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  static bool classof(const CGCapturedStmtInfo *Info) {
20258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    return CGOpenMPRegionInfo::classof(Info) &&
20358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar           cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
20458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar               TaskOutlinedRegion;
20558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
20658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
2073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarprivate:
2083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \brief A variable or parameter storing global thread id for OpenMP
2093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// constructs.
2103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  const VarDecl *ThreadIDVar;
2114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Action for emitting code for untied tasks.
2124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const UntiedTaskActionTy &Action;
2133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar};
2143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
2150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief API for inlined captured statement code generation in OpenMP
2160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// constructs.
2170e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
2180e2c34f92f00628d48968dfea096d36381f494cbStephen Hinespublic:
21958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI,
22087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                            const RegionCodeGenTy &CodeGen,
22187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                            OpenMPDirectiveKind Kind, bool HasCancel)
22287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
22387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        OldCSI(OldCSI),
2240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
2254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // \brief Retrieve the value of the context parameter.
22758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  llvm::Value *getContextValue() const override {
2280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (OuterRegionInfo)
2290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return OuterRegionInfo->getContextValue();
2300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm_unreachable("No context value for inlined OpenMP region");
2310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
2324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
23387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void setContextValue(llvm::Value *V) override {
23458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (OuterRegionInfo) {
23558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      OuterRegionInfo->setContextValue(V);
23658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      return;
23758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    }
23858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm_unreachable("No context value for inlined OpenMP region");
23958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
2404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// \brief Lookup the captured field decl for a variable.
24258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  const FieldDecl *lookup(const VarDecl *VD) const override {
2430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (OuterRegionInfo)
2440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return OuterRegionInfo->lookup(VD);
24558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // If there is no outer outlined region,no need to lookup in a list of
24658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // captured variables, we can use the original one.
24758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    return nullptr;
2480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
2494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
25058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  FieldDecl *getThisFieldDecl() const override {
2510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (OuterRegionInfo)
2520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return OuterRegionInfo->getThisFieldDecl();
2530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return nullptr;
2540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
2554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// \brief Get a variable or parameter for storing global thread id
2570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// inside OpenMP construct.
25858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  const VarDecl *getThreadIDVariable() const override {
2590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (OuterRegionInfo)
2600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return OuterRegionInfo->getThreadIDVariable();
2610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return nullptr;
2620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
2633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
2640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// \brief Get the name of the capture helper.
26558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  StringRef getHelperName() const override {
26658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (auto *OuterRegionInfo = getOldCSI())
26758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      return OuterRegionInfo->getHelperName();
2680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm_unreachable("No helper name for inlined OpenMP construct");
2690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
2700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
2714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void emitUntiedSwitch(CodeGenFunction &CGF) override {
2724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (OuterRegionInfo)
2734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OuterRegionInfo->emitUntiedSwitch(CGF);
2744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CodeGenFunction::CGCapturedStmtInfo *getOldCSI() const { return OldCSI; }
2770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
27858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  static bool classof(const CGCapturedStmtInfo *Info) {
27958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    return CGOpenMPRegionInfo::classof(Info) &&
28058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar           cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
28158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
28258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
2834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ~CGOpenMPInlinedRegionInfo() override = default;
2844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2850e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesprivate:
2860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// \brief CodeGen info about outer OpenMP region.
2870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CodeGenFunction::CGCapturedStmtInfo *OldCSI;
2880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGOpenMPRegionInfo *OuterRegionInfo;
289176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
29058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
29187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// \brief API for captured statement code generation in OpenMP target
29287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// constructs. For this captures, implicit parameters are used instead of the
2934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// captured fields. The name of the target region has to be unique in a given
2944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// application so it is provided by the client, because only the client has
2954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// the information to generate that.
2964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass CGOpenMPTargetRegionInfo final : public CGOpenMPRegionInfo {
29787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarpublic:
29887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGOpenMPTargetRegionInfo(const CapturedStmt &CS,
2994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                           const RegionCodeGenTy &CodeGen, StringRef HelperName)
30087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      : CGOpenMPRegionInfo(CS, TargetRegion, CodeGen, OMPD_target,
3014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                           /*HasCancel=*/false),
3024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        HelperName(HelperName) {}
30387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
30487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  /// \brief This is unused for target regions because each starts executing
30587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  /// with a single thread.
30687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const VarDecl *getThreadIDVariable() const override { return nullptr; }
30787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
30887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  /// \brief Get the name of the capture helper.
3094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  StringRef getHelperName() const override { return HelperName; }
31087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
31187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  static bool classof(const CGCapturedStmtInfo *Info) {
31287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return CGOpenMPRegionInfo::classof(Info) &&
31387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar           cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == TargetRegion;
31487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
3154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprivate:
3174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  StringRef HelperName;
3184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
3194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void EmptyCodeGen(CodeGenFunction &, PrePostActionTy &) {
3214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm_unreachable("No codegen for expressions");
3224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
3234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief API for generation of expressions captured in a innermost OpenMP
3244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// region.
3254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass CGOpenMPInnerExprInfo final : public CGOpenMPInlinedRegionInfo {
3264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
3274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGOpenMPInnerExprInfo(CodeGenFunction &CGF, const CapturedStmt &CS)
3284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, EmptyCodeGen,
3294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  OMPD_unknown,
3304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  /*HasCancel=*/false),
3314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        PrivScope(CGF) {
3324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Make sure the globals captured in the provided statement are local by
3334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // using the privatization logic. We assume the same variable is not
3344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // captured more than once.
3354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto &C : CS.captures()) {
3364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (!C.capturesVariable() && !C.capturesVariableByCopy())
3374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        continue;
3384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const VarDecl *VD = C.getCapturedVar();
3404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (VD->isLocalVarDeclOrParm())
3414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        continue;
3424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DeclRefExpr DRE(const_cast<VarDecl *>(VD),
3444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      /*RefersToEnclosingVariableOrCapture=*/false,
3454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      VD->getType().getNonReferenceType(), VK_LValue,
3464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      SourceLocation());
3474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      PrivScope.addPrivate(VD, [&CGF, &DRE]() -> Address {
3484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        return CGF.EmitLValue(&DRE).getAddress();
3494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      });
3504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
3514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    (void)PrivScope.Privatize();
3524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Lookup the captured field decl for a variable.
3554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const FieldDecl *lookup(const VarDecl *VD) const override {
3564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *FD = CGOpenMPInlinedRegionInfo::lookup(VD))
3574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return FD;
3584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return nullptr;
3594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Emit the captured statement body.
3624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void EmitBody(CodeGenFunction &CGF, const Stmt *S) override {
3634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm_unreachable("No body for expressions");
3644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Get a variable or parameter for storing global thread id
3674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// inside OpenMP construct.
3684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const VarDecl *getThreadIDVariable() const override {
3694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm_unreachable("No thread id for expressions");
3704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Get the name of the capture helper.
3734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  StringRef getHelperName() const override {
3744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm_unreachable("No helper name for expressions");
3754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static bool classof(const CGCapturedStmtInfo *Info) { return false; }
3784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprivate:
3804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Private scope to capture global variables.
3814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction::OMPPrivateScope PrivScope;
38287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar};
38387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
38458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar/// \brief RAII for emitting code of OpenMP constructs.
38558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarclass InlinedOpenMPRegionRAII {
38658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CodeGenFunction &CGF;
3874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
3884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FieldDecl *LambdaThisCaptureField = nullptr;
38958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
39058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarpublic:
39158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  /// \brief Constructs region for combined constructs.
39258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  /// \param CodeGen Code generation sequence for combined directives. Includes
39358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  /// a list of functions used for code generation of implicitly inlined
39458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  /// regions.
39587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen,
39687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                          OpenMPDirectiveKind Kind, bool HasCancel)
39758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      : CGF(CGF) {
39858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // Start emission for the construct.
39987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo(
40087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel);
4014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
4024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LambdaThisCaptureField = CGF.LambdaThisCaptureField;
4034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.LambdaThisCaptureField = nullptr;
40458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
4054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
40658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  ~InlinedOpenMPRegionRAII() {
40758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // Restore original CapturedStmtInfo only if we're done with code emission.
40858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    auto *OldCSI =
40958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI();
41058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    delete CGF.CapturedStmtInfo;
41158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    CGF.CapturedStmtInfo = OldCSI;
4124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
4134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.LambdaThisCaptureField = LambdaThisCaptureField;
4144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
4154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
4164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Values for bit flags used in the ident_t to describe the fields.
4184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// All enumeric elements are named and described in accordance with the code
4194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// from http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
4204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarenum OpenMPLocationFlags {
4214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Use trampoline for internal microtask.
4224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_IDENT_IMD = 0x01,
4234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Use c-style ident structure.
4244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_IDENT_KMPC = 0x02,
4254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Atomic reduction option for kmpc_reduce.
4264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_ATOMIC_REDUCE = 0x10,
4274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Explicit 'barrier' directive.
4284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_IDENT_BARRIER_EXPL = 0x20,
4294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Implicit barrier in code.
4304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_IDENT_BARRIER_IMPL = 0x40,
4314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Implicit barrier in 'for' directive.
4324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
4334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Implicit barrier in 'sections' directive.
4344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
4354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Implicit barrier in 'single' directive.
4364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140
4374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
4384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Describes ident structure that describes a source location.
4404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// All descriptions are taken from
4414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
4424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Original structure:
4434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// typedef struct ident {
4444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///    kmp_int32 reserved_1;   /**<  might be used in Fortran;
4454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                                  see above  */
4464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///    kmp_int32 flags;        /**<  also f.flags; KMP_IDENT_xxx flags;
4474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                                  KMP_IDENT_KMPC identifies this union
4484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                                  member  */
4494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///    kmp_int32 reserved_2;   /**<  not really used in Fortran any more;
4504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                                  see above */
4514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///#if USE_ITT_BUILD
4524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                            /*  but currently used for storing
4534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                                region-specific ITT */
4544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                            /*  contextual information. */
4554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///#endif /* USE_ITT_BUILD */
4564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///    kmp_int32 reserved_3;   /**< source[4] in Fortran, do not use for
4574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                                 C++  */
4584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///    char const *psource;    /**< String describing the source location.
4594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                            The string is composed of semi-colon separated
4604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//                             fields which describe the source file,
4614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                            the function and a pair of line numbers that
4624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                            delimit the construct.
4634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                             */
4644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// } ident_t;
4654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarenum IdentFieldIndex {
4664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief might be used in Fortran
4674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  IdentField_Reserved_1,
4684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
4694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  IdentField_Flags,
4704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Not really used in Fortran any more
4714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  IdentField_Reserved_2,
4724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Source[4] in Fortran, do not use for C++
4734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  IdentField_Reserved_3,
4744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief String describing the source location. The string is composed of
4754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// semi-colon separated fields which describe the source file, the function
4764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// and a pair of line numbers that delimit the construct.
4774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  IdentField_PSource
4784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
4794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Schedule types for 'omp for' loops (these enumerators are taken from
4814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// the enum sched_type in kmp.h).
4824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarenum OpenMPSchedType {
4834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Lower bound for default (unordered) versions.
4844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_lower = 32,
4854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_static_chunked = 33,
4864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_static = 34,
4874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_dynamic_chunked = 35,
4884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_guided_chunked = 36,
4894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_runtime = 37,
4904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_auto = 38,
4914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// static with chunk adjustment (e.g., simd)
4924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_static_balanced_chunked   = 45,
4934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Lower bound for 'ordered' versions.
4944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_ord_lower = 64,
4954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_ord_static_chunked = 65,
4964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_ord_static = 66,
4974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_ord_dynamic_chunked = 67,
4984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_ord_guided_chunked = 68,
4994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_ord_runtime = 69,
5004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_ord_auto = 70,
5014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_default = OMP_sch_static,
5024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief dist_schedule types
5034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_dist_sch_static_chunked = 91,
5044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_dist_sch_static = 92,
5054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers.
5064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Set if the monotonic schedule modifier was present.
5074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_modifier_monotonic = (1 << 29),
5084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Set if the nonmonotonic schedule modifier was present.
5094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_sch_modifier_nonmonotonic = (1 << 30),
5104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
5114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
5124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarenum OpenMPRTLFunction {
5134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc,
5144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// kmpc_micro microtask, ...);
5154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_fork_call,
5164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Call to void *__kmpc_threadprivate_cached(ident_t *loc,
5174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// kmp_int32 global_tid, void *data, size_t size, void ***cache);
5184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_threadprivate_cached,
5194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Call to void __kmpc_threadprivate_register( ident_t *,
5204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
5214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_threadprivate_register,
5224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to __kmpc_int32 kmpc_global_thread_num(ident_t *loc);
5234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_global_thread_num,
5244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
5254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_critical_name *crit);
5264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_critical,
5274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_critical_with_hint(ident_t *loc, kmp_int32
5284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // global_tid, kmp_critical_name *crit, uintptr_t hint);
5294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_critical_with_hint,
5304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
5314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_critical_name *crit);
5324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_end_critical,
5334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
5344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // global_tid);
5354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_cancel_barrier,
5364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
5374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_barrier,
5384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
5394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_for_static_fini,
5404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
5414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // global_tid);
5424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_serialized_parallel,
5434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
5444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // global_tid);
5454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_end_serialized_parallel,
5464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
5474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_int32 num_threads);
5484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_push_num_threads,
5494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_flush(ident_t *loc);
5504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_flush,
5514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_master(ident_t *, kmp_int32 global_tid);
5524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_master,
5534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_end_master(ident_t *, kmp_int32 global_tid);
5544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_end_master,
5554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
5564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // int end_part);
5574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_omp_taskyield,
5584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_single(ident_t *, kmp_int32 global_tid);
5594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_single,
5604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_end_single(ident_t *, kmp_int32 global_tid);
5614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_end_single,
5624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
5634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
5644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_routine_entry_t *task_entry);
5654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_omp_task_alloc,
5664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *
5674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // new_task);
5684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_omp_task,
5694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
5704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
5714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_int32 didit);
5724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_copyprivate,
5734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
5744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
5754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
5764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_reduce,
5774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
5784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
5794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
5804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // *lck);
5814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_reduce_nowait,
5824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
5834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_critical_name *lck);
5844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_end_reduce,
5854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
5864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_critical_name *lck);
5874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_end_reduce_nowait,
5884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
5894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_task_t * new_task);
5904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_omp_task_begin_if0,
5914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
5924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_task_t * new_task);
5934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_omp_task_complete_if0,
5944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
5954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_ordered,
5964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
5974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_end_ordered,
5984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
5994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // global_tid);
6004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_omp_taskwait,
6014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
6024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_taskgroup,
6034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
6044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_end_taskgroup,
6054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
6064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // int proc_bind);
6074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_push_proc_bind,
6084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32
6094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // gtid, kmp_task_t * new_task, kmp_int32 ndeps, kmp_depend_info_t
6104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
6114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_omp_task_with_deps,
6124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32
6134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
6144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
6154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_omp_wait_deps,
6164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
6174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // global_tid, kmp_int32 cncl_kind);
6184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_cancellationpoint,
6194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
6204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_int32 cncl_kind);
6214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_cancel,
6224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid,
6234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_int32 num_teams, kmp_int32 thread_limit);
6244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_push_num_teams,
6254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro
6264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // microtask, ...);
6274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_fork_teams,
6284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
6294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
6304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // sched, kmp_uint64 grainsize, void *task_dup);
6314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_taskloop,
6324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, kmp_int32
6334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // num_dims, struct kmp_dim *dims);
6344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_doacross_init,
6354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_doacross_fini(ident_t *loc, kmp_int32 gtid);
6364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_doacross_fini,
6374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_doacross_post(ident_t *loc, kmp_int32 gtid, kmp_int64
6384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // *vec);
6394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_doacross_post,
6404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
6414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // *vec);
6424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__kmpc_doacross_wait,
6434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
6444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
6454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Offloading related calls
6464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
6474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to int32_t __tgt_target(int32_t device_id, void *host_ptr, int32_t
6484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // arg_num, void** args_base, void **args, size_t *arg_sizes, int32_t
6494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // *arg_types);
6504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__tgt_target,
6514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to int32_t __tgt_target_teams(int32_t device_id, void *host_ptr,
6524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes,
6534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // int32_t *arg_types, int32_t num_teams, int32_t thread_limit);
6544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__tgt_target_teams,
6554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __tgt_register_lib(__tgt_bin_desc *desc);
6564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__tgt_register_lib,
6574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __tgt_unregister_lib(__tgt_bin_desc *desc);
6584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__tgt_unregister_lib,
6594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __tgt_target_data_begin(int32_t device_id, int32_t arg_num,
6604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // void** args_base, void **args, size_t *arg_sizes, int32_t *arg_types);
6614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__tgt_target_data_begin,
6624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __tgt_target_data_end(int32_t device_id, int32_t arg_num,
6634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // void** args_base, void **args, size_t *arg_sizes, int32_t *arg_types);
6644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__tgt_target_data_end,
6654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __tgt_target_data_update(int32_t device_id, int32_t arg_num,
6664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // void** args_base, void **args, size_t *arg_sizes, int32_t *arg_types);
6674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPRTL__tgt_target_data_update,
6684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
6694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
6704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// A basic class for pre|post-action for advanced codegen sequence for OpenMP
6714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// region.
6724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass CleanupTy final : public EHScopeStack::Cleanup {
6734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  PrePostActionTy *Action;
6744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
6754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
6764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  explicit CleanupTy(PrePostActionTy *Action) : Action(Action) {}
6774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
6784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!CGF.HaveInsertPoint())
6794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return;
6804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Action->Exit(CGF);
68158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
68258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar};
68358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
68487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // anonymous namespace
68587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
6864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid RegionCodeGenTy::operator()(CodeGenFunction &CGF) const {
6874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction::RunCleanupsScope Scope(CGF);
6884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (PrePostAction) {
6894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EHStack.pushCleanup<CleanupTy>(NormalAndEHCleanup, PrePostAction);
6904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Callback(CodeGen, CGF, *PrePostAction);
6914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else {
6924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PrePostActionTy Action;
6934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Callback(CodeGen, CGF, Action);
6944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
69587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
696176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
697176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesLValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
6984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return CGF.EmitLoadOfPointerLValue(
6994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.GetAddrOfLocalVar(getThreadIDVariable()),
7004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      getThreadIDVariable()->getType()->castAs<PointerType>());
701176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
702176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
70358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) {
70487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
70587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
70658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // 1.2.2 OpenMP Language Terminology
70758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Structured block - An executable statement with a single entry at the
70858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // top and a single exit at the bottom.
70958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // The point of exit cannot be a branch out of the structured block.
71058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // longjmp() and throw() must not violate the entry/exit criteria.
71158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.EHStack.pushTerminate();
7124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGen(CGF);
71358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.EHStack.popTerminate();
714176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
715176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
7163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarLValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
7173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    CodeGenFunction &CGF) {
71887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()),
71987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                            getThreadIDVariable()->getType(),
72087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                            AlignmentSource::Decl);
7213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
7223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
7236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesCGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
7244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    : CGM(CGM), OffloadEntriesInfoManager(CGM) {
7256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  IdentTy = llvm::StructType::create(
7266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      "ident_t", CGM.Int32Ty /* reserved_1 */, CGM.Int32Ty /* flags */,
7276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      CGM.Int32Ty /* reserved_2 */, CGM.Int32Ty /* reserved_3 */,
728176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CGM.Int8PtrTy /* psource */, nullptr);
729176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
7304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
7314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  loadOffloadInfoMetadata();
732176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
733176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
7343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarvoid CGOpenMPRuntime::clear() {
7353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  InternalVars.clear();
7363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
7373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
7384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic llvm::Function *
7394967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainaremitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty,
7404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          const Expr *CombinerInitializer, const VarDecl *In,
7414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          const VarDecl *Out, bool IsCombiner) {
7424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // void .omp_combiner.(Ty *in, Ty *out);
7434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &C = CGM.getContext();
7444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  QualType PtrTy = C.getPointerType(Ty).withRestrict();
7454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FunctionArgList Args;
7464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ImplicitParamDecl OmpOutParm(C, /*DC=*/nullptr, Out->getLocation(),
7474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                               /*Id=*/nullptr, PtrTy);
7484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ImplicitParamDecl OmpInParm(C, /*DC=*/nullptr, In->getLocation(),
7494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              /*Id=*/nullptr, PtrTy);
7504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Args.push_back(&OmpOutParm);
7514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Args.push_back(&OmpInParm);
7524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &FnInfo =
7534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
7544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
7554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *Fn = llvm::Function::Create(
7564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      FnTy, llvm::GlobalValue::InternalLinkage,
7574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      IsCombiner ? ".omp_combiner." : ".omp_initializer.", &CGM.getModule());
7584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo);
7594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Fn->addFnAttr(llvm::Attribute::AlwaysInline);
7604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction CGF(CGM);
7614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Map "T omp_in;" variable to "*omp_in_parm" value in all expressions.
7624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Map "T omp_out;" variable to "*omp_out_parm" value in all expressions.
7634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args);
7644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction::OMPPrivateScope Scope(CGF);
7654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Address AddrIn = CGF.GetAddrOfLocalVar(&OmpInParm);
7664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Scope.addPrivate(In, [&CGF, AddrIn, PtrTy]() -> Address {
7674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return CGF.EmitLoadOfPointerLValue(AddrIn, PtrTy->castAs<PointerType>())
7684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        .getAddress();
7694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  });
7704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Address AddrOut = CGF.GetAddrOfLocalVar(&OmpOutParm);
7714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Scope.addPrivate(Out, [&CGF, AddrOut, PtrTy]() -> Address {
7724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return CGF.EmitLoadOfPointerLValue(AddrOut, PtrTy->castAs<PointerType>())
7734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        .getAddress();
7744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  });
7754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  (void)Scope.Privatize();
7764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitIgnoredExpr(CombinerInitializer);
7774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Scope.ForceCleanup();
7784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.FinishFunction();
7794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Fn;
7804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
7814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
7824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitUserDefinedReduction(
7834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CodeGenFunction *CGF, const OMPDeclareReductionDecl *D) {
7844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (UDRMap.count(D) > 0)
7854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
7864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &C = CGM.getContext();
7874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!In || !Out) {
7884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    In = &C.Idents.get("omp_in");
7894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Out = &C.Idents.get("omp_out");
7904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
7914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Function *Combiner = emitCombinerOrInitializer(
7924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM, D->getType(), D->getCombiner(), cast<VarDecl>(D->lookup(In).front()),
7934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      cast<VarDecl>(D->lookup(Out).front()),
7944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      /*IsCombiner=*/true);
7954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Function *Initializer = nullptr;
7964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *Init = D->getInitializer()) {
7974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!Priv || !Orig) {
7984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Priv = &C.Idents.get("omp_priv");
7994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Orig = &C.Idents.get("omp_orig");
8004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
8014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Initializer = emitCombinerOrInitializer(
8024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM, D->getType(), Init, cast<VarDecl>(D->lookup(Orig).front()),
8034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        cast<VarDecl>(D->lookup(Priv).front()),
8044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*IsCombiner=*/false);
8054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
8064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  UDRMap.insert(std::make_pair(D, std::make_pair(Combiner, Initializer)));
8074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (CGF) {
8084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->CurFn);
8094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Decls.second.push_back(D);
8104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
8114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
8124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
8134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstd::pair<llvm::Function *, llvm::Function *>
8144967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCGOpenMPRuntime::getUserDefinedReduction(const OMPDeclareReductionDecl *D) {
8154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto I = UDRMap.find(D);
8164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (I != UDRMap.end())
8174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return I->second;
8184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  emitUserDefinedReduction(/*CGF=*/nullptr, D);
8194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return UDRMap.lookup(D);
8204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
8214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
82287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// Layout information for ident_t.
82387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic CharUnits getIdentAlign(CodeGenModule &CGM) {
82487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return CGM.getPointerAlign();
82587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
82687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic CharUnits getIdentSize(CodeGenModule &CGM) {
82787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  assert((4 * CGM.getPointerSize()).isMultipleOf(CGM.getPointerAlign()));
82887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return CharUnits::fromQuantity(16) + CGM.getPointerSize();
82987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
8304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic CharUnits getOffsetOfIdentField(IdentFieldIndex Field) {
83187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // All the fields except the last are i32, so this works beautifully.
83287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return unsigned(Field) * CharUnits::fromQuantity(4);
83387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
83487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic Address createIdentFieldGEP(CodeGenFunction &CGF, Address Addr,
8354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   IdentFieldIndex Field,
83687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                   const llvm::Twine &Name = "") {
83787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto Offset = getOffsetOfIdentField(Field);
83887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return CGF.Builder.CreateStructGEP(Addr, Field, Offset, Name);
83987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
84087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
8414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarllvm::Value *CGOpenMPRuntime::emitParallelOrTeamsOutlinedFunction(
84287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
84387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
8443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  assert(ThreadIDVar->getType()->isPointerType() &&
8453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar         "thread id variable must be of type kmp_int32 *");
846176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt());
847176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CodeGenFunction CGF(CGM, true);
84887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  bool HasCancel = false;
84987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (auto *OPD = dyn_cast<OMPParallelDirective>(&D))
85087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    HasCancel = OPD->hasCancel();
85187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
85287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    HasCancel = OPSD->hasCancel();
85387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  else if (auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
85487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    HasCancel = OPFD->hasCancel();
85587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
85687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                    HasCancel);
85787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
85887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
8596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
8606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
86187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarllvm::Value *CGOpenMPRuntime::emitTaskOutlinedFunction(
86287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
8634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const VarDecl *PartIDVar, const VarDecl *TaskTVar,
8644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
8654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool Tied, unsigned &NumberOfParts) {
8664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&UntiedCodeGen = [this, &D, TaskTVar](CodeGenFunction &CGF,
8674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                              PrePostActionTy &) {
8684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *ThreadID = getThreadID(CGF, D.getLocStart());
8694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *UpLoc = emitUpdateLocation(CGF, D.getLocStart());
8704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *TaskArgs[] = {
8714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        UpLoc, ThreadID,
8724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar),
8734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    TaskTVar->getType()->castAs<PointerType>())
8744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            .getPointer()};
8754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task), TaskArgs);
8764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
8774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGOpenMPTaskOutlinedRegionInfo::UntiedTaskActionTy Action(Tied, PartIDVar,
8784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                            UntiedCodeGen);
8794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGen.setAction(Action);
8803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  assert(!ThreadIDVar->getType()->isPointerType() &&
8813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar         "thread id variable must be of type kmp_int32 for tasks");
8823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *CS = cast<CapturedStmt>(D.getAssociatedStmt());
8834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *TD = dyn_cast<OMPTaskDirective>(&D);
8843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CodeGenFunction CGF(CGM, true);
88587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
88687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                        InnermostKind,
8874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        TD ? TD->hasCancel() : false, Action);
88887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
8894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *Res = CGF.GenerateCapturedStmtFunction(*CS);
8904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!Tied)
8914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    NumberOfParts = Action.getNumberOfParts();
8924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Res;
8933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
8943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
8954967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarAddress CGOpenMPRuntime::getOrCreateDefaultLocation(unsigned Flags) {
89687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CharUnits Align = getIdentAlign(CGM);
8976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags);
8986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Entry) {
8996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (!DefaultOpenMPPSource) {
9006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // Initialize default location for psource field of ident_t structure of
9016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // all ident_t objects. Format is ";file;function;line;column;;".
9026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // Taken from
9036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp_str.c
9046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      DefaultOpenMPPSource =
90587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;").getPointer();
9066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      DefaultOpenMPPSource =
9076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
9086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
909176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto DefaultOpenMPLocation = new llvm::GlobalVariable(
910176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        CGM.getModule(), IdentTy, /*isConstant*/ true,
911176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::GlobalValue::PrivateLinkage, /*Initializer*/ nullptr);
9124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    DefaultOpenMPLocation->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
91387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DefaultOpenMPLocation->setAlignment(Align.getQuantity());
9146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
9156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true);
916c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    llvm::Constant *Values[] = {Zero,
917c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                                llvm::ConstantInt::get(CGM.Int32Ty, Flags),
918c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                                Zero, Zero, DefaultOpenMPPSource};
9196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values);
9206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DefaultOpenMPLocation->setInitializer(Init);
92187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    OpenMPDefaultLocMap[Flags] = Entry = DefaultOpenMPLocation;
9226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
92387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return Address(Entry, Align);
9246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
9256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
9260e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
9270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                                 SourceLocation Loc,
9284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                 unsigned Flags) {
9294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Flags |= OMP_IDENT_KMPC;
9306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // If no debug info is generated - return global default location.
9314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo ||
9326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Loc.isInvalid())
93387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return getOrCreateDefaultLocation(Flags).getPointer();
9346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
9356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert(CGF.CurFn && "No function in current CodeGenFunction.");
9366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
93787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address LocValue = Address::invalid();
9380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
9390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (I != OpenMPLocThreadIDMap.end())
94087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    LocValue = Address(I->second.DebugLoc, getIdentAlign(CGF.CGM));
94187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
9420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // OpenMPLocThreadIDMap may have null DebugLoc and non-null ThreadID, if
9430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // GetOpenMPThreadID was called before this routine.
94487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!LocValue.isValid()) {
9456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Generate "ident_t .kmpc_loc.addr;"
94687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Address AI = CGF.CreateTempAlloca(IdentTy, getIdentAlign(CGF.CGM),
94787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                      ".kmpc_loc.addr");
948176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
94987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Elem.second.DebugLoc = AI.getPointer();
9506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    LocValue = AI;
9516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
9526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
9536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
9540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    CGF.Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags),
95587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                             CGM.getSize(getIdentSize(CGF.CGM)));
9566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
9576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
9586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // char **psource = &.kmpc_loc_<flags>.addr.psource;
95987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address PSource = createIdentFieldGEP(CGF, LocValue, IdentField_PSource);
9606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
961c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  auto OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
962c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  if (OMPDebugLoc == nullptr) {
963c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    SmallString<128> Buffer2;
964c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    llvm::raw_svector_ostream OS2(Buffer2);
965c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    // Build debug location
966c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
967c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    OS2 << ";" << PLoc.getFilename() << ";";
968c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    if (const FunctionDecl *FD =
969c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines            dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) {
970c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      OS2 << FD->getQualifiedNameAsString();
971c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    }
972c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
973c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
974c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
9756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
9766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // *psource = ";<File>;<Function>;<Line>;<Column>;;";
977c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  CGF.Builder.CreateStore(OMPDebugLoc, PSource);
978c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
97987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Our callers always pass this to a runtime function, so for
98087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // convenience, go ahead and return a naked pointer.
98187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return LocValue.getPointer();
9826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
9836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
9840e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
9850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                          SourceLocation Loc) {
9866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert(CGF.CurFn && "No function in current CodeGenFunction.");
9876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
988176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::Value *ThreadID = nullptr;
989176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Check whether we've already cached a load of the thread id in this
990176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // function.
9910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
992176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (I != OpenMPLocThreadIDMap.end()) {
993176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    ThreadID = I->second.ThreadID;
994176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (ThreadID != nullptr)
995176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      return ThreadID;
996176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
9974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *OMPRegionInfo =
9980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
9993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    if (OMPRegionInfo->getThreadIDVariable()) {
10000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      // Check if this an outlined function with thread id passed as argument.
10010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      auto LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
10020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      ThreadID = CGF.EmitLoadOfLValue(LVal, Loc).getScalarVal();
10030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      // If value loaded in entry block, cache it and use it everywhere in
10040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      // function.
10050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      if (CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) {
10060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
10070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        Elem.second.ThreadID = ThreadID;
10080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      }
10090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return ThreadID;
1010176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
10116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
10120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
10130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // This is not an outlined function region - need to call __kmpc_int32
10140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // kmpc_global_thread_num(ident_t *loc).
10150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Generate thread id value and cache this value for use across the
10160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // function.
10170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
10180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
10190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  ThreadID =
10200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
10210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                          emitUpdateLocation(CGF, Loc));
10220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
10230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Elem.second.ThreadID = ThreadID;
1024176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return ThreadID;
10256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
10266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
10270e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) {
10286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert(CGF.CurFn && "No function in current CodeGenFunction.");
1029176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (OpenMPLocThreadIDMap.count(CGF.CurFn))
1030176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    OpenMPLocThreadIDMap.erase(CGF.CurFn);
10314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (FunctionUDRMap.count(CGF.CurFn) > 0) {
10324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for(auto *D : FunctionUDRMap[CGF.CurFn]) {
10334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      UDRMap.erase(D);
10344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
10354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    FunctionUDRMap.erase(CGF.CurFn);
10364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
10376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
10386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
10396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
10404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!IdentTy) {
10414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
10426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return llvm::PointerType::getUnqual(IdentTy);
10436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
10446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
10456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
10464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!Kmpc_MicroTy) {
10474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
10484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
10494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 llvm::PointerType::getUnqual(CGM.Int32Ty)};
10504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
10514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
10526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return llvm::PointerType::getUnqual(Kmpc_MicroTy);
10536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
10546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
10556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Constant *
10564967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
10576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::Constant *RTLFn = nullptr;
10584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  switch (static_cast<OpenMPRTLFunction>(Function)) {
10596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  case OMPRTL__kmpc_fork_call: {
10606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
10616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // microtask, ...);
1062c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1063c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                                getKmpc_MicroPointerTy()};
10646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::FunctionType *FnTy =
1065176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
10666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
10676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    break;
10686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
10696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  case OMPRTL__kmpc_global_thread_num: {
10706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
1071c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
10726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::FunctionType *FnTy =
1073176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
10746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
10756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    break;
10766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1077176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMPRTL__kmpc_threadprivate_cached: {
1078176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Build void *__kmpc_threadprivate_cached(ident_t *loc,
1079176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // kmp_int32 global_tid, void *data, size_t size, void ***cache);
1080176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1081176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                CGM.VoidPtrTy, CGM.SizeTy,
1082176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                CGM.VoidPtrTy->getPointerTo()->getPointerTo()};
1083176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::FunctionType *FnTy =
1084176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg*/ false);
1085176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_cached");
1086176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1087176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1088176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMPRTL__kmpc_critical: {
1089176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Build void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
1090176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // kmp_critical_name *crit);
1091176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *TypeParams[] = {
1092176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        getIdentTyPointerTy(), CGM.Int32Ty,
1093176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1094176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::FunctionType *FnTy =
1095176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1096176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical");
1097176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1098176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
109987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_critical_with_hint: {
110087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 global_tid,
110187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_critical_name *crit, uintptr_t hint);
110287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
110387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                llvm::PointerType::getUnqual(KmpCriticalNameTy),
110487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.IntPtrTy};
110587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
110687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
110787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical_with_hint");
110887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
110987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
1110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMPRTL__kmpc_threadprivate_register: {
1111176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Build void __kmpc_threadprivate_register(ident_t *, void *data,
1112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
1113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // typedef void *(*kmpc_ctor)(void *);
1114176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto KmpcCtorTy =
1115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
1116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                /*isVarArg*/ false)->getPointerTo();
1117176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // typedef void *(*kmpc_cctor)(void *, void *);
1118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *KmpcCopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1119176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto KmpcCopyCtorTy =
1120176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidPtrTy, KmpcCopyCtorTyArgs,
1121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                /*isVarArg*/ false)->getPointerTo();
1122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // typedef void (*kmpc_dtor)(void *);
1123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto KmpcDtorTy =
1124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy, /*isVarArg*/ false)
1125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines            ->getPointerTo();
1126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *FnTyArgs[] = {getIdentTyPointerTy(), CGM.VoidPtrTy, KmpcCtorTy,
1127176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              KmpcCopyCtorTy, KmpcDtorTy};
1128176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto FnTy = llvm::FunctionType::get(CGM.VoidTy, FnTyArgs,
1129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                        /*isVarArg*/ false);
1130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_register");
1131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1133176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMPRTL__kmpc_end_critical: {
1134176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Build void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
1135176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // kmp_critical_name *crit);
1136176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *TypeParams[] = {
1137176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        getIdentTyPointerTy(), CGM.Int32Ty,
1138176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1139176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::FunctionType *FnTy =
1140176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1141176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical");
1142176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1143176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
11440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPRTL__kmpc_cancel_barrier: {
11450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // Build kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
11460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // global_tid);
11470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
11480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::FunctionType *FnTy =
11490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
11500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier");
11510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    break;
11520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
115387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_barrier: {
115487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
115587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
115687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
115787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
115887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier");
115987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
116087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
11610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPRTL__kmpc_for_static_fini: {
11620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // Build void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
1163176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1164176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::FunctionType *FnTy =
1165176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
11660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_fini");
1167176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1168176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1169176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMPRTL__kmpc_push_num_threads: {
1170176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Build void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
1171176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // kmp_int32 num_threads)
1172176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1173176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                CGM.Int32Ty};
1174176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::FunctionType *FnTy =
1175176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1176176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_threads");
1177176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1178176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1179176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMPRTL__kmpc_serialized_parallel: {
1180176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
1181176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // global_tid);
1182176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1183176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::FunctionType *FnTy =
1184176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1185176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel");
1186176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1187176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1188176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMPRTL__kmpc_end_serialized_parallel: {
1189176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
1190176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // global_tid);
1191176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1192176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::FunctionType *FnTy =
1193176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1194176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel");
1195176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1196176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1197176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMPRTL__kmpc_flush: {
11980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // Build void __kmpc_flush(ident_t *loc);
1199176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
1200176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::FunctionType *FnTy =
12010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1202176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_flush");
1203176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    break;
1204176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
12050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPRTL__kmpc_master: {
12060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // Build kmp_int32 __kmpc_master(ident_t *loc, kmp_int32 global_tid);
12070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
12080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::FunctionType *FnTy =
12090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
12100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_master");
12110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    break;
12120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
12130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPRTL__kmpc_end_master: {
12140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // Build void __kmpc_end_master(ident_t *loc, kmp_int32 global_tid);
12150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
12160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::FunctionType *FnTy =
12170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
12180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_master");
12190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    break;
12200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
12210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPRTL__kmpc_omp_taskyield: {
12220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // Build kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
12230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // int end_part);
12240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
12250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::FunctionType *FnTy =
12260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
12270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_taskyield");
12280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    break;
12290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
12300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPRTL__kmpc_single: {
12310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // Build kmp_int32 __kmpc_single(ident_t *loc, kmp_int32 global_tid);
12320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
12330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::FunctionType *FnTy =
12340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
12350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_single");
12360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    break;
12370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
12380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPRTL__kmpc_end_single: {
12390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // Build void __kmpc_end_single(ident_t *loc, kmp_int32 global_tid);
12400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
12410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::FunctionType *FnTy =
12420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
12430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_single");
12440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    break;
12450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
12463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  case OMPRTL__kmpc_omp_task_alloc: {
12473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // Build kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
12483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
12493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // kmp_routine_entry_t *task_entry);
12503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    assert(KmpRoutineEntryPtrTy != nullptr &&
12513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar           "Type kmp_routine_entry_t must be created.");
12523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
12533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                CGM.SizeTy, CGM.SizeTy, KmpRoutineEntryPtrTy};
12543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // Return void * and then cast to particular kmp_task_t type.
12553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
12563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
12573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_alloc");
12583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    break;
12593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
12603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  case OMPRTL__kmpc_omp_task: {
12613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
12623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // *new_task);
12633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
12643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                CGM.VoidPtrTy};
12653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
12663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
12673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task");
12683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    break;
12693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
12703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  case OMPRTL__kmpc_copyprivate: {
12713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // Build void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
1272b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
12733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // kmp_int32 didit);
12743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::Type *CpyTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
12753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    auto *CpyFnTy =
12763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, CpyTypeParams, /*isVarArg=*/false);
1277b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.SizeTy,
12783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                CGM.VoidPtrTy, CpyFnTy->getPointerTo(),
12793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                CGM.Int32Ty};
12803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
12813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
12823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_copyprivate");
12833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    break;
12843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
128558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  case OMPRTL__kmpc_reduce: {
128658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // Build kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
128758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
128858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
128958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
129058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
129158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                               /*isVarArg=*/false);
129258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {
129358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
129458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
129558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::PointerType::getUnqual(KmpCriticalNameTy)};
129658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
129758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
129858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce");
129958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    break;
130058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
130158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  case OMPRTL__kmpc_reduce_nowait: {
130258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // Build kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
130358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
130458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
130558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // *lck);
130658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
130758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
130858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                               /*isVarArg=*/false);
130958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {
131058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
131158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
131258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::PointerType::getUnqual(KmpCriticalNameTy)};
131358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
131458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
131558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce_nowait");
131658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    break;
131758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
131858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  case OMPRTL__kmpc_end_reduce: {
131958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // Build void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
132058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // kmp_critical_name *lck);
132158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {
132258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        getIdentTyPointerTy(), CGM.Int32Ty,
132358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::PointerType::getUnqual(KmpCriticalNameTy)};
132458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
132558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
132658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce");
132758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    break;
132858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
132958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  case OMPRTL__kmpc_end_reduce_nowait: {
133058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // Build __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
133158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // kmp_critical_name *lck);
133258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {
133358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        getIdentTyPointerTy(), CGM.Int32Ty,
133458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::PointerType::getUnqual(KmpCriticalNameTy)};
133558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
133658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
133758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    RTLFn =
133858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce_nowait");
133958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    break;
134058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
1341b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  case OMPRTL__kmpc_omp_task_begin_if0: {
1342b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
1343b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // *new_task);
1344b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1345b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                CGM.VoidPtrTy};
1346b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
1347b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1348b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    RTLFn =
1349b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_begin_if0");
1350b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    break;
1351b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
1352b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  case OMPRTL__kmpc_omp_task_complete_if0: {
1353b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
1354b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // *new_task);
1355b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1356b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                CGM.VoidPtrTy};
1357b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
1358b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1359b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy,
1360b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                      /*Name=*/"__kmpc_omp_task_complete_if0");
1361b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    break;
1362b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
1363b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  case OMPRTL__kmpc_ordered: {
1364b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // Build void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
1365b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1366b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
1367b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1368b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_ordered");
1369b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    break;
1370b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
1371b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  case OMPRTL__kmpc_end_ordered: {
137287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
1373b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1374b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
1375b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1376b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_ordered");
1377b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    break;
1378b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
1379b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  case OMPRTL__kmpc_omp_taskwait: {
1380b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // Build kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 global_tid);
1381b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1382b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::FunctionType *FnTy =
1383b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1384b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_omp_taskwait");
1385b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    break;
1386b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
138787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_taskgroup: {
138887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
138987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
139087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
139187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
139287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_taskgroup");
139387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
139487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
139587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_end_taskgroup: {
139687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
139787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
139887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
139987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
140087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_taskgroup");
140187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
140287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
140387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_push_proc_bind: {
140487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
140587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // int proc_bind)
140687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
140787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
140887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
140987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_proc_bind");
141087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
141187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
141287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_omp_task_with_deps: {
141387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
141487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
141587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
141687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {
141787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        getIdentTyPointerTy(), CGM.Int32Ty, CGM.VoidPtrTy, CGM.Int32Ty,
141887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGM.VoidPtrTy,         CGM.Int32Ty, CGM.VoidPtrTy};
141987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
142087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
142187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn =
142287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_with_deps");
142387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
142487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
142587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_omp_wait_deps: {
142687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
142787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias,
142887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_depend_info_t *noalias_dep_list);
142987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
143087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.Int32Ty,           CGM.VoidPtrTy,
143187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.Int32Ty,           CGM.VoidPtrTy};
143287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
143387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
143487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_wait_deps");
143587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
143687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
143787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_cancellationpoint: {
143887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
143987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // global_tid, kmp_int32 cncl_kind)
144087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
144187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
144287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
144387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint");
144487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
144587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
144687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__kmpc_cancel: {
144787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
144887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_int32 cncl_kind)
144987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
145087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
145187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
145287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancel");
145387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
145487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
14554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__kmpc_push_num_teams: {
14564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void kmpc_push_num_teams (ident_t loc, kmp_int32 global_tid,
14574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // kmp_int32 num_teams, kmp_int32 num_threads)
14584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
14594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.Int32Ty};
14604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
14614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
14624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_teams");
14634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
14644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
14654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__kmpc_fork_teams: {
14664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro
14674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // microtask, ...);
14684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
14694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                getKmpc_MicroPointerTy()};
14704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
14714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
14724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_teams");
14734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
14744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
14754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__kmpc_taskloop: {
14764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
14774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
14784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // sched, kmp_uint64 grainsize, void *task_dup);
14794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
14804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.IntTy,
14814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrTy,
14824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.IntTy,
14834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int64Ty->getPointerTo(),
14844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int64Ty->getPointerTo(),
14854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int64Ty,
14864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.IntTy,
14874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.IntTy,
14884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int64Ty,
14894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrTy};
14904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
14914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
14924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_taskloop");
14934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
14944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
14954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__kmpc_doacross_init: {
14964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, kmp_int32
14974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // num_dims, struct kmp_dim *dims);
14984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
14994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty,
15004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty,
15014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrTy};
15024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
15034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
15044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_init");
15054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
15064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
15074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__kmpc_doacross_fini: {
15084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __kmpc_doacross_fini(ident_t *loc, kmp_int32 gtid);
15094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
15104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
15114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
15124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_fini");
15134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
15144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
15154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__kmpc_doacross_post: {
15164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __kmpc_doacross_post(ident_t *loc, kmp_int32 gtid, kmp_int64
15174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // *vec);
15184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
15194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int64Ty->getPointerTo()};
15204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
15214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
15224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_post");
15234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
15244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
15254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__kmpc_doacross_wait: {
15264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
15274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // *vec);
15284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
15294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int64Ty->getPointerTo()};
15304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
15314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
15324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_wait");
15334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
15344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
153587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPRTL__tgt_target: {
153687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build int32_t __tgt_target(int32_t device_id, void *host_ptr, int32_t
153787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // arg_num, void** args_base, void **args, size_t *arg_sizes, int32_t
153887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // *arg_types);
153987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *TypeParams[] = {CGM.Int32Ty,
154087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.VoidPtrTy,
154187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.Int32Ty,
154287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
154387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
154487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.SizeTy->getPointerTo(),
154587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CGM.Int32Ty->getPointerTo()};
154687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::FunctionType *FnTy =
154787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
154887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target");
154987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
155087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
15514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__tgt_target_teams: {
15524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build int32_t __tgt_target_teams(int32_t device_id, void *host_ptr,
15534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes,
15544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // int32_t *arg_types, int32_t num_teams, int32_t thread_limit);
15554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {CGM.Int32Ty,
15564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrTy,
15574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty,
15584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
15594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
15604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.SizeTy->getPointerTo(),
15614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty->getPointerTo(),
15624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty,
15634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty};
15644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
15654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
15664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_teams");
15674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
15684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
15694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__tgt_register_lib: {
15704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __tgt_register_lib(__tgt_bin_desc *desc);
15714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    QualType ParamTy =
15724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getContext().getPointerType(getTgtBinaryDescriptorQTy());
15734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {CGM.getTypes().ConvertTypeForMem(ParamTy)};
15744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
15754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
15764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_register_lib");
15774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
15784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
15794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__tgt_unregister_lib: {
15804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __tgt_unregister_lib(__tgt_bin_desc *desc);
15814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    QualType ParamTy =
15824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getContext().getPointerType(getTgtBinaryDescriptorQTy());
15834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {CGM.getTypes().ConvertTypeForMem(ParamTy)};
15844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
15854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
15864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_unregister_lib");
15874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
15884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
15894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__tgt_target_data_begin: {
15904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __tgt_target_data_begin(int32_t device_id, int32_t arg_num,
15914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // void** args_base, void **args, size_t *arg_sizes, int32_t *arg_types);
15924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {CGM.Int32Ty,
15934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty,
15944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
15954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
15964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.SizeTy->getPointerTo(),
15974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty->getPointerTo()};
15984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
15994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
16004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin");
16014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
16024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
16034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__tgt_target_data_end: {
16044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __tgt_target_data_end(int32_t device_id, int32_t arg_num,
16054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // void** args_base, void **args, size_t *arg_sizes, int32_t *arg_types);
16064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {CGM.Int32Ty,
16074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty,
16084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
16094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
16104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.SizeTy->getPointerTo(),
16114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty->getPointerTo()};
16124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
16134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
16144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end");
16154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
16164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
16174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPRTL__tgt_target_data_update: {
16184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build void __tgt_target_data_update(int32_t device_id, int32_t arg_num,
16194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // void** args_base, void **args, size_t *arg_sizes, int32_t *arg_types);
16204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *TypeParams[] = {CGM.Int32Ty,
16214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty,
16224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
16234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.VoidPtrPtrTy,
16244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.SizeTy->getPointerTo(),
16254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                CGM.Int32Ty->getPointerTo()};
16264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::FunctionType *FnTy =
16274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
16284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_update");
16294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
16304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
16316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
16324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(RTLFn && "Unable to find OpenMP runtime function");
16336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return RTLFn;
16346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1635176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
16363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Constant *CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize,
16373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                                             bool IVSigned) {
16383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  assert((IVSize == 32 || IVSize == 64) &&
16393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar         "IV size is not compatible with the omp runtime");
16403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto Name = IVSize == 32 ? (IVSigned ? "__kmpc_for_static_init_4"
16413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       : "__kmpc_for_static_init_4u")
16423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                           : (IVSigned ? "__kmpc_for_static_init_8"
16433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       : "__kmpc_for_static_init_8u");
16443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
16453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto PtrTy = llvm::PointerType::getUnqual(ITy);
16463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::Type *TypeParams[] = {
16473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    getIdentTyPointerTy(),                     // loc
16483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    CGM.Int32Ty,                               // tid
16493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    CGM.Int32Ty,                               // schedtype
16503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
16513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    PtrTy,                                     // p_lower
16523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    PtrTy,                                     // p_upper
16533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    PtrTy,                                     // p_stride
16543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    ITy,                                       // incr
16553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    ITy                                        // chunk
16563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  };
16573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::FunctionType *FnTy =
16583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
16593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return CGM.CreateRuntimeFunction(FnTy, Name);
16603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
16613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
16623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Constant *CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize,
16633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                                            bool IVSigned) {
16643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  assert((IVSize == 32 || IVSize == 64) &&
16653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar         "IV size is not compatible with the omp runtime");
16663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto Name =
16673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      IVSize == 32
16683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar          ? (IVSigned ? "__kmpc_dispatch_init_4" : "__kmpc_dispatch_init_4u")
16693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar          : (IVSigned ? "__kmpc_dispatch_init_8" : "__kmpc_dispatch_init_8u");
16703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
16713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::Type *TypeParams[] = { getIdentTyPointerTy(), // loc
16723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                               CGM.Int32Ty,           // tid
16733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                               CGM.Int32Ty,           // schedtype
16743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                               ITy,                   // lower
16753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                               ITy,                   // upper
16763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                               ITy,                   // stride
16773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                               ITy                    // chunk
16783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  };
16793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::FunctionType *FnTy =
16803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
16813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return CGM.CreateRuntimeFunction(FnTy, Name);
16823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
16833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
1684b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarllvm::Constant *CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize,
1685b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                                            bool IVSigned) {
1686b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  assert((IVSize == 32 || IVSize == 64) &&
1687b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar         "IV size is not compatible with the omp runtime");
1688b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto Name =
1689b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      IVSize == 32
1690b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          ? (IVSigned ? "__kmpc_dispatch_fini_4" : "__kmpc_dispatch_fini_4u")
1691b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          : (IVSigned ? "__kmpc_dispatch_fini_8" : "__kmpc_dispatch_fini_8u");
1692b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  llvm::Type *TypeParams[] = {
1693b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      getIdentTyPointerTy(), // loc
1694b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      CGM.Int32Ty,           // tid
1695b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  };
1696b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  llvm::FunctionType *FnTy =
1697b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1698b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  return CGM.CreateRuntimeFunction(FnTy, Name);
1699b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
1700b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
17013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Constant *CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize,
17023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                                            bool IVSigned) {
17033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  assert((IVSize == 32 || IVSize == 64) &&
17043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar         "IV size is not compatible with the omp runtime");
17053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto Name =
17063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      IVSize == 32
17073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar          ? (IVSigned ? "__kmpc_dispatch_next_4" : "__kmpc_dispatch_next_4u")
17083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar          : (IVSigned ? "__kmpc_dispatch_next_8" : "__kmpc_dispatch_next_8u");
17093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
17103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto PtrTy = llvm::PointerType::getUnqual(ITy);
17113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::Type *TypeParams[] = {
17123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    getIdentTyPointerTy(),                     // loc
17133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    CGM.Int32Ty,                               // tid
17143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
17153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    PtrTy,                                     // p_lower
17163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    PtrTy,                                     // p_upper
17173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    PtrTy                                      // p_stride
17183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  };
17193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::FunctionType *FnTy =
17203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
17213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return CGM.CreateRuntimeFunction(FnTy, Name);
17223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
17233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
1724176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesllvm::Constant *
1725176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesCGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
172687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  assert(!CGM.getLangOpts().OpenMPUseTLS ||
172787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar         !CGM.getContext().getTargetInfo().isTLSSupported());
1728176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Lookup the entry, lazily creating it if necessary.
17290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return getOrCreateInternalVariable(CGM.Int8PtrPtrTy,
1730176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                     Twine(CGM.getMangledName(VD)) + ".cache.");
1731176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1732176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
173387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
173487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                const VarDecl *VD,
173587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                Address VDAddr,
173687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                SourceLocation Loc) {
173787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (CGM.getLangOpts().OpenMPUseTLS &&
173887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGM.getContext().getTargetInfo().isTLSSupported())
173987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return VDAddr;
174087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
174187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto VarTy = VDAddr.getElementType();
17420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
174387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                         CGF.Builder.CreatePointerCast(VDAddr.getPointer(),
174487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                       CGM.Int8PtrTy),
1745176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)),
1746176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         getOrCreateThreadPrivateCache(VD)};
174787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return Address(CGF.EmitRuntimeCall(
174887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args),
174987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                 VDAddr.getAlignment());
1750176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1751176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
17520e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitThreadPrivateVarInit(
175387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CodeGenFunction &CGF, Address VDAddr, llvm::Value *Ctor,
1754176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc) {
1755176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime
1756176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // library.
17570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  auto OMPLoc = emitUpdateLocation(CGF, Loc);
17580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
1759176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      OMPLoc);
1760176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor)
1761176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // to register constructor/destructor for variable.
1762176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::Value *Args[] = {OMPLoc,
176387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                         CGF.Builder.CreatePointerCast(VDAddr.getPointer(),
176487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                       CGM.VoidPtrTy),
1765176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         Ctor, CopyCtor, Dtor};
17660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGF.EmitRuntimeCall(
17670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      createRuntimeFunction(OMPRTL__kmpc_threadprivate_register), Args);
1768176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1769176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
17700e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
177187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    const VarDecl *VD, Address VDAddr, SourceLocation Loc,
1772176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    bool PerformInit, CodeGenFunction *CGF) {
177387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (CGM.getLangOpts().OpenMPUseTLS &&
177487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGM.getContext().getTargetInfo().isTLSSupported())
177587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return nullptr;
177687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
1777176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  VD = VD->getDefinition(CGM.getContext());
1778176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (VD && ThreadPrivateWithDefinition.count(VD) == 0) {
1779176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    ThreadPrivateWithDefinition.insert(VD);
1780176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    QualType ASTTy = VD->getType();
1781176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1782176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr;
1783176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto Init = VD->getAnyInitializer();
1784176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (CGM.getLangOpts().CPlusPlus && PerformInit) {
1785176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      // Generate function that re-emits the declaration's initializer into the
1786176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      // threadprivate copy of the variable VD
1787176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CodeGenFunction CtorCGF(CGM);
1788176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      FunctionArgList Args;
1789176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, SourceLocation(),
1790176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                            /*Id=*/nullptr, CGM.getContext().VoidPtrTy);
1791176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Args.push_back(&Dst);
1792176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
17934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
17944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGM.getContext().VoidPtrTy, Args);
1795176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto FTy = CGM.getTypes().GetFunctionType(FI);
1796176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto Fn = CGM.CreateGlobalInitOrDestructFunction(
179787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          FTy, ".__kmpc_global_ctor_.", FI, Loc);
1798176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI,
1799176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                            Args, SourceLocation());
1800176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto ArgVal = CtorCGF.EmitLoadOfScalar(
180187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
1802176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          CGM.getContext().VoidPtrTy, Dst.getLocation());
180387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Address Arg = Address(ArgVal, VDAddr.getAlignment());
180487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Arg = CtorCGF.Builder.CreateElementBitCast(Arg,
180587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                             CtorCGF.ConvertTypeForMem(ASTTy));
1806176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
1807176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                               /*IsInitializer=*/true);
1808176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      ArgVal = CtorCGF.EmitLoadOfScalar(
180987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
1810176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          CGM.getContext().VoidPtrTy, Dst.getLocation());
1811176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue);
1812176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CtorCGF.FinishFunction();
1813176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Ctor = Fn;
1814176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
1815176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (VD->getType().isDestructedType() != QualType::DK_none) {
1816176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      // Generate function that emits destructor call for the threadprivate copy
1817176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      // of the variable VD
1818176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CodeGenFunction DtorCGF(CGM);
1819176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      FunctionArgList Args;
1820176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, SourceLocation(),
1821176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                            /*Id=*/nullptr, CGM.getContext().VoidPtrTy);
1822176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Args.push_back(&Dst);
1823176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
18244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
18254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGM.getContext().VoidTy, Args);
1826176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto FTy = CGM.getTypes().GetFunctionType(FI);
1827176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto Fn = CGM.CreateGlobalInitOrDestructFunction(
182887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          FTy, ".__kmpc_global_dtor_.", FI, Loc);
18294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
1830176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, Args,
1831176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                            SourceLocation());
18324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // Create a scope with an artificial location for the body of this function.
18334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
1834176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto ArgVal = DtorCGF.EmitLoadOfScalar(
1835176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          DtorCGF.GetAddrOfLocalVar(&Dst),
183687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          /*Volatile=*/false, CGM.getContext().VoidPtrTy, Dst.getLocation());
183787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      DtorCGF.emitDestroy(Address(ArgVal, VDAddr.getAlignment()), ASTTy,
1838176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          DtorCGF.getDestroyer(ASTTy.isDestructedType()),
1839176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
1840176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      DtorCGF.FinishFunction();
1841176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Dtor = Fn;
1842176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
1843176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Do not emit init function if it is not required.
1844176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (!Ctor && !Dtor)
1845176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      return nullptr;
1846176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1847176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::Type *CopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1848176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto CopyCtorTy =
1849176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::FunctionType::get(CGM.VoidPtrTy, CopyCtorTyArgs,
1850176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                /*isVarArg=*/false)->getPointerTo();
1851176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Copying constructor for the threadprivate variable.
1852176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Must be NULL - reserved by runtime, but currently it requires that this
1853176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // parameter is always NULL. Otherwise it fires assertion.
1854176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
1855176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (Ctor == nullptr) {
1856176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto CtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
1857176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                            /*isVarArg=*/false)->getPointerTo();
1858176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Ctor = llvm::Constant::getNullValue(CtorTy);
1859176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
1860176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (Dtor == nullptr) {
1861176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto DtorTy = llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy,
1862176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                            /*isVarArg=*/false)->getPointerTo();
1863176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Dtor = llvm::Constant::getNullValue(DtorTy);
1864176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
1865176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (!CGF) {
1866176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto InitFunctionTy =
1867176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false);
1868176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      auto InitFunction = CGM.CreateGlobalInitOrDestructFunction(
186987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          InitFunctionTy, ".__omp_threadprivate_init_.",
187087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGM.getTypes().arrangeNullaryFunction());
1871176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CodeGenFunction InitCGF(CGM);
1872176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      FunctionArgList ArgList;
1873176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, InitFunction,
1874176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                            CGM.getTypes().arrangeNullaryFunction(), ArgList,
1875176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                            Loc);
18760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
1877176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      InitCGF.FinishFunction();
1878176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      return InitFunction;
1879176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
18800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    emitThreadPrivateVarInit(*CGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
1881176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1882176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return nullptr;
1883176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1884176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1885b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
1886b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// function. Here is the logic:
1887b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// if (Cond) {
1888b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar///   ThenGen();
1889b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// } else {
1890b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar///   ElseGen();
1891b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// }
1892b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstatic void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
1893b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                            const RegionCodeGenTy &ThenGen,
1894b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                            const RegionCodeGenTy &ElseGen) {
1895b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
1896b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
1897b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // If the condition constant folds and can be elided, try to avoid emitting
1898b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // the condition and the dead arm of the if/else.
1899b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  bool CondConstant;
1900b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
19014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (CondConstant)
1902b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      ThenGen(CGF);
19034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    else
1904b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      ElseGen(CGF);
1905b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    return;
1906b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
1907176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1908b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Otherwise, the condition did not fold, or we couldn't elide it.  Just
1909b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // emit the conditional branch.
1910b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto ThenBlock = CGF.createBasicBlock("omp_if.then");
1911b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto ElseBlock = CGF.createBasicBlock("omp_if.else");
1912b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto ContBlock = CGF.createBasicBlock("omp_if.end");
1913b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount=*/0);
1914176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1915b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Emit the 'then' code.
1916b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.EmitBlock(ThenBlock);
19174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ThenGen(CGF);
1918b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.EmitBranch(ContBlock);
1919b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Emit the 'else' code if present.
19204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // There is no need to emit line number for unconditional branch.
19214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  (void)ApplyDebugLocation::CreateEmpty(CGF);
19224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitBlock(ElseBlock);
19234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ElseGen(CGF);
19244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // There is no need to emit line number for unconditional branch.
19254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  (void)ApplyDebugLocation::CreateEmpty(CGF);
19264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitBranch(ContBlock);
1927b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Emit the continuation block for code after the if.
1928b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.EmitBlock(ContBlock, /*IsFinished=*/true);
1929b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
1930176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1931b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
1932b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                       llvm::Value *OutlinedFn,
193387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                       ArrayRef<llvm::Value *> CapturedVars,
1934b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                       const Expr *IfCond) {
193587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
193687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
1937b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *RTLoc = emitUpdateLocation(CGF, Loc);
19384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ThenGen = [OutlinedFn, CapturedVars, RTLoc](CodeGenFunction &CGF,
19394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                     PrePostActionTy &) {
194087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build call __kmpc_fork_call(loc, n, microtask, var1, .., varn);
19414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &RT = CGF.CGM.getOpenMPRuntime();
194287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *Args[] = {
194387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        RTLoc,
194487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
19454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.Builder.CreateBitCast(OutlinedFn, RT.getKmpc_MicroPointerTy())};
194687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::SmallVector<llvm::Value *, 16> RealArgs;
194787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RealArgs.append(std::begin(Args), std::end(Args));
194887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RealArgs.append(CapturedVars.begin(), CapturedVars.end());
194987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
19504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto RTLFn = RT.createRuntimeFunction(OMPRTL__kmpc_fork_call);
195187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.EmitRuntimeCall(RTLFn, RealArgs);
195287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  };
19534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ElseGen = [OutlinedFn, CapturedVars, RTLoc, Loc](CodeGenFunction &CGF,
19544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                          PrePostActionTy &) {
19554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &RT = CGF.CGM.getOpenMPRuntime();
19564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto ThreadID = RT.getThreadID(CGF, Loc);
1957b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // Build calls:
1958b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // __kmpc_serialized_parallel(&Loc, GTid);
1959b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::Value *Args[] = {RTLoc, ThreadID};
19604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitRuntimeCall(
19614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        RT.createRuntimeFunction(OMPRTL__kmpc_serialized_parallel), Args);
1962b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
1963b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // OutlinedFn(&GTid, &zero, CapturedStruct);
19644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto ThreadIDAddr = RT.emitThreadIDAddress(CGF, Loc);
196587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Address ZeroAddr =
19664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.CreateTempAlloca(CGF.Int32Ty, CharUnits::fromQuantity(4),
19674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             /*Name*/ ".zero.addr");
1968b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C*/ 0));
196987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
197087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    OutlinedFnArgs.push_back(ThreadIDAddr.getPointer());
197187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    OutlinedFnArgs.push_back(ZeroAddr.getPointer());
197287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
1973b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
1974b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
1975b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // __kmpc_end_serialized_parallel(&Loc, GTid);
19764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *EndArgs[] = {RT.emitUpdateLocation(CGF, Loc), ThreadID};
1977b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    CGF.EmitRuntimeCall(
19784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        RT.createRuntimeFunction(OMPRTL__kmpc_end_serialized_parallel),
19794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        EndArgs);
1980b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  };
19814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (IfCond)
1982b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    emitOMPIfClause(CGF, IfCond, ThenGen, ElseGen);
19834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  else {
19844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RegionCodeGenTy ThenRCG(ThenGen);
19854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ThenRCG(CGF);
1986b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
1987176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1988176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1989176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// If we're inside an (outlined) parallel region, use the region info's
1990176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// thread-ID variable (it is passed in a first argument of the outlined function
1991176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// as "kmp_int32 *gtid"). Otherwise, if we're not inside parallel region, but in
1992176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// regular serial code region, get thread ID by calling kmp_int32
1993176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// kmpc_global_thread_num(ident_t *loc), stash this thread ID in a temporary and
1994176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// return the address of that temp.
199587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
199687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                             SourceLocation Loc) {
19974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *OMPRegionInfo =
1998176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
19990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (OMPRegionInfo->getThreadIDVariable())
20003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
20010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
20020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  auto ThreadID = getThreadID(CGF, Loc);
2003176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto Int32Ty =
2004176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true);
2005176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto ThreadIDTemp = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".threadid_temp.");
2006176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CGF.EmitStoreOfScalar(ThreadID,
200787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                        CGF.MakeAddrLValue(ThreadIDTemp, Int32Ty));
2008176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2009176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return ThreadIDTemp;
2010176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2011176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2012176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesllvm::Constant *
20130e2c34f92f00628d48968dfea096d36381f494cbStephen HinesCGOpenMPRuntime::getOrCreateInternalVariable(llvm::Type *Ty,
2014176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                             const llvm::Twine &Name) {
2015176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  SmallString<256> Buffer;
2016176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::raw_svector_ostream Out(Buffer);
2017176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Out << Name;
2018176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto RuntimeName = Out.str();
2019176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto &Elem = *InternalVars.insert(std::make_pair(RuntimeName, nullptr)).first;
2020176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (Elem.second) {
2021176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    assert(Elem.second->getType()->getPointerElementType() == Ty &&
2022176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines           "OMP internal variable has different type than requested");
2023176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return &*Elem.second;
2024176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
2025176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2026176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return Elem.second = new llvm::GlobalVariable(
2027176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines             CGM.getModule(), Ty, /*IsConstant*/ false,
2028176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines             llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
2029176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines             Elem.first());
2030176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2031176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
20320e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
2033176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::Twine Name(".gomp_critical_user_", CriticalName);
20340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return getOrCreateInternalVariable(KmpCriticalNameTy, Name.concat(".var"));
2035176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2036176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
203758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarnamespace {
20384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Common pre(post)-action for different OpenMP constructs.
20394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass CommonActionTy final : public PrePostActionTy {
20404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *EnterCallee;
20414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ArrayRef<llvm::Value *> EnterArgs;
20424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *ExitCallee;
20434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ArrayRef<llvm::Value *> ExitArgs;
20444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool Conditional;
20454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::BasicBlock *ContBlock = nullptr;
204658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
204758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarpublic:
20484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CommonActionTy(llvm::Value *EnterCallee, ArrayRef<llvm::Value *> EnterArgs,
20494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                 llvm::Value *ExitCallee, ArrayRef<llvm::Value *> ExitArgs,
20504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                 bool Conditional = false)
20514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
20524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ExitArgs(ExitArgs), Conditional(Conditional) {}
20534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void Enter(CodeGenFunction &CGF) override {
20544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *EnterRes = CGF.EmitRuntimeCall(EnterCallee, EnterArgs);
20554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Conditional) {
20564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *CallBool = CGF.Builder.CreateIsNotNull(EnterRes);
20574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
20584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ContBlock = CGF.createBasicBlock("omp_if.end");
20594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // Generate the branch (If-stmt)
20604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
20614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.EmitBlock(ThenBlock);
20624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
2063b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
20644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void Done(CodeGenFunction &CGF) {
20654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit the rest of blocks/branches
20664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitBranch(ContBlock);
20674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitBlock(ContBlock, true);
20684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
20694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void Exit(CodeGenFunction &CGF) override {
20704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitRuntimeCall(ExitCallee, ExitArgs);
207158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
207258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar};
207387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // anonymous namespace
207458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
207558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
207658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                         StringRef CriticalName,
207758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                         const RegionCodeGenTy &CriticalOpGen,
207887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                         SourceLocation Loc, const Expr *Hint) {
207987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // __kmpc_critical[_with_hint](ident_t *, gtid, Lock[, hint]);
20800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CriticalOpGen();
20810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // __kmpc_end_critical(ident_t *, gtid, Lock);
20820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Prepare arguments and build a call to __kmpc_critical
208387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
208487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
208587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
208687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                         getCriticalRegionLock(CriticalName)};
20874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::SmallVector<llvm::Value *, 4> EnterArgs(std::begin(Args),
20884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                std::end(Args));
208987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (Hint) {
20904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    EnterArgs.push_back(CGF.Builder.CreateIntCast(
20914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitScalarExpr(Hint), CGM.IntPtrTy, /*isSigned=*/false));
20924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
20934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CommonActionTy Action(
20944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      createRuntimeFunction(Hint ? OMPRTL__kmpc_critical_with_hint
20954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 : OMPRTL__kmpc_critical),
20964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      EnterArgs, createRuntimeFunction(OMPRTL__kmpc_end_critical), Args);
20974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CriticalOpGen.setAction(Action);
209887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
2099176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2100176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
21010e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF,
210258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                       const RegionCodeGenTy &MasterOpGen,
21030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                       SourceLocation Loc) {
210487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
210587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
21060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // if(__kmpc_master(ident_t *, gtid)) {
21070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  //   MasterOpGen();
21080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  //   __kmpc_end_master(ident_t *, gtid);
21090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // }
21100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Prepare arguments and build a call to __kmpc_master
21110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
21124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_master), Args,
21134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        createRuntimeFunction(OMPRTL__kmpc_end_master), Args,
21144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        /*Conditional=*/true);
21154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MasterOpGen.setAction(Action);
21164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  emitInlinedDirective(CGF, OMPD_master, MasterOpGen);
21174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Action.Done(CGF);
2118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2119176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
21200e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
21210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                        SourceLocation Loc) {
212287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
212387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
21240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Build call __kmpc_omp_taskyield(loc, thread_id, 0);
21250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Value *Args[] = {
21260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
21270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)};
21280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), Args);
21294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
21304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Region->emitUntiedSwitch(CGF);
21310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
21320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
213387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF,
213487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          const RegionCodeGenTy &TaskgroupOpGen,
213587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          SourceLocation Loc) {
213687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
213787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
213887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // __kmpc_taskgroup(ident_t *, gtid);
213987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // TaskgroupOpGen();
214087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // __kmpc_end_taskgroup(ident_t *, gtid);
214187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Prepare arguments and build a call to __kmpc_taskgroup
21424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
21434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_taskgroup), Args,
21444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        createRuntimeFunction(OMPRTL__kmpc_end_taskgroup),
21454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        Args);
21464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  TaskgroupOpGen.setAction(Action);
21474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  emitInlinedDirective(CGF, OMPD_taskgroup, TaskgroupOpGen);
214887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
214987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
215087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// Given an array of pointers to variables, project the address of a
215187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// given variable.
215287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic Address emitAddrOfVarFromArray(CodeGenFunction &CGF, Address Array,
215387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                      unsigned Index, const VarDecl *Var) {
215487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Pull out the pointer to the variable.
215587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address PtrAddr =
215687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateConstArrayGEP(Array, Index, CGF.getPointerSize());
215787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *Ptr = CGF.Builder.CreateLoad(PtrAddr);
215887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
215987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address Addr = Address(Ptr, CGF.getContext().getDeclAlign(Var));
216087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Addr = CGF.Builder.CreateElementBitCast(
216187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Addr, CGF.ConvertTypeForMem(Var->getType()));
216287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return Addr;
216387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
216487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
21653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Value *emitCopyprivateCopyFunction(
216658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    CodeGenModule &CGM, llvm::Type *ArgsType,
216758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
216858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps) {
21693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto &C = CGM.getContext();
21703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // void copy_func(void *LHSArg, void *RHSArg);
21713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  FunctionArgList Args;
21723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr,
21733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                           C.VoidPtrTy);
21743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr,
21753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                           C.VoidPtrTy);
21763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  Args.push_back(&LHSArg);
21773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  Args.push_back(&RHSArg);
21784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &CGFI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
21793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *Fn = llvm::Function::Create(
21803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
21813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      ".omp.copyprivate.copy_func", &CGM.getModule());
218287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, CGFI);
21833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CodeGenFunction CGF(CGM);
21843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args);
218558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Dest = (void*[n])(LHSArg);
21863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Src = (void*[n])(RHSArg);
218787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
218887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
218987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ArgsType), CGF.getPointerAlign());
219087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
219187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
219287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ArgsType), CGF.getPointerAlign());
21933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // *(Type0*)Dst[0] = *(Type0*)Src[0];
21943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // *(Type1*)Dst[1] = *(Type1*)Src[1];
21953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // ...
21963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // *(Typen*)Dst[n] = *(Typen*)Src[n];
21973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  for (unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
219887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto DestVar = cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl());
219987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Address DestAddr = emitAddrOfVarFromArray(CGF, LHS, I, DestVar);
220087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
220187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto SrcVar = cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl());
220287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Address SrcAddr = emitAddrOfVarFromArray(CGF, RHS, I, SrcVar);
220387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
2204b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
2205b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    QualType Type = VD->getType();
220687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.EmitOMPCopy(Type, DestAddr, SrcAddr, DestVar, SrcVar, AssignmentOps[I]);
22073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
22083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CGF.FinishFunction();
22093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return Fn;
22103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
22113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
22120e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
221358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                       const RegionCodeGenTy &SingleOpGen,
22143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       SourceLocation Loc,
22153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       ArrayRef<const Expr *> CopyprivateVars,
22163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       ArrayRef<const Expr *> SrcExprs,
22173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       ArrayRef<const Expr *> DstExprs,
22183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       ArrayRef<const Expr *> AssignmentOps) {
221987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
222087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
22213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  assert(CopyprivateVars.size() == SrcExprs.size() &&
22223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar         CopyprivateVars.size() == DstExprs.size() &&
22233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar         CopyprivateVars.size() == AssignmentOps.size());
22243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto &C = CGM.getContext();
22253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // int32 did_it = 0;
22260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // if(__kmpc_single(ident_t *, gtid)) {
22270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  //   SingleOpGen();
22280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  //   __kmpc_end_single(ident_t *, gtid);
22293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  //   did_it = 1;
22300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // }
22313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
22323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // <copy_func>, did_it);
22333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
223487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address DidIt = Address::invalid();
22353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  if (!CopyprivateVars.empty()) {
22363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // int32 did_it = 0;
22373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
22383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    DidIt = CGF.CreateMemTemp(KmpInt32Ty, ".omp.copyprivate.did_it");
223987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.Builder.CreateStore(CGF.Builder.getInt32(0), DidIt);
22403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
22410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Prepare arguments and build a call to __kmpc_single
22420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
22434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_single), Args,
22444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        createRuntimeFunction(OMPRTL__kmpc_end_single), Args,
22454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        /*Conditional=*/true);
22464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SingleOpGen.setAction(Action);
22474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  emitInlinedDirective(CGF, OMPD_single, SingleOpGen);
22484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (DidIt.isValid()) {
22494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // did_it = 1;
22504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.Builder.CreateStore(CGF.Builder.getInt32(1), DidIt);
22514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
22524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Action.Done(CGF);
22533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
22543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // <copy_func>, did_it);
225587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (DidIt.isValid()) {
22563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size());
22573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    auto CopyprivateArrayTy =
22583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
22593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                               /*IndexTypeQuals=*/0);
22603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // Create a list of all private variables for copyprivate.
226187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Address CopyprivateList =
22623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list");
22633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    for (unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
226487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Address Elem = CGF.Builder.CreateConstArrayGEP(
226587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CopyprivateList, I, CGF.getPointerSize());
226687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateStore(
22673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar          CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
226887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar              CGF.EmitLValue(CopyprivateVars[I]).getPointer(), CGF.VoidPtrTy),
226987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          Elem);
22703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    }
22713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // Build function that copies private values from single region to all other
22723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // threads in the corresponding parallel region.
22733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    auto *CpyFn = emitCopyprivateCopyFunction(
22743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        CGM, CGF.ConvertTypeForMem(CopyprivateArrayTy)->getPointerTo(),
227558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        CopyprivateVars, SrcExprs, DstExprs, AssignmentOps);
22764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *BufSize = CGF.getTypeSize(CopyprivateArrayTy);
227787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Address CL =
227887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList,
227987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                      CGF.VoidPtrTy);
228087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto *DidItVal = CGF.Builder.CreateLoad(DidIt);
22813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::Value *Args[] = {
22823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        emitUpdateLocation(CGF, Loc), // ident_t *<loc>
22833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        getThreadID(CGF, Loc),        // i32 <gtid>
2284b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        BufSize,                      // size_t <buf_size>
228587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CL.getPointer(),              // void *<copyprivate list>
22863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        CpyFn,                        // void (*) (void *, void *) <copy_func>
22873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        DidItVal                      // i32 did_it
22883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    };
22893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_copyprivate), Args);
22903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
22910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
22920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
2293b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF,
2294b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                        const RegionCodeGenTy &OrderedOpGen,
229587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                        SourceLocation Loc, bool IsThreads) {
229687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
229787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
2298b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // __kmpc_ordered(ident_t *, gtid);
2299b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // OrderedOpGen();
2300b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // __kmpc_end_ordered(ident_t *, gtid);
2301b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Prepare arguments and build a call to __kmpc_ordered
230287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (IsThreads) {
2303b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
23044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_ordered), Args,
23054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          createRuntimeFunction(OMPRTL__kmpc_end_ordered),
23064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          Args);
23074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OrderedOpGen.setAction(Action);
23084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
23094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
2310b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
231187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
2312b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
2313b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
23140e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
231587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                      OpenMPDirectiveKind Kind, bool EmitChecks,
231687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                      bool ForceSimpleCall) {
231787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
231887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
23190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Build call __kmpc_cancel_barrier(loc, thread_id);
232087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Build call __kmpc_barrier(loc, thread_id);
23214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned Flags;
23224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (Kind == OMPD_for)
23234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Flags = OMP_IDENT_BARRIER_IMPL_FOR;
23244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  else if (Kind == OMPD_sections)
23254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Flags = OMP_IDENT_BARRIER_IMPL_SECTIONS;
23264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  else if (Kind == OMPD_single)
23274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Flags = OMP_IDENT_BARRIER_IMPL_SINGLE;
23284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  else if (Kind == OMPD_barrier)
23294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Flags = OMP_IDENT_BARRIER_EXPL;
23304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  else
23314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Flags = OMP_IDENT_BARRIER_IMPL;
233287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
233387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // thread_id);
23340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
23350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                         getThreadID(CGF, Loc)};
23364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *OMPRegionInfo =
23374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
233887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
233987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *Result = CGF.EmitRuntimeCall(
234087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
234187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      if (EmitChecks) {
234287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        // if (__kmpc_cancel_barrier()) {
234387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        //   exit from construct;
234487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        // }
234587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
234687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        auto *ContBB = CGF.createBasicBlock(".cancel.continue");
234787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
234887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
234987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.EmitBlock(ExitBB);
235087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        //   exit from construct;
235187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        auto CancelDestination =
235287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
235387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.EmitBranchThroughCleanup(CancelDestination);
235487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.EmitBlock(ContBB, /*IsFinished=*/true);
235587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      }
235687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      return;
235787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
235887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
235987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_barrier), Args);
23600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
23610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
23620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// \brief Map the OpenMP loop schedule to the runtime enumeration.
23630e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstatic OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
2364b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                          bool Chunked, bool Ordered) {
23650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  switch (ScheduleKind) {
23660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPC_SCHEDULE_static:
2367b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    return Chunked ? (Ordered ? OMP_ord_static_chunked : OMP_sch_static_chunked)
2368b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                   : (Ordered ? OMP_ord_static : OMP_sch_static);
23690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPC_SCHEDULE_dynamic:
2370b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    return Ordered ? OMP_ord_dynamic_chunked : OMP_sch_dynamic_chunked;
23710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPC_SCHEDULE_guided:
2372b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    return Ordered ? OMP_ord_guided_chunked : OMP_sch_guided_chunked;
23730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPC_SCHEDULE_runtime:
2374b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    return Ordered ? OMP_ord_runtime : OMP_sch_runtime;
2375b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  case OMPC_SCHEDULE_auto:
2376b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    return Ordered ? OMP_ord_auto : OMP_sch_auto;
23770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  case OMPC_SCHEDULE_unknown:
23780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    assert(!Chunked && "chunk was specified but schedule kind not known");
2379b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    return Ordered ? OMP_ord_static : OMP_sch_static;
23800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
23810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm_unreachable("Unexpected runtime schedule");
23820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
23830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
23844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Map the OpenMP distribute schedule to the runtime enumeration.
23854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic OpenMPSchedType
23864967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainargetRuntimeSchedule(OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) {
23874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // only static is allowed for dist_schedule
23884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Chunked ? OMP_dist_sch_static_chunked : OMP_dist_sch_static;
23894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
23904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
23910e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool CGOpenMPRuntime::isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
23920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                         bool Chunked) const {
2393b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto Schedule = getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
23940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return Schedule == OMP_sch_static;
23950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
23960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
23974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool CGOpenMPRuntime::isStaticNonchunked(
23984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
23994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
24004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Schedule == OMP_dist_sch_static;
24014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
24024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
24034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
24040e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool CGOpenMPRuntime::isDynamic(OpenMPScheduleClauseKind ScheduleKind) const {
2405b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto Schedule =
2406b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      getRuntimeSchedule(ScheduleKind, /*Chunked=*/false, /*Ordered=*/false);
24070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  assert(Schedule != OMP_sch_static_chunked && "cannot be chunked here");
24080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return Schedule != OMP_sch_static;
24090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
24100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
24114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic int addMonoNonMonoModifier(OpenMPSchedType Schedule,
24124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  OpenMPScheduleClauseModifier M1,
24134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  OpenMPScheduleClauseModifier M2) {
24144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  int Modifier = 0;
24154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  switch (M1) {
24164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_monotonic:
24174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Modifier = OMP_sch_modifier_monotonic;
24184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
24194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
24204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Modifier = OMP_sch_modifier_nonmonotonic;
24214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
24224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_simd:
24234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Schedule == OMP_sch_static_chunked)
24244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Schedule = OMP_sch_static_balanced_chunked;
24254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
24264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_last:
24274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_unknown:
24284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
24294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
24304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  switch (M2) {
24314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_monotonic:
24324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Modifier = OMP_sch_modifier_monotonic;
24334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
24344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
24354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Modifier = OMP_sch_modifier_nonmonotonic;
24364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
24374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_simd:
24384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Schedule == OMP_sch_static_chunked)
24394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Schedule = OMP_sch_static_balanced_chunked;
24404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
24414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_last:
24424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPC_SCHEDULE_MODIFIER_unknown:
24434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
24444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
24454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Schedule | Modifier;
24464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
24474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
244887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CGOpenMPRuntime::emitForDispatchInit(CodeGenFunction &CGF,
244987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          SourceLocation Loc,
24504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                          const OpenMPScheduleTy &ScheduleKind,
245187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          unsigned IVSize, bool IVSigned,
245287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          bool Ordered, llvm::Value *UB,
245387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          llvm::Value *Chunk) {
245487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
245587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
2456b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  OpenMPSchedType Schedule =
24574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      getRuntimeSchedule(ScheduleKind.Schedule, Chunk != nullptr, Ordered);
245887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  assert(Ordered ||
245987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar         (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked &&
24604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked &&
24614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Schedule != OMP_sch_static_balanced_chunked));
246287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Call __kmpc_dispatch_init(
246387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  //          ident_t *loc, kmp_int32 tid, kmp_int32 schedule,
246487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  //          kmp_int[32|64] lower, kmp_int[32|64] upper,
246587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  //          kmp_int[32|64] stride, kmp_int[32|64] chunk);
246687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
246787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // If the Chunk was not specified in the clause - use default value 1.
246887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (Chunk == nullptr)
246987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Chunk = CGF.Builder.getIntN(IVSize, 1);
247087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *Args[] = {
24714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
24724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.getInt32(addMonoNonMonoModifier(
24734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Schedule, ScheduleKind.M1, ScheduleKind.M2)), // Schedule type
24744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.getIntN(IVSize, 0),                   // Lower
24754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      UB,                                               // Upper
24764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.getIntN(IVSize, 1),                   // Stride
24774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Chunk                                             // Chunk
247887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  };
247987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitRuntimeCall(createDispatchInitFunction(IVSize, IVSigned), Args);
248087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
24813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
24824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void emitForStaticInitCall(
24834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId,
24844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Constant *ForStaticInitFunction, OpenMPSchedType Schedule,
24854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
24864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned IVSize, bool Ordered, Address IL, Address LB, Address UB,
24874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Address ST, llvm::Value *Chunk) {
24884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
24894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar     return;
24904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
24914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   assert(!Ordered);
24924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   assert(Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked ||
24934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Schedule == OMP_sch_static_balanced_chunked ||
24944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked ||
24954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Schedule == OMP_dist_sch_static ||
24964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Schedule == OMP_dist_sch_static_chunked);
24974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
24984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   // Call __kmpc_for_static_init(
24994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   //          ident_t *loc, kmp_int32 tid, kmp_int32 schedtype,
25004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   //          kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower,
25014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   //          kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride,
25024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   //          kmp_int[32|64] incr, kmp_int[32|64] chunk);
25034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   if (Chunk == nullptr) {
25044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar     assert((Schedule == OMP_sch_static || Schedule == OMP_ord_static ||
25054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar             Schedule == OMP_dist_sch_static) &&
25064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            "expected static non-chunked schedule");
25074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar     // If the Chunk was not specified in the clause - use default value 1.
25084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       Chunk = CGF.Builder.getIntN(IVSize, 1);
25094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   } else {
25104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar     assert((Schedule == OMP_sch_static_chunked ||
25114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar             Schedule == OMP_sch_static_balanced_chunked ||
25124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar             Schedule == OMP_ord_static_chunked ||
25134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar             Schedule == OMP_dist_sch_static_chunked) &&
25144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            "expected static chunked schedule");
25154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   }
25164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   llvm::Value *Args[] = {
25174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       UpdateLocation, ThreadId, CGF.Builder.getInt32(addMonoNonMonoModifier(
25184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     Schedule, M1, M2)), // Schedule type
25194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       IL.getPointer(),                                  // &isLastIter
25204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       LB.getPointer(),                                  // &LB
25214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       UB.getPointer(),                                  // &UB
25224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       ST.getPointer(),                                  // &Stride
25234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       CGF.Builder.getIntN(IVSize, 1),                   // Incr
25244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       Chunk                                             // Chunk
25254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   };
25264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar   CGF.EmitRuntimeCall(ForStaticInitFunction, Args);
25274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
25284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
252987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF,
253087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                        SourceLocation Loc,
25314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        const OpenMPScheduleTy &ScheduleKind,
253287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                        unsigned IVSize, bool IVSigned,
253387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                        bool Ordered, Address IL, Address LB,
253487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                        Address UB, Address ST,
253587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                        llvm::Value *Chunk) {
25364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OpenMPSchedType ScheduleNum =
25374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      getRuntimeSchedule(ScheduleKind.Schedule, Chunk != nullptr, Ordered);
25384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *UpdatedLocation = emitUpdateLocation(CGF, Loc);
25394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *ThreadId = getThreadID(CGF, Loc);
25404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *StaticInitFunction = createForStaticInitFunction(IVSize, IVSigned);
25414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
25424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, IVSize,
25434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        Ordered, IL, LB, UB, ST, Chunk);
25444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
25454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
25464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitDistributeStaticInit(
25474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CodeGenFunction &CGF, SourceLocation Loc,
25484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OpenMPDistScheduleClauseKind SchedKind, unsigned IVSize, bool IVSigned,
25494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool Ordered, Address IL, Address LB, Address UB, Address ST,
25504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *Chunk) {
25514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OpenMPSchedType ScheduleNum = getRuntimeSchedule(SchedKind, Chunk != nullptr);
25524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *UpdatedLocation = emitUpdateLocation(CGF, Loc);
25534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *ThreadId = getThreadID(CGF, Loc);
25544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *StaticInitFunction = createForStaticInitFunction(IVSize, IVSigned);
25554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
25564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        ScheduleNum, OMPC_SCHEDULE_MODIFIER_unknown,
25574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        OMPC_SCHEDULE_MODIFIER_unknown, IVSize, Ordered, IL, LB,
25584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        UB, ST, Chunk);
25590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
25600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
2561b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF,
2562b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                          SourceLocation Loc) {
256387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
256487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
25650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid);
25664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
25670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini),
25680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      Args);
25690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
25700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
2571b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
2572b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                                 SourceLocation Loc,
2573b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                                 unsigned IVSize,
2574b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                                 bool IVSigned) {
257587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
257687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
2577b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Call __kmpc_for_dynamic_fini_(4|8)[u](ident_t *loc, kmp_int32 tid);
25784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
2579b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.EmitRuntimeCall(createDispatchFiniFunction(IVSize, IVSigned), Args);
2580b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
2581b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
25823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF,
25833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                          SourceLocation Loc, unsigned IVSize,
258487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          bool IVSigned, Address IL,
258587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          Address LB, Address UB,
258687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          Address ST) {
25873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Call __kmpc_dispatch_next(
25883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  //          ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
25893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  //          kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
25903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  //          kmp_int[32|64] *p_stride);
25913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::Value *Args[] = {
25924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitUpdateLocation(CGF, Loc),
25934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      getThreadID(CGF, Loc),
259487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      IL.getPointer(), // &isLastIter
259587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      LB.getPointer(), // &Lower
259687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      UB.getPointer(), // &Upper
259787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ST.getPointer()  // &Stride
25983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  };
25993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::Value *Call =
26003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args);
26013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return CGF.EmitScalarConversion(
26023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Call, CGF.getContext().getIntTypeForBitwidth(32, /* Signed */ true),
260387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.getContext().BoolTy, Loc);
26043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
26053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
26060e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
26070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                           llvm::Value *NumThreads,
26080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                           SourceLocation Loc) {
260987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
261087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
2611176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Build call __kmpc_push_num_threads(&loc, global_tid, num_threads)
2612176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::Value *Args[] = {
26130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2614176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)};
26150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_threads),
26160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      Args);
2617176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2618176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
261987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF,
262087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                         OpenMPProcBindClauseKind ProcBind,
262187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                         SourceLocation Loc) {
262287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
262387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
262487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Constants for proc bind value accepted by the runtime.
262587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  enum ProcBindTy {
262687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ProcBindFalse = 0,
262787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ProcBindTrue,
262887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ProcBindMaster,
262987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ProcBindClose,
263087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ProcBindSpread,
263187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ProcBindIntel,
263287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ProcBindDefault
263387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  } RuntimeProcBind;
263487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  switch (ProcBind) {
263587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPC_PROC_BIND_master:
263687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RuntimeProcBind = ProcBindMaster;
263787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
263887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPC_PROC_BIND_close:
263987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RuntimeProcBind = ProcBindClose;
264087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
264187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPC_PROC_BIND_spread:
264287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RuntimeProcBind = ProcBindSpread;
264387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
264487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case OMPC_PROC_BIND_unknown:
264587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm_unreachable("Unsupported proc_bind value.");
264687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
264787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Build call __kmpc_push_proc_bind(&loc, global_tid, proc_bind)
264887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *Args[] = {
264987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
265087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm::ConstantInt::get(CGM.IntTy, RuntimeProcBind, /*isSigned=*/true)};
265187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_proc_bind), Args);
265287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
265387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
26540e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>,
26550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                SourceLocation Loc) {
265687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
265787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
26580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Build call void __kmpc_flush(ident_t *loc)
26590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_flush),
26600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      emitUpdateLocation(CGF, Loc));
26610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
26620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
26633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarnamespace {
26643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \brief Indexes of fields for type kmp_task_t.
26653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarenum KmpTaskTFields {
26663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \brief List of shared variables.
26673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  KmpTaskTShareds,
26683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \brief Task routine.
26693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  KmpTaskTRoutine,
26703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \brief Partition id for the untied tasks.
26713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  KmpTaskTPartId,
26724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Function with call of destructors for private variables.
26734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Data1,
26744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Task priority.
26754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Data2,
26764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// (Taskloops only) Lower bound.
26774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  KmpTaskTLowerBound,
26784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// (Taskloops only) Upper bound.
26794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  KmpTaskTUpperBound,
26804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// (Taskloops only) Stride.
26814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  KmpTaskTStride,
26824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// (Taskloops only) Is last iteration flag.
26834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  KmpTaskTLastIter,
26843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar};
268587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // anonymous namespace
26863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
26874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::empty() const {
26884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // FIXME: Add other entries type when they become supported.
26894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return OffloadEntriesTargetRegion.empty();
26904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
26914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
26924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Initialize target region entry.
26934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
26944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
26954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    StringRef ParentName, unsigned LineNum,
26964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    unsigned Order) {
26974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
26984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                             "only required for the device "
26994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                             "code generation.");
27004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
27014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OffloadEntryInfoTargetRegion(Order, /*Addr=*/nullptr, /*ID=*/nullptr);
27024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ++OffloadingEntriesNum;
27034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
27044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
27064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
27074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  StringRef ParentName, unsigned LineNum,
27084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  llvm::Constant *Addr, llvm::Constant *ID) {
27094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If we are emitting code for a target, the entry is already initialized,
27104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // only has to be registered.
27114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (CGM.getLangOpts().OpenMPIsDevice) {
27124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum) &&
27134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar           "Entry must exist.");
27144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &Entry =
27154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
27164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(Entry.isValid() && "Entry not initialized!");
27174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Entry.setAddress(Addr);
27184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Entry.setID(ID);
27194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
27204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else {
27214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum++, Addr, ID);
27224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
27234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
27244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
27254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::hasTargetRegionEntryInfo(
27274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned DeviceID, unsigned FileID, StringRef ParentName,
27284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned LineNum) const {
27294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
27304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (PerDevice == OffloadEntriesTargetRegion.end())
27314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
27324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto PerFile = PerDevice->second.find(FileID);
27334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (PerFile == PerDevice->second.end())
27344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
27354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto PerParentName = PerFile->second.find(ParentName);
27364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (PerParentName == PerFile->second.end())
27374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
27384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto PerLine = PerParentName->second.find(LineNum);
27394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (PerLine == PerParentName->second.end())
27404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
27414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Fail if this entry is already registered.
27424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (PerLine->second.getAddress() || PerLine->second.getID())
27434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
27444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return true;
27454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
27464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::OffloadEntriesInfoManagerTy::actOnTargetRegionEntriesInfo(
27484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const OffloadTargetRegionEntryInfoActTy &Action) {
27494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Scan all target region entries and perform the provided action.
27504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto &D : OffloadEntriesTargetRegion)
27514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto &F : D.second)
27524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto &P : F.second)
27534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        for (auto &L : P.second)
27544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Action(D.first, F.first, P.first(), L.first, L.second);
27554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
27564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Create a Ctor/Dtor-like function whose body is emitted through
27584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \a Codegen. This is used to emit the two functions that register and
27594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// unregister the descriptor of the current compilation unit.
27604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic llvm::Function *
27614967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarcreateOffloadingBinaryDescriptorFunction(CodeGenModule &CGM, StringRef Name,
27624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         const RegionCodeGenTy &Codegen) {
27634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &C = CGM.getContext();
27644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FunctionArgList Args;
27654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ImplicitParamDecl DummyPtr(C, /*DC=*/nullptr, SourceLocation(),
27664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             /*Id=*/nullptr, C.VoidPtrTy);
27674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Args.push_back(&DummyPtr);
27684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction CGF(CGM);
27704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  GlobalDecl();
27714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
27724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto FTy = CGM.getTypes().GetFunctionType(FI);
27734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *Fn =
27744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.CreateGlobalInitOrDestructFunction(FTy, Name, FI, SourceLocation());
27754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FI, Args, SourceLocation());
27764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Codegen(CGF);
27774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.FinishFunction();
27784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Fn;
27794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
27804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarllvm::Function *
27824967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCGOpenMPRuntime::createOffloadingBinaryDescriptorRegistration() {
27834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If we don't have entries or if we are emitting code for the device, we
27854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // don't need to do anything.
27864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (CGM.getLangOpts().OpenMPIsDevice || OffloadEntriesInfoManager.empty())
27874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return nullptr;
27884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &M = CGM.getModule();
27904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &C = CGM.getContext();
27914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Get list of devices we care about
27934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &Devices = CGM.getLangOpts().OMPTargetTriples;
27944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // We should be creating an offloading descriptor only if there are devices
27964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // specified.
27974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(!Devices.empty() && "No OpenMP offloading devices??");
27984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
27994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create the external variables that will point to the begin and end of the
28004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // host entries section. These will be defined by the linker.
28014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *OffloadEntryTy =
28024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().ConvertTypeForMem(getTgtOffloadEntryQTy());
28034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::GlobalVariable *HostEntriesBegin = new llvm::GlobalVariable(
28044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      M, OffloadEntryTy, /*isConstant=*/true,
28054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::GlobalValue::ExternalLinkage, /*Initializer=*/nullptr,
28064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ".omp_offloading.entries_begin");
28074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::GlobalVariable *HostEntriesEnd = new llvm::GlobalVariable(
28084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      M, OffloadEntryTy, /*isConstant=*/true,
28094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::GlobalValue::ExternalLinkage, /*Initializer=*/nullptr,
28104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ".omp_offloading.entries_end");
28114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create all device images
28134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::SmallVector<llvm::Constant *, 4> DeviceImagesEntires;
28144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *DeviceImageTy = cast<llvm::StructType>(
28154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().ConvertTypeForMem(getTgtDeviceImageQTy()));
28164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (unsigned i = 0; i < Devices.size(); ++i) {
28184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    StringRef T = Devices[i].getTriple();
28194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *ImgBegin = new llvm::GlobalVariable(
28204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        M, CGM.Int8Ty, /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage,
28214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Initializer=*/nullptr,
28224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Twine(".omp_offloading.img_start.") + Twine(T));
28234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *ImgEnd = new llvm::GlobalVariable(
28244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        M, CGM.Int8Ty, /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage,
28254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Initializer=*/nullptr, Twine(".omp_offloading.img_end.") + Twine(T));
28264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Constant *Dev =
28284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::ConstantStruct::get(DeviceImageTy, ImgBegin, ImgEnd,
28294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  HostEntriesBegin, HostEntriesEnd, nullptr);
28304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    DeviceImagesEntires.push_back(Dev);
28314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
28324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create device images global array.
28344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::ArrayType *DeviceImagesInitTy =
28354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::ArrayType::get(DeviceImageTy, DeviceImagesEntires.size());
28364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Constant *DeviceImagesInit =
28374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::ConstantArray::get(DeviceImagesInitTy, DeviceImagesEntires);
28384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::GlobalVariable *DeviceImages = new llvm::GlobalVariable(
28404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      M, DeviceImagesInitTy, /*isConstant=*/true,
28414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::GlobalValue::InternalLinkage, DeviceImagesInit,
28424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ".omp_offloading.device_images");
28434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  DeviceImages->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
28444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // This is a Zero array to be used in the creation of the constant expressions
28464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Constant *Index[] = {llvm::Constant::getNullValue(CGM.Int32Ty),
28474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             llvm::Constant::getNullValue(CGM.Int32Ty)};
28484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create the target region descriptor.
28504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *BinaryDescriptorTy = cast<llvm::StructType>(
28514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().ConvertTypeForMem(getTgtBinaryDescriptorQTy()));
28524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Constant *TargetRegionsDescriptorInit = llvm::ConstantStruct::get(
28534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      BinaryDescriptorTy, llvm::ConstantInt::get(CGM.Int32Ty, Devices.size()),
28544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::ConstantExpr::getGetElementPtr(DeviceImagesInitTy, DeviceImages,
28554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                           Index),
28564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      HostEntriesBegin, HostEntriesEnd, nullptr);
28574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *Desc = new llvm::GlobalVariable(
28594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      M, BinaryDescriptorTy, /*isConstant=*/true,
28604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::GlobalValue::InternalLinkage, TargetRegionsDescriptorInit,
28614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ".omp_offloading.descriptor");
28624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Emit code to register or unregister the descriptor at execution
28644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // startup or closing, respectively.
28654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create a variable to drive the registration and unregistration of the
28674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // descriptor, so we can reuse the logic that emits Ctors and Dtors.
28684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *IdentInfo = &C.Idents.get(".omp_offloading.reg_unreg_var");
28694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ImplicitParamDecl RegUnregVar(C, C.getTranslationUnitDecl(), SourceLocation(),
28704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                IdentInfo, C.CharTy);
28714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *UnRegFn = createOffloadingBinaryDescriptorFunction(
28734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM, ".omp_offloading.descriptor_unreg",
28744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      [&](CodeGenFunction &CGF, PrePostActionTy &) {
28754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitCallOrInvoke(createRuntimeFunction(OMPRTL__tgt_unregister_lib),
28764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             Desc);
28774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      });
28784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *RegFn = createOffloadingBinaryDescriptorFunction(
28794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM, ".omp_offloading.descriptor_reg",
28804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      [&](CodeGenFunction &CGF, PrePostActionTy &) {
28814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitCallOrInvoke(createRuntimeFunction(OMPRTL__tgt_register_lib),
28824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             Desc);
28834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getCXXABI().registerGlobalDtor(CGF, RegUnregVar, UnRegFn, Desc);
28844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      });
28854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return RegFn;
28864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
28874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::createOffloadEntry(llvm::Constant *ID,
28894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         llvm::Constant *Addr, uint64_t Size) {
28904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  StringRef Name = Addr->getName();
28914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *TgtOffloadEntryType = cast<llvm::StructType>(
28924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().ConvertTypeForMem(getTgtOffloadEntryQTy()));
28934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::LLVMContext &C = CGM.getModule().getContext();
28944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Module &M = CGM.getModule();
28954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Make sure the address has the right type.
28974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Constant *AddrPtr = llvm::ConstantExpr::getBitCast(ID, CGM.VoidPtrTy);
28984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
28994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create constant string with the name.
29004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
29014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::GlobalVariable *Str =
29034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      new llvm::GlobalVariable(M, StrPtrInit->getType(), /*isConstant=*/true,
29044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                               llvm::GlobalValue::InternalLinkage, StrPtrInit,
29054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                               ".omp_offloading.entry_name");
29064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
29074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Constant *StrPtr = llvm::ConstantExpr::getBitCast(Str, CGM.Int8PtrTy);
29084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create the entry struct.
29104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Constant *EntryInit = llvm::ConstantStruct::get(
29114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      TgtOffloadEntryType, AddrPtr, StrPtr,
29124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::ConstantInt::get(CGM.SizeTy, Size), nullptr);
29134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::GlobalVariable *Entry = new llvm::GlobalVariable(
29144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      M, TgtOffloadEntryType, true, llvm::GlobalValue::ExternalLinkage,
29154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      EntryInit, ".omp_offloading.entry");
29164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // The entry has to be created in the section the linker expects it to be.
29184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Entry->setSection(".omp_offloading.entries");
29194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // We can't have any padding between symbols, so we need to have 1-byte
29204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // alignment.
29214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Entry->setAlignment(1);
29224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
29234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
29254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Emit the offloading entries and metadata so that the device codegen side
29264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // can
29274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // easily figure out what to emit. The produced metadata looks like this:
29284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
29294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // !omp_offload.info = !{!1, ...}
29304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
29314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Right now we only generate metadata for function that contain target
29324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // regions.
29334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If we do not have entries, we dont need to do anything.
29354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (OffloadEntriesInfoManager.empty())
29364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
29374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Module &M = CGM.getModule();
29394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::LLVMContext &C = M.getContext();
29404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SmallVector<OffloadEntriesInfoManagerTy::OffloadEntryInfo *, 16>
29414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OrderedEntries(OffloadEntriesInfoManager.size());
29424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create the offloading info metadata node.
29444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata("omp_offload.info");
29454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Auxiliar methods to create metadata values and strings.
29474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto getMDInt = [&](unsigned v) {
29484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return llvm::ConstantAsMetadata::get(
29494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::ConstantInt::get(llvm::Type::getInt32Ty(C), v));
29504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
29514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto getMDString = [&](StringRef v) { return llvm::MDString::get(C, v); };
29534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create function that emits metadata for each target region entry;
29554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&TargetRegionMetadataEmitter = [&](
29564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned Line,
29574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion &E) {
29584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::SmallVector<llvm::Metadata *, 32> Ops;
29594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Generate metadata for target regions. Each entry of this metadata
29604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // contains:
29614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // - Entry 0 -> Kind of this type of metadata (0).
29624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // - Entry 1 -> Device ID of the file where the entry was identified.
29634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // - Entry 2 -> File ID of the file where the entry was identified.
29644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // - Entry 3 -> Mangled name of the function where the entry was identified.
29654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // - Entry 4 -> Line in the file where the entry was identified.
29664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // - Entry 5 -> Order the entry was created.
29674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // The first element of the metadata node is the kind.
29684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Ops.push_back(getMDInt(E.getKind()));
29694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Ops.push_back(getMDInt(DeviceID));
29704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Ops.push_back(getMDInt(FileID));
29714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Ops.push_back(getMDString(ParentName));
29724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Ops.push_back(getMDInt(Line));
29734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Ops.push_back(getMDInt(E.getOrder()));
29744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Save this entry in the right position of the ordered entries array.
29764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OrderedEntries[E.getOrder()] = &E;
29774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Add metadata to the named metadata node.
29794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MD->addOperand(llvm::MDNode::get(C, Ops));
29804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
29814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OffloadEntriesInfoManager.actOnTargetRegionEntriesInfo(
29834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      TargetRegionMetadataEmitter);
29844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *E : OrderedEntries) {
29864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(E && "All ordered entries must exist!");
29874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *CE =
29884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
29894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                E)) {
29904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      assert(CE->getID() && CE->getAddress() &&
29914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar             "Entry ID and Addr are invalid!");
29924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      createOffloadEntry(CE->getID(), CE->getAddress(), /*Size=*/0);
29934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else
29944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm_unreachable("Unsupported entry kind.");
29954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
29964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
29974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
29984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Loads all the offload entries information from the host IR
29994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// metadata.
30004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::loadOffloadInfoMetadata() {
30014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If we are in target mode, load the metadata from the host IR. This code has
30024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // to match the metadaata creation in createOffloadEntriesAndInfoMetadata().
30034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGM.getLangOpts().OpenMPIsDevice)
30054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
30064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (CGM.getLangOpts().OMPHostIRFile.empty())
30084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
30094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto Buf = llvm::MemoryBuffer::getFile(CGM.getLangOpts().OMPHostIRFile);
30114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (Buf.getError())
30124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
30134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::LLVMContext C;
30154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto ME = llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C);
30164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (ME.getError())
30184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
30194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::NamedMDNode *MD = ME.get()->getNamedMetadata("omp_offload.info");
30214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!MD)
30224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
30234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto I : MD->operands()) {
30254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::MDNode *MN = cast<llvm::MDNode>(I);
30264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto getMDInt = [&](unsigned Idx) {
30284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::ConstantAsMetadata *V =
30294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          cast<llvm::ConstantAsMetadata>(MN->getOperand(Idx));
30304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return cast<llvm::ConstantInt>(V->getValue())->getZExtValue();
30314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    };
30324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto getMDString = [&](unsigned Idx) {
30344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::MDString *V = cast<llvm::MDString>(MN->getOperand(Idx));
30354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return V->getString();
30364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    };
30374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    switch (getMDInt(0)) {
30394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    default:
30404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm_unreachable("Unexpected metadata!");
30414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
30424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
30434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        OFFLOAD_ENTRY_INFO_TARGET_REGION:
30444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OffloadEntriesInfoManager.initializeTargetRegionEntryInfo(
30454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          /*DeviceID=*/getMDInt(1), /*FileID=*/getMDInt(2),
30464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          /*ParentName=*/getMDString(3), /*Line=*/getMDInt(4),
30474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          /*Order=*/getMDInt(5));
30484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
30494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
30504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
30514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
30524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) {
30543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  if (!KmpRoutineEntryPtrTy) {
30553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type.
30563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    auto &C = CGM.getContext();
30573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
30583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    FunctionProtoType::ExtProtoInfo EPI;
30593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    KmpRoutineEntryPtrQTy = C.getPointerType(
30603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
30613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    KmpRoutineEntryPtrTy = CGM.getTypes().ConvertType(KmpRoutineEntryPtrQTy);
30623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
30633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
30643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
306587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic FieldDecl *addFieldToRecordDecl(ASTContext &C, DeclContext *DC,
306687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                       QualType FieldTy) {
30673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *Field = FieldDecl::Create(
30683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy,
30693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()),
30703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
30713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  Field->setAccess(AS_public);
30723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  DC->addDecl(Field);
307387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return Field;
30743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
30753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
30764967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarQualType CGOpenMPRuntime::getTgtOffloadEntryQTy() {
30774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Make sure the type of the entry is already created. This is the type we
30794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // have to create:
30804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // struct __tgt_offload_entry{
30814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   void      *addr;       // Pointer to the offload entry info.
30824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //                          // (function or global)
30834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   char      *name;       // Name of the function or global.
30844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   size_t     size;       // Size of the entry info (0 if it a function).
30854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // };
30864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (TgtOffloadEntryQTy.isNull()) {
30874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ASTContext &C = CGM.getContext();
30884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *RD = C.buildImplicitRecord("__tgt_offload_entry");
30894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD->startDefinition();
30904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.VoidPtrTy);
30914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.getPointerType(C.CharTy));
30924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.getSizeType());
30934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD->completeDefinition();
30944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    TgtOffloadEntryQTy = C.getRecordType(RD);
30954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
30964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return TgtOffloadEntryQTy;
30974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
30984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
30994967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarQualType CGOpenMPRuntime::getTgtDeviceImageQTy() {
31004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // These are the types we need to build:
31014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // struct __tgt_device_image{
31024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // void   *ImageStart;       // Pointer to the target code start.
31034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // void   *ImageEnd;         // Pointer to the target code end.
31044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // // We also add the host entries to the device image, as it may be useful
31054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // // for the target runtime to have access to that information.
31064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // __tgt_offload_entry  *EntriesBegin;   // Begin of the table with all
31074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //                                       // the entries.
31084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // __tgt_offload_entry  *EntriesEnd;     // End of the table with all the
31094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //                                       // entries (non inclusive).
31104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // };
31114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (TgtDeviceImageQTy.isNull()) {
31124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ASTContext &C = CGM.getContext();
31134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *RD = C.buildImplicitRecord("__tgt_device_image");
31144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD->startDefinition();
31154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.VoidPtrTy);
31164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.VoidPtrTy);
31174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
31184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
31194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD->completeDefinition();
31204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    TgtDeviceImageQTy = C.getRecordType(RD);
31214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
31224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return TgtDeviceImageQTy;
31234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
31244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
31254967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarQualType CGOpenMPRuntime::getTgtBinaryDescriptorQTy() {
31264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // struct __tgt_bin_desc{
31274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   int32_t              NumDevices;      // Number of devices supported.
31284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   __tgt_device_image   *DeviceImages;   // Arrays of device images
31294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //                                         // (one per device).
31304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   __tgt_offload_entry  *EntriesBegin;   // Begin of the table with all the
31314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //                                         // entries.
31324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   __tgt_offload_entry  *EntriesEnd;     // End of the table with all the
31334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //                                         // entries (non inclusive).
31344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // };
31354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (TgtBinaryDescriptorQTy.isNull()) {
31364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ASTContext &C = CGM.getContext();
31374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *RD = C.buildImplicitRecord("__tgt_bin_desc");
31384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD->startDefinition();
31394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(
31404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
31414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.getPointerType(getTgtDeviceImageQTy()));
31424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
31434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
31444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD->completeDefinition();
31454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    TgtBinaryDescriptorQTy = C.getRecordType(RD);
31464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
31474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return TgtBinaryDescriptorQTy;
31484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
31494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3150b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarnamespace {
3151b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstruct PrivateHelpersTy {
3152b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  PrivateHelpersTy(const VarDecl *Original, const VarDecl *PrivateCopy,
3153b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                   const VarDecl *PrivateElemInit)
3154b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      : Original(Original), PrivateCopy(PrivateCopy),
3155b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        PrivateElemInit(PrivateElemInit) {}
3156b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  const VarDecl *Original;
3157b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  const VarDecl *PrivateCopy;
3158b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  const VarDecl *PrivateElemInit;
3159b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar};
3160b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainartypedef std::pair<CharUnits /*Align*/, PrivateHelpersTy> PrivateDataTy;
316187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // anonymous namespace
3162b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
3163b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstatic RecordDecl *
316487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarcreatePrivatesRecordDecl(CodeGenModule &CGM, ArrayRef<PrivateDataTy> Privates) {
3165b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (!Privates.empty()) {
3166b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto &C = CGM.getContext();
3167b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // Build struct .kmp_privates_t. {
3168b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    //         /*  private vars  */
3169b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    //       };
3170b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto *RD = C.buildImplicitRecord(".kmp_privates.t");
3171b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    RD->startDefinition();
3172b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    for (auto &&Pair : Privates) {
317387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *VD = Pair.second.Original;
317487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto Type = VD->getType();
3175b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      Type = Type.getNonReferenceType();
317687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *FD = addFieldToRecordDecl(C, RD, Type);
317787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      if (VD->hasAttrs()) {
317887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        for (specific_attr_iterator<AlignedAttr> I(VD->getAttrs().begin()),
317987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar             E(VD->getAttrs().end());
318087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar             I != E; ++I)
318187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          FD->addAttr(*I);
318287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      }
3183b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    }
3184b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    RD->completeDefinition();
3185b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    return RD;
3186b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
3187b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  return nullptr;
3188b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
3189b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
3190b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstatic RecordDecl *
31914967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarcreateKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind,
31924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         QualType KmpInt32Ty,
3193b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                         QualType KmpRoutineEntryPointerQTy) {
31943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto &C = CGM.getContext();
31953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Build struct kmp_task_t {
31963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  //         void *              shareds;
31973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  //         kmp_routine_entry_t routine;
31983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  //         kmp_int32           part_id;
31994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //         kmp_cmplrdata_t data1;
32004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //         kmp_cmplrdata_t data2;
32014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // For taskloops additional fields:
32024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //         kmp_uint64          lb;
32034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //         kmp_uint64          ub;
32044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //         kmp_int64           st;
32054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //         kmp_int32           liter;
32063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  //       };
32074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *UD = C.buildImplicitRecord("kmp_cmplrdata_t", TTK_Union);
32084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  UD->startDefinition();
32094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  addFieldToRecordDecl(C, UD, KmpInt32Ty);
32104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  addFieldToRecordDecl(C, UD, KmpRoutineEntryPointerQTy);
32114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  UD->completeDefinition();
32124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  QualType KmpCmplrdataTy = C.getRecordType(UD);
32133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *RD = C.buildImplicitRecord("kmp_task_t");
32143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  RD->startDefinition();
32153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  addFieldToRecordDecl(C, RD, C.VoidPtrTy);
32163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
32173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  addFieldToRecordDecl(C, RD, KmpInt32Ty);
32184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
32194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
32204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (isOpenMPTaskLoopDirective(Kind)) {
32214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    QualType KmpUInt64Ty =
32224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
32234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    QualType KmpInt64Ty =
32244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
32254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, KmpUInt64Ty);
32264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, KmpUInt64Ty);
32274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, KmpInt64Ty);
32284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, KmpInt32Ty);
32294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
32303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  RD->completeDefinition();
3231b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  return RD;
3232b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
3233b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
3234b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstatic RecordDecl *
3235b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga NainarcreateKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
323687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                     ArrayRef<PrivateDataTy> Privates) {
3237b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto &C = CGM.getContext();
3238b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Build struct kmp_task_t_with_privates {
3239b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  //         kmp_task_t task_data;
3240b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  //         .kmp_privates_t. privates;
3241b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  //       };
3242b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *RD = C.buildImplicitRecord("kmp_task_t_with_privates");
3243b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  RD->startDefinition();
3244b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  addFieldToRecordDecl(C, RD, KmpTaskTQTy);
3245b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (auto *PrivateRD = createPrivatesRecordDecl(CGM, Privates)) {
3246b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    addFieldToRecordDecl(C, RD, C.getRecordType(PrivateRD));
3247b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
3248b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  RD->completeDefinition();
3249b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  return RD;
32503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
32513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
32523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \brief Emit a proxy function which accepts kmp_task_t as the second
32533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// argument.
32543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \code
32553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
32564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///   TaskFunction(gtid, tt->part_id, &tt->privates, task_privates_map, tt,
32574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///   For taskloops:
32584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///   tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
3259b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar///   tt->shareds);
32603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar///   return 0;
32613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// }
32623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \endcode
32633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Value *
32643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainaremitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
32654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      OpenMPDirectiveKind Kind, QualType KmpInt32Ty,
32664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      QualType KmpTaskTWithPrivatesPtrQTy,
3267b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                      QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy,
326858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                      QualType SharedsPtrTy, llvm::Value *TaskFunction,
3269b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                      llvm::Value *TaskPrivatesMap) {
32703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto &C = CGM.getContext();
32713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  FunctionArgList Args;
32723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty);
32733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc,
327487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                /*Id=*/nullptr,
327587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                KmpTaskTWithPrivatesPtrQTy.withRestrict());
32763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  Args.push_back(&GtidArg);
32773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  Args.push_back(&TaskTypeArg);
32783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto &TaskEntryFnInfo =
32794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
32803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *TaskEntryTy = CGM.getTypes().GetFunctionType(TaskEntryFnInfo);
32813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *TaskEntry =
32823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      llvm::Function::Create(TaskEntryTy, llvm::GlobalValue::InternalLinkage,
32833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                             ".omp_task_entry.", &CGM.getModule());
328487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGM.SetInternalFunctionAttributes(/*D=*/nullptr, TaskEntry, TaskEntryFnInfo);
32853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CodeGenFunction CGF(CGM);
32863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CGF.disableDebugInfo();
32873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args);
32883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
3289b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // TaskFunction(gtid, tt->task_data.part_id, &tt->privates, task_privates_map,
32904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // tt,
32914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // For taskloops:
32924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
3293b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // tt->task_data.shareds);
32943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *GtidParam = CGF.EmitLoadOfScalar(
329587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false, KmpInt32Ty, Loc);
32964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue TDBase = CGF.EmitLoadOfPointerLValue(
32974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.GetAddrOfLocalVar(&TaskTypeArg),
32984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
3299b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *KmpTaskTWithPrivatesQTyRD =
3300b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
3301b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  LValue Base =
3302b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      CGF.EmitLValueForField(TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
3303b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
3304b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
3305b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto PartIdLVal = CGF.EmitLValueForField(Base, *PartIdFI);
33064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *PartidParam = PartIdLVal.getPointer();
3307b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
3308b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
3309b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto SharedsLVal = CGF.EmitLValueForField(Base, *SharedsFI);
3310b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *SharedsParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3311b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      CGF.EmitLoadOfLValue(SharedsLVal, Loc).getScalarVal(),
3312b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      CGF.ConvertTypeForMem(SharedsPtrTy));
3313b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
3314b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
3315b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  llvm::Value *PrivatesParam;
3316b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
3317b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto PrivatesLVal = CGF.EmitLValueForField(TDBase, *PrivatesFI);
3318b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    PrivatesParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
331987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        PrivatesLVal.getPointer(), CGF.VoidPtrTy);
33204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else
3321b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    PrivatesParam = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
33224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
33234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *CommonArgs[] = {GtidParam, PartidParam, PrivatesParam,
33244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                               TaskPrivatesMap,
33254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                               CGF.Builder
33264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   .CreatePointerBitCastOrAddrSpaceCast(
33274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       TDBase.getAddress(), CGF.VoidPtrTy)
33284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   .getPointer()};
33294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SmallVector<llvm::Value *, 16> CallArgs(std::begin(CommonArgs),
33304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                          std::end(CommonArgs));
33314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (isOpenMPTaskLoopDirective(Kind)) {
33324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto LBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound);
33334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto LBLVal = CGF.EmitLValueForField(Base, *LBFI);
33344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *LBParam = CGF.EmitLoadOfLValue(LBLVal, Loc).getScalarVal();
33354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto UBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound);
33364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto UBLVal = CGF.EmitLValueForField(Base, *UBFI);
33374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *UBParam = CGF.EmitLoadOfLValue(UBLVal, Loc).getScalarVal();
33384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto StFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTStride);
33394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto StLVal = CGF.EmitLValueForField(Base, *StFI);
33404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *StParam = CGF.EmitLoadOfLValue(StLVal, Loc).getScalarVal();
33414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
33424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto LILVal = CGF.EmitLValueForField(Base, *LIFI);
33434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *LIParam = CGF.EmitLoadOfLValue(LILVal, Loc).getScalarVal();
33444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CallArgs.push_back(LBParam);
33454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CallArgs.push_back(UBParam);
33464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CallArgs.push_back(StParam);
33474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CallArgs.push_back(LIParam);
3348b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
33494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CallArgs.push_back(SharedsParam);
3350b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
33513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CGF.EmitCallOrInvoke(TaskFunction, CallArgs);
33523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CGF.EmitStoreThroughLValue(
33533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      RValue::get(CGF.Builder.getInt32(/*C=*/0)),
335487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.MakeAddrLValue(CGF.ReturnValue, KmpInt32Ty));
33553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  CGF.FinishFunction();
33563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return TaskEntry;
33573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
33583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
3359b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstatic llvm::Value *emitDestructorsFunction(CodeGenModule &CGM,
3360b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                            SourceLocation Loc,
3361b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                            QualType KmpInt32Ty,
3362b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                            QualType KmpTaskTWithPrivatesPtrQTy,
3363b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                            QualType KmpTaskTWithPrivatesQTy) {
3364b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto &C = CGM.getContext();
3365b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  FunctionArgList Args;
3366b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty);
3367b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc,
336887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                /*Id=*/nullptr,
336987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                KmpTaskTWithPrivatesPtrQTy.withRestrict());
3370b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  Args.push_back(&GtidArg);
3371b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  Args.push_back(&TaskTypeArg);
3372b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  FunctionType::ExtInfo Info;
3373b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto &DestructorFnInfo =
33744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
3375b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *DestructorFnTy = CGM.getTypes().GetFunctionType(DestructorFnInfo);
3376b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *DestructorFn =
3377b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      llvm::Function::Create(DestructorFnTy, llvm::GlobalValue::InternalLinkage,
3378b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                             ".omp_task_destructor.", &CGM.getModule());
337987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGM.SetInternalFunctionAttributes(/*D=*/nullptr, DestructorFn,
338087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                    DestructorFnInfo);
3381b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CodeGenFunction CGF(CGM);
3382b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.disableDebugInfo();
3383b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.StartFunction(GlobalDecl(), KmpInt32Ty, DestructorFn, DestructorFnInfo,
3384b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                    Args);
3385b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
33864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue Base = CGF.EmitLoadOfPointerLValue(
33874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.GetAddrOfLocalVar(&TaskTypeArg),
33884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
3389b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *KmpTaskTWithPrivatesQTyRD =
3390b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
3391b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
3392b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  Base = CGF.EmitLValueForField(Base, *FI);
3393b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  for (auto *Field :
3394b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar       cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
3395b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    if (auto DtorKind = Field->getType().isDestructedType()) {
3396b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      auto FieldLValue = CGF.EmitLValueForField(Base, Field);
3397b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      CGF.pushDestroy(DtorKind, FieldLValue.getAddress(), Field->getType());
3398b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    }
3399b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
3400b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.FinishFunction();
3401b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  return DestructorFn;
3402b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
3403b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
3404b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// \brief Emit a privates mapping function for correct handling of private and
3405b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// firstprivate variables.
3406b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// \code
3407b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// void .omp_task_privates_map.(const .privates. *noalias privs, <ty1>
3408b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// **noalias priv1,...,  <tyn> **noalias privn) {
3409b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar///   *priv1 = &.privates.priv1;
3410b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar///   ...;
3411b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar///   *privn = &.privates.privn;
3412b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// }
3413b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar/// \endcode
3414b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstatic llvm::Value *
3415b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga NainaremitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc,
341687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                               ArrayRef<const Expr *> PrivateVars,
341787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                               ArrayRef<const Expr *> FirstprivateVars,
34184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                               ArrayRef<const Expr *> LastprivateVars,
3419b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                               QualType PrivatesQTy,
342087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                               ArrayRef<PrivateDataTy> Privates) {
3421b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto &C = CGM.getContext();
3422b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  FunctionArgList Args;
3423b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  ImplicitParamDecl TaskPrivatesArg(
3424b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3425b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      C.getPointerType(PrivatesQTy).withConst().withRestrict());
3426b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  Args.push_back(&TaskPrivatesArg);
3427b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
3428b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  unsigned Counter = 1;
3429b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  for (auto *E: PrivateVars) {
3430b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    Args.push_back(ImplicitParamDecl::Create(
3431b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        C, /*DC=*/nullptr, Loc,
3432b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        /*Id=*/nullptr, C.getPointerType(C.getPointerType(E->getType()))
3433b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                            .withConst()
3434b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                            .withRestrict()));
3435b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3436b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    PrivateVarsPos[VD] = Counter;
3437b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    ++Counter;
3438b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
3439b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  for (auto *E : FirstprivateVars) {
3440b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    Args.push_back(ImplicitParamDecl::Create(
3441b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        C, /*DC=*/nullptr, Loc,
3442b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        /*Id=*/nullptr, C.getPointerType(C.getPointerType(E->getType()))
3443b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                            .withConst()
3444b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                            .withRestrict()));
3445b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3446b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    PrivateVarsPos[VD] = Counter;
3447b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    ++Counter;
3448b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
34494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *E: LastprivateVars) {
34504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Args.push_back(ImplicitParamDecl::Create(
34514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        C, /*DC=*/nullptr, Loc,
34524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Id=*/nullptr, C.getPointerType(C.getPointerType(E->getType()))
34534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            .withConst()
34544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            .withRestrict()));
34554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
34564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PrivateVarsPos[VD] = Counter;
34574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++Counter;
34584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3459b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto &TaskPrivatesMapFnInfo =
34604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
3461b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *TaskPrivatesMapTy =
3462b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      CGM.getTypes().GetFunctionType(TaskPrivatesMapFnInfo);
3463b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *TaskPrivatesMap = llvm::Function::Create(
3464b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      TaskPrivatesMapTy, llvm::GlobalValue::InternalLinkage,
3465b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      ".omp_task_privates_map.", &CGM.getModule());
346687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGM.SetInternalFunctionAttributes(/*D=*/nullptr, TaskPrivatesMap,
346787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                    TaskPrivatesMapFnInfo);
3468b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
3469b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CodeGenFunction CGF(CGM);
3470b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.disableDebugInfo();
3471b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskPrivatesMap,
3472b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                    TaskPrivatesMapFnInfo, Args);
3473b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
3474b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // *privi = &.privates.privi;
34754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue Base = CGF.EmitLoadOfPointerLValue(
34764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.GetAddrOfLocalVar(&TaskPrivatesArg),
34774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      TaskPrivatesArg.getType()->castAs<PointerType>());
3478b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->getAsTagDecl());
3479b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  Counter = 0;
3480b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  for (auto *Field : PrivatesQTyRD->fields()) {
3481b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto FieldLVal = CGF.EmitLValueForField(Base, Field);
3482b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
348387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto RefLVal = CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(VD), VD->getType());
34844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto RefLoadLVal = CGF.EmitLoadOfPointerLValue(
34854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        RefLVal.getAddress(), RefLVal.getType()->castAs<PointerType>());
348687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.EmitStoreOfScalar(FieldLVal.getPointer(), RefLoadLVal);
3487b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    ++Counter;
3488b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
3489b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.FinishFunction();
3490b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  return TaskPrivatesMap;
3491b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
3492b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
3493b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstatic int array_pod_sort_comparator(const PrivateDataTy *P1,
3494b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                     const PrivateDataTy *P2) {
3495b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  return P1->first < P2->first ? 1 : (P2->first < P1->first ? -1 : 0);
3496b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
3497b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
34984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Emit initialization for private variables in task-based directives.
34994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void emitPrivatesInit(CodeGenFunction &CGF,
35004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             const OMPExecutableDirective &D,
35014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             Address KmpTaskSharedsPtr, LValue TDBase,
35024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             const RecordDecl *KmpTaskTWithPrivatesQTyRD,
35034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             QualType SharedsTy, QualType SharedsPtrTy,
35044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             const OMPTaskDataTy &Data,
35054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             ArrayRef<PrivateDataTy> Privates, bool ForDup) {
35064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &C = CGF.getContext();
35074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
35084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue PrivatesBase = CGF.EmitLValueForField(TDBase, *FI);
35094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue SrcBase;
35104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!Data.FirstprivateVars.empty()) {
35114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    SrcBase = CGF.MakeAddrLValue(
35124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
35134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)),
35144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        SharedsTy);
35154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
35164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction::CGCapturedStmtInfo CapturesInfo(
35174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      cast<CapturedStmt>(*D.getAssociatedStmt()));
35184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
35194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto &&Pair : Privates) {
35204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *VD = Pair.second.PrivateCopy;
35214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *Init = VD->getAnyInitializer();
35224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Init && (!ForDup || (isa<CXXConstructExpr>(Init) &&
35234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             !CGF.isTrivialInitializer(Init)))) {
35244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      LValue PrivateLValue = CGF.EmitLValueForField(PrivatesBase, *FI);
35254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (auto *Elem = Pair.second.PrivateElemInit) {
35264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *OriginalVD = Pair.second.Original;
35274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *SharedField = CapturesInfo.lookup(OriginalVD);
35284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto SharedRefLValue = CGF.EmitLValueForField(SrcBase, SharedField);
35294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        SharedRefLValue = CGF.MakeAddrLValue(
35304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)),
35314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            SharedRefLValue.getType(), AlignmentSource::Decl);
35324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        QualType Type = OriginalVD->getType();
35334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (Type->isArrayType()) {
35344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          // Initialize firstprivate array.
35354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          if (!isa<CXXConstructExpr>(Init) || CGF.isTrivialInitializer(Init)) {
35364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            // Perform simple memcpy.
35374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            CGF.EmitAggregateAssign(PrivateLValue.getAddress(),
35384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    SharedRefLValue.getAddress(), Type);
35394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          } else {
35404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            // Initialize firstprivate array using element-by-element
35414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            // intialization.
35424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            CGF.EmitOMPAggregateAssign(
35434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                PrivateLValue.getAddress(), SharedRefLValue.getAddress(), Type,
35444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                [&CGF, Elem, Init, &CapturesInfo](Address DestElement,
35454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                  Address SrcElement) {
35464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                  // Clean up any temporaries needed by the initialization.
35474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                  CodeGenFunction::OMPPrivateScope InitScope(CGF);
35484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                  InitScope.addPrivate(
35494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      Elem, [SrcElement]() -> Address { return SrcElement; });
35504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                  (void)InitScope.Privatize();
35514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                  // Emit initialization for single element.
35524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                  CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(
35534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      CGF, &CapturesInfo);
35544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                  CGF.EmitAnyExprToMem(Init, DestElement,
35554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       Init->getType().getQualifiers(),
35564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       /*IsInitializer=*/false);
35574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                });
35584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          }
35594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        } else {
35604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CodeGenFunction::OMPPrivateScope InitScope(CGF);
35614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          InitScope.addPrivate(Elem, [SharedRefLValue]() -> Address {
35624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            return SharedRefLValue.getAddress();
35634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          });
35644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          (void)InitScope.Privatize();
35654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CapturesInfo);
35664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF.EmitExprAsInit(Init, VD, PrivateLValue,
35674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             /*capturedByInit=*/false);
35684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        }
35694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      } else
35704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitExprAsInit(Init, VD, PrivateLValue, /*capturedByInit=*/false);
35714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
35724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++FI;
35734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
35744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
35754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
35764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Check if duplication function is required for taskloops.
35774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic bool checkInitIsRequired(CodeGenFunction &CGF,
35784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                ArrayRef<PrivateDataTy> Privates) {
35794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool InitRequired = false;
35804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto &&Pair : Privates) {
35814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *VD = Pair.second.PrivateCopy;
35824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *Init = VD->getAnyInitializer();
35834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    InitRequired = InitRequired || (Init && isa<CXXConstructExpr>(Init) &&
35844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    !CGF.isTrivialInitializer(Init));
35854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
35864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return InitRequired;
35874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
35884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
35894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
35904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Emit task_dup function (for initialization of
35914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// private/firstprivate/lastprivate vars and last_iter flag)
35924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \code
35934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// void __task_dup_entry(kmp_task_t *task_dst, const kmp_task_t *task_src, int
35944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// lastpriv) {
35954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// // setup lastprivate flag
35964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///    task_dst->last = lastpriv;
35974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// // could be constructor calls here...
35984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// }
35994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \endcode
36004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic llvm::Value *
36014967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainaremitTaskDupFunction(CodeGenModule &CGM, SourceLocation Loc,
36024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    const OMPExecutableDirective &D,
36034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    QualType KmpTaskTWithPrivatesPtrQTy,
36044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    const RecordDecl *KmpTaskTWithPrivatesQTyRD,
36054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    const RecordDecl *KmpTaskTQTyRD, QualType SharedsTy,
36064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    QualType SharedsPtrTy, const OMPTaskDataTy &Data,
36074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    ArrayRef<PrivateDataTy> Privates, bool WithLastIter) {
36084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &C = CGM.getContext();
36094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FunctionArgList Args;
36104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ImplicitParamDecl DstArg(C, /*DC=*/nullptr, Loc,
36114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                           /*Id=*/nullptr, KmpTaskTWithPrivatesPtrQTy);
36124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ImplicitParamDecl SrcArg(C, /*DC=*/nullptr, Loc,
36134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                           /*Id=*/nullptr, KmpTaskTWithPrivatesPtrQTy);
36144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ImplicitParamDecl LastprivArg(C, /*DC=*/nullptr, Loc,
36154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                /*Id=*/nullptr, C.IntTy);
36164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Args.push_back(&DstArg);
36174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Args.push_back(&SrcArg);
36184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Args.push_back(&LastprivArg);
36194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &TaskDupFnInfo =
36204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
36214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *TaskDupTy = CGM.getTypes().GetFunctionType(TaskDupFnInfo);
36224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *TaskDup =
36234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Function::Create(TaskDupTy, llvm::GlobalValue::InternalLinkage,
36244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             ".omp_task_dup.", &CGM.getModule());
36254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGM.SetInternalFunctionAttributes(/*D=*/nullptr, TaskDup, TaskDupFnInfo);
36264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction CGF(CGM);
36274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.disableDebugInfo();
36284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskDup, TaskDupFnInfo, Args);
36294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
36304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue TDBase = CGF.EmitLoadOfPointerLValue(
36314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.GetAddrOfLocalVar(&DstArg),
36324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
36334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // task_dst->liter = lastpriv;
36344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (WithLastIter) {
36354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
36364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LValue Base = CGF.EmitLValueForField(
36374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
36384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
36394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *Lastpriv = CGF.EmitLoadOfScalar(
36404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.GetAddrOfLocalVar(&LastprivArg), /*Volatile=*/false, C.IntTy, Loc);
36414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitStoreOfScalar(Lastpriv, LILVal);
36424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
36434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
36444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Emit initial values for private copies (if any).
36454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(!Privates.empty());
36464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Address KmpTaskSharedsPtr = Address::invalid();
36474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!Data.FirstprivateVars.empty()) {
36484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LValue TDBase = CGF.EmitLoadOfPointerLValue(
36494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.GetAddrOfLocalVar(&SrcArg),
36504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
36514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LValue Base = CGF.EmitLValueForField(
36524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
36534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    KmpTaskSharedsPtr = Address(
36544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.EmitLoadOfScalar(CGF.EmitLValueForField(
36554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 Base, *std::next(KmpTaskTQTyRD->field_begin(),
36564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                  KmpTaskTShareds)),
36574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             Loc),
36584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.getNaturalTypeAlignment(SharedsTy));
36594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
36604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, TDBase, KmpTaskTWithPrivatesQTyRD,
36614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                   SharedsTy, SharedsPtrTy, Data, Privates, /*ForDup=*/true);
36624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.FinishFunction();
36634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return TaskDup;
36644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
36654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
36664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Checks if destructor function is required to be generated.
36674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \return true if cleanups are required, false otherwise.
36684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic bool
36694967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarcheckDestructorsRequired(const RecordDecl *KmpTaskTWithPrivatesQTyRD) {
36704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsCleanup = false;
36714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
36724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *PrivateRD = cast<RecordDecl>(FI->getType()->getAsTagDecl());
36734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *FD : PrivateRD->fields()) {
36744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    NeedsCleanup = NeedsCleanup || FD->getType().isDestructedType();
36754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (NeedsCleanup)
36764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
36774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
36784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return NeedsCleanup;
36794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
36804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
36814967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCGOpenMPRuntime::TaskResultTy
36824967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
36834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              const OMPExecutableDirective &D,
36844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              llvm::Value *TaskFunction, QualType SharedsTy,
36854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              Address Shareds, const OMPTaskDataTy &Data) {
36863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto &C = CGM.getContext();
36874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::SmallVector<PrivateDataTy, 4> Privates;
3688b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Aggregate privates and sort them by the alignment.
36894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto I = Data.PrivateCopies.begin();
36904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *E : Data.PrivateVars) {
3691b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3692b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    Privates.push_back(std::make_pair(
369387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        C.getDeclAlign(VD),
3694b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
3695b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                         /*PrivateElemInit=*/nullptr)));
3696b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    ++I;
3697b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
36984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  I = Data.FirstprivateCopies.begin();
36994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto IElemInitRef = Data.FirstprivateInits.begin();
37004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *E : Data.FirstprivateVars) {
3701b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3702b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    Privates.push_back(std::make_pair(
370387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        C.getDeclAlign(VD),
3704b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        PrivateHelpersTy(
3705b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar            VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
3706b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar            cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl()))));
37074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++I;
37084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++IElemInitRef;
37094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
37104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  I = Data.LastprivateCopies.begin();
37114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *E : Data.LastprivateVars) {
37124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
37134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Privates.push_back(std::make_pair(
37144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        C.getDeclAlign(VD),
37154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
37164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         /*PrivateElemInit=*/nullptr)));
37174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++I;
3718b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
3719b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  llvm::array_pod_sort(Privates.begin(), Privates.end(),
3720b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                       array_pod_sort_comparator);
37213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
37223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Build type kmp_routine_entry_t (if not built yet).
37233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  emitKmpRoutineEntryT(KmpInt32Ty);
3724b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Build type kmp_task_t (if not built yet).
3725b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (KmpTaskTQTy.isNull()) {
37264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    KmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
37274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
3728b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
3729b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
37303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Build particular struct kmp_task_t for the given task.
3731b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *KmpTaskTWithPrivatesQTyRD =
3732b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      createKmpTaskTWithPrivatesRecordDecl(CGM, KmpTaskTQTy, Privates);
3733b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
3734b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  QualType KmpTaskTWithPrivatesPtrQTy =
3735b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      C.getPointerType(KmpTaskTWithPrivatesQTy);
3736b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *KmpTaskTWithPrivatesTy = CGF.ConvertType(KmpTaskTWithPrivatesQTy);
3737b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *KmpTaskTWithPrivatesPtrTy = KmpTaskTWithPrivatesTy->getPointerTo();
37384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *KmpTaskTWithPrivatesTySize = CGF.getTypeSize(KmpTaskTWithPrivatesQTy);
37393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  QualType SharedsPtrTy = C.getPointerType(SharedsTy);
37403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
3741b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Emit initial values for private copies (if any).
3742b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  llvm::Value *TaskPrivatesMap = nullptr;
3743b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *TaskPrivatesMapTy =
3744b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      std::next(cast<llvm::Function>(TaskFunction)->getArgumentList().begin(),
3745b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                3)
3746b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          ->getType();
3747b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (!Privates.empty()) {
3748b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
3749b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    TaskPrivatesMap = emitTaskPrivateMappingFunction(
37504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM, Loc, Data.PrivateVars, Data.FirstprivateVars, Data.LastprivateVars,
37514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        FI->getType(), Privates);
3752b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3753b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        TaskPrivatesMap, TaskPrivatesMapTy);
3754b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  } else {
3755b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    TaskPrivatesMap = llvm::ConstantPointerNull::get(
3756b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        cast<llvm::PointerType>(TaskPrivatesMapTy));
3757b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
37583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid,
37593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // kmp_task_t *tt);
3760b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *TaskEntry = emitProxyTaskFunction(
37614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM, Loc, D.getDirectiveKind(), KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
37624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      KmpTaskTWithPrivatesQTy, KmpTaskTQTy, SharedsPtrTy, TaskFunction,
37634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      TaskPrivatesMap);
37643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
37653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Build call kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
37663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
37673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // kmp_routine_entry_t *task_entry);
37683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Task flags. Format is taken from
37693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h,
37703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // description of kmp_tasking_flags struct.
37714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  enum {
37724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    TiedFlag = 0x1,
37734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    FinalFlag = 0x2,
37744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    DestructorsFlag = 0x8,
37754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PriorityFlag = 0x20
37764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
37774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned Flags = Data.Tied ? TiedFlag : 0;
37784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsCleanup = false;
37794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!Privates.empty()) {
37804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    NeedsCleanup = checkDestructorsRequired(KmpTaskTWithPrivatesQTyRD);
37814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (NeedsCleanup)
37824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Flags = Flags | DestructorsFlag;
37834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
37844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (Data.Priority.getInt())
37854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Flags = Flags | PriorityFlag;
37863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *TaskFlags =
37874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Data.Final.getPointer()
37884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          ? CGF.Builder.CreateSelect(Data.Final.getPointer(),
37893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                     CGF.Builder.getInt32(FinalFlag),
37903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                     CGF.Builder.getInt32(/*C=*/0))
37914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          : CGF.Builder.getInt32(Data.Final.getInt() ? FinalFlag : 0);
37923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
379387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto *SharedsSize = CGM.getSize(C.getTypeSizeInChars(SharedsTy));
379487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *AllocArgs[] = {emitUpdateLocation(CGF, Loc),
379587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                              getThreadID(CGF, Loc), TaskFlags,
379687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                              KmpTaskTWithPrivatesTySize, SharedsSize,
379787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                              CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
379887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                  TaskEntry, KmpRoutineEntryPtrTy)};
37993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  auto *NewTask = CGF.EmitRuntimeCall(
38003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      createRuntimeFunction(OMPRTL__kmpc_omp_task_alloc), AllocArgs);
3801b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *NewTaskNewTaskTTy = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3802b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      NewTask, KmpTaskTWithPrivatesPtrTy);
3803b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  LValue Base = CGF.MakeNaturalAlignAddrLValue(NewTaskNewTaskTTy,
3804b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                               KmpTaskTWithPrivatesQTy);
3805b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  LValue TDBase =
3806b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      CGF.EmitLValueForField(Base, *KmpTaskTWithPrivatesQTyRD->field_begin());
38073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Fill the data in the resulting kmp_task_t record.
38083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Copy shareds if there are any.
380987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address KmpTaskSharedsPtr = Address::invalid();
3810b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (!SharedsTy->getAsStructureType()->getDecl()->field_empty()) {
381187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    KmpTaskSharedsPtr =
381287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        Address(CGF.EmitLoadOfScalar(
381387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                    CGF.EmitLValueForField(
381487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                        TDBase, *std::next(KmpTaskTQTyRD->field_begin(),
381587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                           KmpTaskTShareds)),
381687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                    Loc),
381787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                CGF.getNaturalTypeAlignment(SharedsTy));
3818b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    CGF.EmitAggregateCopy(KmpTaskSharedsPtr, Shareds, SharedsTy);
3819b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
3820b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Emit initial values for private copies (if any).
38214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  TaskResultTy Result;
3822b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (!Privates.empty()) {
38234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, Base, KmpTaskTWithPrivatesQTyRD,
38244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                     SharedsTy, SharedsPtrTy, Data, Privates,
38254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                     /*ForDup=*/false);
38264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
38274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        (!Data.LastprivateVars.empty() || checkInitIsRequired(CGF, Privates))) {
38284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Result.TaskDupFn = emitTaskDupFunction(
38294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGM, Loc, D, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTyRD,
38304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          KmpTaskTQTyRD, SharedsTy, SharedsPtrTy, Data, Privates,
38314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          /*WithLastIter=*/!Data.LastprivateVars.empty());
3832b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    }
3833b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
38344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Fields of union "kmp_cmplrdata_t" for destructors and priority.
38354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  enum { Priority = 0, Destructors = 1 };
38363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Provide pointer to function with destructors for privates.
38374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
38384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *KmpCmplrdataUD = (*FI)->getType()->getAsUnionType()->getDecl();
38394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (NeedsCleanup) {
38404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *DestructorFn = emitDestructorsFunction(
38414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
38424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        KmpTaskTWithPrivatesQTy);
38434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LValue Data1LV = CGF.EmitLValueForField(TDBase, *FI);
38444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LValue DestructorsLV = CGF.EmitLValueForField(
38454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors));
38464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
38474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              DestructorFn, KmpRoutineEntryPtrTy),
38484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          DestructorsLV);
38494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
38504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Set priority.
38514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (Data.Priority.getInt()) {
38524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LValue Data2LV = CGF.EmitLValueForField(
38534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2));
38544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    LValue PriorityLV = CGF.EmitLValueForField(
38554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority));
38564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitStoreOfScalar(Data.Priority.getPointer(), PriorityLV);
38574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
38584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Result.NewTask = NewTask;
38594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Result.TaskEntry = TaskEntry;
38604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Result.NewTaskNewTaskTTy = NewTaskNewTaskTTy;
38614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Result.TDBase = TDBase;
38624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Result.KmpTaskTQTyRD = KmpTaskTQTyRD;
38634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Result;
38644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
38654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
38664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
38674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   const OMPExecutableDirective &D,
38684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   llvm::Value *TaskFunction,
38694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   QualType SharedsTy, Address Shareds,
38704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   const Expr *IfCond,
38714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   const OMPTaskDataTy &Data) {
38724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
38734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
38744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
38754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  TaskResultTy Result =
38764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
38774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *NewTask = Result.NewTask;
38784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *TaskEntry = Result.TaskEntry;
38794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *NewTaskNewTaskTTy = Result.NewTaskNewTaskTTy;
38804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue TDBase = Result.TDBase;
38814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RecordDecl *KmpTaskTQTyRD = Result.KmpTaskTQTyRD;
38824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &C = CGM.getContext();
388387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Process list of dependences.
388487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address DependenciesArray = Address::invalid();
38854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned NumDependencies = Data.Dependences.size();
388687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (NumDependencies) {
388787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Dependence kind for RTL.
388887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3 };
388987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
389087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RecordDecl *KmpDependInfoRD;
389187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    QualType FlagsTy =
389287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        C.getIntTypeForBitwidth(C.getTypeSize(C.BoolTy), /*Signed=*/false);
389387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
389487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (KmpDependInfoTy.isNull()) {
389587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      KmpDependInfoRD = C.buildImplicitRecord("kmp_depend_info");
389687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      KmpDependInfoRD->startDefinition();
389787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      addFieldToRecordDecl(C, KmpDependInfoRD, C.getIntPtrType());
389887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      addFieldToRecordDecl(C, KmpDependInfoRD, C.getSizeType());
389987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
390087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      KmpDependInfoRD->completeDefinition();
390187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
39024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else
390387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
390487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CharUnits DependencySize = C.getTypeSizeInChars(KmpDependInfoTy);
390587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Define type kmp_depend_info[<Dependences.size()>];
390687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    QualType KmpDependInfoArrayTy = C.getConstantArrayType(
390787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies),
390887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        ArrayType::Normal, /*IndexTypeQuals=*/0);
390987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_depend_info[<Dependences.size()>] deps;
39104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    DependenciesArray =
39114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr");
391287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    for (unsigned i = 0; i < NumDependencies; ++i) {
39134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const Expr *E = Data.Dependences[i].second;
391487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto Addr = CGF.EmitLValue(E);
391587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm::Value *Size;
391687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      QualType Ty = E->getType();
391787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      if (auto *ASE = dyn_cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts())) {
391887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        LValue UpAddrLVal =
391987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            CGF.EmitOMPArraySectionExpr(ASE, /*LowerBound=*/false);
392087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::Value *UpAddr =
392187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            CGF.Builder.CreateConstGEP1_32(UpAddrLVal.getPointer(), /*Idx0=*/1);
392287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::Value *LowIntPtr =
392387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            CGF.Builder.CreatePtrToInt(Addr.getPointer(), CGM.SizeTy);
392487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGM.SizeTy);
392587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        Size = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr);
392687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      } else
39274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Size = CGF.getTypeSize(Ty);
392887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto Base = CGF.MakeAddrLValue(
392987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGF.Builder.CreateConstArrayGEP(DependenciesArray, i, DependencySize),
393087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          KmpDependInfoTy);
393187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // deps[i].base_addr = &<Dependences[i].second>;
393287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto BaseAddrLVal = CGF.EmitLValueForField(
393387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
393487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitStoreOfScalar(
393587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGF.Builder.CreatePtrToInt(Addr.getPointer(), CGF.IntPtrTy),
393687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          BaseAddrLVal);
393787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // deps[i].len = sizeof(<Dependences[i].second>);
393887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto LenLVal = CGF.EmitLValueForField(
393987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          Base, *std::next(KmpDependInfoRD->field_begin(), Len));
394087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitStoreOfScalar(Size, LenLVal);
394187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // deps[i].flags = <Dependences[i].first>;
394287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      RTLDependenceKindTy DepKind;
39434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      switch (Data.Dependences[i].first) {
394487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      case OMPC_DEPEND_in:
394587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        DepKind = DepIn;
394687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        break;
394787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Out and InOut dependencies must use the same code.
394887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      case OMPC_DEPEND_out:
394987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      case OMPC_DEPEND_inout:
395087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        DepKind = DepInOut;
395187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        break;
395287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      case OMPC_DEPEND_source:
39534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      case OMPC_DEPEND_sink:
395487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      case OMPC_DEPEND_unknown:
395587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm_unreachable("Unknown task dependence type");
395687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      }
395787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto FlagsLVal = CGF.EmitLValueForField(
395887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          Base, *std::next(KmpDependInfoRD->field_begin(), Flags));
395987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
396087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                            FlagsLVal);
396187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
396287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DependenciesArray = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
396387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.Builder.CreateStructGEP(DependenciesArray, 0, CharUnits::Zero()),
396487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.VoidPtrTy);
396587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
396687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
39673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc()
39683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // libcall.
396987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
397087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
397187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list) if dependence
397287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // list is not empty
3973b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  auto *ThreadID = getThreadID(CGF, Loc);
397487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto *UpLoc = emitUpdateLocation(CGF, Loc);
397587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *TaskArgs[] = { UpLoc, ThreadID, NewTask };
397687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *DepTaskArgs[7];
397787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (NumDependencies) {
397887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepTaskArgs[0] = UpLoc;
397987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepTaskArgs[1] = ThreadID;
398087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepTaskArgs[2] = NewTask;
398187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepTaskArgs[3] = CGF.Builder.getInt32(NumDependencies);
398287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepTaskArgs[4] = DependenciesArray.getPointer();
398387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepTaskArgs[5] = CGF.Builder.getInt32(0);
398487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
398587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
39864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ThenCodeGen = [this, Loc, &Data, TDBase, KmpTaskTQTyRD,
39874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        NumDependencies, &TaskArgs,
39884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        &DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
39894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!Data.Tied) {
39904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
39914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
39924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
39934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
399487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (NumDependencies) {
39954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.EmitRuntimeCall(
39964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          createRuntimeFunction(OMPRTL__kmpc_omp_task_with_deps), DepTaskArgs);
399787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    } else {
399887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task),
399987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                          TaskArgs);
400087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
40014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Check if parent region is untied and build return for untied task;
40024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *Region =
40034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
40044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Region->emitUntiedSwitch(CGF);
4005b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  };
4006b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
400787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *DepWaitTaskArgs[6];
400887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (NumDependencies) {
400987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepWaitTaskArgs[0] = UpLoc;
401087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepWaitTaskArgs[1] = ThreadID;
401187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepWaitTaskArgs[2] = CGF.Builder.getInt32(NumDependencies);
401287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepWaitTaskArgs[3] = DependenciesArray.getPointer();
401387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
401487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
401587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
40164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ElseCodeGen = [&TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
40174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        NumDependencies, &DepWaitTaskArgs](CodeGenFunction &CGF,
40184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                           PrePostActionTy &) {
40194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &RT = CGF.CGM.getOpenMPRuntime();
402087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CodeGenFunction::RunCleanupsScope LocalScope(CGF);
402187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
402287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
402387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info
402487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // is specified.
402587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (NumDependencies)
40264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__kmpc_omp_wait_deps),
402787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                          DepWaitTaskArgs);
40284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Call proxy_task_entry(gtid, new_task);
40294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy](
40304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CodeGenFunction &CGF, PrePostActionTy &Action) {
40314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Action.Enter(CGF);
40324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
40334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.EmitCallOrInvoke(TaskEntry, OutlinedFnArgs);
40344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    };
40354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
403687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
403787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_task_t *new_task);
403887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
403987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // kmp_task_t *new_task);
40404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RegionCodeGenTy RCG(CodeGen);
40414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CommonActionTy Action(
40424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        RT.createRuntimeFunction(OMPRTL__kmpc_omp_task_begin_if0), TaskArgs,
40434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        RT.createRuntimeFunction(OMPRTL__kmpc_omp_task_complete_if0), TaskArgs);
40444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RCG.setAction(Action);
40454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RCG(CGF);
404687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  };
404787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
40484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (IfCond)
4049b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    emitOMPIfClause(CGF, IfCond, ThenCodeGen, ElseCodeGen);
40504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  else {
40514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RegionCodeGenTy ThenRCG(ThenCodeGen);
40524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ThenRCG(CGF);
4053b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  }
40543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
40553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
40564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
40574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       const OMPLoopDirective &D,
40584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       llvm::Value *TaskFunction,
40594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       QualType SharedsTy, Address Shareds,
40604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       const Expr *IfCond,
40614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       const OMPTaskDataTy &Data) {
40624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
40634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
40644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  TaskResultTy Result =
40654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
40664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc()
40674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // libcall.
40684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
40694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
40704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // sched, kmp_uint64 grainsize, void *task_dup);
40714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *ThreadID = getThreadID(CGF, Loc);
40724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
40734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *IfVal;
40744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (IfCond) {
40754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    IfVal = CGF.Builder.CreateIntCast(CGF.EvaluateExprAsBool(IfCond), CGF.IntTy,
40764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                      /*isSigned=*/true);
40774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else
40784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    IfVal = llvm::ConstantInt::getSigned(CGF.IntTy, /*V=*/1);
40794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
40804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue LBLVal = CGF.EmitLValueForField(
40814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Result.TDBase,
40824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound));
40834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *LBVar =
40844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      cast<VarDecl>(cast<DeclRefExpr>(D.getLowerBoundVariable())->getDecl());
40854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitAnyExprToMem(LBVar->getInit(), LBLVal.getAddress(), LBLVal.getQuals(),
40864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                       /*IsInitializer=*/true);
40874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue UBLVal = CGF.EmitLValueForField(
40884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Result.TDBase,
40894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound));
40904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *UBVar =
40914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      cast<VarDecl>(cast<DeclRefExpr>(D.getUpperBoundVariable())->getDecl());
40924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitAnyExprToMem(UBVar->getInit(), UBLVal.getAddress(), UBLVal.getQuals(),
40934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                       /*IsInitializer=*/true);
40944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue StLVal = CGF.EmitLValueForField(
40954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Result.TDBase,
40964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTStride));
40974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *StVar =
40984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl());
40994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(), StLVal.getQuals(),
41004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                       /*IsInitializer=*/true);
41014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
41024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *TaskArgs[] = {
41034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      UpLoc, ThreadID, Result.NewTask, IfVal, LBLVal.getPointer(),
41044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      UBLVal.getPointer(), CGF.EmitLoadOfScalar(StLVal, SourceLocation()),
41054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::ConstantInt::getSigned(CGF.IntTy, Data.Nogroup ? 1 : 0),
41064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::ConstantInt::getSigned(
41074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF.IntTy, Data.Schedule.getPointer()
41084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         ? Data.Schedule.getInt() ? NumTasks : Grainsize
41094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         : NoSchedule),
41104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Data.Schedule.getPointer()
41114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          ? CGF.Builder.CreateIntCast(Data.Schedule.getPointer(), CGF.Int64Ty,
41124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                      /*isSigned=*/false)
41134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          : llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0),
41144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Result.TaskDupFn
41154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          ? CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Result.TaskDupFn,
41164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                            CGF.VoidPtrTy)
41174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          : llvm::ConstantPointerNull::get(CGF.VoidPtrTy)};
41184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_taskloop), TaskArgs);
41194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
41204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
412187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// \brief Emit reduction operation for each element of array (required for
412287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// array sections) LHS op = RHS.
412387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// \param Type Type of array.
412487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// \param LHSVar Variable on the left side of the reduction operation
412587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// (references element of array in original variable).
412687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// \param RHSVar Variable on the right side of the reduction operation
412787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// (references element of array in original variable).
412887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// \param RedOpGen Generator of reduction operation with use of LHSVar and
412987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// RHSVar.
413087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic void EmitOMPAggregateReduction(
413187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CodeGenFunction &CGF, QualType Type, const VarDecl *LHSVar,
413287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    const VarDecl *RHSVar,
413387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    const llvm::function_ref<void(CodeGenFunction &CGF, const Expr *,
413487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                  const Expr *, const Expr *)> &RedOpGen,
413587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    const Expr *XExpr = nullptr, const Expr *EExpr = nullptr,
413687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    const Expr *UpExpr = nullptr) {
413787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Perform element-by-element initialization.
413887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  QualType ElementTy;
413987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address LHSAddr = CGF.GetAddrOfLocalVar(LHSVar);
414087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address RHSAddr = CGF.GetAddrOfLocalVar(RHSVar);
414187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
414287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Drill down to the base element type on both arrays.
414387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto ArrayTy = Type->getAsArrayTypeUnsafe();
414487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, LHSAddr);
414587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
414687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto RHSBegin = RHSAddr.getPointer();
414787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto LHSBegin = LHSAddr.getPointer();
414887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Cast from pointer to array type to pointer to single element.
414987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto LHSEnd = CGF.Builder.CreateGEP(LHSBegin, NumElements);
415087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // The basic structure here is a while-do loop.
415187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto BodyBB = CGF.createBasicBlock("omp.arraycpy.body");
415287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto DoneBB = CGF.createBasicBlock("omp.arraycpy.done");
415387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto IsEmpty =
415487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateICmpEQ(LHSBegin, LHSEnd, "omp.arraycpy.isempty");
415587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
415687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
415787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Enter the loop body, making that address the current address.
415887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto EntryBB = CGF.Builder.GetInsertBlock();
415987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitBlock(BodyBB);
416087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
416187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
416287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
416387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::PHINode *RHSElementPHI = CGF.Builder.CreatePHI(
416487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      RHSBegin->getType(), 2, "omp.arraycpy.srcElementPast");
416587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  RHSElementPHI->addIncoming(RHSBegin, EntryBB);
416687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address RHSElementCurrent =
416787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Address(RHSElementPHI,
416887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar              RHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
416987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
417087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::PHINode *LHSElementPHI = CGF.Builder.CreatePHI(
417187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      LHSBegin->getType(), 2, "omp.arraycpy.destElementPast");
417287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  LHSElementPHI->addIncoming(LHSBegin, EntryBB);
417387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address LHSElementCurrent =
417487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Address(LHSElementPHI,
417587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar              LHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
417687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
417787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Emit copy.
417887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CodeGenFunction::OMPPrivateScope Scope(CGF);
417987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Scope.addPrivate(LHSVar, [=]() -> Address { return LHSElementCurrent; });
418087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Scope.addPrivate(RHSVar, [=]() -> Address { return RHSElementCurrent; });
418187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Scope.Privatize();
418287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  RedOpGen(CGF, XExpr, EExpr, UpExpr);
418387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Scope.ForceCleanup();
418487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
418587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Shift the address forward by one element.
418687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto LHSElementNext = CGF.Builder.CreateConstGEP1_32(
418787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      LHSElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
418887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto RHSElementNext = CGF.Builder.CreateConstGEP1_32(
418987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      RHSElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
419087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Check whether we've reached the end.
419187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto Done =
419287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateICmpEQ(LHSElementNext, LHSEnd, "omp.arraycpy.done");
419387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
419487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  LHSElementPHI->addIncoming(LHSElementNext, CGF.Builder.GetInsertBlock());
419587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  RHSElementPHI->addIncoming(RHSElementNext, CGF.Builder.GetInsertBlock());
419687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
419787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Done.
419887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
419987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
420087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
42014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Emit reduction combiner. If the combiner is a simple expression emit it as
42024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// is, otherwise consider it as combiner of UDR decl and emit it as a call of
42034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// UDR combiner function.
42044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void emitReductionCombiner(CodeGenFunction &CGF,
42054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  const Expr *ReductionOp) {
42064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *CE = dyn_cast<CallExpr>(ReductionOp))
42074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
42084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (auto *DRE =
42094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
42104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) {
42114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          std::pair<llvm::Function *, llvm::Function *> Reduction =
42124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
42134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          RValue Func = RValue::get(Reduction.first);
42144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
42154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF.EmitIgnoredExpr(ReductionOp);
42164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          return;
42174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        }
42184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitIgnoredExpr(ReductionOp);
42194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
42204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
422158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarstatic llvm::Value *emitReductionFunction(CodeGenModule &CGM,
422258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                          llvm::Type *ArgsType,
422387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                          ArrayRef<const Expr *> Privates,
422458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                          ArrayRef<const Expr *> LHSExprs,
422558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                          ArrayRef<const Expr *> RHSExprs,
422658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                          ArrayRef<const Expr *> ReductionOps) {
422758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto &C = CGM.getContext();
422858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
422958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // void reduction_func(void *LHSArg, void *RHSArg);
423058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  FunctionArgList Args;
423158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr,
423258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                           C.VoidPtrTy);
423358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, SourceLocation(), /*Id=*/nullptr,
423458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                           C.VoidPtrTy);
423558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  Args.push_back(&LHSArg);
423658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  Args.push_back(&RHSArg);
42374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &CGFI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
423858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto *Fn = llvm::Function::Create(
423958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
424058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      ".omp.reduction.reduction_func", &CGM.getModule());
424187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, CGFI);
424258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CodeGenFunction CGF(CGM);
424358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args);
424458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
424558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Dst = (void*[n])(LHSArg);
424658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Src = (void*[n])(RHSArg);
424787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
424887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
424987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ArgsType), CGF.getPointerAlign());
425087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
425187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
425287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ArgsType), CGF.getPointerAlign());
425358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
425458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
425558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
425658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
425758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CodeGenFunction::OMPPrivateScope Scope(CGF);
425887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto IPriv = Privates.begin();
425987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  unsigned Idx = 0;
426087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  for (unsigned I = 0, E = ReductionOps.size(); I < E; ++I, ++IPriv, ++Idx) {
426187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto RHSVar = cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl());
426287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Scope.addPrivate(RHSVar, [&]() -> Address {
426387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      return emitAddrOfVarFromArray(CGF, RHS, Idx, RHSVar);
426487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    });
426587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto LHSVar = cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl());
426687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Scope.addPrivate(LHSVar, [&]() -> Address {
426787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      return emitAddrOfVarFromArray(CGF, LHS, Idx, LHSVar);
426887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    });
426987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    QualType PrivTy = (*IPriv)->getType();
42704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (PrivTy->isVariablyModifiedType()) {
427187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Get array size and emit VLA type.
427287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ++Idx;
427387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Address Elem =
427487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGF.Builder.CreateConstArrayGEP(LHS, Idx, CGF.getPointerSize());
427587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm::Value *Ptr = CGF.Builder.CreateLoad(Elem);
42764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto *VLA = CGF.getContext().getAsVariableArrayType(PrivTy);
42774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto *OVE = cast<OpaqueValueExpr>(VLA->getSizeExpr());
427887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CodeGenFunction::OpaqueValueMapping OpaqueMap(
42794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF, OVE, RValue::get(CGF.Builder.CreatePtrToInt(Ptr, CGF.SizeTy)));
428087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitVariablyModifiedType(PrivTy);
428187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
428258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
428358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  Scope.Privatize();
428487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  IPriv = Privates.begin();
428587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto ILHS = LHSExprs.begin();
428687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto IRHS = RHSExprs.begin();
428758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  for (auto *E : ReductionOps) {
428887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if ((*IPriv)->getType()->isArrayType()) {
428987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Emit reduction for array section.
429087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
429187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
42924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      EmitOMPAggregateReduction(
42934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF, (*IPriv)->getType(), LHSVar, RHSVar,
42944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
42954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            emitReductionCombiner(CGF, E);
42964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          });
429787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    } else
429887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Emit reduction for array subscript or single variable.
42994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitReductionCombiner(CGF, E);
43004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++IPriv;
43014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++ILHS;
43024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++IRHS;
430358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
430458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  Scope.ForceCleanup();
430558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.FinishFunction();
430658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  return Fn;
4307176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
43080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
43094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void emitSingleReductionCombiner(CodeGenFunction &CGF,
43104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        const Expr *ReductionOp,
43114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        const Expr *PrivateRef,
43124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        const DeclRefExpr *LHS,
43134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        const DeclRefExpr *RHS) {
43144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (PrivateRef->getType()->isArrayType()) {
43154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit reduction for array section.
43164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *LHSVar = cast<VarDecl>(LHS->getDecl());
43174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *RHSVar = cast<VarDecl>(RHS->getDecl());
43184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    EmitOMPAggregateReduction(
43194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF, PrivateRef->getType(), LHSVar, RHSVar,
43204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
43214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          emitReductionCombiner(CGF, ReductionOp);
43224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        });
43234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else
43244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit reduction for array subscript or single variable.
43254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitReductionCombiner(CGF, ReductionOp);
43264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
43274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
432858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
432987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                    ArrayRef<const Expr *> Privates,
433058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                    ArrayRef<const Expr *> LHSExprs,
433158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                    ArrayRef<const Expr *> RHSExprs,
433258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                    ArrayRef<const Expr *> ReductionOps,
433387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                    bool WithNowait, bool SimpleReduction) {
433487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
433587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
433658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Next code should be emitted for reduction:
433758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //
433858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // static kmp_critical_name lock = { 0 };
433958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //
434058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
434158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
434258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
434358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
434458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  *(Type<n>-1*)rhs[<n>-1]);
434558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // }
434658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //
434758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // ...
434858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
434958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
435058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // RedList, reduce_func, &<lock>)) {
435158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // case 1:
435258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
435358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
435458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
435558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
435658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // break;
435758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // case 2:
435858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
435958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
436058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
4361b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // [__kmpc_end_reduce(<loc>, <gtid>, &<lock>);]
436258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // break;
436358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // default:;
436458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // }
436587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  //
436687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // if SimpleReduction is true, only the next code is generated:
436787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  //  ...
436887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  //  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
436987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  //  ...
437058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
437158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto &C = CGM.getContext();
437258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
437387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (SimpleReduction) {
437487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CodeGenFunction::RunCleanupsScope Scope(CGF);
437587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto IPriv = Privates.begin();
437687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto ILHS = LHSExprs.begin();
437787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto IRHS = RHSExprs.begin();
437887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    for (auto *E : ReductionOps) {
43794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
43804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  cast<DeclRefExpr>(*IRHS));
43814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++IPriv;
43824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++ILHS;
43834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++IRHS;
438487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
438587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
438687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
438787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
438858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // 1. Build a list of reduction variables.
438958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
439087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto Size = RHSExprs.size();
439187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  for (auto *E : Privates) {
43924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (E->getType()->isVariablyModifiedType())
439387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Reserve place for array size.
439487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ++Size;
439587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
439687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size);
439758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  QualType ReductionArrayTy =
439858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
439958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                             /*IndexTypeQuals=*/0);
440087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address ReductionList =
440158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
440287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto IPriv = Privates.begin();
440387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  unsigned Idx = 0;
440487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
440587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Address Elem =
440687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateConstArrayGEP(ReductionList, Idx, CGF.getPointerSize());
440787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.Builder.CreateStore(
440858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
440987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            CGF.EmitLValue(RHSExprs[I]).getPointer(), CGF.VoidPtrTy),
441087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        Elem);
44114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if ((*IPriv)->getType()->isVariablyModifiedType()) {
441287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Store array size.
441387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ++Idx;
441487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx,
441587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                             CGF.getPointerSize());
44164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *Size = CGF.Builder.CreateIntCast(
44174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF.getVLASize(
44184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                 CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
44194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              .first,
44204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF.SizeTy, /*isSigned=*/false);
44214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
44224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              Elem);
442387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
442458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
442558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
442658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // 2. Emit reduce_func().
442758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto *ReductionFn = emitReductionFunction(
442887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGM, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), Privates,
442987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      LHSExprs, RHSExprs, ReductionOps);
443058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
443158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // 3. Create static kmp_critical_name lock = { 0 };
443258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto *Lock = getCriticalRegionLock(".reduction");
443358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
443458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // 4. Build res = __kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
443558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // RedList, reduce_func, &<lock>);
44364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *IdentTLoc = emitUpdateLocation(CGF, Loc, OMP_ATOMIC_REDUCE);
443758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto *ThreadId = getThreadID(CGF, Loc);
44384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
443987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto *RL =
444087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(ReductionList.getPointer(),
444187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                    CGF.VoidPtrTy);
444258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  llvm::Value *Args[] = {
444358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      IdentTLoc,                             // ident_t *<loc>
444458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      ThreadId,                              // i32 <gtid>
444558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      CGF.Builder.getInt32(RHSExprs.size()), // i32 <n>
444658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      ReductionArrayTySize,                  // size_type sizeof(RedList)
444758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      RL,                                    // void *RedList
444858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      ReductionFn, // void (*) (void *, void *) <reduce_func>
444958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      Lock         // kmp_critical_name *&<lock>
445058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  };
445158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto Res = CGF.EmitRuntimeCall(
445258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      createRuntimeFunction(WithNowait ? OMPRTL__kmpc_reduce_nowait
445358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                       : OMPRTL__kmpc_reduce),
445458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      Args);
445558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
445658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // 5. Build switch(res)
445758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto *DefaultBB = CGF.createBasicBlock(".omp.reduction.default");
445858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto *SwInst = CGF.Builder.CreateSwitch(Res, DefaultBB, /*NumCases=*/2);
445958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
446058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // 6. Build case 1:
446158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
446258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
446358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
446458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
446558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // break;
446658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto *Case1BB = CGF.createBasicBlock(".omp.reduction.case1");
446758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  SwInst->addCase(CGF.Builder.getInt32(1), Case1BB);
446858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.EmitBlock(Case1BB);
446958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
44704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Add emission of __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
44714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *EndArgs[] = {
44724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      IdentTLoc, // ident_t *<loc>
44734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ThreadId,  // i32 <gtid>
44744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Lock       // kmp_critical_name *&<lock>
44754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
44764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&CodeGen = [&Privates, &LHSExprs, &RHSExprs, &ReductionOps](
44774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CodeGenFunction &CGF, PrePostActionTy &Action) {
447887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto IPriv = Privates.begin();
447987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto ILHS = LHSExprs.begin();
448087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto IRHS = RHSExprs.begin();
448158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    for (auto *E : ReductionOps) {
44824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
44834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  cast<DeclRefExpr>(*IRHS));
44844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++IPriv;
44854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++ILHS;
44864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++IRHS;
448758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    }
44884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
44894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RegionCodeGenTy RCG(CodeGen);
44904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CommonActionTy Action(
44914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      nullptr, llvm::None,
44924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      createRuntimeFunction(WithNowait ? OMPRTL__kmpc_end_reduce_nowait
44934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       : OMPRTL__kmpc_end_reduce),
44944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      EndArgs);
44954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RCG.setAction(Action);
44964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RCG(CGF);
449758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
449858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.EmitBranch(DefaultBB);
449958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
450058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // 7. Build case 2:
450158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
450258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
450358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  //  ...
450458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // break;
450558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto *Case2BB = CGF.createBasicBlock(".omp.reduction.case2");
450658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
450758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.EmitBlock(Case2BB);
450858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
45094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&AtomicCodeGen = [Loc, &Privates, &LHSExprs, &RHSExprs, &ReductionOps](
45104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CodeGenFunction &CGF, PrePostActionTy &Action) {
451187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto ILHS = LHSExprs.begin();
451287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto IRHS = RHSExprs.begin();
451387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto IPriv = Privates.begin();
451458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    for (auto *E : ReductionOps) {
45154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const Expr *XExpr = nullptr;
45164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const Expr *EExpr = nullptr;
45174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const Expr *UpExpr = nullptr;
45184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      BinaryOperatorKind BO = BO_Comma;
45194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (auto *BO = dyn_cast<BinaryOperator>(E)) {
45204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (BO->getOpcode() == BO_Assign) {
45214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          XExpr = BO->getLHS();
45224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          UpExpr = BO->getRHS();
4523b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        }
45244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
45254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // Try to emit update expression as a simple atomic.
45264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto *RHSExpr = UpExpr;
45274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (RHSExpr) {
45284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // Analyze RHS part of the whole expression.
45294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (auto *ACO = dyn_cast<AbstractConditionalOperator>(
45304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                RHSExpr->IgnoreParenImpCasts())) {
45314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          // If this is a conditional operator, analyze its condition for
45324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          // min/max reduction operator.
45334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          RHSExpr = ACO->getCond();
453458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        }
45354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (auto *BORHS =
45364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                dyn_cast<BinaryOperator>(RHSExpr->IgnoreParenImpCasts())) {
45374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          EExpr = BORHS->getRHS();
45384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          BO = BORHS->getOpcode();
453987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        }
45404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
45414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (XExpr) {
45424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
45434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto &&AtomicRedGen = [BO, VD, IPriv,
45444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                               Loc](CodeGenFunction &CGF, const Expr *XExpr,
45454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    const Expr *EExpr, const Expr *UpExpr) {
45464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          LValue X = CGF.EmitLValue(XExpr);
45474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          RValue E;
45484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          if (EExpr)
45494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            E = CGF.EmitAnyExpr(EExpr);
45504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF.EmitOMPAtomicSimpleUpdateExpr(
45514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              X, E, BO, /*IsXLHSInRHSPart=*/true,
45524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              llvm::AtomicOrdering::Monotonic, Loc,
45534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              [&CGF, UpExpr, VD, IPriv, Loc](RValue XRValue) {
45544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
45554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                PrivateScope.addPrivate(
45564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    VD, [&CGF, VD, XRValue, Loc]() -> Address {
45574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      Address LHSTemp = CGF.CreateMemTemp(VD->getType());
45584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      CGF.emitOMPSimpleStore(
45594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          CGF.MakeAddrLValue(LHSTemp, VD->getType()), XRValue,
45604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          VD->getType().getNonReferenceType(), Loc);
45614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      return LHSTemp;
45624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    });
45634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                (void)PrivateScope.Privatize();
45644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                return CGF.EmitAnyExpr(UpExpr);
45654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              });
45664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        };
45674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if ((*IPriv)->getType()->isArrayType()) {
45684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          // Emit atomic reduction for array section.
45694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
45704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), VD, RHSVar,
45714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    AtomicRedGen, XExpr, EExpr, UpExpr);
45724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        } else
45734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          // Emit atomic reduction for array subscript or single variable.
45744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          AtomicRedGen(CGF, XExpr, EExpr, UpExpr);
45754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      } else {
45764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // Emit as a critical region.
45774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto &&CritRedGen = [E, Loc](CodeGenFunction &CGF, const Expr *,
45784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     const Expr *, const Expr *) {
45794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          auto &RT = CGF.CGM.getOpenMPRuntime();
45804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          RT.emitCriticalRegion(
45814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              CGF, ".atomic_reduction",
45824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              [=](CodeGenFunction &CGF, PrePostActionTy &Action) {
45834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                Action.Enter(CGF);
45844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                emitReductionCombiner(CGF, E);
45854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              },
45864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              Loc);
45874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        };
45884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if ((*IPriv)->getType()->isArrayType()) {
45894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
45904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
45914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), LHSVar, RHSVar,
45924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    CritRedGen);
45934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        } else
45944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CritRedGen(CGF, nullptr, nullptr, nullptr);
45954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
45964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++ILHS;
45974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++IRHS;
45984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++IPriv;
459958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    }
46004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
46014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RegionCodeGenTy AtomicRCG(AtomicCodeGen);
46024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!WithNowait) {
46034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Add emission of __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
46044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *EndArgs[] = {
46054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        IdentTLoc, // ident_t *<loc>
46064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ThreadId,  // i32 <gtid>
46074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Lock       // kmp_critical_name *&<lock>
46084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    };
46094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CommonActionTy Action(nullptr, llvm::None,
46104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          createRuntimeFunction(OMPRTL__kmpc_end_reduce),
46114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          EndArgs);
46124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    AtomicRCG.setAction(Action);
46134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    AtomicRCG(CGF);
46144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else
46154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    AtomicRCG(CGF);
461658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
461758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.EmitBranch(DefaultBB);
461858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
461958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar}
462058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
4621b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
4622b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                       SourceLocation Loc) {
462387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
462487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
4625b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
4626b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // global_tid);
4627b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
4628b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Ignore return result until untied tasks are supported.
4629b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskwait), Args);
46304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
46314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Region->emitUntiedSwitch(CGF);
4632b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
4633b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
463458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
463587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                           OpenMPDirectiveKind InnerKind,
463687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                           const RegionCodeGenTy &CodeGen,
463787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                           bool HasCancel) {
463887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
463987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
464087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
464158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
46420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
46430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
464487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarnamespace {
464587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarenum RTCancelKind {
464687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CancelNoreq = 0,
464787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CancelParallel = 1,
464887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CancelLoop = 2,
464987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CancelSections = 3,
465087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CancelTaskgroup = 4
465187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar};
46524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // anonymous namespace
465387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
465487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion) {
465587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  RTCancelKind CancelKind = CancelNoreq;
465687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (CancelRegion == OMPD_parallel)
465787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CancelKind = CancelParallel;
465887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  else if (CancelRegion == OMPD_for)
465987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CancelKind = CancelLoop;
466087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  else if (CancelRegion == OMPD_sections)
466187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CancelKind = CancelSections;
466287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  else {
466387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    assert(CancelRegion == OMPD_taskgroup);
466487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CancelKind = CancelTaskgroup;
466587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
466687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return CancelKind;
466787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
466887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
466987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CGOpenMPRuntime::emitCancellationPointCall(
467087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CodeGenFunction &CGF, SourceLocation Loc,
467187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    OpenMPDirectiveKind CancelRegion) {
467287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
467387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
467487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Build call kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
467587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // global_tid, kmp_int32 cncl_kind);
467687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (auto *OMPRegionInfo =
467787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
467887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (OMPRegionInfo->hasCancel()) {
467987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm::Value *Args[] = {
468087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
468187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
468287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Ignore return result until untied tasks are supported.
468387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *Result = CGF.EmitRuntimeCall(
468487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
468587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // if (__kmpc_cancellationpoint()) {
468687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      //  __kmpc_cancel_barrier();
468787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      //   exit from construct;
468887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // }
468987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
469087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *ContBB = CGF.createBasicBlock(".cancel.continue");
469187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
469287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
469387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitBlock(ExitBB);
469487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // __kmpc_cancel_barrier();
469587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
469687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // exit from construct;
469787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto CancelDest =
469887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
469987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitBranchThroughCleanup(CancelDest);
470087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitBlock(ContBB, /*IsFinished=*/true);
470187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
470287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
470387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
470487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
470587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
470687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                     const Expr *IfCond,
470787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                     OpenMPDirectiveKind CancelRegion) {
470887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
470987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
471087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
471187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // kmp_int32 cncl_kind);
471287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (auto *OMPRegionInfo =
471387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
47144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &&ThenGen = [Loc, CancelRegion, OMPRegionInfo](CodeGenFunction &CGF,
47154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                        PrePostActionTy &) {
47164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto &RT = CGF.CGM.getOpenMPRuntime();
471787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm::Value *Args[] = {
47184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          RT.emitUpdateLocation(CGF, Loc), RT.getThreadID(CGF, Loc),
471987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
472087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Ignore return result until untied tasks are supported.
47214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto *Result = CGF.EmitRuntimeCall(
47224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          RT.createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
472387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // if (__kmpc_cancel()) {
472487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      //  __kmpc_cancel_barrier();
472587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      //   exit from construct;
472687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // }
472787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
472887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *ContBB = CGF.createBasicBlock(".cancel.continue");
472987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
473087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
473187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitBlock(ExitBB);
473287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // __kmpc_cancel_barrier();
47334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      RT.emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
473487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // exit from construct;
473587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      auto CancelDest =
473687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
473787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitBranchThroughCleanup(CancelDest);
473887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.EmitBlock(ContBB, /*IsFinished=*/true);
473987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    };
474087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (IfCond)
47414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitOMPIfClause(CGF, IfCond, ThenGen,
47424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      [](CodeGenFunction &, PrePostActionTy &) {});
47434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    else {
47444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      RegionCodeGenTy ThenRCG(ThenGen);
47454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ThenRCG(CGF);
47464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
474787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
474887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
474987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
47504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Obtain information that uniquely identifies a target entry. This
47514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// consists of the file and device IDs as well as line number associated with
47524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// the relevant entry source location.
47534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void getTargetEntryUniqueInfo(ASTContext &C, SourceLocation Loc,
47544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     unsigned &DeviceID, unsigned &FileID,
47554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     unsigned &LineNum) {
47564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &SM = C.getSourceManager();
47584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // The loc should be always valid and have a file ID (the user cannot use
47604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // #pragma directives in macros)
47614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(Loc.isValid() && "Source location is expected to be always valid.");
47634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(Loc.isFileID() && "Source location is expected to refer to a file.");
47644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
47664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(PLoc.isValid() && "Source location is expected to be always valid.");
47674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::sys::fs::UniqueID ID;
47694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (llvm::sys::fs::getUniqueID(PLoc.getFilename(), ID))
47704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm_unreachable("Source file with target region no longer exists!");
47714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  DeviceID = ID.getDevice();
47734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FileID = ID.getFile();
47744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LineNum = PLoc.getLine();
47754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
47764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTargetOutlinedFunction(
47784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const OMPExecutableDirective &D, StringRef ParentName,
47794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
47804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
47814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(!ParentName.empty() && "Invalid target region parent name!");
47824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
47844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   IsOffloadEntry, CodeGen);
47854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
47864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
47874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTargetOutlinedFunctionHelper(
47884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const OMPExecutableDirective &D, StringRef ParentName,
47894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
47904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
47914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create a unique name for the entry function using the source location
47924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // information of the current target region. The name will be something like:
47934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
47944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // __omp_offloading_DD_FFFF_PP_lBB
47954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
47964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // where DD_FFFF is an ID unique to the file (device and file IDs), PP is the
47974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // mangled name of the function that encloses the target region and BB is the
47984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // line number of the target region.
47994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned DeviceID;
48014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned FileID;
48024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned Line;
48034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  getTargetEntryUniqueInfo(CGM.getContext(), D.getLocStart(), DeviceID, FileID,
48044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                           Line);
48054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SmallString<64> EntryFnName;
48064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  {
48074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::raw_svector_ostream OS(EntryFnName);
48084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OS << "__omp_offloading" << llvm::format("_%x", DeviceID)
48094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar       << llvm::format("_%x_", FileID) << ParentName << "_l" << Line;
48104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
48114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
481287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const CapturedStmt &CS = *cast<CapturedStmt>(D.getAssociatedStmt());
481387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
481487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CodeGenFunction CGF(CGM, true);
48154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
481687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
481787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
48184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OutlinedFn = CGF.GenerateOpenMPCapturedStmtFunction(CS);
48194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If this target outline function is not an offload entry, we don't need to
48214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // register it.
48224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!IsOffloadEntry)
482387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return;
48244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // The target region ID is used by the runtime library to identify the current
48264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // target region, so it only has to be unique and not necessarily point to
48274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // anything. It could be the pointer to the outlined function that implements
48284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the target region, but we aren't using that so that the compiler doesn't
48294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // need to keep that, and could therefore inline the host function if proven
48304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // worthwhile during optimization. In the other hand, if emitting code for the
48314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // device, the ID has to be the function address so that it can retrieved from
48324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the offloading entry and launched by the runtime library. We also mark the
48334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // outlined function to have external linkage in case we are emitting code for
48344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the device, because these functions will be entry points to the device.
48354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (CGM.getLangOpts().OpenMPIsDevice) {
48374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.Int8PtrTy);
48384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OutlinedFn->setLinkage(llvm::GlobalValue::ExternalLinkage);
48394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else
48404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OutlinedFnID = new llvm::GlobalVariable(
48414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
48424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::GlobalValue::PrivateLinkage,
48434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::Constant::getNullValue(CGM.Int8Ty), ".omp_offload.region_id");
48444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Register the information for the entry associated with this target region.
48464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
48474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID);
48484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
48494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// discard all CompoundStmts intervening between two constructs
48514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic const Stmt *ignoreCompoundStmts(const Stmt *Body) {
48524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  while (auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
48534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Body = CS->body_front();
48544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Body;
48564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
48574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Emit the num_teams clause of an enclosed teams directive at the
48594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// target region scope. If there is no teams directive associated with the
48604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// target directive, or if there is no num_teams clause associated with the
48614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// enclosed teams directive, return nullptr.
48624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic llvm::Value *
48634967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainaremitNumTeamsClauseForTargetDirective(CGOpenMPRuntime &OMPRuntime,
48644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     CodeGenFunction &CGF,
48654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     const OMPExecutableDirective &D) {
48664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the "
48684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                              "teams directive expected to be "
48694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                              "emitted only for the host!");
48704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // FIXME: For the moment we do not support combined directives with target and
48724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // teams, so we do not expect to get any num_teams clause in the provided
48734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // directive. Once we support that, this assertion can be replaced by the
48744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // actual emission of the clause expression.
48754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(D.getSingleClause<OMPNumTeamsClause>() == nullptr &&
48764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar         "Not expecting clause in directive.");
48774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If the current target region has a teams region enclosed, we need to get
48794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the number of teams to pass to the runtime function call. This is done
48804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // by generating the expression in a inlined region. This is required because
48814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the expression is captured in the enclosing target environment when the
48824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // teams directive is not combined with target.
48834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const CapturedStmt &CS = *cast<CapturedStmt>(D.getAssociatedStmt());
48854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // FIXME: Accommodate other combined directives with teams when they become
48874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // available.
48884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *TeamsDir = dyn_cast_or_null<OMPTeamsDirective>(
48894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          ignoreCompoundStmts(CS.getCapturedStmt()))) {
48904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *NTE = TeamsDir->getSingleClause<OMPNumTeamsClause>()) {
48914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGOpenMPInnerExprInfo CGInfo(CGF, CS);
48924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
48934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *NumTeams = CGF.EmitScalarExpr(NTE->getNumTeams());
48944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return CGF.Builder.CreateIntCast(NumTeams, CGF.Int32Ty,
48954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       /*IsSigned=*/true);
48964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
48974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
48984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // If we have an enclosed teams directive but no num_teams clause we use
48994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // the default value 0.
49004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return CGF.Builder.getInt32(0);
49014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
49024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // No teams associated with the directive.
49044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return nullptr;
49054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
49064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Emit the thread_limit clause of an enclosed teams directive at the
49084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// target region scope. If there is no teams directive associated with the
49094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// target directive, or if there is no thread_limit clause associated with the
49104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// enclosed teams directive, return nullptr.
49114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic llvm::Value *
49124967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainaremitThreadLimitClauseForTargetDirective(CGOpenMPRuntime &OMPRuntime,
49134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        CodeGenFunction &CGF,
49144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                        const OMPExecutableDirective &D) {
49154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the "
49174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                              "teams directive expected to be "
49184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                              "emitted only for the host!");
49194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // FIXME: For the moment we do not support combined directives with target and
49214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // teams, so we do not expect to get any thread_limit clause in the provided
49224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // directive. Once we support that, this assertion can be replaced by the
49234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // actual emission of the clause expression.
49244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(D.getSingleClause<OMPThreadLimitClause>() == nullptr &&
49254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar         "Not expecting clause in directive.");
49264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If the current target region has a teams region enclosed, we need to get
49284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the thread limit to pass to the runtime function call. This is done
49294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // by generating the expression in a inlined region. This is required because
49304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the expression is captured in the enclosing target environment when the
49314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // teams directive is not combined with target.
49324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const CapturedStmt &CS = *cast<CapturedStmt>(D.getAssociatedStmt());
49344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // FIXME: Accommodate other combined directives with teams when they become
49364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // available.
49374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *TeamsDir = dyn_cast_or_null<OMPTeamsDirective>(
49384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          ignoreCompoundStmts(CS.getCapturedStmt()))) {
49394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *TLE = TeamsDir->getSingleClause<OMPThreadLimitClause>()) {
49404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGOpenMPInnerExprInfo CGInfo(CGF, CS);
49414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
49424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *ThreadLimit = CGF.EmitScalarExpr(TLE->getThreadLimit());
49434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return CGF.Builder.CreateIntCast(ThreadLimit, CGF.Int32Ty,
49444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       /*IsSigned=*/true);
49454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
49464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // If we have an enclosed teams directive but no thread_limit clause we use
49484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // the default value 0.
49494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return CGF.Builder.getInt32(0);
49504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
49514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // No teams associated with the directive.
49534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return nullptr;
49544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
49554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarnamespace {
49574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// \brief Utility to handle information from clauses associated with a given
49584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// construct that use mappable expressions (e.g. 'map' clause, 'to' clause).
49594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// It provides a convenient interface to obtain the information and generate
49604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// code for that information.
49614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass MappableExprsHandler {
49624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
496387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  /// \brief Values for bit flags used to specify the mapping type for
496487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  /// offloading.
496587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  enum OpenMPOffloadMappingFlags {
496687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    /// \brief Allocate memory on the device and move data from host to device.
496787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    OMP_MAP_TO = 0x01,
496887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    /// \brief Allocate memory on the device and move data from device to host.
496987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    OMP_MAP_FROM = 0x02,
49704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// \brief Always perform the requested mapping action on the element, even
49714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// if it was already mapped before.
49724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OMP_MAP_ALWAYS = 0x04,
49734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// \brief Delete the element from the device environment, ignoring the
49744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// current reference count associated with the element.
49754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OMP_MAP_DELETE = 0x08,
49764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// \brief The element being mapped is a pointer, therefore the pointee
49774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// should be mapped as well.
49784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OMP_MAP_IS_PTR = 0x10,
49794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// \brief This flags signals that an argument is the first one relating to
49804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// a map/private clause expression. For some cases a single
49814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// map/privatization results in multiple arguments passed to the runtime
49824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// library.
49834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OMP_MAP_FIRST_REF = 0x20,
49844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// \brief This flag signals that the reference being passed is a pointer to
49854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// private data.
49864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OMP_MAP_PRIVATE_PTR = 0x80,
498787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    /// \brief Pass the element to the device by value.
49884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OMP_MAP_PRIVATE_VAL = 0x100,
498987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  };
499087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
49914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  typedef SmallVector<llvm::Value *, 16> MapValuesArrayTy;
49924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  typedef SmallVector<unsigned, 16> MapFlagsArrayTy;
49934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprivate:
49954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Directive from where the map clauses were extracted.
49964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const OMPExecutableDirective &Directive;
49974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
49984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Function the directive is being generated for.
49994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction &CGF;
50004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Set of all first private variables in the current directive.
50024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::SmallPtrSet<const VarDecl *, 8> FirstPrivateDecls;
50034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *getExprTypeSize(const Expr *E) const {
50054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto ExprTy = E->getType().getCanonicalType();
50064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Reference types are ignored for mapping purposes.
50084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *RefTy = ExprTy->getAs<ReferenceType>())
50094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ExprTy = RefTy->getPointeeType().getCanonicalType();
50104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Given that an array section is considered a built-in type, we need to
50124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // do the calculation based on the length of the section instead of relying
50134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // on CGF.getTypeSize(E->getType()).
50144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (const auto *OAE = dyn_cast<OMPArraySectionExpr>(E)) {
50154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(
50164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            OAE->getBase()->IgnoreParenImpCasts())
50174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            .getCanonicalType();
50184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // If there is no length associated with the expression, that means we
50204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // are using the whole length of the base.
50214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (!OAE->getLength() && OAE->getColonLoc().isValid())
50224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        return CGF.getTypeSize(BaseTy);
50234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *ElemSize;
50254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (auto *PTy = BaseTy->getAs<PointerType>())
50264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ElemSize = CGF.getTypeSize(PTy->getPointeeType().getCanonicalType());
50274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      else {
50284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *ATy = cast<ArrayType>(BaseTy.getTypePtr());
50294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert(ATy && "Expecting array type if not a pointer type.");
50304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ElemSize = CGF.getTypeSize(ATy->getElementType().getCanonicalType());
50314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
50324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // If we don't have a length at this point, that is because we have an
50344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // array section with a single element.
50354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (!OAE->getLength())
50364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        return ElemSize;
50374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto *LengthVal = CGF.EmitScalarExpr(OAE->getLength());
50394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      LengthVal =
50404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF.Builder.CreateIntCast(LengthVal, CGF.SizeTy, /*isSigned=*/false);
50414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return CGF.Builder.CreateNUWMul(LengthVal, ElemSize);
50424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
50434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return CGF.getTypeSize(ExprTy);
50444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
50454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Return the corresponding bits for a given map clause modifier. Add
50474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// a flag marking the map as a pointer if requested. Add a flag marking the
50484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// map as the first one of a series of maps that relate to the same map
50494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// expression.
50504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned getMapTypeBits(OpenMPMapClauseKind MapType,
50514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          OpenMPMapClauseKind MapTypeModifier, bool AddPtrFlag,
50524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          bool AddIsFirstFlag) const {
50534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned Bits = 0u;
50544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    switch (MapType) {
50554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPC_MAP_alloc:
50564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPC_MAP_release:
50574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // alloc and release is the default behavior in the runtime library,  i.e.
50584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // if we don't pass any bits alloc/release that is what the runtime is
50594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // going to do. Therefore, we don't need to signal anything for these two
50604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // type modifiers.
50614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
50624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPC_MAP_to:
50634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Bits = OMP_MAP_TO;
50644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
50654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPC_MAP_from:
50664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Bits = OMP_MAP_FROM;
50674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
50684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPC_MAP_tofrom:
50694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Bits = OMP_MAP_TO | OMP_MAP_FROM;
50704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
50714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPC_MAP_delete:
50724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Bits = OMP_MAP_DELETE;
50734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
50744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    default:
50754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm_unreachable("Unexpected map type!");
50764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
50774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
50784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (AddPtrFlag)
50794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Bits |= OMP_MAP_IS_PTR;
50804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (AddIsFirstFlag)
50814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Bits |= OMP_MAP_FIRST_REF;
50824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (MapTypeModifier == OMPC_MAP_always)
50834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Bits |= OMP_MAP_ALWAYS;
50844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return Bits;
50854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
50864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Return true if the provided expression is a final array section. A
50884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// final array section, is one whose length can't be proved to be one.
50894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool isFinalArraySectionExpression(const Expr *E) const {
50904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
50914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // It is not an array section and therefore not a unity-size one.
50934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!OASE)
50944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return false;
50954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
50964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // An array section with no colon always refer to a single element.
50974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (OASE->getColonLoc().isInvalid())
50984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return false;
50994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
51004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *Length = OASE->getLength();
51014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
51024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // If we don't have a length we have to check if the array has size 1
51034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // for this dimension. Also, we should always expect a length if the
51044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // base type is pointer.
51054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!Length) {
51064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto BaseQTy = OMPArraySectionExpr::getBaseOriginalType(
51074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         OASE->getBase()->IgnoreParenImpCasts())
51084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         .getCanonicalType();
51094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
51104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        return ATy->getSize().getSExtValue() != 1;
51114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // If we don't have a constant dimension length, we have to consider
51124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // the current section as having any size, so it is not necessarily
51134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // unitary. If it happen to be unity size, that's user fault.
51144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return true;
51154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
51164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
51174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Check if the length evaluates to 1.
51184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::APSInt ConstLength;
51194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!Length->EvaluateAsInt(ConstLength, CGF.getContext()))
51204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return true; // Can have more that size 1.
51214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
51224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return ConstLength.getSExtValue() != 1;
51234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
51244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
51254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Generate the base pointers, section pointers, sizes and map type
51264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// bits for the provided map type, map modifier, and expression components.
51274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \a IsFirstComponent should be set to true if the provided set of
51284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// components is the first associated with a capture.
51294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void generateInfoForComponentList(
51304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapTypeModifier,
51314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
51324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      MapValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
51334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
51344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      bool IsFirstComponentList) const {
51354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
51364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // The following summarizes what has to be generated for each map and the
51374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // types bellow. The generated information is expressed in this order:
51384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // base pointer, section pointer, size, flags
51394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // (to add to the ones that come from the map type and modifier).
51404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // double d;
51424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // int i[100];
51434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // float *p;
51444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // struct S1 {
51464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //   int i;
51474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //   float f[50];
51484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // }
51494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // struct S2 {
51504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //   int i;
51514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //   float f[50];
51524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //   S1 s;
51534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //   double *p;
51544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //   struct S2 *ps;
51554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // }
51564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // S2 s;
51574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // S2 *ps;
51584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(d)
51604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &d, &d, sizeof(double), noflags
51614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(i)
51634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &i, &i, 100*sizeof(int), noflags
51644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(i[1:23])
51664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &i(=&i[0]), &i[1], 23*sizeof(int), noflags
51674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(p)
51694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &p, &p, sizeof(float*), noflags
51704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(p[1:24])
51724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // p, &p[1], 24*sizeof(float), noflags
51734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s)
51754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &s, sizeof(S2), noflags
51764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.i)
51784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.i), sizeof(int), noflags
51794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.s.f)
51814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.i.f), 50*sizeof(int), noflags
51824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.p)
51844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.p), sizeof(double*), noflags
51854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.p[:22], s.a s.b)
51874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.p), sizeof(double*), noflags
51884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(s.p), &(s.p[0]), 22*sizeof(double), ptr_flag + extra_flag
51894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.ps)
51914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.ps), sizeof(S2*), noflags
51924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.ps->s.i)
51944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.ps), sizeof(S2*), noflags
51954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(s.ps), &(s.ps->s.i), sizeof(int), ptr_flag + extra_flag
51964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
51974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.ps->ps)
51984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.ps), sizeof(S2*), noflags
51994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag + extra_flag
52004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.ps->ps->ps)
52024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.ps), sizeof(S2*), noflags
52034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag + extra_flag
52044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(s.ps->ps), &(s.ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag
52054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(s.ps->ps->s.f[:22])
52074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &s, &(s.ps), sizeof(S2*), noflags
52084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag + extra_flag
52094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(s.ps->ps), &(s.ps->ps->s.f[0]), 22*sizeof(float), ptr_flag + extra_flag
52104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps)
52124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &ps, &ps, sizeof(S2*), noflags
52134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->i)
52154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->i), sizeof(int), noflags
52164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->s.f)
52184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->s.f[0]), 50*sizeof(float), noflags
52194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->p)
52214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->p), sizeof(double*), noflags
52224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->p[:22])
52244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->p), sizeof(double*), noflags
52254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(ps->p), &(ps->p[0]), 22*sizeof(double), ptr_flag + extra_flag
52264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->ps)
52284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->ps), sizeof(S2*), noflags
52294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->ps->s.i)
52314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->ps), sizeof(S2*), noflags
52324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(ps->ps), &(ps->ps->s.i), sizeof(int), ptr_flag + extra_flag
52334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->ps->ps)
52354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->ps), sizeof(S2*), noflags
52364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag
52374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->ps->ps->ps)
52394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->ps), sizeof(S2*), noflags
52404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag
52414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(ps->ps->ps), &(ps->ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag
52424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //
52434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // map(ps->ps->ps->s.f[:22])
52444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // ps, &(ps->ps), sizeof(S2*), noflags
52454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag
52464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // &(ps->ps->ps), &(ps->ps->ps->s.f[0]), 22*sizeof(float), ptr_flag +
52474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // extra_flag
52484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Track if the map information being generated is the first for a capture.
52504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool IsCaptureFirstInfo = IsFirstComponentList;
52514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Scan the components from the base to the complete expression.
52534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto CI = Components.rbegin();
52544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto CE = Components.rend();
52554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto I = CI;
52564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Track if the map information being generated is the first for a list of
52584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // components.
52594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool IsExpressionFirstInfo = true;
52604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *BP = nullptr;
52614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *ME = dyn_cast<MemberExpr>(I->getAssociatedExpression())) {
52634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // The base is the 'this' pointer. The content of the pointer is going
52644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // to be the base of the field being mapped.
52654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      BP = CGF.EmitScalarExpr(ME->getBase());
52664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else {
52674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // The base is the reference to the variable.
52684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // BP = &Var.
52694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      BP = CGF.EmitLValue(cast<DeclRefExpr>(I->getAssociatedExpression()))
52704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               .getPointer();
52714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // If the variable is a pointer and is being dereferenced (i.e. is not
52734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // the last component), the base has to be the pointer itself, not its
52744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // reference.
52754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (I->getAssociatedDeclaration()->getType()->isAnyPointerType() &&
52764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          std::next(I) != CE) {
52774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto PtrAddr = CGF.MakeNaturalAlignAddrLValue(
52784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            BP, I->getAssociatedDeclaration()->getType());
52794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        BP = CGF.EmitLoadOfPointerLValue(PtrAddr.getAddress(),
52804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         I->getAssociatedDeclaration()
52814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                             ->getType()
52824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                             ->getAs<PointerType>())
52834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                 .getPointer();
52844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // We do not need to generate individual map information for the
52864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // pointer, it can be associated with the combined storage.
52874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ++I;
52884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
52894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
52904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (; I != CE; ++I) {
52924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto Next = std::next(I);
52934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // We need to generate the addresses and sizes if this is the last
52954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // component, if the component is a pointer or if it is an array section
52964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // whose length can't be proved to be one. If this is a pointer, it
52974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // becomes the base address for the following components.
52984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
52994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // A final array section, is one whose length can't be proved to be one.
53004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      bool IsFinalArraySection =
53014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          isFinalArraySectionExpression(I->getAssociatedExpression());
53024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // Get information on whether the element is a pointer. Have to do a
53044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // special treatment for array sections given that they are built-in
53054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // types.
53064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const auto *OASE =
53074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          dyn_cast<OMPArraySectionExpr>(I->getAssociatedExpression());
53084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      bool IsPointer =
53094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          (OASE &&
53104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar           OMPArraySectionExpr::getBaseOriginalType(OASE)
53114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               .getCanonicalType()
53124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               ->isAnyPointerType()) ||
53134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          I->getAssociatedExpression()->getType()->isAnyPointerType();
53144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (Next == CE || IsPointer || IsFinalArraySection) {
53164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // If this is not the last component, we expect the pointer to be
53184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // associated with an array expression or member expression.
53194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert((Next == CE ||
53204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                isa<MemberExpr>(Next->getAssociatedExpression()) ||
53214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) ||
53224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) &&
53234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               "Unexpected expression");
53244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // Save the base we are currently using.
53264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        BasePointers.push_back(BP);
53274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *LB = CGF.EmitLValue(I->getAssociatedExpression()).getPointer();
53294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *Size = getExprTypeSize(I->getAssociatedExpression());
53304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Pointers.push_back(LB);
53324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Sizes.push_back(Size);
53334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // We need to add a pointer flag for each map that comes from the
53344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // same expression except for the first one. We also need to signal
53354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // this map is the first one that relates with the current capture
53364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // (there is a set of entries for each capture).
53374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Types.push_back(getMapTypeBits(MapType, MapTypeModifier,
53384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       !IsExpressionFirstInfo,
53394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       IsCaptureFirstInfo));
53404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // If we have a final array section, we are done with this expression.
53424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (IsFinalArraySection)
53434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          break;
53444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // The pointer becomes the base for the next element.
53464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (Next != CE)
53474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          BP = LB;
53484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        IsExpressionFirstInfo = false;
53504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        IsCaptureFirstInfo = false;
53514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        continue;
53524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
53534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
53544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
53554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Return the adjusted map modifiers if the declaration a capture
53574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// refers to appears in a first-private clause. This is expected to be used
53584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// only with directives that start with 'target'.
53594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned adjustMapModifiersForPrivateClauses(const CapturedStmt::Capture &Cap,
53604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                               unsigned CurrentModifiers) {
53614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(Cap.capturesVariable() && "Expected capture by reference only!");
53624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // A first private variable captured by reference will use only the
53644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // 'private ptr' and 'map to' flag. Return the right flags if the captured
53654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // declaration is known as first-private in this handler.
53664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (FirstPrivateDecls.count(Cap.getCapturedVar()))
53674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return MappableExprsHandler::OMP_MAP_PRIVATE_PTR |
53684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar             MappableExprsHandler::OMP_MAP_TO;
53694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // We didn't modify anything.
53714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return CurrentModifiers;
53724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
53734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
53754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler(const OMPExecutableDirective &Dir, CodeGenFunction &CGF)
53764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      : Directive(Dir), CGF(CGF) {
53774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Extract firstprivate clause information.
53784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (const auto *C : Dir.getClausesOfKind<OMPFirstprivateClause>())
53794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (const auto *D : C->varlists())
53804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        FirstPrivateDecls.insert(
53814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl());
53824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
53834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Generate all the base pointers, section pointers, sizes and map
53854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// types for the extracted mappable expressions.
53864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void generateAllInfo(MapValuesArrayTy &BasePointers,
53874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                       MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
53884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                       MapFlagsArrayTy &Types) const {
53894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    BasePointers.clear();
53904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Pointers.clear();
53914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Sizes.clear();
53924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Types.clear();
53934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
53944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    struct MapInfo {
53954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
53964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OpenMPMapClauseKind MapType;
53974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      OpenMPMapClauseKind MapTypeModifier;
53984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    };
53994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // We have to process the component lists that relate with the same
54014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // declaration in a single chunk so that we can generate the map flags
54024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // correctly. Therefore, we organize all lists in a map.
54034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::DenseMap<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
54044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Helper function to fill the information map for the different supported
54064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // clauses.
54074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &&InfoGen =
54084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        [&Info](const ValueDecl *D,
54094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                OMPClauseMappableExprCommon::MappableExprComponentListRef L,
54104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapModifier) {
54114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          const ValueDecl *VD =
54124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
54134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Info[VD].push_back({L, MapType, MapModifier});
54144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        };
54154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *C : Directive.getClausesOfKind<OMPMapClause>())
54174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto L : C->component_lists())
54184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifier());
54194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *C : Directive.getClausesOfKind<OMPToClause>())
54204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto L : C->component_lists())
54214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        InfoGen(L.first, L.second, OMPC_MAP_to, OMPC_MAP_unknown);
54224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *C : Directive.getClausesOfKind<OMPFromClause>())
54234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto L : C->component_lists())
54244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        InfoGen(L.first, L.second, OMPC_MAP_from, OMPC_MAP_unknown);
54254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto &M : Info) {
54274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // We need to know when we generate information for the first component
54284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // associated with a capture, because the mapping flags depend on it.
54294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      bool IsFirstComponentList = true;
54304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (MapInfo &L : M.second) {
54314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert(!L.Components.empty() &&
54324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               "Not expecting declaration with no component lists.");
54334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        generateInfoForComponentList(L.MapType, L.MapTypeModifier, L.Components,
54344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     BasePointers, Pointers, Sizes, Types,
54354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     IsFirstComponentList);
54364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        IsFirstComponentList = false;
54374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
54384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
54394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
54404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Generate the base pointers, section pointers, sizes and map types
54424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// associated to a given capture.
54434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void generateInfoForCapture(const CapturedStmt::Capture *Cap,
54444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              MapValuesArrayTy &BasePointers,
54454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              MapValuesArrayTy &Pointers,
54464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              MapValuesArrayTy &Sizes,
54474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              MapFlagsArrayTy &Types) const {
54484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(!Cap->capturesVariableArrayType() &&
54494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar           "Not expecting to generate map info for a variable array type!");
54504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    BasePointers.clear();
54524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Pointers.clear();
54534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Sizes.clear();
54544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Types.clear();
54554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const ValueDecl *VD =
54574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Cap->capturesThis()
54584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            ? nullptr
54594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            : cast<ValueDecl>(Cap->getCapturedVar()->getCanonicalDecl());
54604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // We need to know when we generating information for the first component
54624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // associated with a capture, because the mapping flags depend on it.
54634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool IsFirstComponentList = true;
54644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *C : Directive.getClausesOfKind<OMPMapClause>())
54654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto L : C->decl_component_lists(VD)) {
54664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert(L.first == VD &&
54674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               "We got information for the wrong declaration??");
54684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert(!L.second.empty() &&
54694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               "Not expecting declaration with no component lists.");
54704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        generateInfoForComponentList(C->getMapType(), C->getMapTypeModifier(),
54714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     L.second, BasePointers, Pointers, Sizes,
54724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     Types, IsFirstComponentList);
54734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        IsFirstComponentList = false;
54744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
547587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
54764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
54774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
54784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Generate the default map information for a given capture \a CI,
54804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// record field declaration \a RI and captured value \a CV.
54814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void generateDefaultMapInfo(
54824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const CapturedStmt::Capture &CI, const FieldDecl &RI, llvm::Value *CV,
54834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      MappableExprsHandler::MapValuesArrayTy &CurBasePointers,
54844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      MappableExprsHandler::MapValuesArrayTy &CurPointers,
54854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      MappableExprsHandler::MapValuesArrayTy &CurSizes,
54864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      MappableExprsHandler::MapFlagsArrayTy &CurMapTypes) {
54874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
54884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Do the default mapping.
54894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (CI.capturesThis()) {
54904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurBasePointers.push_back(CV);
54914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurPointers.push_back(CV);
54924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const PointerType *PtrTy = cast<PointerType>(RI.getType().getTypePtr());
54934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurSizes.push_back(CGF.getTypeSize(PtrTy->getPointeeType()));
54944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // Default map type.
54954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_TO |
54964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            MappableExprsHandler::OMP_MAP_FROM);
54974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else if (CI.capturesVariableByCopy()) {
54984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurBasePointers.push_back(CV);
54994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurPointers.push_back(CV);
55004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (!RI.getType()->isAnyPointerType()) {
55014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // We have to signal to the runtime captures passed by value that are
55024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // not pointers.
55034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_PRIVATE_VAL);
55044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CurSizes.push_back(CGF.getTypeSize(RI.getType()));
55054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      } else {
55064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // Pointers are implicitly mapped with a zero size and no flags
55074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        // (other than first map that is added for all implicit maps).
55084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CurMapTypes.push_back(0u);
55094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CurSizes.push_back(llvm::Constant::getNullValue(CGF.SizeTy));
55104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
55114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else {
55124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      assert(CI.capturesVariable() && "Expected captured reference.");
55134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurBasePointers.push_back(CV);
55144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurPointers.push_back(CV);
55154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
55164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      const ReferenceType *PtrTy =
55174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          cast<ReferenceType>(RI.getType().getTypePtr());
55184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      QualType ElementType = PtrTy->getPointeeType();
55194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurSizes.push_back(CGF.getTypeSize(ElementType));
55204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // The default map type for a scalar/complex type is 'to' because by
55214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // default the value doesn't have to be retrieved. For an aggregate
55224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // type, the default is 'tofrom'.
55234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurMapTypes.push_back(ElementType->isAggregateType()
55244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                ? (MappableExprsHandler::OMP_MAP_TO |
55254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   MappableExprsHandler::OMP_MAP_FROM)
55264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                : MappableExprsHandler::OMP_MAP_TO);
55274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
55284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // If we have a capture by reference we may need to add the private
55294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // pointer flag if the base declaration shows in some first-private
55304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // clause.
55314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurMapTypes.back() =
55324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          adjustMapModifiersForPrivateClauses(CI, CurMapTypes.back());
55334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
55344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Every default map produces a single argument, so, it is always the
55354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // first one.
55364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CurMapTypes.back() |= MappableExprsHandler::OMP_MAP_FIRST_REF;
55374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
55384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
55394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
55404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarenum OpenMPOffloadingReservedDeviceIDs {
55414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Device ID if the device was not defined, runtime should get it
55424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// from environment variables in the spec.
55434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMP_DEVICEID_UNDEF = -1,
55444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
55454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // anonymous namespace
55464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
55474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Emit the arrays used to pass the captures and map information to the
55484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// offloading runtime library. If there is no map or capture information,
55494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// return nullptr by reference.
55504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void
55514967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainaremitOffloadingArrays(CodeGenFunction &CGF, llvm::Value *&BasePointersArray,
55524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                     llvm::Value *&PointersArray, llvm::Value *&SizesArray,
55534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                     llvm::Value *&MapTypesArray,
55544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                     MappableExprsHandler::MapValuesArrayTy &BasePointers,
55554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                     MappableExprsHandler::MapValuesArrayTy &Pointers,
55564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                     MappableExprsHandler::MapValuesArrayTy &Sizes,
55574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                     MappableExprsHandler::MapFlagsArrayTy &MapTypes) {
55584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &CGM = CGF.CGM;
555987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto &Ctx = CGF.getContext();
556087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
55614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  BasePointersArray = PointersArray = SizesArray = MapTypesArray = nullptr;
55624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
55634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (unsigned PointerNumVal = BasePointers.size()) {
55644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Detect if we have any capture size requiring runtime evaluation of the
55654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // size so that a constant array could be eventually used.
55664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    bool hasRuntimeEvaluationCaptureSize = false;
55674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *S : Sizes)
55684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (!isa<llvm::Constant>(S)) {
55694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        hasRuntimeEvaluationCaptureSize = true;
55704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        break;
55714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
557287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
55734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::APInt PointerNumAP(32, PointerNumVal, /*isSigned=*/true);
55744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    QualType PointerArrayType =
55754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Ctx.getConstantArrayType(Ctx.VoidPtrTy, PointerNumAP, ArrayType::Normal,
55764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 /*IndexTypeQuals=*/0);
55774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
55784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    BasePointersArray =
55794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.CreateMemTemp(PointerArrayType, ".offload_baseptrs").getPointer();
55804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PointersArray =
55814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.CreateMemTemp(PointerArrayType, ".offload_ptrs").getPointer();
55824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
55834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // If we don't have any VLA types or other types that require runtime
55844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // evaluation, we can use a constant array for the map sizes, otherwise we
55854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // need to fill up the arrays as we do for the pointers.
55864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (hasRuntimeEvaluationCaptureSize) {
55874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      QualType SizeArrayType = Ctx.getConstantArrayType(
55884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Ctx.getSizeType(), PointerNumAP, ArrayType::Normal,
55894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          /*IndexTypeQuals=*/0);
55904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      SizesArray =
55914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer();
55924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else {
55934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // We expect all the sizes to be constant, so we collect them to create
55944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // a constant array.
55954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      SmallVector<llvm::Constant *, 16> ConstSizes;
55964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto S : Sizes)
55974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ConstSizes.push_back(cast<llvm::Constant>(S));
55984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
55994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto *SizesArrayInit = llvm::ConstantArray::get(
56004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          llvm::ArrayType::get(CGM.SizeTy, ConstSizes.size()), ConstSizes);
56014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto *SizesArrayGbl = new llvm::GlobalVariable(
56024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGM.getModule(), SizesArrayInit->getType(),
56034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
56044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          SizesArrayInit, ".offload_sizes");
56054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
56064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      SizesArray = SizesArrayGbl;
56074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
56084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
56094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // The map types are always constant so we don't need to generate code to
56104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // fill arrays. Instead, we create an array constant.
56114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Constant *MapTypesArrayInit =
56124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::ConstantDataArray::get(CGF.Builder.getContext(), MapTypes);
56134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *MapTypesArrayGbl = new llvm::GlobalVariable(
56144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getModule(), MapTypesArrayInit->getType(),
56154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
56164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        MapTypesArrayInit, ".offload_maptypes");
56174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
56184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MapTypesArray = MapTypesArrayGbl;
56194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
56204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (unsigned i = 0; i < PointerNumVal; ++i) {
56214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *BPVal = BasePointers[i];
56224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (BPVal->getType()->isPointerTy())
56234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        BPVal = CGF.Builder.CreateBitCast(BPVal, CGM.VoidPtrTy);
56244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      else {
56254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert(BPVal->getType()->isIntegerTy() &&
56264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               "If not a pointer, the value type must be an integer.");
56274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        BPVal = CGF.Builder.CreateIntToPtr(BPVal, CGM.VoidPtrTy);
56284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
56294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *BP = CGF.Builder.CreateConstInBoundsGEP2_32(
56304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          llvm::ArrayType::get(CGM.VoidPtrTy, PointerNumVal), BasePointersArray,
56314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          0, i);
56324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
56334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.CreateStore(BPVal, BPAddr);
56344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
56354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *PVal = Pointers[i];
56364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (PVal->getType()->isPointerTy())
56374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        PVal = CGF.Builder.CreateBitCast(PVal, CGM.VoidPtrTy);
56384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      else {
56394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert(PVal->getType()->isIntegerTy() &&
56404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar               "If not a pointer, the value type must be an integer.");
56414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        PVal = CGF.Builder.CreateIntToPtr(PVal, CGM.VoidPtrTy);
56424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
56434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32(
56444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          llvm::ArrayType::get(CGM.VoidPtrTy, PointerNumVal), PointersArray, 0,
56454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          i);
56464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
56474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.CreateStore(PVal, PAddr);
56484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
56494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (hasRuntimeEvaluationCaptureSize) {
56504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::Value *S = CGF.Builder.CreateConstInBoundsGEP2_32(
56514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            llvm::ArrayType::get(CGM.SizeTy, PointerNumVal), SizesArray,
56524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            /*Idx0=*/0,
56534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            /*Idx1=*/i);
56544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Address SAddr(S, Ctx.getTypeAlignInChars(Ctx.getSizeType()));
56554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF.Builder.CreateStore(
56564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            CGF.Builder.CreateIntCast(Sizes[i], CGM.SizeTy, /*isSigned=*/true),
56574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            SAddr);
56584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
56594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
56604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
56614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
56624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief Emit the arguments to be passed to the runtime library based on the
56634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// arrays of pointers, sizes and map types.
56644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void emitOffloadingArraysArgument(
56654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg,
56664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg,
56674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *&MapTypesArrayArg, llvm::Value *BasePointersArray,
56684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *PointersArray, llvm::Value *SizesArray,
56694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *MapTypesArray, unsigned NumElems) {
56704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &CGM = CGF.CGM;
56714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (NumElems) {
56724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    BasePointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
56734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::ArrayType::get(CGM.VoidPtrTy, NumElems), BasePointersArray,
56744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Idx0=*/0, /*Idx1=*/0);
56754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
56764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::ArrayType::get(CGM.VoidPtrTy, NumElems), PointersArray,
56774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Idx0=*/0,
56784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Idx1=*/0);
56794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    SizesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
56804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::ArrayType::get(CGM.SizeTy, NumElems), SizesArray,
56814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Idx0=*/0, /*Idx1=*/0);
56824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MapTypesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
56834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::ArrayType::get(CGM.Int32Ty, NumElems), MapTypesArray,
56844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Idx0=*/0,
56854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /*Idx1=*/0);
56864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else {
56874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
56884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
56894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    SizesArrayArg = llvm::ConstantPointerNull::get(CGM.SizeTy->getPointerTo());
56904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MapTypesArrayArg =
56914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo());
56924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
56934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
56944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
56954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF,
56964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     const OMPExecutableDirective &D,
56974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     llvm::Value *OutlinedFn,
56984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     llvm::Value *OutlinedFnID,
56994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     const Expr *IfCond, const Expr *Device,
57004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     ArrayRef<llvm::Value *> CapturedVars) {
57014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
57024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
57034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
57044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(OutlinedFn && "Invalid outlined function!");
57054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
57064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &Ctx = CGF.getContext();
57074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
57084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Fill up the arrays with all the captured variables.
57094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapValuesArrayTy KernelArgs;
57104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapValuesArrayTy BasePointers;
57114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapValuesArrayTy Pointers;
57124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapValuesArrayTy Sizes;
57134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapFlagsArrayTy MapTypes;
57144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
57154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapValuesArrayTy CurBasePointers;
57164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapValuesArrayTy CurPointers;
57174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapValuesArrayTy CurSizes;
57184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler::MapFlagsArrayTy CurMapTypes;
57194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
57204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Get mappable expression information.
57214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MappableExprsHandler MEHandler(D, CGF);
572287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
572387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const CapturedStmt &CS = *cast<CapturedStmt>(D.getAssociatedStmt());
572487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto RI = CS.getCapturedRecordDecl()->field_begin();
572587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto CV = CapturedVars.begin();
572687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  for (CapturedStmt::const_capture_iterator CI = CS.capture_begin(),
572787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                            CE = CS.capture_end();
572887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar       CI != CE; ++CI, ++RI, ++CV) {
572987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    StringRef Name;
573087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    QualType Ty;
573187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
57324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CurBasePointers.clear();
57334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CurPointers.clear();
57344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CurSizes.clear();
57354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CurMapTypes.clear();
57364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
57374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // VLA sizes are passed to the outlined region by copy and do not have map
57384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // information associated.
573987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (CI->capturesVariableArrayType()) {
57404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurBasePointers.push_back(*CV);
57414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurPointers.push_back(*CV);
57424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurSizes.push_back(CGF.getTypeSize(RI->getType()));
574387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Copy to the device as an argument. No need to retrieve it.
57444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_PRIVATE_VAL |
57454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            MappableExprsHandler::OMP_MAP_FIRST_REF);
574687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    } else {
57474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // If we have any information in the map clause, we use it, otherwise we
57484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      // just do a default mapping.
57494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      MEHandler.generateInfoForCapture(CI, CurBasePointers, CurPointers,
57504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       CurSizes, CurMapTypes);
57514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (CurBasePointers.empty())
57524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        MEHandler.generateDefaultMapInfo(*CI, **RI, *CV, CurBasePointers,
57534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         CurPointers, CurSizes, CurMapTypes);
575487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
57554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // We expect to have at least an element of information for this capture.
57564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(!CurBasePointers.empty() && "Non-existing map pointer for capture!");
57574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(CurBasePointers.size() == CurPointers.size() &&
57584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar           CurBasePointers.size() == CurSizes.size() &&
57594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar           CurBasePointers.size() == CurMapTypes.size() &&
57604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar           "Inconsistent map information sizes!");
57614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
57624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // The kernel args are always the first elements of the base pointers
57634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // associated with a capture.
57644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    KernelArgs.push_back(CurBasePointers.front());
57654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // We need to append the results of this capture to what we already have.
57664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
57674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Pointers.append(CurPointers.begin(), CurPointers.end());
57684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Sizes.append(CurSizes.begin(), CurSizes.end());
57694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MapTypes.append(CurMapTypes.begin(), CurMapTypes.end());
577087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
577187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
577287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Keep track on whether the host function has to be executed.
577387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto OffloadErrorQType =
577487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Ctx.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true);
577587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto OffloadError = CGF.MakeAddrLValue(
577687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.CreateMemTemp(OffloadErrorQType, ".run_host_version"),
577787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      OffloadErrorQType);
577887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitStoreOfScalar(llvm::Constant::getNullValue(CGM.Int32Ty),
577987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                        OffloadError);
578087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
578187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Fill up the pointer arrays and transfer execution to the device.
57824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ThenGen = [&Ctx, &BasePointers, &Pointers, &Sizes, &MapTypes, Device,
57834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    OutlinedFnID, OffloadError, OffloadErrorQType,
57844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    &D](CodeGenFunction &CGF, PrePostActionTy &) {
57854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &RT = CGF.CGM.getOpenMPRuntime();
57864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit the offloading arrays.
578787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *BasePointersArray;
578887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *PointersArray;
578987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *SizesArray;
579087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *MapTypesArray;
57914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOffloadingArrays(CGF, BasePointersArray, PointersArray, SizesArray,
57924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         MapTypesArray, BasePointers, Pointers, Sizes,
57934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         MapTypes);
57944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOffloadingArraysArgument(CGF, BasePointersArray, PointersArray,
57954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 SizesArray, MapTypesArray, BasePointersArray,
57964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 PointersArray, SizesArray, MapTypesArray,
57974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 BasePointers.size());
579887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
579987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // On top of the arrays that were filled up, the target offloading call
580087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // takes as arguments the device id as well as the host pointer. The host
580187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // pointer is used by the runtime library to identify the current target
580287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // region, so it only has to be unique and not necessarily point to
580387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // anything. It could be the pointer to the outlined function that
580487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // implements the target region, but we aren't using that so that the
580587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // compiler doesn't need to keep that, and could therefore inline the host
580687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // function if proven worthwhile during optimization.
580787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
58084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // From this point on, we need to have an ID of the target region defined.
58094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(OutlinedFnID && "Invalid outlined function ID!");
581087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
581187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Emit device ID if any.
581287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *DeviceID;
581387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (Device)
581487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
58154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                           CGF.Int32Ty, /*isSigned=*/true);
581687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    else
581787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      DeviceID = CGF.Builder.getInt32(OMP_DEVICEID_UNDEF);
581887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
58194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit the number of elements in the offloading arrays.
58204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *PointerNum = CGF.Builder.getInt32(BasePointers.size());
58214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
58224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Return value of the runtime offloading call.
58234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *Return;
58244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
58254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *NumTeams = emitNumTeamsClauseForTargetDirective(RT, CGF, D);
58264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *ThreadLimit = emitThreadLimitClauseForTargetDirective(RT, CGF, D);
58274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
58284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // If we have NumTeams defined this means that we have an enclosed teams
58294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // region. Therefore we also expect to have ThreadLimit defined. These two
58304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // values should be defined in the presence of a teams directive, regardless
58314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // of having any clauses associated. If the user is using teams but no
58324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // clauses, these two values will be the default that should be passed to
58334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // the runtime library - a 32-bit integer with the value zero.
58344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (NumTeams) {
58354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      assert(ThreadLimit && "Thread limit expression should be available along "
58364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            "with number of teams.");
58374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *OffloadingArgs[] = {
58384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          DeviceID,          OutlinedFnID,  PointerNum,
58394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          BasePointersArray, PointersArray, SizesArray,
58404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          MapTypesArray,     NumTeams,      ThreadLimit};
58414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Return = CGF.EmitRuntimeCall(
58424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          RT.createRuntimeFunction(OMPRTL__tgt_target_teams), OffloadingArgs);
58434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else {
58444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::Value *OffloadingArgs[] = {
58454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          DeviceID,      OutlinedFnID, PointerNum,   BasePointersArray,
58464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          PointersArray, SizesArray,   MapTypesArray};
58474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Return = CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__tgt_target),
58484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   OffloadingArgs);
58494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
585087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
585187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.EmitStoreOfScalar(Return, OffloadError);
585287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  };
585387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
58544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Notify that the host version must be executed.
58554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ElseGen = [OffloadError](CodeGenFunction &CGF, PrePostActionTy &) {
58564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitStoreOfScalar(llvm::ConstantInt::get(CGF.Int32Ty, /*V=*/-1u),
58574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          OffloadError);
58584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
58594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
58604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If we have a target function ID it means that we need to support
58614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // offloading, otherwise, just execute on the host. We need to execute on host
58624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // regardless of the conditional in the if clause if, e.g., the user do not
58634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // specify target triples.
58644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (OutlinedFnID) {
58654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (IfCond)
58664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitOMPIfClause(CGF, IfCond, ThenGen, ElseGen);
58674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    else {
58684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      RegionCodeGenTy ThenRCG(ThenGen);
58694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ThenRCG(CGF);
58704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
587187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  } else {
58724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RegionCodeGenTy ElseRCG(ElseGen);
58734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ElseRCG(CGF);
587487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
587587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
587687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Check the error code and execute the host version if required.
587787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto OffloadFailedBlock = CGF.createBasicBlock("omp_offload.failed");
587887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto OffloadContBlock = CGF.createBasicBlock("omp_offload.cont");
587987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto OffloadErrorVal = CGF.EmitLoadOfScalar(OffloadError, SourceLocation());
588087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  auto Failed = CGF.Builder.CreateIsNotNull(OffloadErrorVal);
588187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
588287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
588387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitBlock(OffloadFailedBlock);
58844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.Builder.CreateCall(OutlinedFn, KernelArgs);
588587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitBranch(OffloadContBlock);
588687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
588787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitBlock(OffloadContBlock, /*IsFinished=*/true);
588887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
58894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
58904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
58914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                    StringRef ParentName) {
58924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!S)
58934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
58944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
58954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If we find a OMP target directive, codegen the outline function and
58964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // register the result.
58974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // FIXME: Add other directives with target when they become supported.
58984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool isTargetDirective = isa<OMPTargetDirective>(S);
58994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (isTargetDirective) {
59014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *E = cast<OMPExecutableDirective>(S);
59024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned DeviceID;
59034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned FileID;
59044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned Line;
59054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    getTargetEntryUniqueInfo(CGM.getContext(), E->getLocStart(), DeviceID,
59064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             FileID, Line);
59074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Is this a target region that should not be emitted as an entry point? If
59094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // so just signal we are done with this target region.
59104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!OffloadEntriesInfoManager.hasTargetRegionEntryInfo(DeviceID, FileID,
59114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                            ParentName, Line))
59124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return;
59134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Function *Fn;
59154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Constant *Addr;
59164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    std::tie(Fn, Addr) =
59174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CodeGenFunction::EmitOMPTargetDirectiveOutlinedFunction(
59184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            CGM, cast<OMPTargetDirective>(*E), ParentName,
59194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            /*isOffloadEntry=*/true);
59204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(Fn && Addr && "Target region emission failed.");
59214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
59224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
59234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (const OMPExecutableDirective *E = dyn_cast<OMPExecutableDirective>(S)) {
59254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!E->hasAssociatedStmt())
59264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return;
59274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    scanForTargetRegionsFunctions(
59294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        cast<CapturedStmt>(E->getAssociatedStmt())->getCapturedStmt(),
59304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ParentName);
59314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
59324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
59334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If this is a lambda function, look into its body.
59354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *L = dyn_cast<LambdaExpr>(S))
59364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    S = L->getBody();
59374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Keep looking for target regions recursively.
59394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *II : S->children())
59404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    scanForTargetRegionsFunctions(II, ParentName);
59414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
59424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
59444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &FD = *cast<FunctionDecl>(GD.getDecl());
59454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If emitting code for the host, we do not process FD here. Instead we do
59474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the normal code generation.
59484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGM.getLangOpts().OpenMPIsDevice)
59494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
59504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Try to detect target regions in the function.
59524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  scanForTargetRegionsFunctions(FD.getBody(), CGM.getMangledName(GD));
59534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // We should not emit any function othen that the ones created during the
59554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // scanning. Therefore, we signal that this function is completely dealt
59564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // with.
59574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return true;
59584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
59594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
59614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGM.getLangOpts().OpenMPIsDevice)
59624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
59634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Check if there are Ctors/Dtors in this declaration and look for target
59654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // regions in it. We use the complete variant to produce the kernel name
59664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // mangling.
59674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  QualType RDTy = cast<VarDecl>(GD.getDecl())->getType();
59684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *RD = RDTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) {
59694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *Ctor : RD->ctors()) {
59704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      StringRef ParentName =
59714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGM.getMangledName(GlobalDecl(Ctor, Ctor_Complete));
59724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      scanForTargetRegionsFunctions(Ctor->getBody(), ParentName);
59734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
59744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *Dtor = RD->getDestructor();
59754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Dtor) {
59764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      StringRef ParentName =
59774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CGM.getMangledName(GlobalDecl(Dtor, Dtor_Complete));
59784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      scanForTargetRegionsFunctions(Dtor->getBody(), ParentName);
59794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
59804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
59814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If we are in target mode we do not emit any global (declare target is not
59834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // implemented yet). Therefore we signal that GD was processed in this case.
59844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return true;
59854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
59864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {
59884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *VD = GD.getDecl();
59894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (isa<FunctionDecl>(VD))
59904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return emitTargetFunctions(GD);
59914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return emitTargetGlobalVariable(GD);
59934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
59944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
59954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarllvm::Function *CGOpenMPRuntime::emitRegistrationFunction() {
59964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If we have offloading in the current module, we need to emit the entries
59974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // now and register the offloading descriptor.
59984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  createOffloadEntriesAndInfoMetadata();
59994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create and register the offloading binary descriptors. This is the main
60014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // entity that captures all the information about offloading in the current
60024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // compilation unit.
60034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return createOffloadingBinaryDescriptorRegistration();
60044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
60054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF,
60074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    const OMPExecutableDirective &D,
60084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    SourceLocation Loc,
60094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    llvm::Value *OutlinedFn,
60104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    ArrayRef<llvm::Value *> CapturedVars) {
60114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
60124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
60134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *RTLoc = emitUpdateLocation(CGF, Loc);
60154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CodeGenFunction::RunCleanupsScope Scope(CGF);
60164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Build call __kmpc_fork_teams(loc, n, microtask, var1, .., varn);
60184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *Args[] = {
60194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      RTLoc,
60204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
60214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy())};
60224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::SmallVector<llvm::Value *, 16> RealArgs;
60234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RealArgs.append(std::begin(Args), std::end(Args));
60244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RealArgs.append(CapturedVars.begin(), CapturedVars.end());
60254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_teams);
60274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitRuntimeCall(RTLFn, RealArgs);
60284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
60294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
60314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         const Expr *NumTeams,
60324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         const Expr *ThreadLimit,
60334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         SourceLocation Loc) {
60344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
60354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
60364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *RTLoc = emitUpdateLocation(CGF, Loc);
60384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *NumTeamsVal =
60404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      (NumTeams)
60414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(NumTeams),
60424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                      CGF.CGM.Int32Ty, /* isSigned = */ true)
60434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          : CGF.Builder.getInt32(0);
60444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *ThreadLimitVal =
60464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      (ThreadLimit)
60474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(ThreadLimit),
60484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                      CGF.CGM.Int32Ty, /* isSigned = */ true)
60494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          : CGF.Builder.getInt32(0);
60504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Build call __kmpc_push_num_teamss(&loc, global_tid, num_teams, thread_limit)
60524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *PushNumTeamsArgs[] = {RTLoc, getThreadID(CGF, Loc), NumTeamsVal,
60534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     ThreadLimitVal};
60544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_teams),
60554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      PushNumTeamsArgs);
60564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
60574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTargetDataCalls(CodeGenFunction &CGF,
60594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                          const OMPExecutableDirective &D,
60604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                          const Expr *IfCond,
60614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                          const Expr *Device,
60624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                          const RegionCodeGenTy &CodeGen) {
60634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
60654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
60664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *BasePointersArray = nullptr;
60684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *PointersArray = nullptr;
60694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *SizesArray = nullptr;
60704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *MapTypesArray = nullptr;
60714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned NumOfPtrs = 0;
60724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Generate the code for the opening of the data environment. Capture all the
60744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // arguments of the runtime call by reference because they are used in the
60754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // closing of the region.
60764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&BeginThenGen = [&D, &CGF, &BasePointersArray, &PointersArray,
60774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         &SizesArray, &MapTypesArray, Device,
60784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         &NumOfPtrs](CodeGenFunction &CGF, PrePostActionTy &) {
60794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Fill up the arrays with all the mapped variables.
60804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler::MapValuesArrayTy BasePointers;
60814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler::MapValuesArrayTy Pointers;
60824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler::MapValuesArrayTy Sizes;
60834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler::MapFlagsArrayTy MapTypes;
60844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Get map clause information.
60864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler MCHandler(D, CGF);
60874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MCHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
60884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    NumOfPtrs = BasePointers.size();
60894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Fill up the arrays and create the arguments.
60914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOffloadingArrays(CGF, BasePointersArray, PointersArray, SizesArray,
60924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         MapTypesArray, BasePointers, Pointers, Sizes,
60934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         MapTypes);
60944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
60954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *BasePointersArrayArg = nullptr;
60964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *PointersArrayArg = nullptr;
60974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *SizesArrayArg = nullptr;
60984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *MapTypesArrayArg = nullptr;
60994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
61004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 SizesArrayArg, MapTypesArrayArg,
61014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 BasePointersArray, PointersArray, SizesArray,
61024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 MapTypesArray, NumOfPtrs);
61034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit device ID if any.
61054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *DeviceID = nullptr;
61064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Device)
61074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
61084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                           CGF.Int32Ty, /*isSigned=*/true);
61094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    else
61104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DeviceID = CGF.Builder.getInt32(OMP_DEVICEID_UNDEF);
61114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit the number of elements in the offloading arrays.
61134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *PointerNum = CGF.Builder.getInt32(NumOfPtrs);
61144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *OffloadingArgs[] = {
61164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        DeviceID,         PointerNum,    BasePointersArrayArg,
61174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
61184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &RT = CGF.CGM.getOpenMPRuntime();
61194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__tgt_target_data_begin),
61204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        OffloadingArgs);
61214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
61224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Generate code for the closing of the data region.
61244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&EndThenGen = [&CGF, &BasePointersArray, &PointersArray, &SizesArray,
61254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                       &MapTypesArray, Device,
61264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                       &NumOfPtrs](CodeGenFunction &CGF, PrePostActionTy &) {
61274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(BasePointersArray && PointersArray && SizesArray && MapTypesArray &&
61284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar           NumOfPtrs && "Invalid data environment closing arguments.");
61294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *BasePointersArrayArg = nullptr;
61314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *PointersArrayArg = nullptr;
61324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *SizesArrayArg = nullptr;
61334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *MapTypesArrayArg = nullptr;
61344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
61354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 SizesArrayArg, MapTypesArrayArg,
61364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 BasePointersArray, PointersArray, SizesArray,
61374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                 MapTypesArray, NumOfPtrs);
61384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit device ID if any.
61404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *DeviceID = nullptr;
61414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Device)
61424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
61434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                           CGF.Int32Ty, /*isSigned=*/true);
61444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    else
61454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DeviceID = CGF.Builder.getInt32(OMP_DEVICEID_UNDEF);
61464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit the number of elements in the offloading arrays.
61484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *PointerNum = CGF.Builder.getInt32(NumOfPtrs);
61494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *OffloadingArgs[] = {
61514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        DeviceID,         PointerNum,    BasePointersArrayArg,
61524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
61534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &RT = CGF.CGM.getOpenMPRuntime();
61544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__tgt_target_data_end),
61554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        OffloadingArgs);
61564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
61574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // In the event we get an if clause, we don't have to take any action on the
61594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // else side.
61604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ElseGen = [](CodeGenFunction &CGF, PrePostActionTy &) {};
61614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (IfCond) {
61634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOMPIfClause(CGF, IfCond, BeginThenGen, ElseGen);
61644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else {
61654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RegionCodeGenTy BeginThenRCG(BeginThenGen);
61664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    BeginThenRCG(CGF);
61674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
61684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data, CodeGen);
61704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (IfCond) {
61724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOMPIfClause(CGF, IfCond, EndThenGen, ElseGen);
61734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else {
61744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RegionCodeGenTy EndThenRCG(EndThenGen);
61754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    EndThenRCG(CGF);
61764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
61774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
61784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitTargetDataStandAloneCall(
61804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
61814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const Expr *Device) {
61824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
61834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
61844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert((isa<OMPTargetEnterDataDirective>(D) ||
61864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          isa<OMPTargetExitDataDirective>(D) ||
61874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          isa<OMPTargetUpdateDirective>(D)) &&
61884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar         "Expecting either target enter, exit data, or update directives.");
61894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Generate the code for the opening of the data environment.
61914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ThenGen = [&D, &CGF, Device](CodeGenFunction &CGF, PrePostActionTy &) {
61924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Fill up the arrays with all the mapped variables.
61934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler::MapValuesArrayTy BasePointers;
61944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler::MapValuesArrayTy Pointers;
61954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler::MapValuesArrayTy Sizes;
61964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler::MapFlagsArrayTy MapTypes;
61974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
61984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Get map clause information.
61994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MappableExprsHandler MEHandler(D, CGF);
62004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    MEHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
62014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *BasePointersArrayArg = nullptr;
62034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *PointersArrayArg = nullptr;
62044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *SizesArrayArg = nullptr;
62054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *MapTypesArrayArg = nullptr;
62064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Fill up the arrays and create the arguments.
62084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOffloadingArrays(CGF, BasePointersArrayArg, PointersArrayArg,
62094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         SizesArrayArg, MapTypesArrayArg, BasePointers,
62104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         Pointers, Sizes, MapTypes);
62114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOffloadingArraysArgument(
62124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGF, BasePointersArrayArg, PointersArrayArg, SizesArrayArg,
62134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        MapTypesArrayArg, BasePointersArrayArg, PointersArrayArg, SizesArrayArg,
62144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        MapTypesArrayArg, BasePointers.size());
62154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit device ID if any.
62174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *DeviceID = nullptr;
62184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Device)
62194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
62204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                           CGF.Int32Ty, /*isSigned=*/true);
62214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    else
62224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      DeviceID = CGF.Builder.getInt32(OMP_DEVICEID_UNDEF);
62234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Emit the number of elements in the offloading arrays.
62254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto *PointerNum = CGF.Builder.getInt32(BasePointers.size());
62264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Value *OffloadingArgs[] = {
62284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        DeviceID,         PointerNum,    BasePointersArrayArg,
62294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
62304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto &RT = CGF.CGM.getOpenMPRuntime();
62324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Select the right runtime function call for each expected standalone
62334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // directive.
62344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OpenMPRTLFunction RTLFn;
62354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    switch (D.getDirectiveKind()) {
62364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    default:
62374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm_unreachable("Unexpected standalone target data directive.");
62384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
62394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPD_target_enter_data:
62404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      RTLFn = OMPRTL__tgt_target_data_begin;
62414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
62424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPD_target_exit_data:
62434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      RTLFn = OMPRTL__tgt_target_data_end;
62444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
62454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    case OMPD_target_update:
62464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      RTLFn = OMPRTL__tgt_target_data_update;
62474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      break;
62484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
62494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitRuntimeCall(RT.createRuntimeFunction(RTLFn), OffloadingArgs);
62504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
62514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // In the event we get an if clause, we don't have to take any action on the
62534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // else side.
62544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &&ElseGen = [](CodeGenFunction &CGF, PrePostActionTy &) {};
62554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (IfCond) {
62574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    emitOMPIfClause(CGF, IfCond, ThenGen, ElseGen);
62584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else {
62594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RegionCodeGenTy ThenGenRCG(ThenGen);
62604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ThenGenRCG(CGF);
62614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
62624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
62634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarnamespace {
62654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Kind of parameter in a function with 'declare simd' directive.
62664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  enum ParamKindTy { LinearWithVarStride, Linear, Uniform, Vector };
62674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// Attribute set of the parameter.
62684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  struct ParamAttrTy {
62694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ParamKindTy Kind = Vector;
62704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::APSInt StrideOrArg;
62714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::APSInt Alignment;
62724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
62734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // namespace
62744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic unsigned evaluateCDTSize(const FunctionDecl *FD,
62764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                ArrayRef<ParamAttrTy> ParamAttrs) {
62774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Every vector variant of a SIMD-enabled function has a vector length (VLEN).
62784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If OpenMP clause "simdlen" is used, the VLEN is the value of the argument
62794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // of that clause. The VLEN value must be power of 2.
62804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // In other case the notion of the function`s "characteristic data type" (CDT)
62814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // is used to compute the vector length.
62824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // CDT is defined in the following order:
62834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   a) For non-void function, the CDT is the return type.
62844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   b) If the function has any non-uniform, non-linear parameters, then the
62854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   CDT is the type of the first such parameter.
62864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   c) If the CDT determined by a) or b) above is struct, union, or class
62874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   type which is pass-by-value (except for the type that maps to the
62884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   built-in complex data type), the characteristic data type is int.
62894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   d) If none of the above three cases is applicable, the CDT is int.
62904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // The VLEN is then determined based on the CDT and the size of vector
62914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // register of that ISA for which current vector version is generated. The
62924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // VLEN is computed using the formula below:
62934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //   VLEN  = sizeof(vector_register) / sizeof(CDT),
62944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // where vector register size specified in section 3.2.1 Registers and the
62954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Stack Frame of original AMD64 ABI document.
62964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  QualType RetType = FD->getReturnType();
62974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (RetType.isNull())
62984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return 0;
62994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASTContext &C = FD->getASTContext();
63004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  QualType CDT;
63014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!RetType.isNull() && !RetType->isVoidType())
63024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CDT = RetType;
63034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  else {
63044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned Offset = 0;
63054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
63064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (ParamAttrs[Offset].Kind == Vector)
63074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CDT = C.getPointerType(C.getRecordType(MD->getParent()));
63084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++Offset;
63094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
63104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (CDT.isNull()) {
63114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
63124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (ParamAttrs[I + Offset].Kind == Vector) {
63134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          CDT = FD->getParamDecl(I)->getType();
63144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          break;
63154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        }
63164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
63174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
63184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
63194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (CDT.isNull())
63204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CDT = C.IntTy;
63214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CDT = CDT->getCanonicalTypeUnqualified();
63224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (CDT->isRecordType() || CDT->isUnionType())
63234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CDT = C.IntTy;
63244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return C.getTypeSize(CDT);
63254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
63264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
63274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic void
63284967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainaremitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn,
63294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                           llvm::APSInt VLENVal,
63304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                           ArrayRef<ParamAttrTy> ParamAttrs,
63314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                           OMPDeclareSimdDeclAttr::BranchStateTy State) {
63324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  struct ISADataTy {
63334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    char ISA;
63344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned VecRegSize;
63354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
63364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ISADataTy ISAData[] = {
63374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      {
63384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          'b', 128
63394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }, // SSE
63404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      {
63414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          'c', 256
63424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }, // AVX
63434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      {
63444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          'd', 256
63454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }, // AVX2
63464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      {
63474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          'e', 512
63484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }, // AVX512
63494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
63504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::SmallVector<char, 2> Masked;
63514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  switch (State) {
63524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPDeclareSimdDeclAttr::BS_Undefined:
63534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Masked.push_back('N');
63544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Masked.push_back('M');
63554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
63564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPDeclareSimdDeclAttr::BS_Notinbranch:
63574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Masked.push_back('N');
63584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
63594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  case OMPDeclareSimdDeclAttr::BS_Inbranch:
63604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Masked.push_back('M');
63614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    break;
63624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
63634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto Mask : Masked) {
63644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto &Data : ISAData) {
63654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      SmallString<256> Buffer;
63664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      llvm::raw_svector_ostream Out(Buffer);
63674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Out << "_ZGV" << Data.ISA << Mask;
63684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (!VLENVal) {
63694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Out << llvm::APSInt::getUnsigned(Data.VecRegSize /
63704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         evaluateCDTSize(FD, ParamAttrs));
63714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      } else
63724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Out << VLENVal;
63734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto &ParamAttr : ParamAttrs) {
63744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        switch (ParamAttr.Kind){
63754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        case LinearWithVarStride:
63764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Out << 's' << ParamAttr.StrideOrArg;
63774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          break;
63784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        case Linear:
63794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Out << 'l';
63804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          if (!!ParamAttr.StrideOrArg)
63814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            Out << ParamAttr.StrideOrArg;
63824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          break;
63834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        case Uniform:
63844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Out << 'u';
63854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          break;
63864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        case Vector:
63874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Out << 'v';
63884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          break;
63894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        }
63904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (!!ParamAttr.Alignment)
63914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Out << 'a' << ParamAttr.Alignment;
63924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
63934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Out << '_' << Fn->getName();
63944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Fn->addFnAttr(Out.str());
63954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
63964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
63974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
63984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
63994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
64004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                              llvm::Function *Fn) {
64014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASTContext &C = CGM.getContext();
64024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FD = FD->getCanonicalDecl();
64034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Map params to their positions in function decl.
64044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::DenseMap<const Decl *, unsigned> ParamPositions;
64054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (isa<CXXMethodDecl>(FD))
64064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ParamPositions.insert({FD, 0});
64074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned ParamPos = ParamPositions.size();
64084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *P : FD->parameters()) {
64094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ParamPositions.insert({P->getCanonicalDecl(), ParamPos});
64104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ++ParamPos;
64114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
64124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (auto *Attr : FD->specific_attrs<OMPDeclareSimdDeclAttr>()) {
64134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::SmallVector<ParamAttrTy, 8> ParamAttrs(ParamPositions.size());
64144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Mark uniform parameters.
64154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *E : Attr->uniforms()) {
64164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      E = E->IgnoreParenImpCasts();
64174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      unsigned Pos;
64184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (isa<CXXThisExpr>(E))
64194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Pos = ParamPositions[FD];
64204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      else {
64214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
64224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        ->getCanonicalDecl();
64234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Pos = ParamPositions[PVD];
64244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
64254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ParamAttrs[Pos].Kind = Uniform;
64264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
64274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Get alignment info.
64284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto NI = Attr->alignments_begin();
64294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *E : Attr->aligneds()) {
64304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      E = E->IgnoreParenImpCasts();
64314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      unsigned Pos;
64324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      QualType ParmTy;
64334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (isa<CXXThisExpr>(E)) {
64344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Pos = ParamPositions[FD];
64354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ParmTy = E->getType();
64364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      } else {
64374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
64384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        ->getCanonicalDecl();
64394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Pos = ParamPositions[PVD];
64404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ParmTy = PVD->getType();
64414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
64424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ParamAttrs[Pos].Alignment =
64434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          (*NI) ? (*NI)->EvaluateKnownConstInt(C)
64444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                : llvm::APSInt::getUnsigned(
64454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      C.toCharUnitsFromBits(C.getOpenMPDefaultSimdAlign(ParmTy))
64464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          .getQuantity());
64474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++NI;
64484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
64494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Mark linear parameters.
64504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto SI = Attr->steps_begin();
64514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto MI = Attr->modifiers_begin();
64524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto *E : Attr->linears()) {
64534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      E = E->IgnoreParenImpCasts();
64544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      unsigned Pos;
64554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (isa<CXXThisExpr>(E))
64564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Pos = ParamPositions[FD];
64574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      else {
64584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
64594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        ->getCanonicalDecl();
64604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Pos = ParamPositions[PVD];
64614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
64624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      auto &ParamAttr = ParamAttrs[Pos];
64634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ParamAttr.Kind = Linear;
64644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (*SI) {
64654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        if (!(*SI)->EvaluateAsInt(ParamAttr.StrideOrArg, C,
64664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  Expr::SE_AllowSideEffects)) {
64674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          if (auto *DRE = cast<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
64684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            if (auto *StridePVD = cast<ParmVarDecl>(DRE->getDecl())) {
64694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              ParamAttr.Kind = LinearWithVarStride;
64704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar              ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
64714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                  ParamPositions[StridePVD->getCanonicalDecl()]);
64724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            }
64734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          }
64744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        }
64754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
64764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++SI;
64774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++MI;
64784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
64794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::APSInt VLENVal;
64804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (const Expr *VLEN = Attr->getSimdlen())
64814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      VLENVal = VLEN->EvaluateKnownConstInt(C);
64824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    OMPDeclareSimdDeclAttr::BranchStateTy State = Attr->getBranchState();
64834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (CGM.getTriple().getArch() == llvm::Triple::x86 ||
64844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getTriple().getArch() == llvm::Triple::x86_64)
64854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitX86DeclareSimdFunction(FD, Fn, VLENVal, ParamAttrs, State);
64864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
64874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
64884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
64894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarnamespace {
64904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Cleanup action for doacross support.
64914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass DoacrossCleanupTy final : public EHScopeStack::Cleanup {
64924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
64934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static const int DoacrossFinArgs = 2;
64944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
64954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprivate:
64964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *RTLFn;
64974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *Args[DoacrossFinArgs];
64984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
64994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
65004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  DoacrossCleanupTy(llvm::Value *RTLFn, ArrayRef<llvm::Value *> CallArgs)
65014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      : RTLFn(RTLFn) {
65024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(CallArgs.size() == DoacrossFinArgs);
65034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
65044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
65054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
65064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!CGF.HaveInsertPoint())
65074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return;
65084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGF.EmitRuntimeCall(RTLFn, Args);
65094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
65104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
65114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // namespace
65124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
65134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF,
65144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       const OMPLoopDirective &D) {
65154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!CGF.HaveInsertPoint())
65164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return;
65174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
65184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASTContext &C = CGM.getContext();
65194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
65204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  RecordDecl *RD;
65214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (KmpDimTy.isNull()) {
65224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Build struct kmp_dim {  // loop bounds info casted to kmp_int64
65234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //  kmp_int64 lo; // lower
65244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //  kmp_int64 up; // upper
65254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    //  kmp_int64 st; // stride
65264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // };
65274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD = C.buildImplicitRecord("kmp_dim");
65284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD->startDefinition();
65294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, Int64Ty);
65304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, Int64Ty);
65314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    addFieldToRecordDecl(C, RD, Int64Ty);
65324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD->completeDefinition();
65334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    KmpDimTy = C.getRecordType(RD);
65344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else
65354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RD = cast<RecordDecl>(KmpDimTy->getAsTagDecl());
65364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
65374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Address DimsAddr = CGF.CreateMemTemp(KmpDimTy, "dims");
65384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitNullInitialization(DimsAddr, KmpDimTy);
65394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  enum { LowerFD = 0, UpperFD, StrideFD };
65404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Fill dims with data.
65414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue DimsLVal = CGF.MakeAddrLValue(DimsAddr, KmpDimTy);
65424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // dims.upper = num_iterations;
65434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue UpperLVal =
65444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.EmitLValueForField(DimsLVal, *std::next(RD->field_begin(), UpperFD));
65454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *NumIterVal = CGF.EmitScalarConversion(
65464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.EmitScalarExpr(D.getNumIterations()), D.getNumIterations()->getType(),
65474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Int64Ty, D.getNumIterations()->getExprLoc());
65484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitStoreOfScalar(NumIterVal, UpperLVal);
65494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // dims.stride = 1;
65504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LValue StrideLVal =
65514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGF.EmitLValueForField(DimsLVal, *std::next(RD->field_begin(), StrideFD));
65524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty, /*V=*/1),
65534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                        StrideLVal);
65544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
65554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Build call void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid,
65564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // kmp_int32 num_dims, struct kmp_dim * dims);
65574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *Args[] = {emitUpdateLocation(CGF, D.getLocStart()),
65584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         getThreadID(CGF, D.getLocStart()),
65594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         llvm::ConstantInt::getSigned(CGM.Int32Ty, 1),
65604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
65614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                             DimsAddr.getPointer(), CGM.VoidPtrTy)};
65624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
65634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_init);
65644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitRuntimeCall(RTLFn, Args);
65654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
65664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      emitUpdateLocation(CGF, D.getLocEnd()), getThreadID(CGF, D.getLocEnd())};
65674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *FiniRTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_fini);
65684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EHStack.pushCleanup<DoacrossCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
65694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                             llvm::makeArrayRef(FiniArgs));
65704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
65714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
65724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
65734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                          const OMPDependClause *C) {
65744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  QualType Int64Ty =
65754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
65764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const Expr *CounterVal = C->getCounterValue();
65774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  assert(CounterVal);
65784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *CntVal = CGF.EmitScalarConversion(CGF.EmitScalarExpr(CounterVal),
65794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                 CounterVal->getType(), Int64Ty,
65804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                 CounterVal->getExprLoc());
65814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Address CntAddr = CGF.CreateMemTemp(Int64Ty, ".cnt.addr");
65824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitStoreOfScalar(CntVal, CntAddr, /*Volatile=*/false, Int64Ty);
65834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *Args[] = {emitUpdateLocation(CGF, C->getLocStart()),
65844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         getThreadID(CGF, C->getLocStart()),
65854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         CntAddr.getPointer()};
65864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Value *RTLFn;
65874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (C->getDependencyKind() == OMPC_DEPEND_source)
65884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_post);
65894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  else {
65904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(C->getDependencyKind() == OMPC_DEPEND_sink);
65914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_wait);
65924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
65934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CGF.EmitRuntimeCall(RTLFn, Args);
65944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
65954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
6596