From 795e7c64d5f67006246d172e5cd58233cb76f05e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 4 Nov 2024 17:26:17 -0800 Subject: wasm linker: aggressive DODification The goals of this branch are to: * compile faster when using the wasm linker and backend * enable saving compiler state by directly copying in-memory linker state to disk. * more efficient compiler memory utilization * introduce integer type safety to wasm linker code * generate better WebAssembly code * fully participate in incremental compilation * do as much work as possible outside of flush(), while continuing to do linker garbage collection. * avoid unnecessary heap allocations * avoid unnecessary indirect function calls In order to accomplish this goals, this removes the ZigObject abstraction, as well as Symbol and Atom. These abstractions resulted in overly generic code, doing unnecessary work, and needless complications that simply go away by creating a better in-memory data model and emitting more things lazily. For example, this makes wasm codegen emit MIR which is then lowered to wasm code during linking, with optimal function indexes etc, or relocations are emitted if outputting an object. Previously, this would always emit relocations, which are fully unnecessary when emitting an executable, and required all function calls to use the maximum size LEB encoding. This branch introduces the concept of the "prelink" phase which occurs after all object files have been parsed, but before any Zcu updates are sent to the linker. This allows the linker to fully parse all objects into a compact memory model, which is guaranteed to be complete when Zcu code is generated. This commit is not a complete implementation of all these goals; it is not even passing semantic analysis. --- src/link/Elf/relocatable.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/link/Elf/relocatable.zig') diff --git a/src/link/Elf/relocatable.zig b/src/link/Elf/relocatable.zig index 3035c33790..83bfe6d1f7 100644 --- a/src/link/Elf/relocatable.zig +++ b/src/link/Elf/relocatable.zig @@ -2,7 +2,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!v const gpa = comp.gpa; const diags = &comp.link_diags; - if (diags.hasErrors()) return error.FlushFailure; + if (diags.hasErrors()) return error.LinkFailure; // First, we flush relocatable object file generated with our backends. if (elf_file.zigObjectPtr()) |zig_object| { @@ -127,13 +127,13 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!v try elf_file.base.file.?.setEndPos(total_size); try elf_file.base.file.?.pwriteAll(buffer.items, 0); - if (diags.hasErrors()) return error.FlushFailure; + if (diags.hasErrors()) return error.LinkFailure; } pub fn flushObject(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void { const diags = &comp.link_diags; - if (diags.hasErrors()) return error.FlushFailure; + if (diags.hasErrors()) return error.LinkFailure; // Now, we are ready to resolve the symbols across all input files. // We will first resolve the files in the ZigObject, next in the parsed @@ -179,7 +179,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void try elf_file.writeShdrTable(); try elf_file.writeElfHeader(); - if (diags.hasErrors()) return error.FlushFailure; + if (diags.hasErrors()) return error.LinkFailure; } fn claimUnresolved(elf_file: *Elf) void { @@ -259,7 +259,7 @@ fn initComdatGroups(elf_file: *Elf) !void { } } -fn updateSectionSizes(elf_file: *Elf) !void { +fn updateSectionSizes(elf_file: *Elf) link.File.FlushError!void { const slice = elf_file.sections.slice(); for (slice.items(.atom_list_2)) |*atom_list| { if (atom_list.atoms.keys().len == 0) continue; -- cgit v1.2.3