Revert "[OPENMP] Allow runtime insert its own code inside OpenMP regions."
Reverting because of failed tests. llvm-svn: 264577
This commit is contained in:
parent
424be92831
commit
f539faa733
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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*
|
||||||
|
|
|
@ -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 %{{.+}})
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue