3939#include " llvm/Transforms/Utils/ValueMapper.h"
4040#include < iostream>
4141
42+ #include " llvm/ADT/StringExtras.h"
43+ #include " llvm/Object/ArchiveWriter.h"
44+ #include " llvm/Object/OffloadBinary.h"
45+ #include " llvm/Support/CommandLine.h"
46+ #include " llvm/Support/FileOutputBuffer.h"
47+ #include " llvm/Support/MemoryBuffer.h"
48+ #include " llvm/Support/Path.h"
49+ #include " llvm/Support/Signals.h"
50+ // #include "llvm/Support/StringSaver.h"
51+ // #include "llvm/Support/WithColor.h"
52+
4253// for raw `write` in the bad-alloc handler
4354#ifdef _MSC_VER
4455#include < io.h>
@@ -57,6 +68,55 @@ using namespace llvm;
5768using namespace llvm ::sys;
5869using namespace llvm ::object;
5970
71+ static Error writeFile (StringRef Filename, StringRef Data) {
72+ Expected<std::unique_ptr<FileOutputBuffer>> OutputOrErr =
73+ FileOutputBuffer::create (Filename, Data.size ());
74+ if (!OutputOrErr)
75+ return OutputOrErr.takeError ();
76+ std::unique_ptr<FileOutputBuffer> Output = std::move (*OutputOrErr);
77+ llvm::copy (Data, Output->getBufferStart ());
78+ if (Error E = Output->commit ())
79+ return E;
80+ return Error::success ();
81+ }
82+
83+ extern " C" bool rustBundleImages () {
84+ SmallVector<char , 1024 > BinaryData;
85+ raw_svector_ostream OS (BinaryData);
86+ BumpPtrAllocator Alloc;
87+ StringSaver Saver (Alloc);
88+
89+ DenseMap<StringRef, StringRef> Args;
90+ Args[" triple" ] = " amdgcn-amd-amdhsa" ; // required
91+ Args[" arch" ] = " gfx90a" ; // optional, but from rustc?
92+
93+ {
94+ OffloadBinary::OffloadingImage ImageBinary{};
95+
96+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ObjectOrErr =
97+ llvm::MemoryBuffer::getFileOrSTDIN (" device.bc" );
98+ if (std::error_code EC = ObjectOrErr.getError ())
99+ return false ;
100+
101+ // Clang uses the '.o' suffix for LTO bitcode.
102+ ImageBinary.TheImageKind = object::IMG_Bitcode;
103+ ImageBinary.Image = std::move (*ObjectOrErr);
104+ ImageBinary.TheOffloadKind = object::OFK_OpenMP;
105+ for (const auto &[Key, Value] : Args) {
106+ ImageBinary.StringData [Key] = Value;
107+ }
108+ llvm::SmallString<0 > Buffer = OffloadBinary::write (ImageBinary);
109+ if (Buffer.size () % OffloadBinary::getAlignment () != 0 )
110+ // "Offload binary has invalid size alignment");
111+ return false ;
112+ OS << Buffer;
113+ }
114+ if (Error E = writeFile (" host.out" ,
115+ StringRef (BinaryData.begin (), BinaryData.size ())))
116+ return false ;
117+ return true ;
118+ }
119+
60120// This opcode is an LLVM detail that could hypothetically change (?), so
61121// verify that the hard-coded value in `dwarf_const.rs` still agrees with LLVM.
62122static_assert (dwarf::DW_OP_LLVM_fragment == 0x1000 );
0 commit comments