llvm/clang/lib/CodeGen/CGStmtOpenMP.cpp

//===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit OpenMP nodes as LLVM code.
//
//===----------------------------------------------------------------------===//

#include "CGCleanup.h"
#include "CGOpenMPRuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Debug.h"
#include <optional>
usingnamespaceclang;
usingnamespaceCodeGen;
usingnamespacellvm::omp;

#define TTL_CODEGEN_TYPE

static const VarDecl *getBaseDecl(const Expr *Ref);
static OpenMPDirectiveKind
getEffectiveDirectiveKind(const OMPExecutableDirective &S);

namespace {
/// Lexical scope for OpenMP executable constructs, that handles correct codegen
/// for captured expressions.
class OMPLexicalScope : public CodeGenFunction::LexicalScope {};

/// Lexical scope for OpenMP parallel construct, that handles correct codegen
/// for captured expressions.
class OMPParallelScope final : public OMPLexicalScope {};

/// Lexical scope for OpenMP teams construct, that handles correct codegen
/// for captured expressions.
class OMPTeamsScope final : public OMPLexicalScope {};

/// Private scope for OpenMP loop-based directives, that supports capturing
/// of used expression from loop statement.
class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {};

class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope {};

} // namespace

// The loop directive with a bind clause will be mapped to a different
// directive with corresponding semantics.
static OpenMPDirectiveKind
getEffectiveDirectiveKind(const OMPExecutableDirective &S) {}

static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
                                         const OMPExecutableDirective &S,
                                         const RegionCodeGenTy &CodeGen);

LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) {}

llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {}

void CodeGenFunction::GenerateOpenMPCapturedVars(
    const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {}

static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc,
                                    QualType DstType, StringRef Name,
                                    LValue AddrLV) {}

static QualType getCanonicalParamType(ASTContext &C, QualType T) {}

namespace {
/// Contains required data for proper outlined function codegen.
struct FunctionOptions {};
} // namespace

static llvm::Function *emitOutlinedFunctionPrologue(
    CodeGenFunction &CGF, FunctionArgList &Args,
    llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>>
        &LocalAddrs,
    llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
        &VLASizes,
    llvm::Value *&CXXThisValue, const FunctionOptions &FO) {}

llvm::Function *
CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
                                                    SourceLocation Loc) {}

//===----------------------------------------------------------------------===//
//                              OpenMP Directive Emission
//===----------------------------------------------------------------------===//
void CodeGenFunction::EmitOMPAggregateAssign(
    Address DestAddr, Address SrcAddr, QualType OriginalType,
    const llvm::function_ref<void(Address, Address)> CopyGen) {}

void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,
                                  Address SrcAddr, const VarDecl *DestVD,
                                  const VarDecl *SrcVD, const Expr *Copy) {}

bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
                                                OMPPrivateScope &PrivateScope) {}

void CodeGenFunction::EmitOMPPrivateClause(
    const OMPExecutableDirective &D,
    CodeGenFunction::OMPPrivateScope &PrivateScope) {}

bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {}

bool CodeGenFunction::EmitOMPLastprivateClauseInit(
    const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) {}

void CodeGenFunction::EmitOMPLastprivateClauseFinal(
    const OMPExecutableDirective &D, bool NoFinals,
    llvm::Value *IsLastIterCond) {}

void CodeGenFunction::EmitOMPReductionClauseInit(
    const OMPExecutableDirective &D,
    CodeGenFunction::OMPPrivateScope &PrivateScope, bool ForInscan) {}

void CodeGenFunction::EmitOMPReductionClauseFinal(
    const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) {}

