1//===- OffloadEmitter.cpp -------------------------------------------------===//
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#include "llvm/Object/OffloadBinary.h"
10#include "llvm/ObjectYAML/OffloadYAML.h"
11#include "llvm/ObjectYAML/yaml2obj.h"
12#include "llvm/Support/Compression.h"
13#include "llvm/Support/Error.h"
14#include "llvm/Support/raw_ostream.h"
15
16using namespace llvm;
17using namespace OffloadYAML;
18
19namespace llvm {
20namespace yaml {
21
22bool yaml2offload(Binary &Doc, raw_ostream &Out, ErrorHandler EH) {
23 SmallVector<object::OffloadBinary::OffloadingImage> Images;
24 for (const auto &Member : Doc.Members) {
25 object::OffloadBinary::OffloadingImage Image{};
26 if (Member.ImageKind)
27 Image.TheImageKind = *Member.ImageKind;
28 if (Member.OffloadKind)
29 Image.TheOffloadKind = *Member.OffloadKind;
30 if (Member.Flags)
31 Image.Flags = *Member.Flags;
32
33 if (Member.StringEntries)
34 for (const auto &Entry : *Member.StringEntries)
35 Image.StringData[Entry.Key] = Entry.Value;
36
37 SmallVector<char, 1024> Data;
38 raw_svector_ostream OS(Data);
39 if (Member.Content)
40 Member.Content->writeAsBinary(OS);
41 Image.Image = MemoryBuffer::getMemBufferCopy(InputData: OS.str());
42 Images.push_back(Elt: std::move(Image));
43 }
44
45 // Copy the data to a new buffer so we can modify the bytes directly.
46 SmallString<0> Buffer;
47 if (Doc.Compression) {
48 Expected<SmallString<0>> CompressedOrErr = object::OffloadBinary::write(
49 OffloadingData: Images, Compress: compression::Params(*Doc.Compression));
50 if (!CompressedOrErr) {
51 EH(toString(E: CompressedOrErr.takeError()));
52 return false;
53 }
54 Buffer = std::move(*CompressedOrErr);
55 } else {
56 Buffer = object::OffloadBinary::write(OffloadingData: Images);
57 }
58 auto *TheHeader =
59 reinterpret_cast<object::OffloadBinary::Header *>(&Buffer[0]);
60 if (Doc.Version)
61 TheHeader->Version = *Doc.Version;
62 if (Doc.Size)
63 TheHeader->Size = *Doc.Size;
64 if (Doc.EntriesOffset)
65 TheHeader->EntriesOffset = *Doc.EntriesOffset;
66 if (Doc.EntriesCount)
67 TheHeader->EntriesCount = *Doc.EntriesCount;
68
69 Out.write(Ptr: Buffer.begin(), Size: Buffer.size());
70
71 return true;
72}
73
74} // namespace yaml
75} // namespace llvm
76