void SimpleModuleProvider::UnwrapModuleContainer(llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const { StreamFile.init((const unsigned char *)Buffer.getBufferStart(), (const unsigned char *)Buffer.getBufferEnd()); }
void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBufferRef _object) { Guard g{x_cacheMutex}; // Only in "on" and "write" mode if (g_mode != CacheMode::on && g_mode != CacheMode::write) return; // TODO: Disabled because is not thread-safe. // if (g_listener) // g_listener->stateChanged(ExecState::CacheWrite); auto&& id = _module->getModuleIdentifier(); llvm::SmallString<256> cachePath{getVersionedCacheDir()}; if (auto err = llvm::sys::fs::create_directories(cachePath)) { DLOG(cache) << "Cannot create cache dir " << cachePath.str().str() << " (error: " << err.message() << "\n"; return; } llvm::sys::path::append(cachePath, id); DLOG(cache) << id << ": write\n"; std::error_code error; llvm::raw_fd_ostream cacheFile(cachePath, error, llvm::sys::fs::F_None); cacheFile << _object.getBuffer(); }
void PystonObjectCache::notifyObjectCompiled(const llvm::Module* M, llvm::MemoryBufferRef Obj) #endif { RELEASE_ASSERT(module_identifier == M->getModuleIdentifier(), ""); RELEASE_ASSERT(!hash_before_codegen.empty(), ""); llvm::SmallString<128> cache_file = cache_dir; llvm::sys::path::append(cache_file, hash_before_codegen); if (!llvm::sys::fs::exists(cache_dir.str()) && llvm::sys::fs::create_directories(cache_dir.str())) return; CompressedFile::writeFile(cache_file, Obj.getBuffer()); }
StringRef RawPCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const { return Buffer.getBuffer(); }
// With -fembed-bitcode, save a copy of the llvm IR as data in the // __LLVM,__bitcode section. void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf) { if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off) return; // Save llvm.compiler.used and remote it. SmallVector<Constant*, 2> UsedArray; SmallSet<GlobalValue*, 4> UsedGlobals; Type *UsedElementType = Type::getInt8Ty(M->getContext())->getPointerTo(0); GlobalVariable *Used = collectUsedGlobalVariables(*M, UsedGlobals, true); for (auto *GV : UsedGlobals) { if (GV->getName() != "llvm.embedded.module" && GV->getName() != "llvm.cmdline") UsedArray.push_back( ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType)); } if (Used) Used->eraseFromParent(); // Embed the bitcode for the llvm module. std::string Data; ArrayRef<uint8_t> ModuleData; Triple T(M->getTargetTriple()); // Create a constant that contains the bitcode. // In case of embedding a marker, ignore the input Buf and use the empty // ArrayRef. It is also legal to create a bitcode marker even Buf is empty. if (CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker) { if (!isBitcode((const unsigned char *)Buf.getBufferStart(), (const unsigned char *)Buf.getBufferEnd())) { // If the input is LLVM Assembly, bitcode is produced by serializing // the module. Use-lists order need to be perserved in this case. llvm::raw_string_ostream OS(Data); llvm::WriteBitcodeToFile(M, OS, /* ShouldPreserveUseListOrder */ true); ModuleData = ArrayRef<uint8_t>((const uint8_t *)OS.str().data(), OS.str().size()); } else // If the input is LLVM bitcode, write the input byte stream directly. ModuleData = ArrayRef<uint8_t>((const uint8_t *)Buf.getBufferStart(), Buf.getBufferSize()); } llvm::Constant *ModuleConstant = llvm::ConstantDataArray::get(M->getContext(), ModuleData); llvm::GlobalVariable *GV = new llvm::GlobalVariable( *M, ModuleConstant->getType(), true, llvm::GlobalValue::PrivateLinkage, ModuleConstant); GV->setSection(getSectionNameForBitcode(T)); UsedArray.push_back( ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType)); if (llvm::GlobalVariable *Old = M->getGlobalVariable("llvm.embedded.module", true)) { assert(Old->hasOneUse() && "llvm.embedded.module can only be used once in llvm.compiler.used"); GV->takeName(Old); Old->eraseFromParent(); } else { GV->setName("llvm.embedded.module"); } // Skip if only bitcode needs to be embedded. if (CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode) { // Embed command-line options. ArrayRef<uint8_t> CmdData(const_cast<uint8_t *>(CGOpts.CmdArgs.data()), CGOpts.CmdArgs.size()); llvm::Constant *CmdConstant = llvm::ConstantDataArray::get(M->getContext(), CmdData); GV = new llvm::GlobalVariable(*M, CmdConstant->getType(), true, llvm::GlobalValue::PrivateLinkage, CmdConstant); GV->setSection(getSectionNameForCommandline(T)); UsedArray.push_back( ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType)); if (llvm::GlobalVariable *Old = M->getGlobalVariable("llvm.cmdline", true)) { assert(Old->hasOneUse() && "llvm.cmdline can only be used once in llvm.compiler.used"); GV->takeName(Old); Old->eraseFromParent(); } else { GV->setName("llvm.cmdline"); } } if (UsedArray.empty()) return; // Recreate llvm.compiler.used. ArrayType *ATy = ArrayType::get(UsedElementType, UsedArray.size()); auto *NewUsed = new GlobalVariable( *M, ATy, false, llvm::GlobalValue::AppendingLinkage, llvm::ConstantArray::get(ATy, UsedArray), "llvm.compiler.used"); NewUsed->setSection("llvm.metadata"); }
void RawPCHContainerOperations::ExtractPCH( llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const { StreamFile.init((const unsigned char *)Buffer.getBufferStart(), (const unsigned char *)Buffer.getBufferEnd()); }