Index: clang/include/clang/Basic/OpenMPKinds.h =================================================================== --- clang/include/clang/Basic/OpenMPKinds.h +++ clang/include/clang/Basic/OpenMPKinds.h @@ -170,13 +170,6 @@ unsigned OpenMPVersion); const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); -/// Checks if the specified directive is a directive with an associated -/// loop construct. -/// \param DKind Specified directive. -/// \return true - the directive is a loop-associated directive like 'omp simd' -/// or 'omp for' directive, otherwise - false. -bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind); - /// Checks if the specified directive is a worksharing directive. /// \param DKind Specified directive. /// \return true - the directive is a worksharing directive like 'omp for', @@ -230,21 +223,6 @@ /// otherwise - false. bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind); -/// Checks if the specified directive is a distribute directive. -/// \param DKind Specified directive. -/// \return true - the directive is a distribute-directive like 'omp -/// distribute', -/// otherwise - false. -bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind); - -/// Checks if the specified composite/combined directive constitutes a -/// distribute directive in the outermost nest. For example, -/// 'omp distribute parallel for' or 'omp distribute'. -/// \param DKind Specified directive. -/// \return true - the directive has distribute on the outermost nest. -/// otherwise - false. -bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind); - /// Checks if the specified clause is one of private clauses like /// 'private', 'firstprivate', 'reduction' etc.. /// \param Kind Clause kind. Index: clang/lib/Basic/OpenMPKinds.cpp =================================================================== --- clang/lib/Basic/OpenMPKinds.cpp +++ clang/lib/Basic/OpenMPKinds.cpp @@ -427,28 +427,6 @@ llvm_unreachable("Invalid OpenMP simple clause kind"); } -bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { - return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd || - DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd || - DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd || - DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd || - DKind == OMPD_parallel_master_taskloop || - DKind == OMPD_parallel_master_taskloop_simd || - DKind == OMPD_distribute || DKind == OMPD_target_parallel_for || - DKind == OMPD_distribute_parallel_for || - DKind == OMPD_distribute_parallel_for_simd || - DKind == OMPD_distribute_simd || - DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd || - DKind == OMPD_teams_distribute || - DKind == OMPD_teams_distribute_simd || - DKind == OMPD_teams_distribute_parallel_for_simd || - DKind == OMPD_teams_distribute_parallel_for || - DKind == OMPD_target_teams_distribute || - DKind == OMPD_target_teams_distribute_parallel_for || - DKind == OMPD_target_teams_distribute_parallel_for_simd || - DKind == OMPD_target_teams_distribute_simd; -} - bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_for || DKind == OMPD_for_simd || DKind == OMPD_sections || DKind == OMPD_section || @@ -531,24 +509,6 @@ DKind == OMPD_target_parallel_for_simd; } -bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) { - return Kind == OMPD_distribute || Kind == OMPD_distribute_parallel_for || - Kind == OMPD_distribute_parallel_for_simd || - Kind == OMPD_distribute_simd; - // TODO add next directives. -} - -bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) { - return isOpenMPNestingDistributeDirective(Kind) || - Kind == OMPD_teams_distribute || Kind == OMPD_teams_distribute_simd || - Kind == OMPD_teams_distribute_parallel_for_simd || - Kind == OMPD_teams_distribute_parallel_for || - Kind == OMPD_target_teams_distribute || - Kind == OMPD_target_teams_distribute_parallel_for || - Kind == OMPD_target_teams_distribute_parallel_for_simd || - Kind == OMPD_target_teams_distribute_simd; -} - bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) { return Kind == OMPC_private || Kind == OMPC_firstprivate || Kind == OMPC_lastprivate || Kind == OMPC_linear || Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -2792,21 +2792,30 @@ void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind) { - if (!CGF.HaveInsertPoint()) - return; - // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid); - llvm::Value *Args[] = { - emitUpdateLocation(CGF, Loc, - isOpenMPDistributeDirective(DKind) - ? OMP_IDENT_WORK_DISTRIBUTE - : isOpenMPLoopDirective(DKind) - ? OMP_IDENT_WORK_LOOP - : OMP_IDENT_WORK_SECTIONS), - getThreadID(CGF, Loc)}; - auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc); - CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_for_static_fini), - Args); + if (CGF.CGM.getLangOpts().OpenMPIRBuilder) { + // TODO: The following debug location creation should be removed + // when we fully support parfor generation with IRBuilder. Currently + // having this here ensures that the barrier generated has the + // same location as without IRBuilder. + auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc); + OMPBuilder.CreateForStaticFinish(CGF.Builder, DKind); + } else { + if (!CGF.HaveInsertPoint()) + return; + // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid); + llvm::Value *Args[] = { + emitUpdateLocation(CGF, Loc, + isOpenMPDistributeDirective(DKind) + ? OMP_IDENT_WORK_DISTRIBUTE + : isOpenMPLoopDirective(DKind) + ? OMP_IDENT_WORK_LOOP + : OMP_IDENT_WORK_SECTIONS), + getThreadID(CGF, Loc)}; + auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc); + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( + CGM.getModule(), OMPRTL___kmpc_for_static_fini), + Args); + } } void CGOpenMPRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF, Index: llvm/include/llvm/Frontend/OpenMP/OMPConstants.h =================================================================== --- llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -79,6 +79,17 @@ #define OMP_IDENT_FLAG(Enum, ...) constexpr auto Enum = omp::IdentFlag::Enum; #include "llvm/Frontend/OpenMP/OMPKinds.def" +/// Return true if \p DKind composite/combined directive constitutes +/// a distribute directive in the outermost nest. +bool isOpenMPNestingDistributeDirective(Directive DKind); + +/// Return true if \p DKind directive is a distribute directive. +bool isOpenMPDistributeDirective(Directive DKind); + +/// Return true if \p DKind directive is a loop associated directive like +/// 'omp simd' or 'omp for'. +bool isOpenMPLoopDirective(Directive DKind); + } // end namespace omp } // end namespace llvm Index: llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h =================================================================== --- llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -178,6 +178,12 @@ /// \param Loc The location where the flush directive was encountered void CreateFlush(const LocationDescription &Loc); + /// Generator for 'for static fini' + /// + /// \param Loc The location at which the request originated and is fulfilled. + /// \param DK The directive which caused the static finish + void CreateForStaticFinish(const LocationDescription &Loc, omp::Directive DK); + /// Generator for '#omp taskwait' /// /// \param Loc The location where the taskwait directive was encountered. @@ -274,6 +280,12 @@ /// \param Loc The location at which the request originated and is fulfilled. void emitTaskyieldImpl(const LocationDescription &Loc); + /// Generate a for static fini runtime call. + /// + /// \param Loc The location at which the request originated and is fulfilled. + /// \param DK The directive which caused the static finish + void emitForStaticFinish(const LocationDescription &Loc, omp::Directive DK); + /// Return the current thread ID. /// /// \param Ident The ident (ident_t*) describing the query origin. Index: llvm/include/llvm/Frontend/OpenMP/OMPKinds.def =================================================================== --- llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -950,6 +950,9 @@ __OMP_IDENT_FLAG(BARRIER_IMPL_SECTIONS, 0x00C0) __OMP_IDENT_FLAG(BARRIER_IMPL_SINGLE, 0x0140) __OMP_IDENT_FLAG(BARRIER_IMPL_WORKSHARE, 0x01C0) +__OMP_IDENT_FLAG(WORK_LOOP, 0x200) +__OMP_IDENT_FLAG(WORK_SECTIONS, 0x400) +__OMP_IDENT_FLAG(WORK_DISTRIBUTE, 0x800) #undef __OMP_IDENT_FLAG #undef OMP_IDENT_FLAG Index: llvm/lib/Frontend/OpenMP/CMakeLists.txt =================================================================== --- llvm/lib/Frontend/OpenMP/CMakeLists.txt +++ llvm/lib/Frontend/OpenMP/CMakeLists.txt @@ -4,6 +4,7 @@ add_llvm_component_library(LLVMFrontendOpenMP OMP.cpp # Generated by tablegen above + OMPConstants.cpp OMPContext.cpp OMPIRBuilder.cpp Index: llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp =================================================================== --- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -1209,3 +1209,24 @@ Worklist.push_back(SuccBB); } } + +void OpenMPIRBuilder::emitForStaticFinish(const LocationDescription &Loc, + Directive DK) { + // Build call void __kmpc_for_static_fini(ident_t *loc, int32 thread_id) + Constant *SrcLocStr = getOrCreateSrcLocStr(Loc); + IdentFlag LocFlags = + isOpenMPDistributeDirective(DK) ? OMP_IDENT_FLAG_WORK_DISTRIBUTE + : isOpenMPLoopDirective(DK) ? OMP_IDENT_FLAG_WORK_LOOP + : OMP_IDENT_FLAG_WORK_SECTIONS; + Value *Args[] = {getOrCreateIdent(SrcLocStr, LocFlags), + getOrCreateThreadID(getOrCreateIdent(SrcLocStr))}; + Builder.CreateCall( + getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_for_static_fini), Args); +} + +void OpenMPIRBuilder::CreateForStaticFinish(const LocationDescription &Loc, + Directive Kind) { + if (!updateToLocation(Loc)) + return; + emitForStaticFinish(Loc, Kind); +}