static void emitPostUpdateForReductionClause(
    CodeGenFunction &CGF, const OMPExecutableDirective &D,
    const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {}

namespace {
/// Codegen lambda for appending distribute lower and upper bounds to outlined
/// parallel function. This is necessary for combined constructs such as
/// 'distribute parallel for'
CodeGenBoundParametersTy;
} // anonymous namespace

static void
checkForLastprivateConditionalUpdate(CodeGenFunction &CGF,
                                     const OMPExecutableDirective &S) {}

static void emitCommonOMPParallelDirective(
    CodeGenFunction &CGF, const OMPExecutableDirective &S,
    OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
    const CodeGenBoundParametersTy &CodeGenBoundParameters) {}

static bool isAllocatableDecl(const VarDecl *VD) {}

static void emitEmptyBoundParameters(CodeGenFunction &,
                                     const OMPExecutableDirective &,
                                     llvm::SmallVectorImpl<llvm::Value *> &) {}

static void emitOMPCopyinClause(CodeGenFunction &CGF,
                                const OMPExecutableDirective &S) {}

Address CodeGenFunction::OMPBuilderCBHelpers::getAddressOfLocalVariable(
    CodeGenFunction &CGF, const VarDecl *VD) {}

Address CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate(
    CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr,
    SourceLocation Loc) {}

std::string CodeGenFunction::OMPBuilderCBHelpers::getNameWithSeparators(
    ArrayRef<StringRef> Parts, StringRef FirstSeparator, StringRef Separator) {}

void CodeGenFunction::OMPBuilderCBHelpers::EmitOMPInlinedRegionBody(
    CodeGenFunction &CGF, const Stmt *RegionBodyStmt, InsertPointTy AllocaIP,
    InsertPointTy CodeGenIP, Twine RegionName) {}

void CodeGenFunction::OMPBuilderCBHelpers::EmitOMPOutlinedRegionBody(
    CodeGenFunction &CGF, const Stmt *RegionBodyStmt, InsertPointTy AllocaIP,
    InsertPointTy CodeGenIP, Twine RegionName) {}

void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {}

void CodeGenFunction::EmitOMPMetaDirective(const OMPMetaDirective &S) {}

namespace {
/// RAII to handle scopes for loop transformation directives.
class OMPTransformDirectiveScopeRAII {};
} // namespace

static void emitBody(CodeGenFunction &CGF, const Stmt *S, const Stmt *NextLoop,
                     int MaxLevel, int Level = 0) {}

void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
                                      JumpDest LoopExit) {}

EmittedClosureTy;

/// Emit a captured statement and return the function as well as its captured
/// closure context.
static EmittedClosureTy emitCapturedStmtFunc(CodeGenFunction &ParentCGF,
                                             const CapturedStmt *S) {}

/// Emit a call to a previously captured closure.
static llvm::CallInst *
emitCapturedStmtCall(CodeGenFunction &ParentCGF, EmittedClosureTy Cap,
                     llvm::ArrayRef<llvm::Value *> Args) {}

llvm::CanonicalLoopInfo *
CodeGenFunction::EmitOMPCollapsedCanonicalLoopNest(const Stmt *S, int Depth) {}

void CodeGenFunction::EmitOMPCanonicalLoop(const OMPCanonicalLoop *S) {}

void CodeGenFunction::EmitOMPInnerLoop(
    const OMPExecutableDirective &S, bool RequiresCleanup, const Expr *LoopCond,
    const Expr *IncExpr,
    const llvm::function_ref<void(CodeGenFunction &)> BodyGen,
    const llvm::function_ref<void(CodeGenFunction &)> PostIncGen) {}

bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {}

void CodeGenFunction::EmitOMPLinearClauseFinal(
    const OMPLoopDirective &D,
    const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {}

static void emitAlignedClause(CodeGenFunction &CGF,
                              const OMPExecutableDirective &D) {}

void CodeGenFunction::EmitOMPPrivateLoopCounters(
    const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) {}

static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
                        const Expr *Cond, llvm::BasicBlock *TrueBlock,
                        llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {}

void CodeGenFunction::EmitOMPLinearClause(
    const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) {}

static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
                                     const OMPExecutableDirective &D) {}

void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D) {}

void CodeGenFunction::EmitOMPSimdFinal(
    const OMPLoopDirective &D,
    const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {}

static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF,
                                         const OMPLoopDirective &S,
                                         CodeGenFunction::JumpDest LoopExit) {}

/// Emit a helper variable and return corresponding lvalue.
static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
                               const DeclRefExpr *Helper) {}

static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S,
                               const RegionCodeGenTy &SimdInitGen,
                               const RegionCodeGenTy &BodyCodeGen) {}

static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
                              PrePostActionTy &Action) {}

// Pass OMPLoopDirective (instead of OMPSimdDirective) to make this function
// available for "loop bind(thread)", which maps to "simd".
static bool isSimdSupportedByOpenMPIRBuilder(const OMPLoopDirective &S) {}

