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
  • [PATCH] D105876... Sri Hari Krishna Narayanan via Phabricator via cfe-commits
    • [PATCH] D1... Johannes Doerfert via Phabricator via cfe-commits
    • [PATCH] D1... Alexey Bataev via Phabricator via cfe-commits
    • [PATCH] D1... Sri Hari Krishna Narayanan via Phabricator via cfe-commits
    • [PATCH] D1... Alexey Bataev via Phabricator via cfe-commits
    • [PATCH] D1... Sri Hari Krishna Narayanan via Phabricator via cfe-commits
    • [PATCH] D1... Johannes Doerfert via Phabricator via cfe-commits
    • [PATCH] D1... Sri Hari Krishna Narayanan via Phabricator via cfe-commits
    • [PATCH] D1... Sri Hari Krishna Narayanan via Phabricator via cfe-commits
    • [PATCH] D1... Alexey Bataev via Phabricator via cfe-commits
    • [PATCH] D1... Sri Hari Krishna Narayanan via Phabricator via cfe-commits

Reply via email to