@@ -177,7 +177,7 @@ static Error writeFile(StringRef Filename, StringRef Data) {
177177// --image=file=device.bc,triple=amdgcn-amd-amdhsa,arch=gfx90a,kind=openmp
178178// The input module is the rust code compiled for a gpu target like amdgpu.
179179// Based on clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
180- extern " C" bool LLVMRustBundleImages (LLVMModuleRef M, TargetMachine &TM) {
180+ extern " C" bool LLVMRustBundleImages (LLVMModuleRef M, TargetMachine &TM, const char *HostOutPath ) {
181181 std::string Storage;
182182 llvm::raw_string_ostream OS1 (Storage);
183183 llvm::WriteBitcodeToFile (*unwrap (M), OS1);
@@ -202,16 +202,16 @@ extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) {
202202 // Offload binary has invalid size alignment
203203 return false ;
204204 OS2 << Buffer;
205- if (Error E = writeFile (" host.out " ,
205+ if (Error E = writeFile (HostOutPath ,
206206 StringRef (BinaryData.begin (), BinaryData.size ())))
207207 return false ;
208208 return true ;
209209}
210210
211211#include " llvm/Bitcode/BitcodeReader.h"
212212Expected<std::unique_ptr<Module>>
213- loadHostModuleFromBitcode (LLVMContext &Ctx) {
214- auto MBOrErr = MemoryBuffer::getFile (" /g/todo " );
213+ loadHostModuleFromBitcode (LLVMContext &Ctx, StringRef LibBCPath ) {
214+ auto MBOrErr = MemoryBuffer::getFile (LibBCPath );
215215 if (!MBOrErr)
216216 return errorCodeToError (MBOrErr.getError ());
217217
@@ -243,11 +243,15 @@ extern "C" void embedBufferInModule(Module &M, MemoryBufferRef Buf) {
243243}
244244
245245Error embedHostOutIntoHostModule (Module &HostM, StringRef HostOutPath) {
246+ llvm::errs () << " embedHostOutIntoHostModule step 1:\n " ;
246247 auto MBOrErr = MemoryBuffer::getFile (HostOutPath);
248+ llvm::errs () << " embedHostOutIntoHostModule step 2:\n " ;
247249 if (!MBOrErr)
248250 return errorCodeToError (MBOrErr.getError ());
249251
252+ llvm::errs () << " embedHostOutIntoHostModule step 3:\n " ;
250253 MemoryBufferRef Buf = (*MBOrErr)->getMemBufferRef ();
254+ llvm::errs () << " embedHostOutIntoHostModule step 4:\n " ;
251255 embedBufferInModule (HostM, Buf);
252256 return Error::success ();
253257}
@@ -267,8 +271,8 @@ Error emitHostObjectWithTM(Module &HostM,
267271 TargetMachine &TM,
268272 StringRef OutObjPath) {
269273 // Make sure module matches the TM
270- HostM.setDataLayout (TM.createDataLayout ());
271- HostM.setTargetTriple (TM.getTargetTriple ().str ());
274+ // HostM.setDataLayout(TM.createDataLayout());
275+ // HostM.setTargetTriple(TM.getTargetTriple().str());
272276
273277 legacy::PassManager PM;
274278 std::error_code EC;
@@ -304,6 +308,65 @@ extern "C" void LLVMRustOffloadMapper(LLVMValueRef OldFn, LLVMValueRef NewFn) {
304308 returns);
305309}
306310
311+ // Create a host TargetMachine with HARDCODED triple/CPU
312+ static std::unique_ptr<TargetMachine> createHostTargetMachine () {
313+ static bool Initialized = false ;
314+ if (!Initialized) {
315+ InitializeAllTargets ();
316+ InitializeAllTargetMCs ();
317+ InitializeAllAsmPrinters ();
318+ InitializeAllAsmParsers ();
319+ Initialized = true ;
320+ }
321+
322+ // Hardcoded host triple + CPU (adapt if your CI/host differs)
323+ std::string TripleStr = " x86_64-unknown-linux-gnu" ;
324+ std::string CPU = " x86-64" ; // OK for X86
325+
326+ std::string Err;
327+ const Target *T = TargetRegistry::lookupTarget (TripleStr, Err);
328+ if (!T) {
329+ // Could log Err here
330+ return nullptr ;
331+ }
332+
333+ TargetOptions Opts;
334+ auto RM = std::optional<Reloc::Model>(Reloc::PIC_);
335+
336+ std::unique_ptr<TargetMachine> TM (
337+ T->createTargetMachine (TripleStr, CPU, /* Features*/ " " , Opts, RM));
338+
339+ return TM;
340+ }
341+
342+ // Top-level entry: host finalize in second rustc invocation
343+ // lib.bc (from first rustc) + host.out (from LLVMRustBundleImages) => host.offload.o
344+ extern " C" bool LLVMRustFinalizeOffload (const char *LibBCPath,
345+ const char *HostOutPath,
346+ const char *OutObjPath) {
347+ LLVMContext Ctx;
348+
349+ // 1. Load host lib.bc
350+ auto ModOrErr = loadHostModuleFromBitcode (Ctx, LibBCPath);
351+ if (!ModOrErr)
352+ return !errorToBool (ModOrErr.takeError ());
353+ std::unique_ptr<Module> HostM = std::move (*ModOrErr);
354+
355+ // 2. Embed host.out
356+ if (Error E = embedHostOutIntoHostModule (*HostM, HostOutPath))
357+ return !errorToBool (std::move (E));
358+
359+ // 3. Create host TM and emit host object
360+ auto HostTM = createHostTargetMachine ();
361+ if (!HostTM)
362+ return false ;
363+
364+ if (Error E = emitHostObjectWithTM (*HostM, *HostTM, OutObjPath))
365+ return !errorToBool (std::move (E));
366+
367+ return true ;
368+ }
369+
307370extern " C" LLVMValueRef LLVMRustGetNamedValue (LLVMModuleRef M, const char *Name,
308371 size_t NameLen) {
309372 return wrap (unwrap (M)->getNamedValue (StringRef (Name, NameLen)));
0 commit comments