4141#include " llvm/Transforms/Utils/ValueMapper.h"
4242#include < iostream>
4343
44+ #include " llvm/Transforms/Utils/ModuleUtils.h"
45+ #include " llvm/Analysis/VectorUtils.h"
46+ #include " llvm/ADT/SmallString.h"
47+ #include " llvm/IR/DerivedTypes.h"
48+ #include " llvm/IR/Function.h"
49+ #include " llvm/IR/IRBuilder.h"
50+ #include " llvm/IR/MDBuilder.h"
51+ #include " llvm/IR/Module.h"
52+ #include " llvm/Support/Casting.h"
53+ #include " llvm/Support/MD5.h"
54+ #include " llvm/Support/raw_ostream.h"
55+ #include " llvm/Support/xxhash.h"
56+
4457// for raw `write` in the bad-alloc handler
4558#ifdef _MSC_VER
4659#include < io.h>
@@ -169,7 +182,7 @@ extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) {
169182 llvm::raw_string_ostream OS1 (Storage);
170183 llvm::WriteBitcodeToFile (*unwrap (M), OS1);
171184 OS1.flush ();
172- auto MB = llvm::MemoryBuffer::getMemBufferCopy (Storage, " module .bc" );
185+ auto MB = llvm::MemoryBuffer::getMemBufferCopy (Storage, " device .bc" );
173186
174187 SmallVector<char , 1024 > BinaryData;
175188 raw_svector_ostream OS2 (BinaryData);
@@ -178,8 +191,12 @@ extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) {
178191 ImageBinary.TheImageKind = object::IMG_Bitcode;
179192 ImageBinary.Image = std::move (MB);
180193 ImageBinary.TheOffloadKind = object::OFK_OpenMP;
181- ImageBinary.StringData [" triple" ] = TM.getTargetTriple ().str ();
182- ImageBinary.StringData [" arch" ] = TM.getTargetCPU ();
194+
195+
196+ std::string TripleStr = TM.getTargetTriple ().str ();
197+ llvm::StringRef CPURef = TM.getTargetCPU ();
198+ ImageBinary.StringData [" triple" ] = TripleStr;
199+ ImageBinary.StringData [" arch" ] = CPURef;
183200 llvm::SmallString<0 > Buffer = OffloadBinary::write (ImageBinary);
184201 if (Buffer.size () % OffloadBinary::getAlignment () != 0 )
185202 // Offload binary has invalid size alignment
@@ -191,6 +208,82 @@ extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) {
191208 return true ;
192209}
193210
211+ #include " llvm/Bitcode/BitcodeReader.h"
212+ Expected<std::unique_ptr<Module>>
213+ loadHostModuleFromBitcode (LLVMContext &Ctx) {
214+ auto MBOrErr = MemoryBuffer::getFile (" /g/todo" );
215+ if (!MBOrErr)
216+ return errorCodeToError (MBOrErr.getError ());
217+
218+ MemoryBufferRef Ref = (*MBOrErr)->getMemBufferRef ();
219+ return parseBitcodeFile (Ref, Ctx);
220+ }
221+
222+ extern " C" void embedBufferInModule (Module &M, MemoryBufferRef Buf) {
223+ StringRef SectionName = " .llvm.offloading" ;
224+ Align Alignment = Align (8 );
225+ // Embed the memory buffer into the module.
226+ Constant *ModuleConstant = ConstantDataArray::get (
227+ M.getContext (), ArrayRef (Buf.getBufferStart (), Buf.getBufferSize ()));
228+ GlobalVariable *GV = new GlobalVariable (
229+ M, ModuleConstant->getType (), true , GlobalValue::PrivateLinkage,
230+ ModuleConstant, " llvm.embedded.object" );
231+ GV->setSection (SectionName);
232+ GV->setAlignment (Alignment);
233+
234+ LLVMContext &Ctx = M.getContext ();
235+ NamedMDNode *MD = M.getOrInsertNamedMetadata (" llvm.embedded.objects" );
236+ Metadata *MDVals[] = {ConstantAsMetadata::get (GV),
237+ MDString::get (Ctx, SectionName)};
238+
239+ MD->addOperand (llvm::MDNode::get (Ctx, MDVals));
240+ GV->setMetadata (LLVMContext::MD_exclude, llvm::MDNode::get (Ctx, {}));
241+
242+ appendToCompilerUsed (M, GV);
243+ }
244+
245+ Error embedHostOutIntoHostModule (Module &HostM, StringRef HostOutPath) {
246+ auto MBOrErr = MemoryBuffer::getFile (HostOutPath);
247+ if (!MBOrErr)
248+ return errorCodeToError (MBOrErr.getError ());
249+
250+ MemoryBufferRef Buf = (*MBOrErr)->getMemBufferRef ();
251+ embedBufferInModule (HostM, Buf);
252+ return Error::success ();
253+ }
254+
255+ #include " llvm/Support/TargetSelect.h"
256+ #include " llvm/Target/TargetMachine.h"
257+ #include " llvm/Target/TargetOptions.h"
258+ #include " llvm/IR/LegacyPassManager.h"
259+ // #include "llvm/Support/Host.h"
260+ // #include "llvm/Support/TargetRegistry.h"
261+ #include " llvm/MC/TargetRegistry.h"
262+ #include " llvm/Support/raw_ostream.h"
263+ #include " llvm/Support/FileSystem.h"
264+ #include " llvm/Support/CodeGen.h" // <-- new
265+
266+ Error emitHostObjectWithTM (Module &HostM,
267+ TargetMachine &TM,
268+ StringRef OutObjPath) {
269+ // Make sure module matches the TM
270+ HostM.setDataLayout (TM.createDataLayout ());
271+ HostM.setTargetTriple (TM.getTargetTriple ().str ());
272+
273+ legacy::PassManager PM;
274+ std::error_code EC;
275+ raw_fd_ostream OS (OutObjPath, EC, sys::fs::OF_None);
276+ if (EC)
277+ return errorCodeToError (EC);
278+
279+ if (TM.addPassesToEmitFile (PM, OS, nullptr , llvm::CodeGenFileType::ObjectFile))
280+ return createStringError (inconvertibleErrorCode (),
281+ " TargetMachine can't emit a file of this type" );
282+
283+ PM.run (HostM);
284+ return Error::success ();
285+ }
286+
194287extern " C" void LLVMRustOffloadMapper (LLVMValueRef OldFn, LLVMValueRef NewFn) {
195288 llvm::Function *oldFn = llvm::unwrap<llvm::Function>(OldFn);
196289 llvm::Function *newFn = llvm::unwrap<llvm::Function>(NewFn);
0 commit comments