diff options
Diffstat (limited to 'lib/CodeGen/CGStmtOpenMP.cpp')
| -rw-r--r-- | lib/CodeGen/CGStmtOpenMP.cpp | 61 |
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. |
