4545#ifdef OFFLOAD
4646#include " llvm/Object/OffloadBinary.h"
4747#include " llvm/Target/TargetMachine.h"
48+ #include " llvm/Transforms/Utils/ModuleUtils.h"
49+ #include " llvm/Analysis/VectorUtils.h"
50+ #include " llvm/ADT/SmallString.h"
51+ #include " llvm/IR/DerivedTypes.h"
52+ #include " llvm/IR/Function.h"
53+ #include " llvm/IR/IRBuilder.h"
54+ #include " llvm/IR/MDBuilder.h"
55+ #include " llvm/IR/Module.h"
56+ #include " llvm/Support/Casting.h"
57+ #include " llvm/Support/MD5.h"
58+ #include " llvm/Support/raw_ostream.h"
59+ #include " llvm/Support/xxhash.h"
4860#endif
4961
5062// for raw `write` in the bad-alloc handler
@@ -179,7 +191,7 @@ extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) {
179191 llvm::raw_string_ostream OS1 (Storage);
180192 llvm::WriteBitcodeToFile (*unwrap (M), OS1);
181193 OS1.flush ();
182- auto MB = llvm::MemoryBuffer::getMemBufferCopy (Storage, " module .bc" );
194+ auto MB = llvm::MemoryBuffer::getMemBufferCopy (Storage, " device .bc" );
183195
184196 SmallVector<char , 1024 > BinaryData;
185197 raw_svector_ostream OS2 (BinaryData);
@@ -188,8 +200,12 @@ extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) {
188200 ImageBinary.TheImageKind = object::IMG_Bitcode;
189201 ImageBinary.Image = std::move (MB);
190202 ImageBinary.TheOffloadKind = object::OFK_OpenMP;
191- ImageBinary.StringData [" triple" ] = TM.getTargetTriple ().str ();
192- ImageBinary.StringData [" arch" ] = TM.getTargetCPU ();
203+
204+
205+ std::string TripleStr = TM.getTargetTriple ().str ();
206+ llvm::StringRef CPURef = TM.getTargetCPU ();
207+ ImageBinary.StringData [" triple" ] = TripleStr;
208+ ImageBinary.StringData [" arch" ] = CPURef;
193209 llvm::SmallString<0 > Buffer = OffloadBinary::write (ImageBinary);
194210 if (Buffer.size () % OffloadBinary::getAlignment () != 0 )
195211 // Offload binary has invalid size alignment
@@ -201,6 +217,82 @@ extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) {
201217 return true ;
202218}
203219
220+ #include " llvm/Bitcode/BitcodeReader.h"
221+ Expected<std::unique_ptr<Module>>
222+ loadHostModuleFromBitcode (LLVMContext &Ctx) {
223+ auto MBOrErr = MemoryBuffer::getFile (" /g/todo" );
224+ if (!MBOrErr)
225+ return errorCodeToError (MBOrErr.getError ());
226+
227+ MemoryBufferRef Ref = (*MBOrErr)->getMemBufferRef ();
228+ return parseBitcodeFile (Ref, Ctx);
229+ }
230+
231+ extern " C" void embedBufferInModule (Module &M, MemoryBufferRef Buf) {
232+ StringRef SectionName = " .llvm.offloading" ;
233+ Align Alignment = Align (8 );
234+ // Embed the memory buffer into the module.
235+ Constant *ModuleConstant = ConstantDataArray::get (
236+ M.getContext (), ArrayRef (Buf.getBufferStart (), Buf.getBufferSize ()));
237+ GlobalVariable *GV = new GlobalVariable (
238+ M, ModuleConstant->getType (), true , GlobalValue::PrivateLinkage,
239+ ModuleConstant, " llvm.embedded.object" );
240+ GV->setSection (SectionName);
241+ GV->setAlignment (Alignment);
242+
243+ LLVMContext &Ctx = M.getContext ();
244+ NamedMDNode *MD = M.getOrInsertNamedMetadata (" llvm.embedded.objects" );
245+ Metadata *MDVals[] = {ConstantAsMetadata::get (GV),
246+ MDString::get (Ctx, SectionName)};
247+
248+ MD->addOperand (llvm::MDNode::get (Ctx, MDVals));
249+ GV->setMetadata (LLVMContext::MD_exclude, llvm::MDNode::get (Ctx, {}));
250+
251+ appendToCompilerUsed (M, GV);
252+ }
253+
254+ Error embedHostOutIntoHostModule (Module &HostM, StringRef HostOutPath) {
255+ auto MBOrErr = MemoryBuffer::getFile (HostOutPath);
256+ if (!MBOrErr)
257+ return errorCodeToError (MBOrErr.getError ());
258+
259+ MemoryBufferRef Buf = (*MBOrErr)->getMemBufferRef ();
260+ embedBufferInModule (HostM, Buf);
261+ return Error::success ();
262+ }
263+
264+ #include " llvm/Support/TargetSelect.h"
265+ #include " llvm/Target/TargetMachine.h"
266+ #include " llvm/Target/TargetOptions.h"
267+ #include " llvm/IR/LegacyPassManager.h"
268+ // #include "llvm/Support/Host.h"
269+ // #include "llvm/Support/TargetRegistry.h"
270+ #include " llvm/MC/TargetRegistry.h"
271+ #include " llvm/Support/raw_ostream.h"
272+ #include " llvm/Support/FileSystem.h"
273+ #include " llvm/Support/CodeGen.h" // <-- new
274+
275+ Error emitHostObjectWithTM (Module &HostM,
276+ TargetMachine &TM,
277+ StringRef OutObjPath) {
278+ // Make sure module matches the TM
279+ HostM.setDataLayout (TM.createDataLayout ());
280+ HostM.setTargetTriple (TM.getTargetTriple ().str ());
281+
282+ legacy::PassManager PM;
283+ std::error_code EC;
284+ raw_fd_ostream OS (OutObjPath, EC, sys::fs::OF_None);
285+ if (EC)
286+ return errorCodeToError (EC);
287+
288+ if (TM.addPassesToEmitFile (PM, OS, nullptr , llvm::CodeGenFileType::ObjectFile))
289+ return createStringError (inconvertibleErrorCode (),
290+ " TargetMachine can't emit a file of this type" );
291+
292+ PM.run (HostM);
293+ return Error::success ();
294+ }
295+
204296extern " C" void LLVMRustOffloadMapper (LLVMValueRef OldFn, LLVMValueRef NewFn) {
205297 llvm::Function *oldFn = llvm::unwrap<llvm::Function>(OldFn);
206298 llvm::Function *newFn = llvm::unwrap<llvm::Function>(NewFn);
0 commit comments