diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -3295,11 +3295,18 @@ SourceLocation Loc) { if (!CGF.HaveInsertPoint()) return; - // Build call __kmpc_omp_taskyield(loc, thread_id, 0); - llvm::Value *Args[] = { - emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), - llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)}; - CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), Args); + llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder(); + if (OMPBuilder) { + OMPBuilder->CreateTaskyield(CGF.Builder); + } else { + // Build call __kmpc_omp_taskyield(loc, thread_id, 0); + llvm::Value *Args[] = { + emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), + llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)}; + CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), + Args); + } + if (auto *Region = dyn_cast_or_null(CGF.CapturedStmtInfo)) Region->emitUntiedSwitch(CGF); } diff --git a/clang/test/OpenMP/taskyield_codegen.cpp b/clang/test/OpenMP/taskyield_codegen.cpp --- a/clang/test/OpenMP/taskyield_codegen.cpp +++ b/clang/test/OpenMP/taskyield_codegen.cpp @@ -1,6 +1,10 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h --- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -171,6 +171,7 @@ Value *IfCondition, Value *NumThreads, omp::ProcBindKind ProcBind, bool IsCancellable); + /// Generator for '#omp flush' /// /// \param Loc The location where the flush directive was encountered @@ -181,6 +182,11 @@ /// \param Loc The location where the taskwait directive was encountered. void CreateTaskwait(const LocationDescription& Loc); + /// Generator for '#omp taskyield' + /// + /// \param Loc The location where the taskyield directive was encountered. + void CreateTaskyield(const LocationDescription& Loc); + ///} @@ -251,6 +257,11 @@ /// \param Loc The location at which the request originated and is fulfilled. void emitTaskwaitImpl(const LocationDescription &Loc); + /// Generate a taskyield runtime call. + /// + /// \param Loc The location at which the request originated and is fulfilled. + void emitTaskyieldImpl(const LocationDescription &Loc); + /// Return the current thread ID. /// /// \param Ident The ident (ident_t*) describing the query origin. diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -170,6 +170,7 @@ __OMP_RTL(__kmpc_global_thread_num, false, Int32, IdentPtr) __OMP_RTL(__kmpc_fork_call, true, Void, IdentPtr, Int32, ParallelTaskPtr) __OMP_RTL(__kmpc_omp_taskwait, false, Int32, IdentPtr, Int32) +__OMP_RTL(__kmpc_omp_taskyield, false, Int32, IdentPtr, Int32, Int32) __OMP_RTL(__kmpc_push_num_threads, false, Void, IdentPtr, Int32, /* Int */ Int32) __OMP_RTL(__kmpc_push_proc_bind, false, Void, IdentPtr, Int32, /* Int */ Int32) diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -709,3 +709,20 @@ return; emitTaskwaitImpl(Loc); } + +void OpenMPIRBuilder::emitTaskyieldImpl(const LocationDescription &Loc) { + // Build call __kmpc_omp_taskyield(loc, thread_id, 0); + Constant *SrcLocStr = getOrCreateSrcLocStr(Loc); + Value *Ident = getOrCreateIdent(SrcLocStr); + Constant *I32Null = ConstantInt::getNullValue(Int32); + Value *Args[] = {Ident, getOrCreateThreadID(Ident), I32Null}; + + Builder.CreateCall(getOrCreateRuntimeFunction(OMPRTL___kmpc_omp_taskyield), + Args); +} + +void OpenMPIRBuilder::CreateTaskyield(const LocationDescription &Loc) { + if (!updateToLocation(Loc)) + return; + emitTaskyieldImpl(Loc); +}