Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===--- Offloading.h - Utilities for handling offloading code  -*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file contains the binary format used for budingling device metadata with
10
// an associated device image. The data can then be stored inside a host object
11
// file to create a fat binary and read by the linker. This is intended to be a
12
// thin wrapper around the image itself. If this format becomes sufficiently
13
// complex it should be moved to a standard binary format like msgpack or ELF.
14
//
15
//===----------------------------------------------------------------------===//
16
 
17
#ifndef LLVM_OBJECT_OFFLOADBINARY_H
18
#define LLVM_OBJECT_OFFLOADBINARY_H
19
 
20
#include "llvm/ADT/StringMap.h"
21
#include "llvm/ADT/StringRef.h"
22
#include "llvm/Object/Binary.h"
23
#include "llvm/Support/Error.h"
24
#include "llvm/Support/MemoryBuffer.h"
25
#include <memory>
26
 
27
namespace llvm {
28
 
29
namespace object {
30
 
31
/// The producer of the associated offloading image.
32
enum OffloadKind : uint16_t {
33
  OFK_None = 0,
34
  OFK_OpenMP,
35
  OFK_Cuda,
36
  OFK_HIP,
37
  OFK_LAST,
38
};
39
 
40
/// The type of contents the offloading image contains.
41
enum ImageKind : uint16_t {
42
  IMG_None = 0,
43
  IMG_Object,
44
  IMG_Bitcode,
45
  IMG_Cubin,
46
  IMG_Fatbinary,
47
  IMG_PTX,
48
  IMG_LAST,
49
};
50
 
51
/// A simple binary serialization of an offloading file. We use this format to
52
/// embed the offloading image into the host executable so it can be extracted
53
/// and used by the linker.
54
///
55
/// Many of these could be stored in the same section by the time the linker
56
/// sees it so we mark this information with a header. The version is used to
57
/// detect ABI stability and the size is used to find other offloading entries
58
/// that may exist in the same section. All offsets are given as absolute byte
59
/// offsets from the beginning of the file.
60
class OffloadBinary : public Binary {
61
public:
62
  using string_iterator = StringMap<StringRef>::const_iterator;
63
  using string_iterator_range = iterator_range<string_iterator>;
64
 
65
  /// The current version of the binary used for backwards compatibility.
66
  static const uint32_t Version = 1;
67
 
68
  /// The offloading metadata that will be serialized to a memory buffer.
69
  struct OffloadingImage {
70
    ImageKind TheImageKind;
71
    OffloadKind TheOffloadKind;
72
    uint32_t Flags;
73
    StringMap<StringRef> StringData;
74
    std::unique_ptr<MemoryBuffer> Image;
75
  };
76
 
77
  /// Attempt to parse the offloading binary stored in \p Data.
78
  static Expected<std::unique_ptr<OffloadBinary>> create(MemoryBufferRef);
79
 
80
  /// Serialize the contents of \p File to a binary buffer to be read later.
81
  static std::unique_ptr<MemoryBuffer> write(const OffloadingImage &);
82
 
83
  static uint64_t getAlignment() { return 8; }
84
 
85
  ImageKind getImageKind() const { return TheEntry->TheImageKind; }
86
  OffloadKind getOffloadKind() const { return TheEntry->TheOffloadKind; }
87
  uint32_t getVersion() const { return TheHeader->Version; }
88
  uint32_t getFlags() const { return TheEntry->Flags; }
89
  uint64_t getSize() const { return TheHeader->Size; }
90
 
91
  StringRef getTriple() const { return getString("triple"); }
92
  StringRef getArch() const { return getString("arch"); }
93
  StringRef getImage() const {
94
    return StringRef(&Buffer[TheEntry->ImageOffset], TheEntry->ImageSize);
95
  }
96
 
97
  // Iterator over all the key and value pairs in the binary.
98
  string_iterator_range strings() const {
99
    return string_iterator_range(StringData.begin(), StringData.end());
100
  }
101
 
102
  StringRef getString(StringRef Key) const { return StringData.lookup(Key); }
103
 
104
  static bool classof(const Binary *V) { return V->isOffloadFile(); }
105
 
106
  struct Header {
107
    uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes.
108
    uint32_t Version = OffloadBinary::Version;   // Version identifier.
109
    uint64_t Size;        // Size in bytes of this entire binary.
110
    uint64_t EntryOffset; // Offset of the metadata entry in bytes.
111
    uint64_t EntrySize;   // Size of the metadata entry in bytes.
112
  };
113
 
114
  struct Entry {
115
    ImageKind TheImageKind;     // The kind of the image stored.
116
    OffloadKind TheOffloadKind; // The producer of this image.
117
    uint32_t Flags;             // Additional flags associated with the image.
118
    uint64_t StringOffset;      // Offset in bytes to the string map.
119
    uint64_t NumStrings;        // Number of entries in the string map.
120
    uint64_t ImageOffset;       // Offset in bytes of the actual binary image.
121
    uint64_t ImageSize;         // Size in bytes of the binary image.
122
  };
123
 
124
  struct StringEntry {
125
    uint64_t KeyOffset;
126
    uint64_t ValueOffset;
127
  };
128
 
129
private:
130
  OffloadBinary(MemoryBufferRef Source, const Header *TheHeader,
131
                const Entry *TheEntry)
132
      : Binary(Binary::ID_Offload, Source), Buffer(Source.getBufferStart()),
133
        TheHeader(TheHeader), TheEntry(TheEntry) {
134
    const StringEntry *StringMapBegin =
135
        reinterpret_cast<const StringEntry *>(&Buffer[TheEntry->StringOffset]);
136
    for (uint64_t I = 0, E = TheEntry->NumStrings; I != E; ++I) {
137
      StringRef Key = &Buffer[StringMapBegin[I].KeyOffset];
138
      StringData[Key] = &Buffer[StringMapBegin[I].ValueOffset];
139
    }
140
  }
141
 
142
  OffloadBinary(const OffloadBinary &Other) = delete;
143
 
144
  /// Map from keys to offsets in the binary.
145
  StringMap<StringRef> StringData;
146
  /// Raw pointer to the MemoryBufferRef for convenience.
147
  const char *Buffer;
148
  /// Location of the header within the binary.
149
  const Header *TheHeader;
150
  /// Location of the metadata entries within the binary.
151
  const Entry *TheEntry;
152
};
153
 
154
/// A class to contain the binary information for a single OffloadBinary that
155
/// owns its memory.
156
class OffloadFile : public OwningBinary<OffloadBinary> {
157
public:
158
  using TargetID = std::pair<StringRef, StringRef>;
159
 
160
  OffloadFile(std::unique_ptr<OffloadBinary> Binary,
161
              std::unique_ptr<MemoryBuffer> Buffer)
162
      : OwningBinary<OffloadBinary>(std::move(Binary), std::move(Buffer)) {}
163
 
164
  /// We use the Triple and Architecture pair to group linker inputs together.
165
  /// This conversion function lets us use these inputs in a hash-map.
166
  operator TargetID() const {
167
    return std::make_pair(getBinary()->getTriple(), getBinary()->getArch());
168
  }
169
};
170
 
171
/// Extracts embedded device offloading code from a memory \p Buffer to a list
172
/// of \p Binaries.
173
Error extractOffloadBinaries(MemoryBufferRef Buffer,
174
                             SmallVectorImpl<OffloadFile> &Binaries);
175
 
176
/// Convert a string \p Name to an image kind.
177
ImageKind getImageKind(StringRef Name);
178
 
179
/// Convert an image kind to its string representation.
180
StringRef getImageKindName(ImageKind Name);
181
 
182
/// Convert a string \p Name to an offload kind.
183
OffloadKind getOffloadKind(StringRef Name);
184
 
185
/// Convert an offload kind to its string representation.
186
StringRef getOffloadKindName(OffloadKind Name);
187
 
188
} // namespace object
189
 
190
} // namespace llvm
191
#endif