static llvm::MapVector<llvm::Value *, llvm::Value *>
GetAlignedMapping(const OMPLoopDirective &S, CodeGenFunction &CGF) {}

// Pass OMPLoopDirective (instead of OMPSimdDirective) to make this function
// available for "loop bind(thread)", which maps to "simd".
static void emitOMPSimdDirective(const OMPLoopDirective &S,
                                 CodeGenFunction &CGF, CodeGenModule &CGM) {}

void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {}

void CodeGenFunction::EmitOMPTileDirective(const OMPTileDirective &S) {}

void CodeGenFunction::EmitOMPReverseDirective(const OMPReverseDirective &S) {}

void CodeGenFunction::EmitOMPInterchangeDirective(
    const OMPInterchangeDirective &S) {}

void CodeGenFunction::EmitOMPUnrollDirective(const OMPUnrollDirective &S) {}

void CodeGenFunction::EmitOMPOuterLoop(
    bool DynamicOrOrdered, bool IsMonotonic, const OMPLoopDirective &S,
    CodeGenFunction::OMPPrivateScope &LoopScope,
    const CodeGenFunction::OMPLoopArguments &LoopArgs,
    const CodeGenFunction::CodeGenLoopTy &CodeGenLoop,
    const CodeGenFunction::CodeGenOrderedTy &CodeGenOrdered) {}

void CodeGenFunction::EmitOMPForOuterLoop(
    const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic,
    const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered,
    const OMPLoopArguments &LoopArgs,
    const CodeGenDispatchBoundsTy &CGDispatchBounds) {}

static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc,
                             const unsigned IVSize, const bool IVSigned) {}

void CodeGenFunction::EmitOMPDistributeOuterLoop(
    OpenMPDistScheduleClauseKind ScheduleKind, const OMPLoopDirective &S,
    OMPPrivateScope &LoopScope, const OMPLoopArguments &LoopArgs,
    const CodeGenLoopTy &CodeGenLoopContent) {}

static std::pair<LValue, LValue>
emitDistributeParallelForInnerBounds(CodeGenFunction &CGF,
                                     const OMPExecutableDirective &S) {}

/// if the 'for' loop has a dispatch schedule (e.g. dynamic, guided) then
/// we need to use the LB and UB expressions generated by the worksharing
/// code generation support, whereas in non combined situations we would
/// just emit 0 and the LastIteration expression
/// This function is necessary due to the difference of the LB and UB
/// types for the RT emission routines for 'for_static_init' and
/// 'for_dispatch_init'
static std::pair<llvm::Value *, llvm::Value *>
emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF,
                                        const OMPExecutableDirective &S,
                                        Address LB, Address UB) {}

static void emitDistributeParallelForDistributeInnerBoundParams(
    CodeGenFunction &CGF, const OMPExecutableDirective &S,
    llvm::SmallVectorImpl<llvm::Value *> &CapturedVars) {}

static void
emitInnerParallelForWhenCombined(CodeGenFunction &CGF,
                                 const OMPLoopDirective &S,
                                 CodeGenFunction::JumpDest LoopExit) {}

void CodeGenFunction::EmitOMPDistributeParallelForDirective(
    const OMPDistributeParallelForDirective &S) {}

void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective(
    const OMPDistributeParallelForSimdDirective &S) {}

void CodeGenFunction::EmitOMPDistributeSimdDirective(
    const OMPDistributeSimdDirective &S) {}

void CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S) {}

void CodeGenFunction::EmitOMPTargetSimdDirective(
    const OMPTargetSimdDirective &S) {}

namespace {
struct ScheduleKindModifiersTy {};
} // namespace

bool CodeGenFunction::EmitOMPWorksharingLoop(
    const OMPLoopDirective &S, Expr *EUB,
    const CodeGenLoopBoundsTy &CodeGenLoopBounds,
    const CodeGenDispatchBoundsTy &CGDispatchBounds) {}

/// The following two functions generate expressions for the loop lower
/// and upper bounds in case of static and dynamic (dispatch) schedule
/// of the associated 'for' or 'distribute' loop.
static std::pair<LValue, LValue>
emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S) {}

/// When dealing with dispatch schedules (e.g. dynamic, guided) we do not
/// consider the lower and upper bound expressions generated by the
/// worksharing loop support, but we use 0 and the iteration space size as
/// constants
static std::pair<llvm::Value *, llvm::Value *>
emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S,
                          Address LB, Address UB) {}

/// Emits internal temp array declarations for the directive with inscan
/// reductions.
/// The code is the following:
/// \code
/// size num_iters = <num_iters>;
/// <type> buffer[num_iters];
/// \endcode
static void emitScanBasedDirectiveDecls(
    CodeGenFunction &CGF, const OMPLoopDirective &S,
    llvm::function_ref<llvm::Value *(CodeGenFunction &)> NumIteratorsGen) {}

/// Copies final inscan reductions values to the original variables.
/// The code is the following:
/// \code
/// <orig_var> = buffer[num_iters-1];
/// \endcode
static void emitScanBasedDirectiveFinals(
    CodeGenFunction &CGF, const OMPLoopDirective &S,
    llvm::function_ref<llvm::Value *(CodeGenFunction &)> NumIteratorsGen) {}

/// Emits the code for the directive with inscan reductions.
/// The code is the following:
/// \code
/// #pragma omp ...
/// for (i: 0..<num_iters>) {
///   <input phase>;
///   buffer[i] = red;
/// }
/// #pragma omp master // in parallel region
/// for (int k = 0; k != ceil(log2(num_iters)); ++k)
/// for (size cnt = last_iter; cnt >= pow(2, k); --k)
///   buffer[i] op= buffer[i-pow(2,k)];
/// #pragma omp barrier // in parallel region
/// #pragma omp ...
/// for (0..<num_iters>) {
///   red = InclusiveScan ? buffer[i] : buffer[i-1];
///   <scan phase>;
/// }
/// \endcode
static void emitScanBasedDirective(
    CodeGenFunction &CGF, const OMPLoopDirective &S,
    llvm::function_ref<llvm::Value *(CodeGenFunction &)> NumIteratorsGen,
    llvm::function_ref<void(CodeGenFunction &)> FirstGen,
    llvm::function_ref<void(CodeGenFunction &)> SecondGen) {}

static bool emitWorksharingDirective(CodeGenFunction &CGF,
                                     const OMPLoopDirective &S,
                                     bool HasCancel) {}

// Pass OMPLoopDirective (instead of OMPForDirective) to make this check
// available for "loop bind(parallel)", which maps to "for".
static bool isForSupportedByOpenMPIRBuilder(const OMPLoopDirective &S,
                                            bool HasCancel) {}

static llvm::omp::ScheduleKind
convertClauseKindToSchedKind(OpenMPScheduleClauseKind ScheduleClauseKind) {}

// Pass OMPLoopDirective (instead of OMPForDirective) to make this function
// available for "loop bind(parallel)", which maps to "for".
static void emitOMPForDirective(const OMPLoopDirective &S, CodeGenFunction &CGF,
                                CodeGenModule &CGM, bool HasCancel) {}

void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {}

void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {}

static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
                                const Twine &Name,
                                llvm::Value *Init = nullptr) {}

void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {}

void CodeGenFunction::EmitOMPScopeDirective(const OMPScopeDirective &S) {}

void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {}

void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {}

void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {}

static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S) {}

void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {}

static void emitMasked(CodeGenFunction &CGF, const OMPExecutableDirective &S) {}

void CodeGenFunction::EmitOMPMaskedDirective(const OMPMaskedDirective &S) {}

void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {}

void CodeGenFunction::EmitOMPParallelForDirective(
    const OMPParallelForDirective &S) {}

void CodeGenFunction::EmitOMPParallelForSimdDirective(
    const OMPParallelForSimdDirective &S) {}

void CodeGenFunction::EmitOMPParallelMasterDirective(
    const OMPParallelMasterDirective &S) {}

void CodeGenFunction::EmitOMPParallelMaskedDirective(
    const OMPParallelMaskedDirective &S) {}

void CodeGenFunction::EmitOMPParallelSectionsDirective(
    const OMPParallelSectionsDirective &S) {}

namespace {
/// Get the list of variables declared in the context of the untied tasks.
class CheckVarsEscapingUntiedTaskDeclContext final
    : public ConstStmtVisitor<CheckVarsEscapingUntiedTaskDeclContext> {};
} // anonymous namespace

