From 19c3e8f0f8857776d4008a9630d0bb89628ab83f Mon Sep 17 00:00:00 2001 From: Daniil Belov <70999565+BelovDV@users.noreply.github.com> Date: Wed, 9 Nov 2022 11:35:40 +0300 Subject: [PATCH 1/2] [perf] --- .../rustc_codegen_llvm/src/back/archive.rs | 29 ++++++++++++++++-- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 12 +++++++- .../rustc_codegen_ssa/src/back/archive.rs | 4 +++ compiler/rustc_codegen_ssa/src/back/link.rs | 6 ++-- .../llvm-wrapper/ArchiveWrapper.cpp | 30 ++++++++++++++++++- 5 files changed, 74 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 5c68abeb08baf..92e3547256cb1 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -28,6 +28,8 @@ use rustc_session::Session; pub struct LlvmArchiveBuilder<'a> { sess: &'a Session, additions: Vec, + + buffers: Vec<(String, Vec)>, } enum Addition { @@ -139,6 +141,10 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { Ok(()) } + fn add_buffer(&mut self, buffer: Vec, name: &str) { + self.buffers.push((name.to_string(), buffer)) + } + /// Adds an arbitrary file to this archive fn add_file(&mut self, file: &Path) { let name = file.file_name().unwrap().to_str().unwrap(); @@ -160,7 +166,7 @@ pub struct LlvmArchiveBuilderBuilder; impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box + 'a> { - Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() }) + Box::new(LlvmArchiveBuilder { sess, additions: Vec::new(), buffers: Vec::new() }) } fn create_dll_import_lib( @@ -320,6 +326,10 @@ impl<'a> LlvmArchiveBuilder<'a> { let mut additions = mem::take(&mut self.additions); let mut strings = Vec::new(); let mut members = Vec::new(); + let addition_buffers = mem::take(&mut self.buffers); + let mut member_buffers = Vec::new(); + let mut string_buffers = Vec::new(); + let mut buffer_buffers = Vec::new(); let dst = CString::new(output.to_str().unwrap())?; @@ -329,7 +339,7 @@ impl<'a> LlvmArchiveBuilder<'a> { Addition::File { path, name_in_archive } => { let path = CString::new(path.to_str().unwrap())?; let name = CString::new(name_in_archive.clone())?; - members.push(llvm::LLVMRustArchiveMemberNew( + members.push(llvm::LLVMRustArchiveMemberNewFile( path.as_ptr(), name.as_ptr(), None, @@ -357,7 +367,7 @@ impl<'a> LlvmArchiveBuilder<'a> { let child_name = Path::new(child_name).file_name().unwrap().to_str().unwrap(); let name = CString::new(child_name)?; - let m = llvm::LLVMRustArchiveMemberNew( + let m = llvm::LLVMRustArchiveMemberNewFile( ptr::null(), name.as_ptr(), Some(child.raw), @@ -368,11 +378,24 @@ impl<'a> LlvmArchiveBuilder<'a> { } } } + for addition in addition_buffers { + let name = CString::new(addition.0)?; + let buffer = addition.1; + member_buffers.push(llvm::LLVMRustArchiveMemberNewBuffer( + name.as_ptr(), + buffer.as_ptr() as *const i8, + buffer.len(), + )); + string_buffers.push(name); + buffer_buffers.push(buffer); + } let r = llvm::LLVMRustWriteArchive( dst.as_ptr(), members.len() as libc::size_t, members.as_ptr() as *const &_, + member_buffers.len() as libc::size_t, + member_buffers.as_ptr() as *const &_, true, kind, ); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8f7728da9dd44..ddfc9e197ea60 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -664,6 +664,8 @@ extern "C" { #[repr(C)] pub struct RustArchiveMember<'a>(InvariantOpaque<'a>); #[repr(C)] +pub struct RustArchiveMemberBuffer<'a>(InvariantOpaque<'a>); +#[repr(C)] pub struct OperandBundleDef<'a>(InvariantOpaque<'a>); #[repr(C)] pub struct Linker<'a>(InvariantOpaque<'a>); @@ -2360,15 +2362,23 @@ extern "C" { Dst: *const c_char, NumMembers: size_t, Members: *const &RustArchiveMember<'_>, + NumMemberBuffers: size_t, + Members: *const &RustArchiveMemberBuffer<'_>, WriteSymbtab: bool, Kind: ArchiveKind, ) -> LLVMRustResult; - pub fn LLVMRustArchiveMemberNew<'a>( + pub fn LLVMRustArchiveMemberNewFile<'a>( Filename: *const c_char, Name: *const c_char, Child: Option<&ArchiveChild<'a>>, ) -> &'a mut RustArchiveMember<'a>; + pub fn LLVMRustArchiveMemberNewBuffer<'a>( + Name: *const c_char, + BufferStart: *const c_char, + BufferSize: size_t, + ) -> &'a mut RustArchiveMember<'a>; pub fn LLVMRustArchiveMemberFree<'a>(Member: &'a mut RustArchiveMember<'a>); + pub fn LLVMRustArchiveMemberBufferFree<'a>(Member: &'a mut RustArchiveMemberBuffer<'a>); pub fn LLVMRustWriteImportLibrary( ImportName: *const c_char, diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 2b1b06d1644c9..159e097bad636 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -72,6 +72,10 @@ pub trait ArchiveBuilderBuilder { pub trait ArchiveBuilder<'a> { fn add_file(&mut self, path: &Path); + fn add_buffer(&mut self, _buffer: Vec, _name: &str) { + unimplemented!(); + } + fn add_archive( &mut self, archive: &Path, diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 4445e5f6c3a64..55ced072fc1c4 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -301,7 +301,8 @@ fn link_rlib<'a>( // normal linkers for the platform. Sometimes this is not possible however. // If it is possible however, placing the metadata object first improves // performance of getting metadata from rlibs. - ab.add_file(&metadata); + ab.add_buffer(metadata, METADATA_FILENAME); + // ab.add_file(&metadata); None } MetadataPosition::Last => Some(metadata), @@ -438,7 +439,8 @@ fn link_rlib<'a>( // // Basically, all this means is that this code should not move above the // code above. - ab.add_file(&trailing_metadata); + ab.add_buffer(trailing_metadata, METADATA_FILENAME); + // ab.add_file(&trailing_metadata); } // Add all bundled static native library dependencies. diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp index 448a1f62f69ed..27fcf37a3b426 100644 --- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp @@ -20,6 +20,13 @@ struct RustArchiveMember { ~RustArchiveMember() {} }; +struct RustArchiveMemberBuffer { + MemoryBufferRef Buffer; + + RustArchiveMemberBuffer() {} + ~RustArchiveMemberBuffer() {} +}; + struct RustArchiveIterator { bool First; Archive::child_iterator Cur; @@ -58,6 +65,7 @@ static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { typedef OwningBinary *LLVMRustArchiveRef; typedef RustArchiveMember *LLVMRustArchiveMemberRef; +typedef RustArchiveMemberBuffer *LLVMRustArchiveMemberBufferRef; typedef Archive::Child *LLVMRustArchiveChildRef; typedef Archive::Child const *LLVMRustArchiveChildConstRef; typedef RustArchiveIterator *LLVMRustArchiveIteratorRef; @@ -155,7 +163,7 @@ LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) { } extern "C" LLVMRustArchiveMemberRef -LLVMRustArchiveMemberNew(char *Filename, char *Name, +LLVMRustArchiveMemberNewFile(char *Filename, char *Name, LLVMRustArchiveChildRef Child) { RustArchiveMember *Member = new RustArchiveMember; Member->Filename = Filename; @@ -165,13 +173,26 @@ LLVMRustArchiveMemberNew(char *Filename, char *Name, return Member; } +extern "C" LLVMRustArchiveMemberBufferRef +LLVMRustArchiveMemberNewBuffer(const char* Name, const char* BufferStart, size_t BufferSize) { + RustArchiveMemberBuffer *Member = new RustArchiveMemberBuffer; + Member->Buffer = MemoryBufferRef(StringRef(BufferStart, BufferSize), StringRef(Name)); + return Member; +} + extern "C" void LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) { delete Member; } +extern "C" void LLVMRustArchiveMemberBufferFree(LLVMRustArchiveMemberBufferRef Member) { + delete Member; +} + extern "C" LLVMRustResult LLVMRustWriteArchive(char *Dst, size_t NumMembers, const LLVMRustArchiveMemberRef *NewMembers, + size_t NumMemberBuffers, + const LLVMRustArchiveMemberBufferRef *NewMemberBuffers, bool WriteSymbtab, LLVMRustArchiveKind RustKind) { std::vector Members; @@ -181,6 +202,7 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers, auto Member = NewMembers[I]; assert(Member->Name); if (Member->Filename) { + // file Expected MOrErr = NewArchiveMember::getFile(Member->Filename, true); if (!MOrErr) { @@ -190,6 +212,7 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers, MOrErr->MemberName = sys::path::filename(MOrErr->MemberName); Members.push_back(std::move(*MOrErr)); } else { + // archive Expected MOrErr = NewArchiveMember::getOldMember(Member->Child, true); if (!MOrErr) { @@ -199,6 +222,11 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers, Members.push_back(std::move(*MOrErr)); } } + for (size_t I = 0; I < NumMemberBuffers; I++) { + auto Member = NewMemberBuffers[I]; + auto M = NewArchiveMember(Member->Buffer); + Members.push_back(std::move(M)); + } auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false); if (!Result) From 8b66395dfc0207fdcd06e0cee6958ce9bff10e2a Mon Sep 17 00:00:00 2001 From: Daniil Belov <70999565+BelovDV@users.noreply.github.com> Date: Wed, 16 Nov 2022 13:04:24 +0300 Subject: [PATCH 2/2] increase add_buffer using --- compiler/rustc_codegen_ssa/src/back/link.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 55ced072fc1c4..1ceffe7b72197 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -8,7 +8,7 @@ use rustc_errors::{ErrorGuaranteed, Handler}; use rustc_fs_util::fix_windows_verbatim_for_gcc; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_metadata::find_native_static_library; -use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME}; +use rustc_metadata::fs::METADATA_FILENAME; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Lto, Strip}; @@ -293,7 +293,6 @@ fn link_rlib<'a>( RlibFlavor::Normal => { let (metadata, metadata_position) = create_wrapper_file(sess, b".rmeta".to_vec(), codegen_results.metadata.raw_data()); - let metadata = emit_wrapper_file(sess, &metadata, tmpdir, METADATA_FILENAME); match metadata_position { MetadataPosition::First => { // Most of the time metadata in rlib files is wrapped in a "dummy" object @@ -387,8 +386,8 @@ fn link_rlib<'a>( let src = read(lib_path) .map_err(|e| sess.emit_fatal(errors::ReadFileError { message: e }))?; let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src); - let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str()); - packed_bundled_libs.push(wrapper_file); + // let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str()); + packed_bundled_libs.push((data, filename)); continue; } ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| { @@ -446,7 +445,7 @@ fn link_rlib<'a>( // Add all bundled static native library dependencies. // Archives added to the end of .rlib archive, see comment above for the reason. for lib in packed_bundled_libs { - ab.add_file(&lib) + ab.add_buffer(lib.0, lib.1.as_str()) } return Ok(ab);