summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2015-07-02 04:17:07 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2015-07-02 04:17:07 +0000
commit0f34da12e42311e943186622412f64d0a93ccf2a (patch)
treea509bd71939516957ff7efb6ff57c4486862cb64 /clang/lib/CodeGen
parent458d74421b002dd670e1ac5f961b703cfb3749b4 (diff)
downloadbcm5719-llvm-0f34da12e42311e943186622412f64d0a93ccf2a.tar.gz
bcm5719-llvm-0f34da12e42311e943186622412f64d0a93ccf2a.zip
[OPENMP 4.0] Codegen for 'cancellation point' directive.
The next code is generated for this construct: ``` if (__kmpc_cancellationpoint(ident_t *loc, kmp_int32 global_tid, kmp_int32 cncl_kind) != 0) <exit from outer innermost construct>; ``` llvm-svn: 241239
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp53
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.h11
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp76
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h4
4 files changed, 108 insertions, 36 deletions
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index f9553a2203c..5fe81c2443c 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -806,6 +806,15 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {
RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_wait_deps");
break;
}
+ case OMPRTL__kmpc_cancellationpoint: {
+ // Build kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
+ // global_tid, kmp_int32 cncl_kind)
+ llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
+ llvm::FunctionType *FnTy =
+ llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
+ RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint");
+ break;
+ }
}
return RTLFn;
}
@@ -2677,3 +2686,47 @@ void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
}
+void CGOpenMPRuntime::emitCancellationPointCall(
+ CodeGenFunction &CGF, SourceLocation Loc,
+ OpenMPDirectiveKind CancelRegion) {
+ // Build call kmp_int32 OMPRTL__kmpc_cancellationpoint(ident_t *loc, kmp_int32
+ // global_tid, kmp_int32 cncl_kind);
+ enum {
+ CancelNoreq = 0,
+ CancelParallel = 1,
+ CancelLoop = 2,
+ CancelSections = 3,
+ CancelTaskgroup = 4
+ } CancelKind = CancelNoreq;
+ if (CancelRegion == OMPD_parallel)
+ CancelKind = CancelParallel;
+ else if (CancelRegion == OMPD_for)
+ CancelKind = CancelLoop;
+ else if (CancelRegion == OMPD_sections)
+ CancelKind = CancelSections;
+ else {
+ assert(CancelRegion == OMPD_taskgroup);
+ CancelKind = CancelTaskgroup;
+ }
+ llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
+ CGF.Builder.getInt32(CancelKind)};
+ // Ignore return result until untied tasks are supported.
+ auto *Result = CGF.EmitRuntimeCall(
+ createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
+ // if (__kmpc_cancellationpoint())
+ // exit from construct;
+ auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
+ auto *ContBB = CGF.createBasicBlock(".cancel.continue");
+ auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
+ CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
+ CGF.EmitBlock(ExitBB);
+ if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_taskgroup) {
+ CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
+ } else {
+ assert(CancelRegion == OMPD_for || CancelRegion == OMPD_sections);
+ BreakStmt PseudoBrStmt(Loc);
+ CGF.EmitBreakStmt(PseudoBrStmt);
+ }
+ CGF.EmitBlock(ContBB, /*IsFinished=*/true);
+}
+
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index 27a0a3244d8..b34ef42098e 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -146,6 +146,9 @@ private:
// gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
// ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
OMPRTL__kmpc_omp_wait_deps,
+ // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
+ // global_tid, kmp_int32 cncl_kind);
+ OMPRTL__kmpc_cancellationpoint,
};
/// \brief Values for bit flags used in the ident_t to describe the fields.
@@ -676,6 +679,14 @@ public:
/// \brief Emit code for 'taskwait' directive.
virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc);
+
+ /// \brief Emit code for 'cancellation point' construct.
+ /// \param CancelRegion Region kind for which the cancellation point must be
+ /// emitted.
+ ///
+ virtual void emitCancellationPointCall(CodeGenFunction &CGF,
+ SourceLocation Loc,
+ OpenMPDirectiveKind CancelRegion);
};
} // namespace CodeGen
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 8666b464984..655fae11a2e 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -505,7 +505,8 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
emitCommonOMPParallelDirective(*this, S, CodeGen);
}
-void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D) {
+void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
+ JumpDest LoopExit) {
RunCleanupsScope BodyScope(*this);
// Update counters values on current iteration.
for (auto I : D.updates()) {
@@ -521,7 +522,7 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D) {
// On a continue in the body, jump to the end.
auto Continue = getJumpDestInCurrentScope("omp.body.continue");
- BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
+ BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
// Emit loop body.
EmitStmt(D.getBody());
// The end (updates/cleanups).
@@ -827,10 +828,10 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
CGF.EmitOMPReductionClauseInit(S, LoopScope);
HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
(void)LoopScope.Privatize();
- CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
- S.getCond(), S.getInc(),
+ CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
+ S.getInc(),
[&S](CodeGenFunction &CGF) {
- CGF.EmitOMPLoopBody(S);
+ CGF.EmitOMPLoopBody(S, JumpDest());
CGF.EmitStopPoint(&S);
},
[](CodeGenFunction &) {});
@@ -979,19 +980,17 @@ void CodeGenFunction::EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind,
}
SourceLocation Loc = S.getLocStart();
- EmitOMPInnerLoop(
- S, LoopScope.requiresCleanups(), S.getCond(),
- S.getInc(),
- [&S](CodeGenFunction &CGF) {
- CGF.EmitOMPLoopBody(S);
- CGF.EmitStopPoint(&S);
- },
- [Ordered, IVSize, IVSigned, Loc](CodeGenFunction &CGF) {
- if (Ordered) {
- CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(
- CGF, Loc, IVSize, IVSigned);
- }
- });
+ EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
+ [&S, LoopExit](CodeGenFunction &CGF) {
+ CGF.EmitOMPLoopBody(S, LoopExit);
+ CGF.EmitStopPoint(&S);
+ },
+ [Ordered, IVSize, IVSigned, Loc](CodeGenFunction &CGF) {
+ if (Ordered) {
+ CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(
+ CGF, Loc, IVSize, IVSigned);
+ }
+ });
EmitBlock(Continue.getBlock());
BreakContinueStack.pop_back();
@@ -1140,6 +1139,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
RT.emitForInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned,
Ordered, IL.getAddress(), LB.getAddress(),
UB.getAddress(), ST.getAddress());
+ auto LoopExit = getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
// UB = min(UB, GlobalUB);
EmitIgnoredExpr(S.getEnsureUpperBound());
// IV = LB;
@@ -1147,11 +1147,12 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
// while (idx <= UB) { BODY; ++idx; }
EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
S.getInc(),
- [&S](CodeGenFunction &CGF) {
- CGF.EmitOMPLoopBody(S);
+ [&S, LoopExit](CodeGenFunction &CGF) {
+ CGF.EmitOMPLoopBody(S, LoopExit);
CGF.EmitStopPoint(&S);
},
[](CodeGenFunction &) {});
+ EmitBlock(LoopExit.getBlock());
// Tell the runtime we are done.
RT.emitForStaticFinish(*this, S.getLocStart());
} else {
@@ -1216,8 +1217,8 @@ static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
return LVal;
}
-static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF,
- const OMPExecutableDirective &S) {
+OpenMPDirectiveKind
+CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
auto *CS = dyn_cast<CompoundStmt>(Stmt);
if (CS && CS->size() > 1) {
@@ -1313,15 +1314,15 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF,
CGF.EmitLoadOfScalar(IL, S.getLocStart())));
};
- CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, CodeGen);
+ CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen);
// Emit barrier for lastprivates only if 'sections' directive has 'nowait'
// clause. Otherwise the barrier will be generated by the codegen for the
// directive.
if (HasLastprivates && S.getSingleClause(OMPC_nowait)) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
- OMPD_unknown);
+ CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
+ OMPD_unknown);
}
return OMPD_sections;
}
@@ -1341,12 +1342,17 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF,
CGF.EmitOMPPrivateClause(S, SingleScope);
(void)SingleScope.Privatize();
+ CGF.BreakContinueStack.push_back(
+ BreakContinue(CGF.getJumpDestInCurrentScope(
+ CGF.createBasicBlock("omp.sections.exit")),
+ JumpDest()));
CGF.EmitStmt(Stmt);
- CGF.EnsureInsertPoint();
+ CGF.EmitBlock(CGF.BreakContinueStack.back().BreakBlock.getBlock());
+ CGF.BreakContinueStack.pop_back();
};
- CGF.CGM.getOpenMPRuntime().emitSingleRegion(CGF, CodeGen, S.getLocStart(),
- llvm::None, llvm::None,
- llvm::None, llvm::None);
+ CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
+ llvm::None, llvm::None, llvm::None,
+ llvm::None);
// Emit barrier for firstprivates, lastprivates or reductions only if
// 'sections' directive has 'nowait' clause. Otherwise the barrier will be
// generated by the codegen for the directive.
@@ -1354,15 +1360,15 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF,
S.getSingleClause(OMPC_nowait)) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
- OMPD_unknown);
+ CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
+ OMPD_unknown);
}
return OMPD_single;
}
void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
LexicalScope Scope(*this, S.getSourceRange());
- OpenMPDirectiveKind EmittedAs = emitSections(*this, S);
+ OpenMPDirectiveKind EmittedAs = EmitSections(S);
// Emit an implicit barrier at the end.
if (!S.getSingleClause(OMPC_nowait)) {
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), EmittedAs);
@@ -1481,7 +1487,7 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective(
// directives: 'parallel' with 'sections' directive.
LexicalScope Scope(*this, S.getSourceRange());
auto &&CodeGen = [&S](CodeGenFunction &CGF) {
- (void)emitSections(CGF, S);
+ (void)CGF.EmitSections(S);
// Emit implicit barrier at the end of parallel region.
CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
OMPD_parallel);
@@ -2102,7 +2108,7 @@ void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
void CodeGenFunction::EmitOMPCancellationPointDirective(
const OMPCancellationPointDirective &S) {
- llvm_unreachable(
- "CodeGen for 'omp cancellation point' is not supported yet.");
+ CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getLocStart(),
+ S.getCancelRegion());
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 2ba893e6a35..e359876981f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2236,7 +2236,7 @@ public:
private:
/// Helpers for the OpenMP loop directives.
- void EmitOMPLoopBody(const OMPLoopDirective &D);
+ void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit);
void EmitOMPSimdInit(const OMPLoopDirective &D);
void EmitOMPSimdFinal(const OMPLoopDirective &D);
/// \brief Emit code for the worksharing loop-based directive.
@@ -2248,6 +2248,8 @@ private:
OMPPrivateScope &LoopScope, bool Ordered,
llvm::Value *LB, llvm::Value *UB, llvm::Value *ST,
llvm::Value *IL, llvm::Value *Chunk);
+ /// \brief Emit code for sections directive.
+ OpenMPDirectiveKind EmitSections(const OMPExecutableDirective &S);
public:
OpenPOWER on IntegriCloud