static void buildDependences(const OMPExecutableDirective &S,
                             OMPTaskDataTy &Data) {}

void CodeGenFunction::EmitOMPTaskBasedDirective(
    const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion,
    const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen,
    OMPTaskDataTy &Data) {}

static ImplicitParamDecl *
createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data,
                                  QualType Ty, CapturedDecl *CD,
                                  SourceLocation Loc) {}

void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
    const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen,
    OMPTargetDataInfo &InputInfo) {}

void CodeGenFunction::processInReduction(const OMPExecutableDirective &S,
                                         OMPTaskDataTy &Data,
                                         CodeGenFunction &CGF,
                                         const CapturedStmt *CS,
                                         OMPPrivateScope &Scope) {}

void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {}

void CodeGenFunction::EmitOMPTaskyieldDirective(
    const OMPTaskyieldDirective &S) {}

void CodeGenFunction::EmitOMPErrorDirective(const OMPErrorDirective &S) {}

void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {}

void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {}

static bool isSupportedByOpenMPIRBuilder(const OMPTaskgroupDirective &T) {}

void CodeGenFunction::EmitOMPTaskgroupDirective(
    const OMPTaskgroupDirective &S) {}

void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {}

void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) {}

void CodeGenFunction::EmitOMPScanDirective(const OMPScanDirective &S) {}

void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
                                            const CodeGenLoopTy &CodeGenLoop,
                                            Expr *IncExpr) {}

// Pass OMPLoopDirective (instead of OMPDistributeDirective) to make this
// function available for "loop bind(teams)", which maps to "distribute".
static void emitOMPDistributeDirective(const OMPLoopDirective &S,
                                       CodeGenFunction &CGF,
                                       CodeGenModule &CGM) {}

void CodeGenFunction::EmitOMPDistributeDirective(
    const OMPDistributeDirective &S) {}

static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
                                                   const CapturedStmt *S,
                                                   SourceLocation Loc) {}

template <typename T>
static void emitRestoreIP(CodeGenFunction &CGF, const T *C,
                          llvm::OpenMPIRBuilder::InsertPointTy AllocaIP,
                          llvm::OpenMPIRBuilder &OMPBuilder) {}

void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {}

static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
                                         QualType SrcType, QualType DestType,
                                         SourceLocation Loc) {}

static CodeGenFunction::ComplexPairTy
convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
                      QualType DestType, SourceLocation Loc) {}

static void emitSimpleAtomicStore(CodeGenFunction &CGF, llvm::AtomicOrdering AO,
                                  LValue LVal, RValue RVal) {}

static RValue emitSimpleAtomicLoad(CodeGenFunction &CGF,
                                   llvm::AtomicOrdering AO, LValue LVal,
                                   SourceLocation Loc) {}

void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal,
                                         QualType RValTy, SourceLocation Loc) {}

static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO,
                                  const Expr *X, const Expr *V,
                                  SourceLocation Loc) {}

static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF,
                                   llvm::AtomicOrdering AO, const Expr *X,
                                   const Expr *E, SourceLocation Loc) {}

static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
                                                RValue Update,
                                                BinaryOperatorKind BO,
                                                llvm::AtomicOrdering AO,
                                                bool IsXLHSInRHSPart) {}

std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr(
    LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
    llvm::AtomicOrdering AO, SourceLocation Loc,
    const llvm::function_ref<RValue(RValue)> CommonGen) {}

static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF,
                                    llvm::AtomicOrdering AO, const Expr *X,
                                    const Expr *E, const Expr *UE,
                                    bool IsXLHSInRHSPart, SourceLocation Loc) {}

static RValue convertToType(CodeGenFunction &CGF, RValue Value,
                            QualType SourceType, QualType ResType,
                            SourceLocation Loc) {}

static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF,
                                     llvm::AtomicOrdering AO,
                                     bool IsPostfixUpdate, const Expr *V,
                                     const Expr *X, const Expr *E,
                                     const Expr *UE, bool IsXLHSInRHSPart,
                                     SourceLocation Loc) {}

static void emitOMPAtomicCompareExpr(
    CodeGenFunction &CGF, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO,
    const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *D,
    const Expr *CE, bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly,
    SourceLocation Loc) {}

