Skip to content

Commit

Permalink
[llvm][frontend][offloading] Move clang-linker-wrapper/OffloadWrapper…
Browse files Browse the repository at this point in the history
….* to llvm/Frontend/Offloading (llvm#78057)

This patch moves `clang/tools/clang-linker-wrapper/OffloadWrapper.*` to
`llvm/Frontend/Offloading` allowing them to be re-utilized by other
projects.

Additionally, it makes minor modifications to the API to make it more
flexible.
Concretely:
 - The `wrap*` methods now have additional arguments `EntryArray`, 
`Suffix` and `EmitSurfacesAndTextures` to specify some additional options.
- The `EntryArray` is now constructed by the caller. This change is needed to
enable JIT compilation, as ORC doesn't fully support `__start_` and `__stop_` 
symbols. Thus, to JIT the code, the `EntryArray` has to be constructed explicitly in the IR.
- The `Suffix` field is used when emitting the descriptor, registration
methods, etc, to make them more readable. It is empty by default.
- The `EmitSurfacesAndTextures` field controls whether to emit surface
and texture registration code, as those functions were removed from `CUDART`
in CUDA 12. It is true by default.
- The function `getOffloadingEntryInitializer` was added to help create
the `EntryArray`, as it returns the constant initializer and not a global
variable.
  • Loading branch information
fabianmcg authored and justinfargnoli committed Jan 28, 2024
1 parent 487f7d0 commit 31c4ec4
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 94 deletions.
16 changes: 8 additions & 8 deletions clang/test/Driver/linker-wrapper-image.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@
// RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-windows-gnu \
// RUN: --linker-path=/usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefixes=CUDA,CUDA-COFF

// CUDA: @.fatbin_image = internal constant [0 x i8] zeroinitializer, section ".nv_fatbin"
// CUDA-NEXT: @.fatbin_wrapper = internal constant %fatbin_wrapper { i32 1180844977, i32 1, ptr @.fatbin_image, ptr null }, section ".nvFatBinSegment", align 8
// CUDA-NEXT: @.cuda.binary_handle = internal global ptr null

// CUDA-ELF: @__start_cuda_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry]
// CUDA-ELF-NEXT: @__stop_cuda_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry]
// CUDA-ELF-NEXT: @__dummy.cuda_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "cuda_offloading_entries"

// CUDA-COFF: @__start_cuda_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "cuda_offloading_entries$OA"
// CUDA-COFF-NEXT: @__stop_cuda_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "cuda_offloading_entries$OZ"

// CUDA: @.fatbin_image = internal constant [0 x i8] zeroinitializer, section ".nv_fatbin"
// CUDA-NEXT: @.fatbin_wrapper = internal constant %fatbin_wrapper { i32 1180844977, i32 1, ptr @.fatbin_image, ptr null }, section ".nvFatBinSegment", align 8
// CUDA-NEXT: @.cuda.binary_handle = internal global ptr null

// CUDA: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.cuda.fatbin_reg, ptr null }]

// CUDA: define internal void @.cuda.fatbin_reg() section ".text.startup" {
Expand Down Expand Up @@ -145,17 +145,17 @@
// RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-windows-gnu \
// RUN: --linker-path=/usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefixes=HIP,HIP-COFF

// HIP: @.fatbin_image = internal constant [0 x i8] zeroinitializer, section ".hip_fatbin"
// HIP-NEXT: @.fatbin_wrapper = internal constant %fatbin_wrapper { i32 1212764230, i32 1, ptr @.fatbin_image, ptr null }, section ".hipFatBinSegment", align 8
// HIP-NEXT: @.hip.binary_handle = internal global ptr null

// HIP-ELF: @__start_hip_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry]
// HIP-ELF-NEXT: @__stop_hip_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry]
// HIP-ELF-NEXT: @__dummy.hip_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "hip_offloading_entries"

// HIP-COFF: @__start_hip_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "hip_offloading_entries$OA"
// HIP-COFF-NEXT: @__stop_hip_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "hip_offloading_entries$OZ"

// HIP: @.fatbin_image = internal constant [0 x i8] zeroinitializer, section ".hip_fatbin"
// HIP-NEXT: @.fatbin_wrapper = internal constant %fatbin_wrapper { i32 1212764230, i32 1, ptr @.fatbin_image, ptr null }, section ".hipFatBinSegment", align 8
// HIP-NEXT: @.hip.binary_handle = internal global ptr null

// HIP: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.hip.fatbin_reg, ptr null }]

// HIP: define internal void @.hip.fatbin_reg() section ".text.startup" {
Expand Down
1 change: 0 additions & 1 deletion clang/tools/clang-linker-wrapper/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ endif()

add_clang_tool(clang-linker-wrapper
ClangLinkerWrapper.cpp
OffloadWrapper.cpp

DEPENDS
${tablegen_deps}
Expand Down
15 changes: 11 additions & 4 deletions clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
//
//===---------------------------------------------------------------------===//

#include "OffloadWrapper.h"
#include "clang/Basic/Version.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/Frontend/Offloading/OffloadWrapper.h"
#include "llvm/Frontend/Offloading/Utility.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Module.h"
Expand Down Expand Up @@ -906,15 +907,21 @@ wrapDeviceImages(ArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,

switch (Kind) {
case OFK_OpenMP:
if (Error Err = wrapOpenMPBinaries(M, BuffersToWrap))
if (Error Err = offloading::wrapOpenMPBinaries(
M, BuffersToWrap,
offloading::getOffloadEntryArray(M, "omp_offloading_entries")))
return std::move(Err);
break;
case OFK_Cuda:
if (Error Err = wrapCudaBinary(M, BuffersToWrap.front()))
if (Error Err = offloading::wrapCudaBinary(
M, BuffersToWrap.front(),
offloading::getOffloadEntryArray(M, "cuda_offloading_entries")))
return std::move(Err);
break;
case OFK_HIP:
if (Error Err = wrapHIPBinary(M, BuffersToWrap.front()))
if (Error Err = offloading::wrapHIPBinary(
M, BuffersToWrap.front(),
offloading::getOffloadEntryArray(M, "hip_offloading_entries")))
return std::move(Err);
break;
default:
Expand Down
28 changes: 0 additions & 28 deletions clang/tools/clang-linker-wrapper/OffloadWrapper.h

This file was deleted.

52 changes: 52 additions & 0 deletions llvm/include/llvm/Frontend/Offloading/OffloadWrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//===- OffloadWrapper.h --r-------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_FRONTEND_OFFLOADING_OFFLOADWRAPPER_H
#define LLVM_FRONTEND_OFFLOADING_OFFLOADWRAPPER_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/Module.h"

namespace llvm {
namespace offloading {
using EntryArrayTy = std::pair<GlobalVariable *, GlobalVariable *>;
/// Wraps the input device images into the module \p M as global symbols and
/// registers the images with the OpenMP Offloading runtime libomptarget.
/// \param EntryArray Optional pair pointing to the `__start` and `__stop`
/// symbols holding the `__tgt_offload_entry` array.
/// \param Suffix An optional suffix appended to the emitted symbols.
llvm::Error wrapOpenMPBinaries(llvm::Module &M,
llvm::ArrayRef<llvm::ArrayRef<char>> Images,
EntryArrayTy EntryArray,
llvm::StringRef Suffix = "");

/// Wraps the input fatbinary image into the module \p M as global symbols and
/// registers the images with the CUDA runtime.
/// \param EntryArray Optional pair pointing to the `__start` and `__stop`
/// symbols holding the `__tgt_offload_entry` array.
/// \param Suffix An optional suffix appended to the emitted symbols.
/// \param EmitSurfacesAndTextures Whether to emit surface and textures
/// registration code. It defaults to false.
llvm::Error wrapCudaBinary(llvm::Module &M, llvm::ArrayRef<char> Images,
EntryArrayTy EntryArray, llvm::StringRef Suffix = "",
bool EmitSurfacesAndTextures = true);

/// Wraps the input bundled image into the module \p M as global symbols and
/// registers the images with the HIP runtime.
/// \param EntryArray Optional pair pointing to the `__start` and `__stop`
/// symbols holding the `__tgt_offload_entry` array.
/// \param Suffix An optional suffix appended to the emitted symbols.
/// \param EmitSurfacesAndTextures Whether to emit surface and textures
/// registration code. It defaults to false.
llvm::Error wrapHIPBinary(llvm::Module &M, llvm::ArrayRef<char> Images,
EntryArrayTy EntryArray, llvm::StringRef Suffix = "",
bool EmitSurfacesAndTextures = true);
} // namespace offloading
} // namespace llvm

#endif // LLVM_FRONTEND_OFFLOADING_OFFLOADWRAPPER_H
6 changes: 6 additions & 0 deletions llvm/include/llvm/Frontend/Offloading/Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ StructType *getEntryTy(Module &M);
void emitOffloadingEntry(Module &M, Constant *Addr, StringRef Name,
uint64_t Size, int32_t Flags, int32_t Data,
StringRef SectionName);
/// Create a constant struct initializer used to register this global at
/// runtime.
/// \return the constant struct and the global variable holding the symbol name.
std::pair<Constant *, GlobalVariable *>
getOffloadingEntryInitializer(Module &M, Constant *Addr, StringRef Name,
uint64_t Size, int32_t Flags, int32_t Data);

/// Creates a pair of globals used to iterate the array of offloading entries by
/// accessing the section variables provided by the linker.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Frontend/Offloading/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_llvm_component_library(LLVMFrontendOffloading
Utility.cpp
OffloadWrapper.cpp

ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/Frontend
Expand All @@ -9,6 +10,7 @@ add_llvm_component_library(LLVMFrontendOffloading

LINK_COMPONENTS
Core
BinaryFormat
Support
TransformUtils
TargetParser
Expand Down
Loading

0 comments on commit 31c4ec4

Please sign in to comment.