aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGStmtOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp61
1 files changed, 51 insertions, 10 deletions
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 26f780fdd7de..8937685fdc7b 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -232,8 +232,15 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
assert(I->capturesVariableArrayType());
II = &getContext().Idents.get("vla");
}
- if (ArgType->isVariablyModifiedType())
- ArgType = getContext().getVariableArrayDecayedType(ArgType);
+ if (ArgType->isVariablyModifiedType()) {
+ bool IsReference = ArgType->isLValueReferenceType();
+ ArgType =
+ getContext().getCanonicalParamType(ArgType.getNonReferenceType());
+ if (IsReference && !ArgType->isPointerType()) {
+ ArgType = getContext().getLValueReferenceType(
+ ArgType, /*SpelledAsLValue=*/false);
+ }
+ }
Args.push_back(ImplicitParamDecl::Create(getContext(), nullptr,
FD->getLocation(), II, ArgType));
++I;
@@ -287,8 +294,14 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
QualType VarTy = Var->getType();
Address ArgAddr = ArgLVal.getAddress();
if (!VarTy->isReferenceType()) {
- ArgAddr = EmitLoadOfReference(
- ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
+ if (ArgLVal.getType()->isLValueReferenceType()) {
+ ArgAddr = EmitLoadOfReference(
+ ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
+ } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
+ assert(ArgLVal.getType()->isPointerType());
+ ArgAddr = EmitLoadOfPointer(
+ ArgAddr, ArgLVal.getType()->castAs<PointerType>());
+ }
}
setAddrOfLocalVar(
Var, Address(ArgAddr.getPointer(), getContext().getDeclAlign(Var)));
@@ -1754,9 +1767,17 @@ void CodeGenFunction::EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic,
EmitBlock(LoopExit.getBlock());
// Tell the runtime we are done.
- if (!DynamicOrOrdered)
- RT.emitForStaticFinish(*this, S.getLocEnd());
+ SourceLocation ELoc = S.getLocEnd();
+ auto &&CodeGen = [DynamicOrOrdered, ELoc](CodeGenFunction &CGF) {
+ if (!DynamicOrOrdered)
+ CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
+ };
+ CodeGen(*this);
+ OpenMPDirectiveKind DKind = S.getDirectiveKind();
+ if (DKind == OMPD_for || DKind == OMPD_parallel_for ||
+ DKind == OMPD_distribute_parallel_for)
+ OMPCancelStack.back().CodeGen = CodeGen;
}
void CodeGenFunction::EmitOMPForOuterLoop(
@@ -1868,6 +1889,7 @@ void CodeGenFunction::EmitOMPDistributeOuterLoop(
void CodeGenFunction::EmitOMPDistributeParallelForDirective(
const OMPDistributeParallelForDirective &S) {
OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
+ OMPCancelStackRAII CancelRegion(*this);
CGM.getOpenMPRuntime().emitInlinedDirective(
*this, OMPD_distribute_parallel_for,
[&S](CodeGenFunction &CGF, PrePostActionTy &) {
@@ -2060,7 +2082,15 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
[](CodeGenFunction &) {});
EmitBlock(LoopExit.getBlock());
// Tell the runtime we are done.
- RT.emitForStaticFinish(*this, S.getLocStart());
+ SourceLocation ELoc = S.getLocEnd();
+ auto &&CodeGen = [ELoc](CodeGenFunction &CGF) {
+ CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
+ };
+ CodeGen(*this);
+ OpenMPDirectiveKind DKind = S.getDirectiveKind();
+ if (DKind == OMPD_for || DKind == OMPD_parallel_for ||
+ DKind == OMPD_distribute_parallel_for)
+ OMPCancelStack.back().CodeGen = CodeGen;
} else {
const bool IsMonotonic =
Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static ||
@@ -2114,6 +2144,7 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
};
{
OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
+ OMPCancelStackRAII CancelRegion(*this);
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
S.hasCancel());
}
@@ -2156,6 +2187,7 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
bool HasLastprivates = false;
auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF,
PrePostActionTy &) {
+ OMPCancelStackRAII CancelRegion(CGF);
auto &C = CGF.CGM.getContext();
auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
// Emit helper vars inits.
@@ -2250,7 +2282,12 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
[](CodeGenFunction &) {});
// Tell the runtime we are done.
- CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
+ SourceLocation ELoc = S.getLocEnd();
+ auto &&FinalCodeGen = [ELoc](CodeGenFunction &CGF) {
+ CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
+ };
+ FinalCodeGen(CGF);
+ CGF.OMPCancelStack.back().CodeGen = FinalCodeGen;
CGF.EmitOMPReductionClauseFinal(S);
// Emit post-update of the reduction variables if IsLastIter != 0.
emitPostUpdateForReductionClause(
@@ -2375,6 +2412,7 @@ void CodeGenFunction::EmitOMPParallelForDirective(
// Emit directive as a combined directive that consists of two implicit
// directives: 'parallel' with 'for' directive.
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
+ OMPCancelStackRAII CancelRegion(CGF);
CGF.EmitOMPWorksharingLoop(S);
};
emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen);
@@ -3377,8 +3415,11 @@ CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
if (Kind == OMPD_parallel || Kind == OMPD_task)
return ReturnBlock;
assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
- Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for);
- return BreakContinueStack.back().BreakBlock;
+ Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
+ Kind == OMPD_distribute_parallel_for);
+ if (!OMPCancelStack.back().ExitBlock.isValid())
+ OMPCancelStack.back().ExitBlock = getJumpDestInCurrentScope("cancel.exit");
+ return OMPCancelStack.back().ExitBlock;
}
// Generate the instructions for '#pragma omp target data' directive.