static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
                              llvm::AtomicOrdering AO,
                              llvm::AtomicOrdering FailAO, bool IsPostfixUpdate,
                              const Expr *X, const Expr *V, const Expr *R,
                              const Expr *E, const Expr *UE, const Expr *D,
                              const Expr *CE, bool IsXLHSInRHSPart,
                              bool IsFailOnly, SourceLocation Loc) {}

void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {}

static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
                                         const OMPExecutableDirective &S,
                                         const RegionCodeGenTy &CodeGen) {}

static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S,
                             PrePostActionTy &Action) {}

void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
                                                  StringRef ParentName,
                                                  const OMPTargetDirective &S) {}

void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {}

static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
                                        const OMPExecutableDirective &S,
                                        OpenMPDirectiveKind InnermostKind,
                                        const RegionCodeGenTy &CodeGen) {}

void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {}

static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
                                  const OMPTargetTeamsDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetTeamsDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsDirective(
    const OMPTargetTeamsDirective &S) {}

static void
emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
                                const OMPTargetTeamsDistributeDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetTeamsDistributeDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective(
    const OMPTargetTeamsDistributeDirective &S) {}

static void emitTargetTeamsDistributeSimdRegion(
    CodeGenFunction &CGF, PrePostActionTy &Action,
    const OMPTargetTeamsDistributeSimdDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetTeamsDistributeSimdDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
    const OMPTargetTeamsDistributeSimdDirective &S) {}

void CodeGenFunction::EmitOMPTeamsDistributeDirective(
    const OMPTeamsDistributeDirective &S) {}

void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective(
    const OMPTeamsDistributeSimdDirective &S) {}

void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective(
    const OMPTeamsDistributeParallelForDirective &S) {}

void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective(
    const OMPTeamsDistributeParallelForSimdDirective &S) {}

void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) {}

static void emitTargetTeamsDistributeParallelForRegion(
    CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S,
    PrePostActionTy &Action) {}

void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetTeamsDistributeParallelForDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective(
    const OMPTargetTeamsDistributeParallelForDirective &S) {}

static void emitTargetTeamsDistributeParallelForSimdRegion(
    CodeGenFunction &CGF,
    const OMPTargetTeamsDistributeParallelForSimdDirective &S,
    PrePostActionTy &Action) {}

void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetTeamsDistributeParallelForSimdDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
    const OMPTargetTeamsDistributeParallelForSimdDirective &S) {}

void CodeGenFunction::EmitOMPCancellationPointDirective(
    const OMPCancellationPointDirective &S) {}

void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {}

CodeGenFunction::JumpDest
CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {}

void CodeGenFunction::EmitOMPUseDevicePtrClause(
    const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope,
    const llvm::DenseMap<const ValueDecl *, llvm::Value *>
        CaptureDeviceAddrMap) {}

static const VarDecl *getBaseDecl(const Expr *Ref) {}

void CodeGenFunction::EmitOMPUseDeviceAddrClause(
    const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope,
    const llvm::DenseMap<const ValueDecl *, llvm::Value *>
        CaptureDeviceAddrMap) {}

// Generate the instructions for '#pragma omp target data' directive.
void CodeGenFunction::EmitOMPTargetDataDirective(
    const OMPTargetDataDirective &S) {}

void CodeGenFunction::EmitOMPTargetEnterDataDirective(
    const OMPTargetEnterDataDirective &S) {}

void CodeGenFunction::EmitOMPTargetExitDataDirective(
    const OMPTargetExitDataDirective &S) {}

static void emitTargetParallelRegion(CodeGenFunction &CGF,
                                     const OMPTargetParallelDirective &S,
                                     PrePostActionTy &Action) {}

void CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetParallelDirective &S) {}

void CodeGenFunction::EmitOMPTargetParallelDirective(
    const OMPTargetParallelDirective &S) {}

static void emitTargetParallelForRegion(CodeGenFunction &CGF,
                                        const OMPTargetParallelForDirective &S,
                                        PrePostActionTy &Action) {}

void CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetParallelForDirective &S) {}

void CodeGenFunction::EmitOMPTargetParallelForDirective(
    const OMPTargetParallelForDirective &S) {}

