Revert "[OPENMP] Allow runtime insert its own code inside OpenMP regions."

Reverting because of failed tests.

llvm-svn: 264577
This commit is contained in:
Alexey Bataev 2016-03-28 12:58:34 +00:00
parent 424be92831
commit f539faa733
10 changed files with 505 additions and 600 deletions

File diff suppressed because it is too large Load Diff

View File

@ -46,44 +46,7 @@ class Address;
class CodeGenFunction; class CodeGenFunction;
class CodeGenModule; class CodeGenModule;
/// A basic class for pre|post-action for advanced codegen sequence for OpenMP typedef llvm::function_ref<void(CodeGenFunction &)> RegionCodeGenTy;
/// region.
class PrePostActionTy {
public:
explicit PrePostActionTy() {}
virtual void Enter(CodeGenFunction &CGF) {}
virtual void Exit(CodeGenFunction &CGF) {}
virtual ~PrePostActionTy() {}
};
/// Class provides a way to call simple version of codegen for OpenMP region, or
/// an advanced with possible pre|post-actions in codegen.
class RegionCodeGenTy final {
intptr_t CodeGen;
typedef void (*CodeGenTy)(intptr_t, CodeGenFunction &, PrePostActionTy &);
CodeGenTy Callback;
mutable PrePostActionTy *PrePostAction;
RegionCodeGenTy() = delete;
RegionCodeGenTy &operator=(const RegionCodeGenTy &) = delete;
template <typename Callable>
static void CallbackFn(intptr_t CodeGen, CodeGenFunction &CGF,
PrePostActionTy &Action) {
return (*reinterpret_cast<Callable *>(CodeGen))(CGF, Action);
}
public:
template <typename Callable>
RegionCodeGenTy(
Callable &&CodeGen,
typename std::enable_if<
!std::is_same<typename std::remove_reference<Callable>::type,
RegionCodeGenTy>::value>::type * = nullptr)
: CodeGen(reinterpret_cast<intptr_t>(&CodeGen)),
Callback(CallbackFn<typename std::remove_reference<Callable>::type>),
PrePostAction(nullptr) {}
void setAction(PrePostActionTy &Action) const { PrePostAction = &Action; }
void operator()(CodeGenFunction &CGF) const;
};
class CGOpenMPRuntime { class CGOpenMPRuntime {
protected: protected:
@ -119,14 +82,14 @@ private:
OpenMPDefaultLocMapTy OpenMPDefaultLocMap; OpenMPDefaultLocMapTy OpenMPDefaultLocMap;
Address getOrCreateDefaultLocation(unsigned Flags); Address getOrCreateDefaultLocation(unsigned Flags);
llvm::StructType *IdentTy = nullptr; llvm::StructType *IdentTy;
/// \brief Map for SourceLocation and OpenMP runtime library debug locations. /// \brief Map for SourceLocation and OpenMP runtime library debug locations.
typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy; typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy;
OpenMPDebugLocMapTy OpenMPDebugLocMap; OpenMPDebugLocMapTy OpenMPDebugLocMap;
/// \brief The type for a microtask which gets passed to __kmpc_fork_call(). /// \brief The type for a microtask which gets passed to __kmpc_fork_call().
/// Original representation is: /// Original representation is:
/// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...); /// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...);
llvm::FunctionType *Kmpc_MicroTy = nullptr; llvm::FunctionType *Kmpc_MicroTy;
/// \brief Stores debug location and ThreadID for the function. /// \brief Stores debug location and ThreadID for the function.
struct DebugLocThreadIdTy { struct DebugLocThreadIdTy {
llvm::Value *DebugLoc; llvm::Value *DebugLoc;
@ -847,15 +810,13 @@ public:
/// \param OutlinedFn Outlined function value to be defined by this call. /// \param OutlinedFn Outlined function value to be defined by this call.
/// \param OutlinedFnID Outlined function ID value to be defined by this call. /// \param OutlinedFnID Outlined function ID value to be defined by this call.
/// \param IsOffloadEntry True if the outlined function is an offload entry. /// \param IsOffloadEntry True if the outlined function is an offload entry.
/// \param CodeGen Code generation sequence for the \a D directive.
/// An oulined function may not be an entry if, e.g. the if clause always /// An oulined function may not be an entry if, e.g. the if clause always
/// evaluates to false. /// evaluates to false.
virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D, virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
StringRef ParentName, StringRef ParentName,
llvm::Function *&OutlinedFn, llvm::Function *&OutlinedFn,
llvm::Constant *&OutlinedFnID, llvm::Constant *&OutlinedFnID,
bool IsOffloadEntry, bool IsOffloadEntry);
const RegionCodeGenTy &CodeGen);
/// \brief Emit the target offloading code associated with \a D. The emitted /// \brief Emit the target offloading code associated with \a D. The emitted
/// code attempts offloading the execution to the device, an the event of /// code attempts offloading the execution to the device, an the event of

View File

@ -305,32 +305,28 @@ void CGOpenMPRuntimeNVPTX::createOffloadEntry(llvm::Constant *ID,
void CGOpenMPRuntimeNVPTX::emitTargetOutlinedFunction( void CGOpenMPRuntimeNVPTX::emitTargetOutlinedFunction(
const OMPExecutableDirective &D, StringRef ParentName, const OMPExecutableDirective &D, StringRef ParentName,
llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) { bool IsOffloadEntry) {
if (!IsOffloadEntry) // Nothing to do. if (!IsOffloadEntry) // Nothing to do.
return; return;
assert(!ParentName.empty() && "Invalid target region parent name!"); assert(!ParentName.empty() && "Invalid target region parent name!");
const CapturedStmt &CS = *cast<CapturedStmt>(D.getAssociatedStmt());
EntryFunctionState EST; EntryFunctionState EST;
WorkerFunctionState WST(CGM); WorkerFunctionState WST(CGM);
// Emit target region as a standalone region. // Emit target region as a standalone region.
class NVPTXPrePostActionTy : public PrePostActionTy { auto &&CodeGen = [&EST, &WST, &CS, &D, this](CodeGenFunction &CGF) {
CGOpenMPRuntimeNVPTX &RT; CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
CGOpenMPRuntimeNVPTX::EntryFunctionState &EST; (void)CGF.EmitOMPFirstprivateClause(D, PrivateScope);
CGOpenMPRuntimeNVPTX::WorkerFunctionState &WST; CGF.EmitOMPPrivateClause(D, PrivateScope);
(void)PrivateScope.Privatize();
public: emitEntryHeader(CGF, EST, WST);
NVPTXPrePostActionTy(CGOpenMPRuntimeNVPTX &RT, CGF.EmitStmt(CS.getCapturedStmt());
CGOpenMPRuntimeNVPTX::EntryFunctionState &EST, emitEntryFooter(CGF, EST);
CGOpenMPRuntimeNVPTX::WorkerFunctionState &WST) };
: RT(RT), EST(EST), WST(WST) {}
void Enter(CodeGenFunction &CGF) override {
RT.emitEntryHeader(CGF, EST, WST);
}
void Exit(CodeGenFunction &CGF) override { RT.emitEntryFooter(CGF, EST); }
} Action(*this, EST, WST);
CodeGen.setAction(Action);
emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID, emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
IsOffloadEntry, CodeGen); IsOffloadEntry, CodeGen);

View File

@ -24,34 +24,6 @@ namespace clang {
namespace CodeGen { namespace CodeGen {
class CGOpenMPRuntimeNVPTX : public CGOpenMPRuntime { class CGOpenMPRuntimeNVPTX : public CGOpenMPRuntime {
public:
class EntryFunctionState {
public:
llvm::BasicBlock *ExitBB;
EntryFunctionState() : ExitBB(nullptr){};
};
class WorkerFunctionState {
public:
llvm::Function *WorkerFn;
const CGFunctionInfo *CGFI;
WorkerFunctionState(CodeGenModule &CGM);
private:
void createWorkerFunction(CodeGenModule &CGM);
};
/// \brief Helper for target entry function. Guide the master and worker
/// threads to their respective locations.
void emitEntryHeader(CodeGenFunction &CGF, EntryFunctionState &EST,
WorkerFunctionState &WST);
/// \brief Signal termination of OMP execution.
void emitEntryFooter(CodeGenFunction &CGF, EntryFunctionState &EST);
private:
// //
// NVPTX calls. // NVPTX calls.
// //
@ -94,6 +66,24 @@ private:
// Outlined function for the workers to execute. // Outlined function for the workers to execute.
llvm::GlobalVariable *WorkID; llvm::GlobalVariable *WorkID;
class EntryFunctionState {
public:
llvm::BasicBlock *ExitBB;
EntryFunctionState() : ExitBB(nullptr){};
};
class WorkerFunctionState {
public:
llvm::Function *WorkerFn;
const CGFunctionInfo *CGFI;
WorkerFunctionState(CodeGenModule &CGM);
private:
void createWorkerFunction(CodeGenModule &CGM);
};
/// \brief Initialize master-worker control state. /// \brief Initialize master-worker control state.
void initializeEnvironment(); void initializeEnvironment();
@ -103,6 +93,14 @@ private:
/// \brief Helper for worker function. Emit body of worker loop. /// \brief Helper for worker function. Emit body of worker loop.
void emitWorkerLoop(CodeGenFunction &CGF, WorkerFunctionState &WST); void emitWorkerLoop(CodeGenFunction &CGF, WorkerFunctionState &WST);
/// \brief Helper for target entry function. Guide the master and worker
/// threads to their respective locations.
void emitEntryHeader(CodeGenFunction &CGF, EntryFunctionState &EST,
WorkerFunctionState &WST);
/// \brief Signal termination of OMP execution.
void emitEntryFooter(CodeGenFunction &CGF, EntryFunctionState &EST);
/// \brief Returns specified OpenMP runtime function for the current OpenMP /// \brief Returns specified OpenMP runtime function for the current OpenMP
/// implementation. Specialized for the NVPTX device. /// implementation. Specialized for the NVPTX device.
/// \param Function OpenMP runtime function. /// \param Function OpenMP runtime function.
@ -131,8 +129,7 @@ private:
StringRef ParentName, StringRef ParentName,
llvm::Function *&OutlinedFn, llvm::Function *&OutlinedFn,
llvm::Constant *&OutlinedFnID, llvm::Constant *&OutlinedFnID,
bool IsOffloadEntry, bool IsOffloadEntry) override;
const RegionCodeGenTy &CodeGen) override;
public: public:
explicit CGOpenMPRuntimeNVPTX(CodeGenModule &CGM); explicit CGOpenMPRuntimeNVPTX(CodeGenModule &CGM);

View File

@ -26,7 +26,8 @@ using namespace CodeGen;
namespace { namespace {
/// Lexical scope for OpenMP executable constructs, that handles correct codegen /// Lexical scope for OpenMP executable constructs, that handles correct codegen
/// for captured expressions. /// for captured expressions.
class OMPLexicalScope : public CodeGenFunction::LexicalScope { class OMPLexicalScope {
CodeGenFunction::LexicalScope Scope;
void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) { void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
for (const auto *C : S.clauses()) { for (const auto *C : S.clauses()) {
if (auto *CPI = OMPClauseWithPreInit::get(C)) { if (auto *CPI = OMPClauseWithPreInit::get(C)) {
@ -47,11 +48,10 @@ class OMPLexicalScope : public CodeGenFunction::LexicalScope {
public: public:
OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
: CodeGenFunction::LexicalScope(CGF, S.getSourceRange()) { : Scope(CGF, S.getSourceRange()) {
emitPreInitStmt(CGF, S); emitPreInitStmt(CGF, S);
} }
}; };
} // namespace } // namespace
llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) { llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
@ -1097,6 +1097,8 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
OpenMPDirectiveKind InnermostKind, OpenMPDirectiveKind InnermostKind,
const RegionCodeGenTy &CodeGen) { const RegionCodeGenTy &CodeGen) {
auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
llvm::SmallVector<llvm::Value *, 16> CapturedVars;
CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
auto OutlinedFn = CGF.CGM.getOpenMPRuntime(). auto OutlinedFn = CGF.CGM.getOpenMPRuntime().
emitParallelOrTeamsOutlinedFunction(S, emitParallelOrTeamsOutlinedFunction(S,
*CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
@ -1108,7 +1110,7 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
CGF, NumThreads, NumThreadsClause->getLocStart()); CGF, NumThreads, NumThreadsClause->getLocStart());
} }
if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) { if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) {
CodeGenFunction::RunCleanupsScope ProcBindScope(CGF); CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
CGF.CGM.getOpenMPRuntime().emitProcBindClause( CGF.CGM.getOpenMPRuntime().emitProcBindClause(
CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart()); CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart());
} }
@ -1120,17 +1122,14 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
break; break;
} }
} }
OMPLexicalScope Scope(CGF, S);
llvm::SmallVector<llvm::Value *, 16> CapturedVars;
CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn, CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn,
CapturedVars, IfCond); CapturedVars, IfCond);
} }
void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
OMPLexicalScope Scope(*this, S);
// Emit parallel region as a standalone region. // Emit parallel region as a standalone region.
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { auto &&CodeGen = [&S](CodeGenFunction &CGF) {
OMPPrivateScope PrivateScope(CGF); OMPPrivateScope PrivateScope(CGF);
bool Copyins = CGF.EmitOMPCopyinClause(S); bool Copyins = CGF.EmitOMPCopyinClause(S);
(void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
@ -1466,7 +1465,7 @@ void CodeGenFunction::EmitOMPSimdFinal(
} }
void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { auto &&CodeGen = [&S](CodeGenFunction &CGF) {
// if (PreCond) { // if (PreCond) {
// for (IV in 0..LastIteration) BODY; // for (IV in 0..LastIteration) BODY;
// <Final counter/linear vars updates>; // <Final counter/linear vars updates>;
@ -1509,6 +1508,7 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
emitAlignedClause(CGF, S); emitAlignedClause(CGF, S);
CGF.EmitOMPLinearClauseInit(S); CGF.EmitOMPLinearClauseInit(S);
bool HasLastprivateClause;
{ {
OMPPrivateScope LoopScope(CGF); OMPPrivateScope LoopScope(CGF);
emitPrivateLoopCounters(CGF, LoopScope, S.counters(), emitPrivateLoopCounters(CGF, LoopScope, S.counters(),
@ -1516,7 +1516,7 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
emitPrivateLinearVars(CGF, S, LoopScope); emitPrivateLinearVars(CGF, S, LoopScope);
CGF.EmitOMPPrivateClause(S, LoopScope); CGF.EmitOMPPrivateClause(S, LoopScope);
CGF.EmitOMPReductionClauseInit(S, LoopScope); CGF.EmitOMPReductionClauseInit(S, LoopScope);
bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
(void)LoopScope.Privatize(); (void)LoopScope.Privatize();
CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
S.getInc(), S.getInc(),
@ -1526,8 +1526,9 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
}, },
[](CodeGenFunction &) {}); [](CodeGenFunction &) {});
// Emit final copy of the lastprivate variables at the end of loops. // Emit final copy of the lastprivate variables at the end of loops.
if (HasLastprivateClause) if (HasLastprivateClause) {
CGF.EmitOMPLastprivateClauseFinal(S); CGF.EmitOMPLastprivateClauseFinal(S);
}
CGF.EmitOMPReductionClauseFinal(S); CGF.EmitOMPReductionClauseFinal(S);
emitPostUpdateForReductionClause( emitPostUpdateForReductionClause(
CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
@ -1542,7 +1543,6 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
CGF.EmitBlock(ContBlock, true); CGF.EmitBlock(ContBlock, true);
} }
}; };
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
} }
@ -1928,12 +1928,11 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
bool HasLastprivates = false; bool HasLastprivates = false;
auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
PrePostActionTy &) {
HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
};
{ {
OMPLexicalScope Scope(*this, S); OMPLexicalScope Scope(*this, S);
auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) {
HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
};
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
S.hasCancel()); S.hasCancel());
} }
@ -1946,12 +1945,11 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {
bool HasLastprivates = false; bool HasLastprivates = false;
auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
PrePostActionTy &) {
HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
};
{ {
OMPLexicalScope Scope(*this, S); OMPLexicalScope Scope(*this, S);
auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) {
HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
};
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
} }
@ -1974,8 +1972,7 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt(); auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
auto *CS = dyn_cast<CompoundStmt>(Stmt); auto *CS = dyn_cast<CompoundStmt>(Stmt);
bool HasLastprivates = false; bool HasLastprivates = false;
auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF, auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF) {
PrePostActionTy &) {
auto &C = CGF.CGM.getContext(); auto &C = CGF.CGM.getContext();
auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
// Emit helper vars inits. // Emit helper vars inits.
@ -2115,10 +2112,10 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
} }
void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) { void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { OMPLexicalScope Scope(*this, S);
auto &&CodeGen = [&S](CodeGenFunction &CGF) {
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
}; };
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen, CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen,
S.hasCancel()); S.hasCancel());
} }
@ -2140,17 +2137,17 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
AssignmentOps.append(C->assignment_ops().begin(), AssignmentOps.append(C->assignment_ops().begin(),
C->assignment_ops().end()); C->assignment_ops().end());
} }
// Emit code for 'single' region along with 'copyprivate' clauses
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
Action.Enter(CGF);
OMPPrivateScope SingleScope(CGF);
(void)CGF.EmitOMPFirstprivateClause(S, SingleScope);
CGF.EmitOMPPrivateClause(S, SingleScope);
(void)SingleScope.Privatize();
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
};
{ {
OMPLexicalScope Scope(*this, S); OMPLexicalScope Scope(*this, S);
// Emit code for 'single' region along with 'copyprivate' clauses
auto &&CodeGen = [&S](CodeGenFunction &CGF) {
CodeGenFunction::OMPPrivateScope SingleScope(CGF);
(void)CGF.EmitOMPFirstprivateClause(S, SingleScope);
CGF.EmitOMPPrivateClause(S, SingleScope);
(void)SingleScope.Privatize();
CGF.EmitStmt(
cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
};
CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(), CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
CopyprivateVars, DestExprs, CopyprivateVars, DestExprs,
SrcExprs, AssignmentOps); SrcExprs, AssignmentOps);
@ -2165,23 +2162,21 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
} }
void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { OMPLexicalScope Scope(*this, S);
Action.Enter(CGF); auto &&CodeGen = [&S](CodeGenFunction &CGF) {
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
}; };
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getLocStart()); CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getLocStart());
} }
void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { OMPLexicalScope Scope(*this, S);
Action.Enter(CGF); auto &&CodeGen = [&S](CodeGenFunction &CGF) {
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
}; };
Expr *Hint = nullptr; Expr *Hint = nullptr;
if (auto *HintClause = S.getSingleClause<OMPHintClause>()) if (auto *HintClause = S.getSingleClause<OMPHintClause>())
Hint = HintClause->getHint(); Hint = HintClause->getHint();
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitCriticalRegion(*this, CGM.getOpenMPRuntime().emitCriticalRegion(*this,
S.getDirectiveName().getAsString(), S.getDirectiveName().getAsString(),
CodeGen, S.getLocStart(), Hint); CodeGen, S.getLocStart(), Hint);
@ -2191,7 +2186,8 @@ void CodeGenFunction::EmitOMPParallelForDirective(
const OMPParallelForDirective &S) { const OMPParallelForDirective &S) {
// Emit directive as a combined directive that consists of two implicit // Emit directive as a combined directive that consists of two implicit
// directives: 'parallel' with 'for' directive. // directives: 'parallel' with 'for' directive.
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { OMPLexicalScope Scope(*this, S);
auto &&CodeGen = [&S](CodeGenFunction &CGF) {
CGF.EmitOMPWorksharingLoop(S); CGF.EmitOMPWorksharingLoop(S);
}; };
emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen); emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen);
@ -2201,7 +2197,8 @@ void CodeGenFunction::EmitOMPParallelForSimdDirective(
const OMPParallelForSimdDirective &S) { const OMPParallelForSimdDirective &S) {
// Emit directive as a combined directive that consists of two implicit // Emit directive as a combined directive that consists of two implicit
// directives: 'parallel' with 'for' directive. // directives: 'parallel' with 'for' directive.
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { OMPLexicalScope Scope(*this, S);
auto &&CodeGen = [&S](CodeGenFunction &CGF) {
CGF.EmitOMPWorksharingLoop(S); CGF.EmitOMPWorksharingLoop(S);
}; };
emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen); emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen);
@ -2211,14 +2208,14 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective(
const OMPParallelSectionsDirective &S) { const OMPParallelSectionsDirective &S) {
// Emit directive as a combined directive that consists of two implicit // Emit directive as a combined directive that consists of two implicit
// directives: 'parallel' with 'sections' directive. // directives: 'parallel' with 'sections' directive.
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { OMPLexicalScope Scope(*this, S);
CGF.EmitSections(S); auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.EmitSections(S); };
};
emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen); emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen);
} }
void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
// Emit outlined function for task construct. // Emit outlined function for task construct.
OMPLexicalScope Scope(*this, S);
auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
auto CapturedStruct = GenerateCapturedStmtArgument(*CS); auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
auto *I = CS->getCapturedDecl()->param_begin(); auto *I = CS->getCapturedDecl()->param_begin();
@ -2268,47 +2265,46 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
} }
} }
auto &&CodeGen = [PartId, &S, &PrivateVars, &FirstprivateVars]( auto &&CodeGen = [PartId, &S, &PrivateVars, &FirstprivateVars](
CodeGenFunction &CGF, PrePostActionTy &) { CodeGenFunction &CGF) {
// Set proper addresses for generated private copies. // Set proper addresses for generated private copies.
auto *CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto *CS = cast<CapturedStmt>(S.getAssociatedStmt());
{ OMPPrivateScope Scope(CGF);
OMPPrivateScope Scope(CGF); if (!PrivateVars.empty() || !FirstprivateVars.empty()) {
if (!PrivateVars.empty() || !FirstprivateVars.empty()) { auto *CopyFn = CGF.Builder.CreateLoad(
auto *CopyFn = CGF.Builder.CreateLoad( CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3)));
CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3))); auto *PrivatesPtr = CGF.Builder.CreateLoad(
auto *PrivatesPtr = CGF.Builder.CreateLoad( CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2)));
CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2))); // Map privates.
// Map privates. llvm::SmallVector<std::pair<const VarDecl *, Address>, 16>
llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs; PrivatePtrs;
llvm::SmallVector<llvm::Value *, 16> CallArgs; llvm::SmallVector<llvm::Value *, 16> CallArgs;
CallArgs.push_back(PrivatesPtr); CallArgs.push_back(PrivatesPtr);
for (auto *E : PrivateVars) { for (auto *E : PrivateVars) {
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Address PrivatePtr = Address PrivatePtr =
CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType())); CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()));
PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr)); PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
CallArgs.push_back(PrivatePtr.getPointer()); CallArgs.push_back(PrivatePtr.getPointer());
}
for (auto *E : FirstprivateVars) {
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Address PrivatePtr =
CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()));
PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
CallArgs.push_back(PrivatePtr.getPointer());
}
CGF.EmitRuntimeCall(CopyFn, CallArgs);
for (auto &&Pair : PrivatePtrs) {
Address Replacement(CGF.Builder.CreateLoad(Pair.second),
CGF.getContext().getDeclAlign(Pair.first));
Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
}
} }
(void)Scope.Privatize(); for (auto *E : FirstprivateVars) {
if (*PartId) { auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
// TODO: emit code for untied tasks. Address PrivatePtr =
CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()));
PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
CallArgs.push_back(PrivatePtr.getPointer());
}
CGF.EmitRuntimeCall(CopyFn, CallArgs);
for (auto &&Pair : PrivatePtrs) {
Address Replacement(CGF.Builder.CreateLoad(Pair.second),
CGF.getContext().getDeclAlign(Pair.first));
Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
} }
CGF.EmitStmt(CS->getCapturedStmt());
} }
(void)Scope.Privatize();
if (*PartId) {
// TODO: emit code for untied tasks.
}
CGF.EmitStmt(CS->getCapturedStmt());
}; };
auto OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( auto OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
S, *I, OMPD_task, CodeGen); S, *I, OMPD_task, CodeGen);
@ -2338,7 +2334,6 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
break; break;
} }
} }
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitTaskCall( CGM.getOpenMPRuntime().emitTaskCall(
*this, S.getLocStart(), S, Tied, Final, OutlinedFn, SharedsTy, *this, S.getLocStart(), S, Tied, Final, OutlinedFn, SharedsTy,
CapturedStruct, IfCond, PrivateVars, PrivateCopies, FirstprivateVars, CapturedStruct, IfCond, PrivateVars, PrivateCopies, FirstprivateVars,
@ -2360,11 +2355,10 @@ void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
void CodeGenFunction::EmitOMPTaskgroupDirective( void CodeGenFunction::EmitOMPTaskgroupDirective(
const OMPTaskgroupDirective &S) { const OMPTaskgroupDirective &S) {
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { OMPLexicalScope Scope(*this, S);
Action.Enter(CGF); auto &&CodeGen = [&S](CodeGenFunction &CGF) {
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
}; };
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getLocStart()); CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getLocStart());
} }
@ -2496,10 +2490,10 @@ void CodeGenFunction::EmitOMPDistributeLoop(const OMPDistributeDirective &S) {
void CodeGenFunction::EmitOMPDistributeDirective( void CodeGenFunction::EmitOMPDistributeDirective(
const OMPDistributeDirective &S) { const OMPDistributeDirective &S) {
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { LexicalScope Scope(*this, S.getSourceRange());
auto &&CodeGen = [&S](CodeGenFunction &CGF) {
CGF.EmitOMPDistributeLoop(S); CGF.EmitOMPDistributeLoop(S);
}; };
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen, CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen,
false); false);
} }
@ -2517,9 +2511,9 @@ static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) { void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
if (!S.getAssociatedStmt()) if (!S.getAssociatedStmt())
return; return;
OMPLexicalScope Scope(*this, S);
auto *C = S.getSingleClause<OMPSIMDClause>(); auto *C = S.getSingleClause<OMPSIMDClause>();
auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF, auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF) {
PrePostActionTy &Action) {
if (C) { if (C) {
auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
llvm::SmallVector<llvm::Value *, 16> CapturedVars; llvm::SmallVector<llvm::Value *, 16> CapturedVars;
@ -2527,12 +2521,10 @@ void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
auto *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS); auto *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS);
CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars); CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars);
} else { } else {
Action.Enter(CGF);
CGF.EmitStmt( CGF.EmitStmt(
cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
} }
}; };
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getLocStart(), !C); CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getLocStart(), !C);
} }
@ -2978,39 +2970,18 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
} }
} }
auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF, OMPLexicalScope Scope(*this, S);
PrePostActionTy &) { auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF) {
CGF.EmitStopPoint(CS); CGF.EmitStopPoint(CS);
EmitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(), EmitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(),
S.getV(), S.getExpr(), S.getUpdateExpr(), S.getV(), S.getExpr(), S.getUpdateExpr(),
S.isXLHSInRHSPart(), S.getLocStart()); S.isXLHSInRHSPart(), S.getLocStart());
}; };
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen); CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen);
} }
std::pair<llvm::Function * /*OutlinedFn*/, llvm::Constant * /*OutlinedFnID*/>
CodeGenFunction::EmitOMPTargetDirectiveOutlinedFunction(
CodeGenModule &CGM, const OMPTargetDirective &S, StringRef ParentName,
bool IsOffloadEntry) {
llvm::Function *OutlinedFn = nullptr;
llvm::Constant *OutlinedFnID = nullptr;
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
OMPPrivateScope PrivateScope(CGF);
(void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
CGF.EmitOMPPrivateClause(S, PrivateScope);
(void)PrivateScope.Privatize();
Action.Enter(CGF);
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
};
// Emit target region as a standalone region.
CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
S, ParentName, OutlinedFn, OutlinedFnID, IsOffloadEntry, CodeGen);
return std::make_pair(OutlinedFn, OutlinedFnID);
}
void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) { void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
OMPLexicalScope Scope(*this, S);
const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt()); const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt());
llvm::SmallVector<llvm::Value *, 16> CapturedVars; llvm::SmallVector<llvm::Value *, 16> CapturedVars;
@ -3056,9 +3027,9 @@ void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
ParentName = ParentName =
CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CurFuncDecl))); CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CurFuncDecl)));
std::tie(Fn, FnID) = EmitOMPTargetDirectiveOutlinedFunction( CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
CGM, S, ParentName, IsOffloadEntry); IsOffloadEntry);
OMPLexicalScope Scope(*this, S);
CGM.getOpenMPRuntime().emitTargetCall(*this, S, Fn, FnID, IfCond, Device, CGM.getOpenMPRuntime().emitTargetCall(*this, S, Fn, FnID, IfCond, Device,
CapturedVars); CapturedVars);
} }
@ -3068,6 +3039,8 @@ static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
OpenMPDirectiveKind InnermostKind, OpenMPDirectiveKind InnermostKind,
const RegionCodeGenTy &CodeGen) { const RegionCodeGenTy &CodeGen) {
auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
llvm::SmallVector<llvm::Value *, 16> CapturedVars;
CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
auto OutlinedFn = CGF.CGM.getOpenMPRuntime(). auto OutlinedFn = CGF.CGM.getOpenMPRuntime().
emitParallelOrTeamsOutlinedFunction(S, emitParallelOrTeamsOutlinedFunction(S,
*CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
@ -3090,16 +3063,14 @@ static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
ThreadLimitVal, S.getLocStart()); ThreadLimitVal, S.getLocStart());
} }
OMPLexicalScope Scope(CGF, S);
llvm::SmallVector<llvm::Value *, 16> CapturedVars;
CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getLocStart(), OutlinedFn, CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getLocStart(), OutlinedFn,
CapturedVars); CapturedVars);
} }
void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) { void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {
LexicalScope Scope(*this, S.getSourceRange());
// Emit parallel region as a standalone region. // Emit parallel region as a standalone region.
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { auto &&CodeGen = [&S](CodeGenFunction &CGF) {
OMPPrivateScope PrivateScope(CGF); OMPPrivateScope PrivateScope(CGF);
(void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
CGF.EmitOMPPrivateClause(S, PrivateScope); CGF.EmitOMPPrivateClause(S, PrivateScope);
@ -3141,12 +3112,10 @@ CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
void CodeGenFunction::EmitOMPTargetDataDirective( void CodeGenFunction::EmitOMPTargetDataDirective(
const OMPTargetDataDirective &S) { const OMPTargetDataDirective &S) {
// emit the code inside the construct for now // emit the code inside the construct for now
OMPLexicalScope Scope(*this, S); auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
CGM.getOpenMPRuntime().emitInlinedDirective( CGM.getOpenMPRuntime().emitInlinedDirective(
*this, OMPD_target_data, [&S](CodeGenFunction &CGF, PrePostActionTy &) { *this, OMPD_target_data,
CGF.EmitStmt( [&CS](CodeGenFunction &CGF) { CGF.EmitStmt(CS->getCapturedStmt()); });
cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
});
} }
void CodeGenFunction::EmitOMPTargetEnterDataDirective( void CodeGenFunction::EmitOMPTargetEnterDataDirective(
@ -3171,22 +3140,18 @@ void CodeGenFunction::EmitOMPTargetParallelForDirective(
void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) { void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
// emit the code inside the construct for now // emit the code inside the construct for now
OMPLexicalScope Scope(*this, S); auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
CGM.getOpenMPRuntime().emitInlinedDirective( CGM.getOpenMPRuntime().emitInlinedDirective(
*this, OMPD_taskloop, [&S](CodeGenFunction &CGF, PrePostActionTy &) { *this, OMPD_taskloop,
CGF.EmitStmt( [&CS](CodeGenFunction &CGF) { CGF.EmitStmt(CS->getCapturedStmt()); });
cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
});
} }
void CodeGenFunction::EmitOMPTaskLoopSimdDirective( void CodeGenFunction::EmitOMPTaskLoopSimdDirective(
const OMPTaskLoopSimdDirective &S) { const OMPTaskLoopSimdDirective &S) {
// emit the code inside the construct for now // emit the code inside the construct for now
OMPLexicalScope Scope(*this, S); auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
CGM.getOpenMPRuntime().emitInlinedDirective( CGM.getOpenMPRuntime().emitInlinedDirective(
*this, OMPD_taskloop_simd, [&S](CodeGenFunction &CGF, PrePostActionTy &) { *this, OMPD_taskloop_simd,
CGF.EmitStmt( [&CS](CodeGenFunction &CGF) { CGF.EmitStmt(CS->getCapturedStmt()); });
cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
});
} }

View File

@ -2366,13 +2366,6 @@ public:
void EmitOMPDistributeDirective(const OMPDistributeDirective &S); void EmitOMPDistributeDirective(const OMPDistributeDirective &S);
void EmitOMPDistributeLoop(const OMPDistributeDirective &S); void EmitOMPDistributeLoop(const OMPDistributeDirective &S);
/// Emit outlined function for the target directive.
static std::pair<llvm::Function * /*OutlinedFn*/,
llvm::Constant * /*OutlinedFnID*/>
EmitOMPTargetDirectiveOutlinedFunction(CodeGenModule &CGM,
const OMPTargetDirective &S,
StringRef ParentName,
bool IsOffloadEntry);
/// \brief Emit inner loop of the worksharing/simd construct. /// \brief Emit inner loop of the worksharing/simd construct.
/// ///
/// \param S Directive, for which the inner loop must be emitted. /// \param S Directive, for which the inner loop must be emitted.

View File

@ -39,11 +39,7 @@ int main() {
#pragma omp critical(the_name1) hint(23) #pragma omp critical(the_name1) hint(23)
foo(); foo();
// CHECK: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]]) // CHECK: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
// CHECK: br label
// CHECK-NOT: call {{.*}}void @__kmpc_end_critical( // CHECK-NOT: call {{.*}}void @__kmpc_end_critical(
// CHECK: br label
// CHECK-NOT: call {{.*}}void @__kmpc_end_critical(
// CHECK: br label
if (a) if (a)
#pragma omp critical(the_name) #pragma omp critical(the_name)
while (1) while (1)

View File

@ -87,6 +87,10 @@ int main() {
// TLS-LAMBDA: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]() // TLS-LAMBDA: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]()
// TLS-LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]]) // TLS-LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]])
// TLS-LAMBDA: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]()
// TLS-LAMBDA: ret i{{[0-9]+}}* [[G]]
// TLS-LAMBDA: }
#pragma omp parallel copyin(g) #pragma omp parallel copyin(g)
{ {
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
@ -118,11 +122,6 @@ int main() {
g = 1; g = 1;
// LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}*
// TLS-LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* // TLS-LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}*
// TLS-LAMBDA: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]()
// TLS-LAMBDA: ret i{{[0-9]+}}* [[G]]
// TLS-LAMBDA: }
[&]() { [&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
@ -150,6 +149,9 @@ int main() {
// TLS-BLOCKS: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]() // TLS-BLOCKS: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]()
// TLS-BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]]) // TLS-BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]])
// TLS-BLOCKS: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]()
// TLS-BLOCKS: ret i{{[0-9]+}}* [[G]]
// TLS-BLOCKS: }
#pragma omp parallel copyin(g) #pragma omp parallel copyin(g)
{ {
// BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
@ -187,10 +189,6 @@ int main() {
// TLS-BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_CAPTURE_DST]] // TLS-BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_CAPTURE_DST]]
// TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}} // TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// TLS-BLOCKS: call {{.*}}void {{%.+}}(i8 // TLS-BLOCKS: call {{.*}}void {{%.+}}(i8
// TLS-BLOCKS: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]()
// TLS-BLOCKS: ret i{{[0-9]+}}* [[G]]
// TLS-BLOCKS: }
^{ ^{
// BLOCKS: define {{.+}} void {{@.+}}(i8* // BLOCKS: define {{.+}} void {{@.+}}(i8*
// TLS-BLOCKS: define {{.+}} void {{@.+}}(i8* // TLS-BLOCKS: define {{.+}} void {{@.+}}(i8*

View File

@ -111,8 +111,8 @@ int main() {
// CHECK-NEXT: invoke void [[FOO]]() // CHECK-NEXT: invoke void [[FOO]]()
// CHECK: to label {{%?}}[[CONT:.+]] unwind // CHECK: to label {{%?}}[[CONT:.+]] unwind
// CHECK: [[CONT]] // CHECK: [[CONT]]
// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
// CHECK: store i32 1, i32* [[DID_IT]] // CHECK: store i32 1, i32* [[DID_IT]]
// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
// CHECK-NEXT: br label {{%?}}[[EXIT]] // CHECK-NEXT: br label {{%?}}[[EXIT]]
// CHECK: [[EXIT]] // CHECK: [[EXIT]]
// CHECK: [[A_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[A_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
@ -255,8 +255,8 @@ void array_func(int n, int a[n], St s[2]) {
// CHECK-LABEL: invoke void @_ZZN2SSC1ERiENKUlvE_clEv( // CHECK-LABEL: invoke void @_ZZN2SSC1ERiENKUlvE_clEv(
// CHECK-SAME: [[CAP_TY]]* [[CAP]]) // CHECK-SAME: [[CAP_TY]]* [[CAP]])
// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
// CHECK: store i32 1, i32* [[DID_IT]], // CHECK: store i32 1, i32* [[DID_IT]],
// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
// CHECK: br label // CHECK: br label
// CHECK: call void @__kmpc_end_single(%{{.+}}* @{{.+}}, i32 %{{.+}}) // CHECK: call void @__kmpc_end_single(%{{.+}}* @{{.+}}, i32 %{{.+}})
@ -334,8 +334,8 @@ void array_func(int n, int a[n], St s[2]) {
// CHECK-NEXT: load i32, i32* % // CHECK-NEXT: load i32, i32* %
// CHECK-NEXT: sdiv i32 %{{.+}}, 1 // CHECK-NEXT: sdiv i32 %{{.+}}, 1
// CHECK-NEXT: store i32 % // CHECK-NEXT: store i32 %
// CHECK-NEXT: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
// CHECK-NEXT: store i32 1, i32* [[DID_IT]], // CHECK-NEXT: store i32 1, i32* [[DID_IT]],
// CHECK-NEXT: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
// CHECK-NEXT: br label // CHECK-NEXT: br label
// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST:%.+]], i64 0, i64 0 // CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST:%.+]], i64 0, i64 0
@ -376,8 +376,8 @@ void array_func(int n, int a[n], St s[2]) {
// CHECK-NEXT: store double* % // CHECK-NEXT: store double* %
// CHECK-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv( // CHECK-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(
// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) // CHECK: store i32 1, i32* [[DID_IT]],
// CHECK-NEXT: store i32 1, i32* [[DID_IT]], // CHECK-NEXT: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
// CHECK-NEXT: br label // CHECK-NEXT: br label
// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) // CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})

View File

@ -32,7 +32,6 @@ int main() {
foo(); foo();
// CHECK-NOT: call {{.*}}void @__kmpc_taskgroup // CHECK-NOT: call {{.*}}void @__kmpc_taskgroup
// CHECK-NOT: call {{.*}}void @__kmpc_end_taskgroup // CHECK-NOT: call {{.*}}void @__kmpc_end_taskgroup
// CHECK: ret
return a; return a;
} }