Index: clang/include/clang/Basic/OpenMPKinds.h =================================================================== --- clang/include/clang/Basic/OpenMPKinds.h +++ clang/include/clang/Basic/OpenMPKinds.h @@ -212,13 +212,6 @@ OpenMPClauseKind CKind, unsigned OpenMPVersion); -/// 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', @@ -272,21 +265,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 @@ -932,28 +932,6 @@ return false; } -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 || @@ -1035,24 +1013,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 @@ -3771,19 +3771,24 @@ 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)}; - CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini), - Args); + llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder(); + if (OMPBuilder) { + 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)}; + CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini), + Args); + } } void CGOpenMPRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF, Index: clang/test/OpenMP/for_codegen.cpp =================================================================== --- clang/test/OpenMP/for_codegen.cpp +++ clang/test/OpenMP/for_codegen.cpp @@ -6,6 +6,13 @@ // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG // RUN: %clang_cc1 -main-file-name for_codegen.cpp %s -o - -emit-llvm -fprofile-instrument=clang -fprofile-instrument-path=for_codegen-test.profraw | FileCheck %s --check-prefix=PROF-INSTR-PATH +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s --check-prefix=CHECK --check-prefix=LIFETIME --check-prefix=OMP45 +// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s +// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP5 +// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45 + + // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 | FileCheck --check-prefix SIMD-ONLY0 %s Index: llvm/include/llvm/Frontend/OpenMPConstants.h =================================================================== --- llvm/include/llvm/Frontend/OpenMPConstants.h +++ llvm/include/llvm/Frontend/OpenMPConstants.h @@ -66,6 +66,28 @@ /// Return a textual representation of the directive \p D. StringRef getOpenMPDirectiveName(Directive D); +/// 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(Directive 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(Directive DKind); + +/// 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(Directive DKind); + /// Forward declarations for LLVM-IR types (simple, function and structure) are /// generated below. Their names are defined and used in OpenMPKinds.def. Here /// we provide the forward declarations, the initializeTypes function will Index: llvm/include/llvm/Frontend/OpenMPKinds.def =================================================================== --- llvm/include/llvm/Frontend/OpenMPKinds.def +++ llvm/include/llvm/Frontend/OpenMPKinds.def @@ -165,6 +165,7 @@ __OMP_RTL(__kmpc_barrier, false, Void, IdentPtr, Int32) __OMP_RTL(__kmpc_cancel_barrier, false, Int32, IdentPtr, Int32) __OMP_RTL(__kmpc_flush, false, Void, IdentPtr) +__OMP_RTL(__kmpc_for_static_fini, false, Void, IdentPtr, Int32) __OMP_RTL(__kmpc_global_thread_num, false, Int32, IdentPtr) __OMP_RTL(__kmpc_fork_call, true, Void, IdentPtr, Int32, ParallelTaskPtr) __OMP_RTL(omp_get_thread_num, false, Int32, ) @@ -229,6 +230,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/include/llvm/Transforms/Utils/OpenMPIRBuilder.h =================================================================== --- llvm/include/llvm/Transforms/Utils/OpenMPIRBuilder.h +++ llvm/include/llvm/Transforms/Utils/OpenMPIRBuilder.h @@ -80,6 +80,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); + private: /// Update the internal location to \p Loc. @@ -123,6 +129,12 @@ /// \param Loc The location at which the request originated and is fulfilled. void emitFlush(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/lib/Frontend/OpenMPConstants.cpp =================================================================== --- llvm/lib/Frontend/OpenMPConstants.cpp +++ llvm/lib/Frontend/OpenMPConstants.cpp @@ -85,3 +85,42 @@ VarName##Ptr = nullptr; #include "llvm/Frontend/OpenMPKinds.def" } + +bool llvm::omp::isOpenMPNestingDistributeDirective(llvm::omp::Directive Kind) { + return Kind == OMPD_distribute || Kind == OMPD_distribute_parallel_for || + Kind == OMPD_distribute_parallel_for_simd || + Kind == OMPD_distribute_simd; +} + +bool llvm::omp::isOpenMPDistributeDirective(llvm::omp::Directive 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 llvm::omp::isOpenMPLoopDirective(llvm::omp::Directive 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; +} Index: llvm/lib/Frontend/OpenMPIRBuilder.cpp =================================================================== --- llvm/lib/Frontend/OpenMPIRBuilder.cpp +++ llvm/lib/Frontend/OpenMPIRBuilder.cpp @@ -259,3 +259,27 @@ return; emitFlush(Loc); } + +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(getOrCreateRuntimeFunction(OMPRTL___kmpc_for_static_fini), Args); +} + +void OpenMPIRBuilder::CreateForStaticFinish(const LocationDescription &Loc, + Directive Kind) +{ + if (!updateToLocation(Loc)) + return; + emitForStaticFinish(Loc, Kind); +}