static void
emitTargetParallelForSimdRegion(CodeGenFunction &CGF,
                                const OMPTargetParallelForSimdDirective &S,
                                PrePostActionTy &Action) {}

void CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetParallelForSimdDirective &S) {}

void CodeGenFunction::EmitOMPTargetParallelForSimdDirective(
    const OMPTargetParallelForSimdDirective &S) {}

/// Emit a helper variable and return corresponding lvalue.
static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper,
                     const ImplicitParamDecl *PVD,
                     CodeGenFunction::OMPPrivateScope &Privates) {}

void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {}

void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {}

void CodeGenFunction::EmitOMPTaskLoopSimdDirective(
    const OMPTaskLoopSimdDirective &S) {}

void CodeGenFunction::EmitOMPMasterTaskLoopDirective(
    const OMPMasterTaskLoopDirective &S) {}

void CodeGenFunction::EmitOMPMasterTaskLoopSimdDirective(
    const OMPMasterTaskLoopSimdDirective &S) {}

void CodeGenFunction::EmitOMPParallelMasterTaskLoopDirective(
    const OMPParallelMasterTaskLoopDirective &S) {}

void CodeGenFunction::EmitOMPParallelMasterTaskLoopSimdDirective(
    const OMPParallelMasterTaskLoopSimdDirective &S) {}

// Generate the instructions for '#pragma omp target update' directive.
void CodeGenFunction::EmitOMPTargetUpdateDirective(
    const OMPTargetUpdateDirective &S) {}

void CodeGenFunction::EmitOMPGenericLoopDirective(
    const OMPGenericLoopDirective &S) {}

void CodeGenFunction::EmitOMPParallelGenericLoopDirective(
    const OMPLoopDirective &S) {}

void CodeGenFunction::EmitOMPTeamsGenericLoopDirective(
    const OMPTeamsGenericLoopDirective &S) {}

#ifndef NDEBUG
static void emitTargetTeamsLoopCodegenStatus(CodeGenFunction &CGF,
                                             std::string StatusMsg,
                                             const OMPExecutableDirective &D) {
  bool IsDevice = CGF.CGM.getLangOpts().OpenMPIsTargetDevice;
  if (IsDevice)
    StatusMsg += ": DEVICE";
  else
    StatusMsg += ": HOST";
  SourceLocation L = D.getBeginLoc();
  auto &SM = CGF.getContext().getSourceManager();
  PresumedLoc PLoc = SM.getPresumedLoc(L);
  const char *FileName = PLoc.isValid() ? PLoc.getFilename() : nullptr;
  unsigned LineNo =
      PLoc.isValid() ? PLoc.getLine() : SM.getExpansionLineNumber(L);
  llvm::dbgs() << StatusMsg << ": " << FileName << ": " << LineNo << "\n";
}
#endif

static void emitTargetTeamsGenericLoopRegionAsParallel(
    CodeGenFunction &CGF, PrePostActionTy &Action,
    const OMPTargetTeamsGenericLoopDirective &S) {}

static void emitTargetTeamsGenericLoopRegionAsDistribute(
    CodeGenFunction &CGF, PrePostActionTy &Action,
    const OMPTargetTeamsGenericLoopDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsGenericLoopDirective(
    const OMPTargetTeamsGenericLoopDirective &S) {}

void CodeGenFunction::EmitOMPTargetTeamsGenericLoopDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetTeamsGenericLoopDirective &S) {}

static void emitTargetParallelGenericLoopRegion(
    CodeGenFunction &CGF, const OMPTargetParallelGenericLoopDirective &S,
    PrePostActionTy &Action) {}

void CodeGenFunction::EmitOMPTargetParallelGenericLoopDeviceFunction(
    CodeGenModule &CGM, StringRef ParentName,
    const OMPTargetParallelGenericLoopDirective &S) {}

/// Emit combined directive 'target parallel loop' as if its constituent
/// constructs are 'target', 'parallel', and 'for'.
void CodeGenFunction::EmitOMPTargetParallelGenericLoopDirective(
    const OMPTargetParallelGenericLoopDirective &S) {}

void CodeGenFunction::EmitSimpleOMPExecutableDirective(
    const OMPExecutableDirective &D) {}

void CodeGenFunction::EmitOMPAssumeDirective(const OMPAssumeDirective &S) {}