sriharikrishna created this revision. sriharikrishna added reviewers: jdoerfert, ABataev, RaviNarayanaswamy. Herald added a subscriber: hiraditya. sriharikrishna requested review of this revision. Herald added subscribers: llvm-commits, cfe-commits, sstefan1. Herald added projects: clang, LLVM.
Implements the OMPIRBuilder portion for the Interop directive. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D105876 Files: clang/lib/CodeGen/CGStmt.cpp clang/lib/CodeGen/CGStmtOpenMP.cpp clang/lib/CodeGen/CodeGenFunction.h clang/test/OpenMP/interop_irbuilder.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
Index: llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp =================================================================== --- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -2173,6 +2173,96 @@ return Builder.CreateCall(Fn, Args, Name); } +CallInst *OpenMPIRBuilder::createOMPInteropInit(const LocationDescription &Loc, + Value *InteropVar, + OMPInteropType InteropType, + llvm::Value *Device, + llvm::Value *NumDependences, + llvm::Value *DependenceAddress, + int HaveNowaitClause) { + IRBuilder<>::InsertPointGuard IPG(Builder); + Builder.restoreIP(Loc.IP); + + Constant *SrcLocStr = getOrCreateSrcLocStr(Loc); + Value *Ident = getOrCreateIdent(SrcLocStr); + Value *ThreadId = getOrCreateThreadID(Ident); + if (Device == NULL) + Device = ConstantInt::get(M.getContext(), APInt(32, -1, true)); + ConstantInt *InteropTypeVal = + ConstantInt::get(M.getContext(), APInt(64, (int)InteropType, true)); + if (NumDependences == nullptr) { + NumDependences = ConstantInt::get(M.getContext(), APInt(32, 0, true)); + PointerType *PointerTy_0 = llvm::Type::getInt8PtrTy(M.getContext()); + DependenceAddress = ConstantPointerNull::get(PointerTy_0); + } + Value *HaveNowaitClauseVal = + ConstantInt::get(M.getContext(), APInt(32, HaveNowaitClause, true)); + Value *Args[] = { + Ident, ThreadId, InteropVar, InteropTypeVal, + Device, NumDependences, DependenceAddress, HaveNowaitClauseVal}; + + Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_interop_init); + + return Builder.CreateCall(Fn, Args); +} + +CallInst *OpenMPIRBuilder::createOMPInteropDestroy( + const LocationDescription &Loc, Value *InteropVar, llvm::Value *Device, + llvm::Value *NumDependences, llvm::Value *DependenceAddress, + int HaveNowaitClause) { + IRBuilder<>::InsertPointGuard IPG(Builder); + Builder.restoreIP(Loc.IP); + + Constant *SrcLocStr = getOrCreateSrcLocStr(Loc); + Value *Ident = getOrCreateIdent(SrcLocStr); + Value *ThreadId = getOrCreateThreadID(Ident); + if (Device == NULL) + Device = ConstantInt::get(M.getContext(), APInt(32, -1, true)); + if (NumDependences == nullptr) { + NumDependences = ConstantInt::get(M.getContext(), APInt(32, 0, true)); + PointerType *PointerTy_0 = llvm::Type::getInt8PtrTy(M.getContext()); + DependenceAddress = ConstantPointerNull::get(PointerTy_0); + } + Value *HaveNowaitClauseVal = + ConstantInt::get(M.getContext(), APInt(32, HaveNowaitClause, true)); + Value *Args[] = { + Ident, ThreadId, InteropVar, Device, + NumDependences, DependenceAddress, HaveNowaitClauseVal}; + + Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_interop_destroy); + + return Builder.CreateCall(Fn, Args); +} + +CallInst *OpenMPIRBuilder::createOMPInteropUse(const LocationDescription &Loc, + Value *InteropVar, + llvm::Value *Device, + llvm::Value *NumDependences, + llvm::Value *DependenceAddress, + int HaveNowaitClause) { + IRBuilder<>::InsertPointGuard IPG(Builder); + Builder.restoreIP(Loc.IP); + Constant *SrcLocStr = getOrCreateSrcLocStr(Loc); + Value *Ident = getOrCreateIdent(SrcLocStr); + Value *ThreadId = getOrCreateThreadID(Ident); + if (Device == NULL) + Device = ConstantInt::get(M.getContext(), APInt(32, -1, true)); + if (NumDependences == nullptr) { + NumDependences = ConstantInt::get(M.getContext(), APInt(32, 0, true)); + PointerType *PointerTy_0 = llvm::Type::getInt8PtrTy(M.getContext()); + DependenceAddress = ConstantPointerNull::get(PointerTy_0); + } + Value *HaveNowaitClauseVal = + ConstantInt::get(M.getContext(), APInt(32, HaveNowaitClause, true)); + Value *Args[] = { + Ident, ThreadId, InteropVar, Device, + NumDependences, DependenceAddress, HaveNowaitClauseVal}; + + Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_interop_use); + + return Builder.CreateCall(Fn, Args); +} + CallInst *OpenMPIRBuilder::createCachedThreadPrivate( const LocationDescription &Loc, llvm::Value *Pointer, llvm::ConstantInt *Size, const llvm::Twine &Name) { Index: llvm/include/llvm/Frontend/OpenMP/OMPKinds.def =================================================================== --- llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -371,6 +371,15 @@ __OMP_RTL(__kmpc_alloc, false, VoidPtr, /* Int */ Int32, SizeTy, VoidPtr) __OMP_RTL(__kmpc_free, false, Void, /* Int */ Int32, VoidPtr, VoidPtr) +__OMP_RTL(__kmpc_interop_init, false, Void, IdentPtr, Int32, VoidPtrPtr, + Int64, Int32, Int32, VoidPtr, Int32) + +__OMP_RTL(__kmpc_interop_destroy, false, Void, IdentPtr, Int32, VoidPtrPtr, + Int32, Int32, VoidPtr, Int32) + +__OMP_RTL(__kmpc_interop_use, false, Void, IdentPtr, Int32, VoidPtrPtr, + Int32, Int32, VoidPtr, Int32) + __OMP_RTL(__kmpc_init_allocator, false, /* omp_allocator_handle_t */ VoidPtr, /* Int */ Int32, /* omp_memespace_handle_t */ VoidPtr, /* Int */ Int32, /* omp_alloctrait_t */ VoidPtr) Index: llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h =================================================================== --- llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -779,6 +779,57 @@ llvm::ConstantInt *Size, const llvm::Twine &Name = Twine("")); + /// Create a runtime call for kmpc_interop_init + /// + /// \param Loc The insert and source location description. + /// \param InteropVar variable to be allocated + /// \param InteropType type of interop operation + /// \param Device devide to which offloading will occur + /// \param NumDependences number of dependence variables + /// \param DependenceAddress pointer to dependence variables + /// \param HaveNowaitClause does nowait clause exist + /// + /// \returns CallInst to the kmpc_interop_init call + CallInst * + createOMPInteropInit(const LocationDescription &Loc, llvm::Value *InteropVar, + OMPInteropType InteropType, llvm::Value *Device, + llvm::Value *NumDependences, + llvm::Value *DependenceAddress, int HaveNowaitClause); + + /// Create a runtime call for kmpc_interop_destroy + /// + /// \param Loc The insert and source location description. + /// \param InteropVar variable to be allocated + /// \param Device devide to which offloading will occur + /// \param NumDependences number of dependence variables + /// \param DependenceAddress pointer to dependence variables + /// \param HaveNowaitClause does nowait clause exist + /// + /// \returns CallInst to the kmpc_interop_destroy call + CallInst *createOMPInteropDestroy(const LocationDescription &Loc, + llvm::Value *InteropVar, + llvm::Value *Device, + llvm::Value *NumDependences, + llvm::Value *DependenceAddress, + int HaveNowaitClause); + + /// Create a runtime call for kmpc_interop_use + /// + /// \param Loc The insert and source location description. + /// \param InteropVar variable to be allocated + /// \param Device devide to which offloading will occur + /// \param NumDependences number of dependence variables + /// \param DependenceAddress pointer to dependence variables + /// \param HaveNowaitClause does nowait clause exist + /// + /// \returns CallInst to the kmpc_interop_use call + CallInst *createOMPInteropUse(const LocationDescription &Loc, + llvm::Value *InteropVar, llvm::Value *Device, + llvm::Value *NumDependences, + llvm::Value *DependenceAddress, + int HaveNowaitClause); + + /// Declarations for LLVM-IR types (simple, array, function and structure) are /// The `omp target` interface /// /// For more information about the usage of this interface, Index: llvm/include/llvm/Frontend/OpenMP/OMPConstants.h =================================================================== --- llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -130,6 +130,8 @@ } // end namespace omp +enum class OMPInteropType { Unknown, Target, TargetSync }; + } // end namespace llvm #endif // LLVM_FRONTEND_OPENMP_OMPCONSTANTS_H Index: clang/test/OpenMP/interop_irbuilder.cpp =================================================================== --- /dev/null +++ clang/test/OpenMP/interop_irbuilder.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -verify -fopenmp -o - %s + +// expected-no-diagnostics +typedef void *omp_interop_t; + +void test1() { + + int device_id = 4; + int D0, D1; + omp_interop_t interop; + + #pragma omp interop init(target: interop) + + #pragma omp interop init(targetsync: interop) + + #pragma omp interop init(target: interop) device(device_id) + + #pragma omp interop init(targetsync: interop) device(device_id) + + #pragma omp interop use(interop) depend(in:D0, D1) nowait + + #pragma omp interop destroy(interop) depend(in:D0, D1) +} + Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -3511,6 +3511,7 @@ const OMPTargetTeamsDistributeParallelForSimdDirective &S); void EmitOMPTargetTeamsDistributeSimdDirective( const OMPTargetTeamsDistributeSimdDirective &S); + void EmitOMPInteropDirective(const OMPInteropDirective &S); /// Emit device code for the target directive. static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, Index: clang/lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- clang/lib/CodeGen/CGStmtOpenMP.cpp +++ clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -6300,6 +6300,65 @@ [](CodeGenFunction &) { return nullptr; }); } +void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) { + llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); + llvm::Value *Device = nullptr; + if (const auto *C = S.getSingleClause<OMPDeviceClause>()) + Device = EmitScalarExpr(C->getDevice()); + + int DependClauseCount = 0; + for (const auto *DC : S.getClausesOfKind<OMPDependClause>()) + DependClauseCount++; + assert(DependClauseCount <= 1 && "Multiple OMPDependClause not supported."); + + llvm::Value *NumDependences = nullptr; + llvm::Value *DependenceAddress = nullptr; + if (const auto *DC = S.getSingleClause<OMPDependClause>()) { + OMPTaskDataTy::DependData Dependencies(DC->getDependencyKind(), + DC->getModifier()); + Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end()); + std::pair<llvm::Value *, Address> DependencePair = + CGM.getOpenMPRuntime().emitDependClause(*this, Dependencies, + DC->getBeginLoc()); + NumDependences = DependencePair.first; + DependenceAddress = Builder.CreatePointerCast( + DependencePair.second.getPointer(), CGM.Int8PtrTy); + } + + int HaveNowaitClause = 0; + if (S.getSingleClause<OMPNowaitClause>()) + HaveNowaitClause = 1; + + if (const auto *C = S.getSingleClause<OMPInitClause>()) { + llvm::Value *InteropvarPtr = + (EmitLValue(C->getInteropVar()).getAddress(*this)).getPointer(); + llvm::OMPInteropType InteropType = llvm::OMPInteropType::Unknown; + if (C->getIsTarget()) + InteropType = llvm::OMPInteropType::Target; + else if (C->getIsTargetSync()) + InteropType = llvm::OMPInteropType::TargetSync; + OMPBuilder.createOMPInteropInit(Builder, InteropvarPtr, InteropType, Device, + NumDependences, DependenceAddress, + HaveNowaitClause); + } else if (const auto *C = S.getSingleClause<OMPDestroyClause>()) { + llvm::Value *InteropvarPtr = + (EmitLValue(C->getInteropVar()).getAddress(*this)).getPointer(); + OMPBuilder.createOMPInteropDestroy(Builder, InteropvarPtr, Device, + NumDependences, DependenceAddress, + HaveNowaitClause); + } else if (const auto *C = S.getSingleClause<OMPUseClause>()) { + llvm::Value *InteropvarPtr = + (EmitLValue(C->getInteropVar()).getAddress(*this)).getPointer(); + OMPBuilder.createOMPInteropUse(Builder, InteropvarPtr, Device, + NumDependences, DependenceAddress, + HaveNowaitClause); + } else if (HaveNowaitClause == true) { + llvm_unreachable("Nowait clause is used separately in Interop Directive."); + } else { + llvm_unreachable("Missing Interop clauses."); + } +} + static void emitTargetTeamsDistributeParallelForRegion( CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S, PrePostActionTy &Action) { Index: clang/lib/CodeGen/CGStmt.cpp =================================================================== --- clang/lib/CodeGen/CGStmt.cpp +++ clang/lib/CodeGen/CGStmt.cpp @@ -381,7 +381,7 @@ cast<OMPTargetTeamsDistributeSimdDirective>(*S)); break; case Stmt::OMPInteropDirectiveClass: - llvm_unreachable("Interop directive not supported yet."); + EmitOMPInteropDirective(cast<OMPInteropDirective>(*S)); break; case Stmt::OMPDispatchDirectiveClass: llvm_unreachable("Dispatch directive not supported yet.");
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits