diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2025-05-28 06:36:47 +0100 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2025-06-12 13:55:39 +0100 |
| commit | 3743c3e39c6bb645db7403fd446953d43ac7c7dc (patch) | |
| tree | e9223b737051f606b7eec326e71e5977f4164dfc /src/Zcu.zig | |
| parent | 424e6ac54b0f8bbfb43f24e28c71ac72169f3719 (diff) | |
| download | zig-3743c3e39c6bb645db7403fd446953d43ac7c7dc.tar.gz zig-3743c3e39c6bb645db7403fd446953d43ac7c7dc.zip | |
compiler: slightly untangle LLVM from the linkers
The main goal of this commit is to make it easier to decouple codegen
from the linkers by being able to do LLVM codegen without going through
the `link.File`; however, this ended up being a nice refactor anyway.
Previously, every linker stored an optional `llvm.Object`, which was
populated when using LLVM for the ZCU *and* linking an output binary;
and `Zcu` also stored an optional `llvm.Object`, which was used only
when we needed LLVM for the ZCU (e.g. for `-femit-llvm-bc`) but were not
emitting a binary.
This situation was incredibly silly. It meant there were N+1 places the
LLVM object might be instead of just 1, and it meant that every linker
had to start a bunch of methods by checking for an LLVM object, and just
dispatching to the corresponding method on *it* instead if it was not
`null`.
Instead, we now always store the LLVM object on the `Zcu` -- which makes
sense, because it corresponds to the object emitted by, well, the Zig
Compilation Unit! The linkers now mostly don't make reference to LLVM.
`Compilation` makes sure to emit the LLVM object if necessary before
calling `flush`, so it is ready for the linker. Also, all of the
`link.File` methods which act on the ZCU -- like `updateNav` -- now
check for the LLVM object in `link.zig` instead of in every single
individual linker implementation. Notably, the change to LLVM emit
improves this rather ludicrous call chain in the `-fllvm -flld` case:
* Compilation.flush
* link.File.flush
* link.Elf.flush
* link.Elf.linkWithLLD
* link.Elf.flushModule
* link.emitLlvmObject
* Compilation.emitLlvmObject
* llvm.Object.emit
Replacing it with this one:
* Compilation.flush
* llvm.Object.emit
...although we do currently still end up in `link.Elf.linkWithLLD` to do
the actual linking. The logic for invoking LLD should probably also be
unified at least somewhat; I haven't done that in this commit.
Diffstat (limited to 'src/Zcu.zig')
| -rw-r--r-- | src/Zcu.zig | 15 |
1 files changed, 2 insertions, 13 deletions
diff --git a/src/Zcu.zig b/src/Zcu.zig index 7223e5a55e..6a6a74e260 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -56,9 +56,8 @@ comptime { /// General-purpose allocator. Used for both temporary and long-term storage. gpa: Allocator, comp: *Compilation, -/// Usually, the LlvmObject is managed by linker code, however, in the case -/// that -fno-emit-bin is specified, the linker code never executes, so we -/// store the LlvmObject here. +/// If the ZCU is emitting an LLVM object (i.e. we are using the LLVM backend), then this is the +/// `LlvmObject` we are emitting to. llvm_object: ?LlvmObject.Ptr, /// Pointer to externally managed resource. @@ -267,16 +266,6 @@ resolved_references: ?std.AutoHashMapUnmanaged(AnalUnit, ?ResolvedReference) = n /// Reset to `false` at the start of each update in `Compilation.update`. skip_analysis_this_update: bool = false, -stage1_flags: packed struct { - have_winmain: bool = false, - have_wwinmain: bool = false, - have_winmain_crt_startup: bool = false, - have_wwinmain_crt_startup: bool = false, - have_dllmain_crt_startup: bool = false, - have_c_main: bool = false, - reserved: u2 = 0, -} = .{}, - test_functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty, global_assembly: std.AutoArrayHashMapUnmanaged(AnalUnit, []u8) = .empty, |
