[clang] [Offloading][NFC] Move creation of offloading entries from OpenMP (PR #70116)

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 24 13:59:48 PDT 2023


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/70116

>From 35347649fe160073e73c3bca96506b6fd96d8a31 Mon Sep 17 00:00:00 2001
From: Joseph Huber <jhuber6 at vols.utk.edu>
Date: Tue, 24 Oct 2023 15:27:21 -0500
Subject: [PATCH] [Offloading][NFC] Move creation of offloading entries from
 OpenMP

Summary:
This patch is a first step to remove dependencies on the OpenMPIRBuilder
for creating generic offloading entires. This patch changes no
functionality and merely moves the code around. In the future the
interface will be changed to allow for more code re-use in the
registeration and creation of offloading entries as well as a more
generic interface for CUDA, HIP, OpenMP, and SYCL(?). Doing this as a
first step to reduce the noise involved in the functional changes.
---
 clang/lib/CodeGen/CGCUDANV.cpp                | 28 +++----
 clang/lib/CodeGen/CMakeLists.txt              |  1 +
 .../llvm/Frontend/Offloading/Utility.h        | 37 +++++++++
 .../llvm/Frontend/OpenMP/OMPIRBuilder.h       | 21 -----
 .../include/llvm/Frontend/OpenMP/OMPKinds.def |  2 -
 llvm/lib/Frontend/CMakeLists.txt              |  1 +
 llvm/lib/Frontend/Offloading/CMakeLists.txt   | 14 ++++
 llvm/lib/Frontend/Offloading/Utility.cpp      | 76 +++++++++++++++++++
 llvm/lib/Frontend/OpenMP/CMakeLists.txt       |  1 +
 llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp     | 43 +----------
 10 files changed, 148 insertions(+), 76 deletions(-)
 create mode 100644 llvm/include/llvm/Frontend/Offloading/Utility.h
 create mode 100644 llvm/lib/Frontend/Offloading/CMakeLists.txt
 create mode 100644 llvm/lib/Frontend/Offloading/Utility.cpp

diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp
index 8a1212f2272e87a..2ef4dc236d091b0 100644
--- a/clang/lib/CodeGen/CGCUDANV.cpp
+++ b/clang/lib/CodeGen/CGCUDANV.cpp
@@ -19,6 +19,7 @@
 #include "clang/Basic/Cuda.h"
 #include "clang/CodeGen/CodeGenABITypes.h"
 #include "clang/CodeGen/ConstantInitBuilder.h"
+#include "llvm/Frontend/Offloading/Utility.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -1129,33 +1130,32 @@ void CGNVCUDARuntime::transformManagedVars() {
 // registered. The linker will provide a pointer to this section so we can
 // register the symbols with the linked device image.
 void CGNVCUDARuntime::createOffloadingEntries() {
-  llvm::OpenMPIRBuilder OMPBuilder(CGM.getModule());
-  OMPBuilder.initialize();
-
   StringRef Section = CGM.getLangOpts().HIP ? "hip_offloading_entries"
                                             : "cuda_offloading_entries";
+  llvm::Module &M = CGM.getModule();
   for (KernelInfo &I : EmittedKernels)
-    OMPBuilder.emitOffloadingEntry(KernelHandles[I.Kernel->getName()],
-                                   getDeviceSideName(cast<NamedDecl>(I.D)), 0,
-                                   DeviceVarFlags::OffloadGlobalEntry, Section);
+    llvm::offloading::emitOffloadingEntry(
+        M, KernelHandles[I.Kernel->getName()],
+        getDeviceSideName(cast<NamedDecl>(I.D)), 0,
+        DeviceVarFlags::OffloadGlobalEntry, Section);
 
   for (VarInfo &I : DeviceVars) {
     uint64_t VarSize =
         CGM.getDataLayout().getTypeAllocSize(I.Var->getValueType());
     if (I.Flags.getKind() == DeviceVarFlags::Variable) {
-      OMPBuilder.emitOffloadingEntry(
-          I.Var, getDeviceSideName(I.D), VarSize,
+      llvm::offloading::emitOffloadingEntry(
+          M, I.Var, getDeviceSideName(I.D), VarSize,
           I.Flags.isManaged() ? DeviceVarFlags::OffloadGlobalManagedEntry
                               : DeviceVarFlags::OffloadGlobalEntry,
           Section);
     } else if (I.Flags.getKind() == DeviceVarFlags::Surface) {
-      OMPBuilder.emitOffloadingEntry(I.Var, getDeviceSideName(I.D), VarSize,
-                                     DeviceVarFlags::OffloadGlobalSurfaceEntry,
-                                     Section);
+      llvm::offloading::emitOffloadingEntry(
+          M, I.Var, getDeviceSideName(I.D), VarSize,
+          DeviceVarFlags::OffloadGlobalSurfaceEntry, Section);
     } else if (I.Flags.getKind() == DeviceVarFlags::Texture) {
-      OMPBuilder.emitOffloadingEntry(I.Var, getDeviceSideName(I.D), VarSize,
-                                     DeviceVarFlags::OffloadGlobalTextureEntry,
-                                     Section);
+      llvm::offloading::emitOffloadingEntry(
+          M, I.Var, getDeviceSideName(I.D), VarSize,
+          DeviceVarFlags::OffloadGlobalTextureEntry, Section);
     }
   }
 }
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index d67ce982d78acf3..da98848e3b44387 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
   Extensions
   FrontendHLSL
   FrontendOpenMP
+  FrontendOffloading
   HIPStdPar
   IPO
   IRPrinter
diff --git a/llvm/include/llvm/Frontend/Offloading/Utility.h b/llvm/include/llvm/Frontend/Offloading/Utility.h
new file mode 100644
index 000000000000000..f74f9e3ff119fd8
--- /dev/null
+++ b/llvm/include/llvm/Frontend/Offloading/Utility.h
@@ -0,0 +1,37 @@
+//===- Utility.h - Collection of geneirc offloading utilities -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/Module.h"
+#include "llvm/Object/OffloadBinary.h"
+
+namespace llvm {
+namespace offloading {
+
+/// Create an offloading section struct used to register this global at
+/// runtime.
+///
+/// Type struct __tgt_offload_entry{
+///   void    *addr;      // Pointer to the offload entry info.
+///                       // (function or global)
+///   char    *name;      // Name of the function or global.
+///   size_t  size;       // Size of the entry info (0 if it a function).
+///   int32_t flags;
+///   int32_t reserved;
+/// };
+///
+/// \param M The module to be used
+/// \param Addr The pointer to the global being registered.
+/// \param Name The symbol name associated with the global.
+/// \param Size The size in bytes of the global (0 for functions).
+/// \param Flags Flags associated with the entry.
+/// \param SectionName The section this entry will be placed at.
+void emitOffloadingEntry(Module &M, Constant *Addr, StringRef Name,
+                         uint64_t Size, int32_t Flags, StringRef SectionName);
+
+} // namespace offloading
+} // namespace llvm
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index 00b4707a7f820d7..c2cfdfd32324dbf 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -1358,27 +1358,6 @@ class OpenMPIRBuilder {
   /// Value.
   GlobalValue *createGlobalFlag(unsigned Value, StringRef Name);
 
-  /// Create an offloading section struct used to register this global at
-  /// runtime.
-  ///
-  /// Type struct __tgt_offload_entry{
-  ///   void    *addr;      // Pointer to the offload entry info.
-  ///                       // (function or global)
-  ///   char    *name;      // Name of the function or global.
-  ///   size_t  size;       // Size of the entry info (0 if it a function).
-  ///   int32_t flags;
-  ///   int32_t reserved;
-  /// };
-  ///
-  /// \param Addr The pointer to the global being registered.
-  /// \param Name The symbol name associated with the global.
-  /// \param Size The size in bytes of the global (0 for functions).
-  /// \param Flags Flags associated with the entry.
-  /// \param SectionName The section this entry will be placed at.
-  void emitOffloadingEntry(Constant *Addr, StringRef Name, uint64_t Size,
-                           int32_t Flags,
-                           StringRef SectionName = "omp_offloading_entries");
-
   /// Generate control flow and cleanup for cancellation.
   ///
   /// \param CancelFlag Flag indicating if the cancellation is performed.
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
index 4823c4cc6b833ec..39780e7c8934cf1 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -88,8 +88,6 @@ __OMP_ARRAY_TYPE(Int32Arr3, Int32, 3)
   OMP_STRUCT_TYPE(VarName, "struct." #Name, Packed, __VA_ARGS__)
 
 __OMP_STRUCT_TYPE(Ident, ident_t, false, Int32, Int32, Int32, Int32, Int8Ptr)
-__OMP_STRUCT_TYPE(OffloadEntry, __tgt_offload_entry, false, Int8Ptr, Int8Ptr, SizeTy,
-                  Int32, Int32)
 __OMP_STRUCT_TYPE(KernelArgs, __tgt_kernel_arguments, false, Int32, Int32, VoidPtrPtr,
 		  VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr,
 		  Int64, Int64, Int32Arr3Ty, Int32Arr3Ty, Int32)
diff --git a/llvm/lib/Frontend/CMakeLists.txt b/llvm/lib/Frontend/CMakeLists.txt
index fa48c975a8b3e5a..5ef092e0a1a9ede 100644
--- a/llvm/lib/Frontend/CMakeLists.txt
+++ b/llvm/lib/Frontend/CMakeLists.txt
@@ -1,3 +1,4 @@
 add_subdirectory(HLSL)
 add_subdirectory(OpenACC)
 add_subdirectory(OpenMP)
+add_subdirectory(Offloading)
diff --git a/llvm/lib/Frontend/Offloading/CMakeLists.txt b/llvm/lib/Frontend/Offloading/CMakeLists.txt
new file mode 100644
index 000000000000000..25eb24785732edf
--- /dev/null
+++ b/llvm/lib/Frontend/Offloading/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_llvm_component_library(LLVMFrontendOffloading
+  Utility.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Frontend
+
+  DEPENDS
+  intrinsics_gen
+
+  LINK_COMPONENTS
+  Core
+  Support
+  TransformUtils
+)
diff --git a/llvm/lib/Frontend/Offloading/Utility.cpp b/llvm/lib/Frontend/Offloading/Utility.cpp
new file mode 100644
index 000000000000000..e676ea27ca9f9e8
--- /dev/null
+++ b/llvm/lib/Frontend/Offloading/Utility.cpp
@@ -0,0 +1,76 @@
+//===- Utility.cpp ------ Collection of geneirc offloading utilities ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Frontend/Offloading/Utility.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Value.h"
+
+using namespace llvm;
+using namespace llvm::offloading;
+
+static IntegerType *getSizeTTy(Module &M) {
+  LLVMContext &C = M.getContext();
+  switch (M.getDataLayout().getPointerTypeSize(Type::getInt8PtrTy(C))) {
+  case 4u:
+    return Type::getInt32Ty(C);
+  case 8u:
+    return Type::getInt64Ty(C);
+  }
+  llvm_unreachable("unsupported pointer type size");
+}
+
+// TODO: Export this to the linker wrapper code registration.
+static StructType *getEntryTy(Module &M) {
+  LLVMContext &C = M.getContext();
+  StructType *EntryTy = StructType::getTypeByName(C, "__tgt_offload_entry");
+  if (!EntryTy)
+    EntryTy = StructType::create("__tgt_offload_entry", Type::getInt8PtrTy(C),
+                                 Type::getInt8PtrTy(C), getSizeTTy(M),
+                                 Type::getInt32Ty(C), Type::getInt32Ty(C));
+  return EntryTy;
+}
+
+// TODO: Rework this interface to be more generic.
+void offloading::emitOffloadingEntry(Module &M, Constant *Addr, StringRef Name,
+                                     uint64_t Size, int32_t Flags,
+                                     StringRef SectionName) {
+  Type *Int8PtrTy = Type::getInt8PtrTy(M.getContext());
+  Type *Int32Ty = Type::getInt32Ty(M.getContext());
+  Type *SizeTy = M.getDataLayout().getIntPtrType(M.getContext());
+
+  Constant *AddrName = ConstantDataArray::getString(M.getContext(), Name);
+
+  // Create the constant string used to look up the symbol in the device.
+  auto *Str =
+      new llvm::GlobalVariable(M, AddrName->getType(), /*isConstant=*/true,
+                               llvm::GlobalValue::InternalLinkage, AddrName,
+                               ".omp_offloading.entry_name");
+  Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+
+  // Construct the offloading entry.
+  Constant *EntryData[] = {
+      ConstantExpr::getPointerBitCastOrAddrSpaceCast(Addr, Int8PtrTy),
+      ConstantExpr::getPointerBitCastOrAddrSpaceCast(Str, Int8PtrTy),
+      ConstantInt::get(SizeTy, Size),
+      ConstantInt::get(Int32Ty, Flags),
+      ConstantInt::get(Int32Ty, 0),
+  };
+  Constant *EntryInitializer = ConstantStruct::get(getEntryTy(M), EntryData);
+
+  auto *Entry = new GlobalVariable(
+      M, getEntryTy(M),
+      /*isConstant=*/true, GlobalValue::WeakAnyLinkage, EntryInitializer,
+      ".omp_offloading.entry." + Name, nullptr, GlobalValue::NotThreadLocal,
+      M.getDataLayout().getDefaultGlobalsAddressSpace());
+
+  // The entry has to be created in the section the linker expects it to be.
+  Entry->setSection(SectionName);
+  Entry->setAlignment(Align(1));
+}
diff --git a/llvm/lib/Frontend/OpenMP/CMakeLists.txt b/llvm/lib/Frontend/OpenMP/CMakeLists.txt
index a2eedabc3ed6903..67aedf5c2b61a5c 100644
--- a/llvm/lib/Frontend/OpenMP/CMakeLists.txt
+++ b/llvm/lib/Frontend/OpenMP/CMakeLists.txt
@@ -20,4 +20,5 @@ add_llvm_component_library(LLVMFrontendOpenMP
   MC
   Scalar
   BitReader
+  FrontendOffloading
   )
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 5b24e9fe2e0c5bd..62c97ff7f292523 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -23,6 +23,7 @@
 #include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/Frontend/Offloading/Utility.h"
 #include "llvm/Frontend/OpenMP/OMPGridValues.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/BasicBlock.h"
@@ -958,44 +959,6 @@ OpenMPIRBuilder::createCancel(const LocationDescription &Loc,
   return Builder.saveIP();
 }
 
-void OpenMPIRBuilder::emitOffloadingEntry(Constant *Addr, StringRef Name,
-                                          uint64_t Size, int32_t Flags,
-                                          StringRef SectionName) {
-  Type *Int8PtrTy = Type::getInt8PtrTy(M.getContext());
-  Type *Int32Ty = Type::getInt32Ty(M.getContext());
-  Type *SizeTy = M.getDataLayout().getIntPtrType(M.getContext());
-
-  Constant *AddrName = ConstantDataArray::getString(M.getContext(), Name);
-
-  // Create the constant string used to look up the symbol in the device.
-  auto *Str =
-      new llvm::GlobalVariable(M, AddrName->getType(), /*isConstant=*/true,
-                               llvm::GlobalValue::InternalLinkage, AddrName,
-                               ".omp_offloading.entry_name");
-  Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-
-  // Construct the offloading entry.
-  Constant *EntryData[] = {
-      ConstantExpr::getPointerBitCastOrAddrSpaceCast(Addr, Int8PtrTy),
-      ConstantExpr::getPointerBitCastOrAddrSpaceCast(Str, Int8PtrTy),
-      ConstantInt::get(SizeTy, Size),
-      ConstantInt::get(Int32Ty, Flags),
-      ConstantInt::get(Int32Ty, 0),
-  };
-  Constant *EntryInitializer =
-      ConstantStruct::get(OpenMPIRBuilder::OffloadEntry, EntryData);
-
-  auto *Entry = new GlobalVariable(
-      M, OpenMPIRBuilder::OffloadEntry,
-      /* isConstant = */ true, GlobalValue::WeakAnyLinkage, EntryInitializer,
-      ".omp_offloading.entry." + Name, nullptr, GlobalValue::NotThreadLocal,
-      M.getDataLayout().getDefaultGlobalsAddressSpace());
-
-  // The entry has to be created in the section the linker expects it to be.
-  Entry->setSection(SectionName);
-  Entry->setAlignment(Align(1));
-}
-
 OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::emitTargetKernel(
     const LocationDescription &Loc, InsertPointTy AllocaIP, Value *&Return,
     Value *Ident, Value *DeviceID, Value *NumTeams, Value *NumThreads,
@@ -5928,7 +5891,9 @@ void OpenMPIRBuilder::createOffloadEntry(Constant *ID, Constant *Addr,
                                          GlobalValue::LinkageTypes,
                                          StringRef Name) {
   if (!Config.isGPU()) {
-    emitOffloadingEntry(ID, Name.empty() ? Addr->getName() : Name, Size, Flags);
+    llvm::offloading::emitOffloadingEntry(
+        M, ID, Name.empty() ? Addr->getName() : Name, Size, Flags,
+        "omp_offloading_entries");
     return;
   }
   // TODO: Add support for global variables on the device after declare target



More information about the cfe-commits mailing list