| author | |
| committer | |
| log | 3743c3e39c6bb645db7403fd446953d43ac7c7dc |
| tree | e9223b737051f606b7eec326e71e5977f4164dfc |
| parent | 424e6ac54b0f8bbfb43f24e28c71ac72169f3719 |
| signature |
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.20 files changed, 227 insertions(+), 337 deletions(-)
src/Compilation.zig+31-41| ... | ... | @@ -2188,14 +2188,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 2188 | 2188 | }, |
| 2189 | 2189 | } |
| 2190 | 2190 | |
| 2191 | // Handle the case of e.g. -fno-emit-bin -femit-llvm-ir. | |
| 2192 | if (options.emit_bin == null and (comp.verbose_llvm_ir != null or | |
| 2193 | comp.verbose_llvm_bc != null or | |
| 2194 | (use_llvm and comp.emit_asm != null) or | |
| 2195 | comp.emit_llvm_ir != null or | |
| 2196 | comp.emit_llvm_bc != null)) | |
| 2197 | { | |
| 2198 | if (opt_zcu) |zcu| zcu.llvm_object = try LlvmObject.create(arena, comp); | |
| 2191 | if (use_llvm) { | |
| 2192 | if (opt_zcu) |zcu| { | |
| 2193 | zcu.llvm_object = try LlvmObject.create(arena, comp); | |
| 2194 | } | |
| 2199 | 2195 | } |
| 2200 | 2196 | |
| 2201 | 2197 | break :comp comp; |
| ... | ... | @@ -2945,6 +2941,33 @@ fn flush( |
| 2945 | 2941 | tid: Zcu.PerThread.Id, |
| 2946 | 2942 | prog_node: std.Progress.Node, |
| 2947 | 2943 | ) !void { |
| 2944 | if (comp.zcu) |zcu| { | |
| 2945 | if (zcu.llvm_object) |llvm_object| { | |
| 2946 | // Emit the ZCU object from LLVM now; it's required to flush the output file. | |
| 2947 | // If there's an output file, it wants to decide where the LLVM object goes! | |
| 2948 | const zcu_obj_emit_loc: ?EmitLoc = if (comp.bin_file) |lf| .{ | |
| 2949 | .directory = null, | |
| 2950 | .basename = lf.zcu_object_sub_path.?, | |
| 2951 | } else null; | |
| 2952 | const sub_prog_node = prog_node.start("LLVM Emit Object", 0); | |
| 2953 | defer sub_prog_node.end(); | |
| 2954 | try llvm_object.emit(.{ | |
| 2955 | .pre_ir_path = comp.verbose_llvm_ir, | |
| 2956 | .pre_bc_path = comp.verbose_llvm_bc, | |
| 2957 | .bin_path = try resolveEmitLoc(arena, default_artifact_directory, zcu_obj_emit_loc), | |
| 2958 | .asm_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_asm), | |
| 2959 | .post_ir_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_llvm_ir), | |
| 2960 | .post_bc_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_llvm_bc), | |
| 2961 | ||
| 2962 | .is_debug = comp.root_mod.optimize_mode == .Debug, | |
| 2963 | .is_small = comp.root_mod.optimize_mode == .ReleaseSmall, | |
| 2964 | .time_report = comp.time_report, | |
| 2965 | .sanitize_thread = comp.config.any_sanitize_thread, | |
| 2966 | .fuzz = comp.config.any_fuzz, | |
| 2967 | .lto = comp.config.lto, | |
| 2968 | }); | |
| 2969 | } | |
| 2970 | } | |
| 2948 | 2971 | if (comp.bin_file) |lf| { |
| 2949 | 2972 | // This is needed before reading the error flags. |
| 2950 | 2973 | lf.flush(arena, tid, prog_node) catch |err| switch (err) { |
| ... | ... | @@ -2952,13 +2975,8 @@ fn flush( |
| 2952 | 2975 | error.OutOfMemory => return error.OutOfMemory, |
| 2953 | 2976 | }; |
| 2954 | 2977 | } |
| 2955 | ||
| 2956 | 2978 | if (comp.zcu) |zcu| { |
| 2957 | 2979 | try link.File.C.flushEmitH(zcu); |
| 2958 | ||
| 2959 | if (zcu.llvm_object) |llvm_object| { | |
| 2960 | try emitLlvmObject(comp, arena, default_artifact_directory, null, llvm_object, prog_node); | |
| 2961 | } | |
| 2962 | 2980 | } |
| 2963 | 2981 | } |
| 2964 | 2982 | |
| ... | ... | @@ -3233,34 +3251,6 @@ fn emitOthers(comp: *Compilation) void { |
| 3233 | 3251 | } |
| 3234 | 3252 | } |
| 3235 | 3253 | |
| 3236 | pub fn emitLlvmObject( | |
| 3237 | comp: *Compilation, | |
| 3238 | arena: Allocator, | |
| 3239 | default_artifact_directory: Cache.Path, | |
| 3240 | bin_emit_loc: ?EmitLoc, | |
| 3241 | llvm_object: LlvmObject.Ptr, | |
| 3242 | prog_node: std.Progress.Node, | |
| 3243 | ) !void { | |
| 3244 | const sub_prog_node = prog_node.start("LLVM Emit Object", 0); | |
| 3245 | defer sub_prog_node.end(); | |
| 3246 | ||
| 3247 | try llvm_object.emit(.{ | |
| 3248 | .pre_ir_path = comp.verbose_llvm_ir, | |
| 3249 | .pre_bc_path = comp.verbose_llvm_bc, | |
| 3250 | .bin_path = try resolveEmitLoc(arena, default_artifact_directory, bin_emit_loc), | |
| 3251 | .asm_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_asm), | |
| 3252 | .post_ir_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_llvm_ir), | |
| 3253 | .post_bc_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_llvm_bc), | |
| 3254 | ||
| 3255 | .is_debug = comp.root_mod.optimize_mode == .Debug, | |
| 3256 | .is_small = comp.root_mod.optimize_mode == .ReleaseSmall, | |
| 3257 | .time_report = comp.time_report, | |
| 3258 | .sanitize_thread = comp.config.any_sanitize_thread, | |
| 3259 | .fuzz = comp.config.any_fuzz, | |
| 3260 | .lto = comp.config.lto, | |
| 3261 | }); | |
| 3262 | } | |
| 3263 | ||
| 3264 | 3254 | fn resolveEmitLoc( |
| 3265 | 3255 | arena: Allocator, |
| 3266 | 3256 | default_artifact_directory: Cache.Path, |
src/Zcu.zig+2-13| ... | ... | @@ -56,9 +56,8 @@ comptime { |
| 56 | 56 | /// General-purpose allocator. Used for both temporary and long-term storage. |
| 57 | 57 | gpa: Allocator, |
| 58 | 58 | comp: *Compilation, |
| 59 | /// Usually, the LlvmObject is managed by linker code, however, in the case | |
| 60 | /// that -fno-emit-bin is specified, the linker code never executes, so we | |
| 61 | /// store the LlvmObject here. | |
| 59 | /// If the ZCU is emitting an LLVM object (i.e. we are using the LLVM backend), then this is the | |
| 60 | /// `LlvmObject` we are emitting to. | |
| 62 | 61 | llvm_object: ?LlvmObject.Ptr, |
| 63 | 62 | |
| 64 | 63 | /// Pointer to externally managed resource. |
| ... | ... | @@ -267,16 +266,6 @@ resolved_references: ?std.AutoHashMapUnmanaged(AnalUnit, ?ResolvedReference) = n |
| 267 | 266 | /// Reset to `false` at the start of each update in `Compilation.update`. |
| 268 | 267 | skip_analysis_this_update: bool = false, |
| 269 | 268 | |
| 270 | stage1_flags: packed struct { | |
| 271 | have_winmain: bool = false, | |
| 272 | have_wwinmain: bool = false, | |
| 273 | have_winmain_crt_startup: bool = false, | |
| 274 | have_wwinmain_crt_startup: bool = false, | |
| 275 | have_dllmain_crt_startup: bool = false, | |
| 276 | have_c_main: bool = false, | |
| 277 | reserved: u2 = 0, | |
| 278 | } = .{}, | |
| 279 | ||
| 280 | 269 | test_functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty, |
| 281 | 270 | |
| 282 | 271 | global_assembly: std.AutoArrayHashMapUnmanaged(AnalUnit, []u8) = .empty, |
src/Zcu/PerThread.zig+9-12| ... | ... | @@ -1784,8 +1784,12 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: *A |
| 1784 | 1784 | }; |
| 1785 | 1785 | } |
| 1786 | 1786 | |
| 1787 | if (comp.bin_file) |lf| { | |
| 1788 | lf.updateFunc(pt, func_index, air.*, liveness) catch |err| switch (err) { | |
| 1787 | if (zcu.llvm_object) |llvm_object| { | |
| 1788 | llvm_object.updateFunc(pt, func_index, air.*, liveness) catch |err| switch (err) { | |
| 1789 | error.OutOfMemory => return error.OutOfMemory, | |
| 1790 | }; | |
| 1791 | } else if (comp.bin_file) |lf| { | |
| 1792 | lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) { | |
| 1789 | 1793 | error.OutOfMemory => return error.OutOfMemory, |
| 1790 | 1794 | error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)), |
| 1791 | 1795 | error.Overflow, error.RelocationNotByteAligned => { |
| ... | ... | @@ -1798,10 +1802,6 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: *A |
| 1798 | 1802 | // Not a retryable failure. |
| 1799 | 1803 | }, |
| 1800 | 1804 | }; |
| 1801 | } else if (zcu.llvm_object) |llvm_object| { | |
| 1802 | llvm_object.updateFunc(pt, func_index, air.*, liveness) catch |err| switch (err) { | |
| 1803 | error.OutOfMemory => return error.OutOfMemory, | |
| 1804 | }; | |
| 1805 | 1805 | } |
| 1806 | 1806 | } |
| 1807 | 1807 | |
| ... | ... | @@ -1877,7 +1877,6 @@ fn createFileRootStruct( |
| 1877 | 1877 | try pt.scanNamespace(namespace_index, decls); |
| 1878 | 1878 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 1879 | 1879 | codegen_type: { |
| 1880 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 1881 | 1880 | if (file.mod.?.strip) break :codegen_type; |
| 1882 | 1881 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 1883 | 1882 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); |
| ... | ... | @@ -3309,10 +3308,10 @@ fn processExportsInner( |
| 3309 | 3308 | .uav => {}, |
| 3310 | 3309 | } |
| 3311 | 3310 | |
| 3312 | if (zcu.comp.bin_file) |lf| { | |
| 3313 | try zcu.handleUpdateExports(export_indices, lf.updateExports(pt, exported, export_indices)); | |
| 3314 | } else if (zcu.llvm_object) |llvm_object| { | |
| 3311 | if (zcu.llvm_object) |llvm_object| { | |
| 3315 | 3312 | try zcu.handleUpdateExports(export_indices, llvm_object.updateExports(pt, exported, export_indices)); |
| 3313 | } else if (zcu.comp.bin_file) |lf| { | |
| 3314 | try zcu.handleUpdateExports(export_indices, lf.updateExports(pt, exported, export_indices)); | |
| 3316 | 3315 | } |
| 3317 | 3316 | } |
| 3318 | 3317 | |
| ... | ... | @@ -4064,7 +4063,6 @@ fn recreateStructType( |
| 4064 | 4063 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 4065 | 4064 | |
| 4066 | 4065 | codegen_type: { |
| 4067 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 4068 | 4066 | if (file.mod.?.strip) break :codegen_type; |
| 4069 | 4067 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 4070 | 4068 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); |
| ... | ... | @@ -4157,7 +4155,6 @@ fn recreateUnionType( |
| 4157 | 4155 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 4158 | 4156 | |
| 4159 | 4157 | codegen_type: { |
| 4160 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 4161 | 4158 | if (file.mod.?.strip) break :codegen_type; |
| 4162 | 4159 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 4163 | 4160 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); |
src/codegen/llvm.zig+18| ... | ... | @@ -1586,6 +1586,24 @@ pub const Object = struct { |
| 1586 | 1586 | const global_index = self.nav_map.get(nav_index).?; |
| 1587 | 1587 | const comp = zcu.comp; |
| 1588 | 1588 | |
| 1589 | // If we're on COFF and linking with LLD, the linker cares about our exports to determine the subsystem in use. | |
| 1590 | if (comp.bin_file != null and | |
| 1591 | comp.bin_file.?.tag == .coff and | |
| 1592 | zcu.comp.config.use_lld and | |
| 1593 | ip.isFunctionType(ip.getNav(nav_index).typeOf(ip))) | |
| 1594 | { | |
| 1595 | const flags = &comp.bin_file.?.cast(.coff).?.lld_export_flags; | |
| 1596 | for (export_indices) |export_index| { | |
| 1597 | const name = export_index.ptr(zcu).opts.name; | |
| 1598 | if (name.eqlSlice("main", ip)) flags.c_main = true; | |
| 1599 | if (name.eqlSlice("WinMain", ip)) flags.winmain = true; | |
| 1600 | if (name.eqlSlice("wWinMain", ip)) flags.wwinmain = true; | |
| 1601 | if (name.eqlSlice("WinMainCRTStartup", ip)) flags.winmain_crt_startup = true; | |
| 1602 | if (name.eqlSlice("wWinMainCRTStartup", ip)) flags.wwinmain_crt_startup = true; | |
| 1603 | if (name.eqlSlice("DllMainCRTStartup", ip)) flags.dllmain_crt_startup = true; | |
| 1604 | } | |
| 1605 | } | |
| 1606 | ||
| 1589 | 1607 | if (export_indices.len != 0) { |
| 1590 | 1608 | return updateExportedGlobal(self, zcu, global_index, export_indices); |
| 1591 | 1609 | } else { |
src/codegen/spirv/Section.zig-2| ... | ... | @@ -386,8 +386,6 @@ test "SPIR-V Section emit() - string" { |
| 386 | 386 | } |
| 387 | 387 | |
| 388 | 388 | test "SPIR-V Section emit() - extended mask" { |
| 389 | if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; | |
| 390 | ||
| 391 | 389 | var section = Section{}; |
| 392 | 390 | defer section.deinit(std.testing.allocator); |
| 393 | 391 |
src/link.zig+48-37| ... | ... | @@ -19,7 +19,6 @@ const Zcu = @import("Zcu.zig"); |
| 19 | 19 | const InternPool = @import("InternPool.zig"); |
| 20 | 20 | const Type = @import("Type.zig"); |
| 21 | 21 | const Value = @import("Value.zig"); |
| 22 | const LlvmObject = @import("codegen/llvm.zig").Object; | |
| 23 | 22 | const lldMain = @import("main.zig").lldMain; |
| 24 | 23 | const Package = @import("Package.zig"); |
| 25 | 24 | const dev = @import("dev.zig"); |
| ... | ... | @@ -704,7 +703,9 @@ pub const File = struct { |
| 704 | 703 | } |
| 705 | 704 | |
| 706 | 705 | /// May be called before or after updateExports for any given Nav. |
| 706 | /// Asserts that the ZCU is not using the LLVM backend. | |
| 707 | 707 | fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void { |
| 708 | assert(base.comp.zcu.?.llvm_object == null); | |
| 708 | 709 | const nav = pt.zcu.intern_pool.getNav(nav_index); |
| 709 | 710 | assert(nav.status == .fully_resolved); |
| 710 | 711 | switch (base.tag) { |
| ... | ... | @@ -721,7 +722,9 @@ pub const File = struct { |
| 721 | 722 | TypeFailureReported, |
| 722 | 723 | }; |
| 723 | 724 | |
| 725 | /// Never called when LLVM is codegenning the ZCU. | |
| 724 | 726 | fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void { |
| 727 | assert(base.comp.zcu.?.llvm_object == null); | |
| 725 | 728 | switch (base.tag) { |
| 726 | 729 | else => {}, |
| 727 | 730 | inline .elf => |tag| { |
| ... | ... | @@ -733,6 +736,7 @@ pub const File = struct { |
| 733 | 736 | |
| 734 | 737 | /// May be called before or after updateExports for any given Decl. |
| 735 | 738 | /// TODO: currently `pub` because `Zcu.PerThread` is calling this. |
| 739 | /// Never called when LLVM is codegenning the ZCU. | |
| 736 | 740 | pub fn updateFunc( |
| 737 | 741 | base: *File, |
| 738 | 742 | pt: Zcu.PerThread, |
| ... | ... | @@ -740,6 +744,7 @@ pub const File = struct { |
| 740 | 744 | air: Air, |
| 741 | 745 | liveness: Air.Liveness, |
| 742 | 746 | ) UpdateNavError!void { |
| 747 | assert(base.comp.zcu.?.llvm_object == null); | |
| 743 | 748 | switch (base.tag) { |
| 744 | 749 | inline else => |tag| { |
| 745 | 750 | dev.check(tag.devFeature()); |
| ... | ... | @@ -756,7 +761,9 @@ pub const File = struct { |
| 756 | 761 | |
| 757 | 762 | /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because |
| 758 | 763 | /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`. |
| 764 | /// Never called when LLVM is codegenning the ZCU. | |
| 759 | 765 | fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) UpdateLineNumberError!void { |
| 766 | assert(base.comp.zcu.?.llvm_object == null); | |
| 760 | 767 | { |
| 761 | 768 | const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?; |
| 762 | 769 | const file = pt.zcu.fileByIndex(ti.file); |
| ... | ... | @@ -846,11 +853,13 @@ pub const File = struct { |
| 846 | 853 | |
| 847 | 854 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` |
| 848 | 855 | /// rather than final output mode. |
| 849 | pub fn flushModule(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void { | |
| 856 | /// Never called when LLVM is codegenning the ZCU. | |
| 857 | fn flushZcu(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void { | |
| 858 | assert(base.comp.zcu.?.llvm_object == null); | |
| 850 | 859 | switch (base.tag) { |
| 851 | 860 | inline else => |tag| { |
| 852 | 861 | dev.check(tag.devFeature()); |
| 853 | return @as(*tag.Type(), @fieldParentPtr("base", base)).flushModule(arena, tid, prog_node); | |
| 862 | return @as(*tag.Type(), @fieldParentPtr("base", base)).flushZcu(arena, tid, prog_node); | |
| 854 | 863 | }, |
| 855 | 864 | } |
| 856 | 865 | } |
| ... | ... | @@ -864,12 +873,14 @@ pub const File = struct { |
| 864 | 873 | /// a list of size 1, meaning that `exported` is exported once. However, it is possible |
| 865 | 874 | /// to export the same thing with multiple different symbol names (aliases). |
| 866 | 875 | /// May be called before or after updateDecl for any given Decl. |
| 876 | /// Never called when LLVM is codegenning the ZCU. | |
| 867 | 877 | pub fn updateExports( |
| 868 | 878 | base: *File, |
| 869 | 879 | pt: Zcu.PerThread, |
| 870 | 880 | exported: Zcu.Exported, |
| 871 | 881 | export_indices: []const Zcu.Export.Index, |
| 872 | 882 | ) UpdateExportsError!void { |
| 883 | assert(base.comp.zcu.?.llvm_object == null); | |
| 873 | 884 | switch (base.tag) { |
| 874 | 885 | inline else => |tag| { |
| 875 | 886 | dev.check(tag.devFeature()); |
| ... | ... | @@ -896,7 +907,9 @@ pub const File = struct { |
| 896 | 907 | /// `Nav`'s address was not yet resolved, or the containing atom gets moved in virtual memory. |
| 897 | 908 | /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate |
| 898 | 909 | /// the block/atom. |
| 910 | /// Never called when LLVM is codegenning the ZCU. | |
| 899 | 911 | pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) !u64 { |
| 912 | assert(base.comp.zcu.?.llvm_object == null); | |
| 900 | 913 | switch (base.tag) { |
| 901 | 914 | .c => unreachable, |
| 902 | 915 | .spirv => unreachable, |
| ... | ... | @@ -909,6 +922,7 @@ pub const File = struct { |
| 909 | 922 | } |
| 910 | 923 | } |
| 911 | 924 | |
| 925 | /// Never called when LLVM is codegenning the ZCU. | |
| 912 | 926 | pub fn lowerUav( |
| 913 | 927 | base: *File, |
| 914 | 928 | pt: Zcu.PerThread, |
| ... | ... | @@ -916,6 +930,7 @@ pub const File = struct { |
| 916 | 930 | decl_align: InternPool.Alignment, |
| 917 | 931 | src_loc: Zcu.LazySrcLoc, |
| 918 | 932 | ) !codegen.GenResult { |
| 933 | assert(base.comp.zcu.?.llvm_object == null); | |
| 919 | 934 | switch (base.tag) { |
| 920 | 935 | .c => unreachable, |
| 921 | 936 | .spirv => unreachable, |
| ... | ... | @@ -928,7 +943,9 @@ pub const File = struct { |
| 928 | 943 | } |
| 929 | 944 | } |
| 930 | 945 | |
| 946 | /// Never called when LLVM is codegenning the ZCU. | |
| 931 | 947 | pub fn getUavVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 { |
| 948 | assert(base.comp.zcu.?.llvm_object == null); | |
| 932 | 949 | switch (base.tag) { |
| 933 | 950 | .c => unreachable, |
| 934 | 951 | .spirv => unreachable, |
| ... | ... | @@ -941,11 +958,13 @@ pub const File = struct { |
| 941 | 958 | } |
| 942 | 959 | } |
| 943 | 960 | |
| 961 | /// Never called when LLVM is codegenning the ZCU. | |
| 944 | 962 | pub fn deleteExport( |
| 945 | 963 | base: *File, |
| 946 | 964 | exported: Zcu.Exported, |
| 947 | 965 | name: InternPool.NullTerminatedString, |
| 948 | 966 | ) void { |
| 967 | assert(base.comp.zcu.?.llvm_object == null); | |
| 949 | 968 | switch (base.tag) { |
| 950 | 969 | .plan9, |
| 951 | 970 | .spirv, |
| ... | ... | @@ -1077,7 +1096,7 @@ pub const File = struct { |
| 1077 | 1096 | } |
| 1078 | 1097 | } |
| 1079 | 1098 | |
| 1080 | pub fn linkAsArchive(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void { | |
| 1099 | fn linkAsArchive(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void { | |
| 1081 | 1100 | dev.check(.lld_linker); |
| 1082 | 1101 | |
| 1083 | 1102 | const tracy = trace(@src()); |
| ... | ... | @@ -1103,9 +1122,12 @@ pub const File = struct { |
| 1103 | 1122 | |
| 1104 | 1123 | // If there is no Zig code to compile, then we should skip flushing the output file |
| 1105 | 1124 | // because it will not be part of the linker line anyway. |
| 1106 | const zcu_obj_path: ?[]const u8 = if (opt_zcu != null) blk: { | |
| 1107 | try base.flushModule(arena, tid, prog_node); | |
| 1108 | ||
| 1125 | const zcu_obj_path: ?[]const u8 = if (opt_zcu) |zcu| blk: { | |
| 1126 | if (zcu.llvm_object == null) { | |
| 1127 | try base.flushZcu(arena, tid, prog_node); | |
| 1128 | } else { | |
| 1129 | // `Compilation.flush` has already made LLVM emit this object file for us. | |
| 1130 | } | |
| 1109 | 1131 | const dirname = fs.path.dirname(full_out_path_z) orelse "."; |
| 1110 | 1132 | break :blk try fs.path.join(arena, &.{ dirname, base.zcu_object_sub_path.? }); |
| 1111 | 1133 | } else null; |
| ... | ... | @@ -1346,21 +1368,6 @@ pub const File = struct { |
| 1346 | 1368 | return output_mode == .Lib and !self.isStatic(); |
| 1347 | 1369 | } |
| 1348 | 1370 | |
| 1349 | pub fn emitLlvmObject( | |
| 1350 | base: File, | |
| 1351 | arena: Allocator, | |
| 1352 | llvm_object: LlvmObject.Ptr, | |
| 1353 | prog_node: std.Progress.Node, | |
| 1354 | ) !void { | |
| 1355 | return base.comp.emitLlvmObject(arena, .{ | |
| 1356 | .root_dir = base.emit.root_dir, | |
| 1357 | .sub_path = std.fs.path.dirname(base.emit.sub_path) orelse "", | |
| 1358 | }, .{ | |
| 1359 | .directory = null, | |
| 1360 | .basename = base.zcu_object_sub_path.?, | |
| 1361 | }, llvm_object, prog_node); | |
| 1362 | } | |
| 1363 | ||
| 1364 | 1371 | pub fn cgFail( |
| 1365 | 1372 | base: *File, |
| 1366 | 1373 | nav_index: InternPool.Nav.Index, |
| ... | ... | @@ -1600,7 +1607,11 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void { |
| 1600 | 1607 | // on the failed type, so when it is changed the `Nav` will be updated. |
| 1601 | 1608 | return; |
| 1602 | 1609 | } |
| 1603 | if (comp.bin_file) |lf| { | |
| 1610 | if (zcu.llvm_object) |llvm_object| { | |
| 1611 | llvm_object.updateNav(pt, nav_index) catch |err| switch (err) { | |
| 1612 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1613 | }; | |
| 1614 | } else if (comp.bin_file) |lf| { | |
| 1604 | 1615 | lf.updateNav(pt, nav_index) catch |err| switch (err) { |
| 1605 | 1616 | error.OutOfMemory => diags.setAllocFailure(), |
| 1606 | 1617 | error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)), |
| ... | ... | @@ -1616,10 +1627,6 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void { |
| 1616 | 1627 | // Not a retryable failure. |
| 1617 | 1628 | }, |
| 1618 | 1629 | }; |
| 1619 | } else if (zcu.llvm_object) |llvm_object| { | |
| 1620 | llvm_object.updateNav(pt, nav_index) catch |err| switch (err) { | |
| 1621 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1622 | }; | |
| 1623 | 1630 | } |
| 1624 | 1631 | }, |
| 1625 | 1632 | .link_func => |func| { |
| ... | ... | @@ -1650,11 +1657,13 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void { |
| 1650 | 1657 | // on the failed type, so when that is changed, this type will be updated. |
| 1651 | 1658 | return; |
| 1652 | 1659 | } |
| 1653 | if (comp.bin_file) |lf| { | |
| 1654 | lf.updateContainerType(pt, ty) catch |err| switch (err) { | |
| 1655 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1656 | error.TypeFailureReported => assert(zcu.failed_types.contains(ty)), | |
| 1657 | }; | |
| 1660 | if (zcu.llvm_object == null) { | |
| 1661 | if (comp.bin_file) |lf| { | |
| 1662 | lf.updateContainerType(pt, ty) catch |err| switch (err) { | |
| 1663 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1664 | error.TypeFailureReported => assert(zcu.failed_types.contains(ty)), | |
| 1665 | }; | |
| 1666 | } | |
| 1658 | 1667 | } |
| 1659 | 1668 | }, |
| 1660 | 1669 | .update_line_number => |ti| { |
| ... | ... | @@ -1664,11 +1673,13 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void { |
| 1664 | 1673 | } |
| 1665 | 1674 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); |
| 1666 | 1675 | defer pt.deactivate(); |
| 1667 | if (comp.bin_file) |lf| { | |
| 1668 | lf.updateLineNumber(pt, ti) catch |err| switch (err) { | |
| 1669 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1670 | else => |e| log.err("update line number failed: {s}", .{@errorName(e)}), | |
| 1671 | }; | |
| 1676 | if (pt.zcu.llvm_object == null) { | |
| 1677 | if (comp.bin_file) |lf| { | |
| 1678 | lf.updateLineNumber(pt, ti) catch |err| switch (err) { | |
| 1679 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1680 | else => |e| log.err("update line number failed: {s}", .{@errorName(e)}), | |
| 1681 | }; | |
| 1682 | } | |
| 1672 | 1683 | } |
| 1673 | 1684 | }, |
| 1674 | 1685 | } |
src/link/C.zig+2-2| ... | ... | @@ -382,7 +382,7 @@ pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedIn |
| 382 | 382 | } |
| 383 | 383 | |
| 384 | 384 | pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 385 | return self.flushModule(arena, tid, prog_node); | |
| 385 | return self.flushZcu(arena, tid, prog_node); | |
| 386 | 386 | } |
| 387 | 387 | |
| 388 | 388 | fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { |
| ... | ... | @@ -400,7 +400,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { |
| 400 | 400 | return defines; |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 403 | pub fn flushZcu(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 404 | 404 | _ = arena; // Has the same lifetime as the call to Compilation.update. |
| 405 | 405 | |
| 406 | 406 | const tracy = trace(@src()); |
src/link/Coff.zig+30-84| ... | ... | @@ -3,9 +3,6 @@ |
| 3 | 3 | //! LLD for traditional linking (linking relocatable object files). |
| 4 | 4 | //! LLD is also the default linker for LLVM. |
| 5 | 5 | |
| 6 | /// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path. | |
| 7 | llvm_object: ?LlvmObject.Ptr = null, | |
| 8 | ||
| 9 | 6 | base: link.File, |
| 10 | 7 | image_base: u64, |
| 11 | 8 | subsystem: ?std.Target.SubSystem, |
| ... | ... | @@ -87,6 +84,16 @@ base_relocs: BaseRelocationTable = .{}, |
| 87 | 84 | /// Hot-code swapping state. |
| 88 | 85 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, |
| 89 | 86 | |
| 87 | /// When linking with LLD, these flags are used to determine the subsystem to pass on the LLD command line. | |
| 88 | lld_export_flags: struct { | |
| 89 | c_main: bool = false, | |
| 90 | winmain: bool = false, | |
| 91 | wwinmain: bool = false, | |
| 92 | winmain_crt_startup: bool = false, | |
| 93 | wwinmain_crt_startup: bool = false, | |
| 94 | dllmain_crt_startup: bool = false, | |
| 95 | } = .{}, | |
| 96 | ||
| 90 | 97 | const is_hot_update_compatible = switch (builtin.target.os.tag) { |
| 91 | 98 | .windows => true, |
| 92 | 99 | else => false, |
| ... | ... | @@ -302,9 +309,6 @@ pub fn createEmpty( |
| 302 | 309 | .pdb_out_path = options.pdb_out_path, |
| 303 | 310 | .repro = options.repro, |
| 304 | 311 | }; |
| 305 | if (use_llvm and comp.config.have_zcu) { | |
| 306 | coff.llvm_object = try LlvmObject.create(arena, comp); | |
| 307 | } | |
| 308 | 312 | errdefer coff.base.destroy(); |
| 309 | 313 | |
| 310 | 314 | if (use_lld and (use_llvm or !comp.config.have_zcu)) { |
| ... | ... | @@ -322,7 +326,6 @@ pub fn createEmpty( |
| 322 | 326 | .mode = link.File.determineMode(use_lld, output_mode, link_mode), |
| 323 | 327 | }); |
| 324 | 328 | |
| 325 | assert(coff.llvm_object == null); | |
| 326 | 329 | const gpa = comp.gpa; |
| 327 | 330 | |
| 328 | 331 | try coff.strtab.buffer.ensureUnusedCapacity(gpa, @sizeOf(u32)); |
| ... | ... | @@ -428,8 +431,6 @@ pub fn open( |
| 428 | 431 | pub fn deinit(coff: *Coff) void { |
| 429 | 432 | const gpa = coff.base.comp.gpa; |
| 430 | 433 | |
| 431 | if (coff.llvm_object) |llvm_object| llvm_object.deinit(); | |
| 432 | ||
| 433 | 434 | for (coff.sections.items(.free_list)) |*free_list| { |
| 434 | 435 | free_list.deinit(gpa); |
| 435 | 436 | } |
| ... | ... | @@ -1103,9 +1104,6 @@ pub fn updateFunc( |
| 1103 | 1104 | if (build_options.skip_non_native and builtin.object_format != .coff) { |
| 1104 | 1105 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 1105 | 1106 | } |
| 1106 | if (coff.llvm_object) |llvm_object| { | |
| 1107 | return llvm_object.updateFunc(pt, func_index, air, liveness); | |
| 1108 | } | |
| 1109 | 1107 | const tracy = trace(@src()); |
| 1110 | 1108 | defer tracy.end(); |
| 1111 | 1109 | |
| ... | ... | @@ -1205,7 +1203,6 @@ pub fn updateNav( |
| 1205 | 1203 | if (build_options.skip_non_native and builtin.object_format != .coff) { |
| 1206 | 1204 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 1207 | 1205 | } |
| 1208 | if (coff.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav_index); | |
| 1209 | 1206 | const tracy = trace(@src()); |
| 1210 | 1207 | defer tracy.end(); |
| 1211 | 1208 | |
| ... | ... | @@ -1330,7 +1327,7 @@ pub fn getOrCreateAtomForLazySymbol( |
| 1330 | 1327 | } |
| 1331 | 1328 | state_ptr.* = .pending_flush; |
| 1332 | 1329 | const atom = atom_ptr.*; |
| 1333 | // anyerror needs to be deferred until flushModule | |
| 1330 | // anyerror needs to be deferred until flushZcu | |
| 1334 | 1331 | if (lazy_sym.ty != .anyerror_type) try coff.updateLazySymbolAtom(pt, lazy_sym, atom, switch (lazy_sym.kind) { |
| 1335 | 1332 | .code => coff.text_section_index.?, |
| 1336 | 1333 | .const_data => coff.rdata_section_index.?, |
| ... | ... | @@ -1463,8 +1460,6 @@ fn updateNavCode( |
| 1463 | 1460 | } |
| 1464 | 1461 | |
| 1465 | 1462 | pub fn freeNav(coff: *Coff, nav_index: InternPool.NavIndex) void { |
| 1466 | if (coff.llvm_object) |llvm_object| return llvm_object.freeNav(nav_index); | |
| 1467 | ||
| 1468 | 1463 | const gpa = coff.base.comp.gpa; |
| 1469 | 1464 | |
| 1470 | 1465 | if (coff.decls.fetchOrderedRemove(nav_index)) |const_kv| { |
| ... | ... | @@ -1485,50 +1480,7 @@ pub fn updateExports( |
| 1485 | 1480 | } |
| 1486 | 1481 | |
| 1487 | 1482 | const zcu = pt.zcu; |
| 1488 | const ip = &zcu.intern_pool; | |
| 1489 | const comp = coff.base.comp; | |
| 1490 | const target = comp.root_mod.resolved_target.result; | |
| 1491 | ||
| 1492 | if (comp.config.use_llvm) { | |
| 1493 | // Even in the case of LLVM, we need to notice certain exported symbols in order to | |
| 1494 | // detect the default subsystem. | |
| 1495 | for (export_indices) |export_idx| { | |
| 1496 | const exp = export_idx.ptr(zcu); | |
| 1497 | const exported_nav_index = switch (exp.exported) { | |
| 1498 | .nav => |nav| nav, | |
| 1499 | .uav => continue, | |
| 1500 | }; | |
| 1501 | const exported_nav = ip.getNav(exported_nav_index); | |
| 1502 | const exported_ty = exported_nav.typeOf(ip); | |
| 1503 | if (!ip.isFunctionType(exported_ty)) continue; | |
| 1504 | const c_cc = target.cCallingConvention().?; | |
| 1505 | const winapi_cc: std.builtin.CallingConvention = switch (target.cpu.arch) { | |
| 1506 | .x86 => .{ .x86_stdcall = .{} }, | |
| 1507 | else => c_cc, | |
| 1508 | }; | |
| 1509 | const exported_cc = Type.fromInterned(exported_ty).fnCallingConvention(zcu); | |
| 1510 | const CcTag = std.builtin.CallingConvention.Tag; | |
| 1511 | if (@as(CcTag, exported_cc) == @as(CcTag, c_cc) and exp.opts.name.eqlSlice("main", ip) and comp.config.link_libc) { | |
| 1512 | zcu.stage1_flags.have_c_main = true; | |
| 1513 | } else if (@as(CcTag, exported_cc) == @as(CcTag, winapi_cc) and target.os.tag == .windows) { | |
| 1514 | if (exp.opts.name.eqlSlice("WinMain", ip)) { | |
| 1515 | zcu.stage1_flags.have_winmain = true; | |
| 1516 | } else if (exp.opts.name.eqlSlice("wWinMain", ip)) { | |
| 1517 | zcu.stage1_flags.have_wwinmain = true; | |
| 1518 | } else if (exp.opts.name.eqlSlice("WinMainCRTStartup", ip)) { | |
| 1519 | zcu.stage1_flags.have_winmain_crt_startup = true; | |
| 1520 | } else if (exp.opts.name.eqlSlice("wWinMainCRTStartup", ip)) { | |
| 1521 | zcu.stage1_flags.have_wwinmain_crt_startup = true; | |
| 1522 | } else if (exp.opts.name.eqlSlice("DllMainCRTStartup", ip)) { | |
| 1523 | zcu.stage1_flags.have_dllmain_crt_startup = true; | |
| 1524 | } | |
| 1525 | } | |
| 1526 | } | |
| 1527 | } | |
| 1528 | ||
| 1529 | if (coff.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices); | |
| 1530 | ||
| 1531 | const gpa = comp.gpa; | |
| 1483 | const gpa = zcu.gpa; | |
| 1532 | 1484 | |
| 1533 | 1485 | const metadata = switch (exported) { |
| 1534 | 1486 | .nav => |nav| blk: { |
| ... | ... | @@ -1621,7 +1573,6 @@ pub fn deleteExport( |
| 1621 | 1573 | exported: Zcu.Exported, |
| 1622 | 1574 | name: InternPool.NullTerminatedString, |
| 1623 | 1575 | ) void { |
| 1624 | if (coff.llvm_object) |_| return; | |
| 1625 | 1576 | const metadata = switch (exported) { |
| 1626 | 1577 | .nav => |nav| coff.navs.getPtr(nav), |
| 1627 | 1578 | .uav => |uav| coff.uavs.getPtr(uav), |
| ... | ... | @@ -1692,7 +1643,7 @@ pub fn flush(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: st |
| 1692 | 1643 | }; |
| 1693 | 1644 | } |
| 1694 | 1645 | switch (comp.config.output_mode) { |
| 1695 | .Exe, .Obj => return coff.flushModule(arena, tid, prog_node), | |
| 1646 | .Exe, .Obj => return coff.flushZcu(arena, tid, prog_node), | |
| 1696 | 1647 | .Lib => return diags.fail("writing lib files not yet implemented for COFF", .{}), |
| 1697 | 1648 | } |
| 1698 | 1649 | } |
| ... | ... | @@ -1711,8 +1662,12 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: |
| 1711 | 1662 | |
| 1712 | 1663 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 1713 | 1664 | // will not be part of the linker line anyway. |
| 1714 | const module_obj_path: ?[]const u8 = if (comp.zcu != null) blk: { | |
| 1715 | try coff.flushModule(arena, tid, prog_node); | |
| 1665 | const module_obj_path: ?[]const u8 = if (comp.zcu) |zcu| blk: { | |
| 1666 | if (zcu.llvm_object == null) { | |
| 1667 | try coff.flushZcu(arena, tid, prog_node); | |
| 1668 | } else { | |
| 1669 | // `Compilation.flush` has already made LLVM emit this object file for us. | |
| 1670 | } | |
| 1716 | 1671 | |
| 1717 | 1672 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 1718 | 1673 | break :blk try fs.path.join(arena, &.{ dirname, coff.base.zcu_object_sub_path.? }); |
| ... | ... | @@ -1998,16 +1953,16 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: |
| 1998 | 1953 | if (coff.subsystem) |explicit| break :blk explicit; |
| 1999 | 1954 | switch (target.os.tag) { |
| 2000 | 1955 | .windows => { |
| 2001 | if (comp.zcu) |module| { | |
| 2002 | if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib) | |
| 1956 | if (comp.zcu != null) { | |
| 1957 | if (coff.lld_export_flags.dllmain_crt_startup or is_dyn_lib) | |
| 2003 | 1958 | break :blk null; |
| 2004 | if (module.stage1_flags.have_c_main or comp.config.is_test or | |
| 2005 | module.stage1_flags.have_winmain_crt_startup or | |
| 2006 | module.stage1_flags.have_wwinmain_crt_startup) | |
| 1959 | if (coff.lld_export_flags.c_main or comp.config.is_test or | |
| 1960 | coff.lld_export_flags.winmain_crt_startup or | |
| 1961 | coff.lld_export_flags.wwinmain_crt_startup) | |
| 2007 | 1962 | { |
| 2008 | 1963 | break :blk .Console; |
| 2009 | 1964 | } |
| 2010 | if (module.stage1_flags.have_winmain or module.stage1_flags.have_wwinmain) | |
| 1965 | if (coff.lld_export_flags.winmain or coff.lld_export_flags.wwinmain) | |
| 2011 | 1966 | break :blk .Windows; |
| 2012 | 1967 | } |
| 2013 | 1968 | }, |
| ... | ... | @@ -2136,8 +2091,8 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: |
| 2136 | 2091 | } else { |
| 2137 | 2092 | try argv.append("-NODEFAULTLIB"); |
| 2138 | 2093 | if (!is_lib and entry_name == null) { |
| 2139 | if (comp.zcu) |module| { | |
| 2140 | if (module.stage1_flags.have_winmain_crt_startup) { | |
| 2094 | if (comp.zcu != null) { | |
| 2095 | if (coff.lld_export_flags.winmain_crt_startup) { | |
| 2141 | 2096 | try argv.append("-ENTRY:WinMainCRTStartup"); |
| 2142 | 2097 | } else { |
| 2143 | 2098 | try argv.append("-ENTRY:wWinMainCRTStartup"); |
| ... | ... | @@ -2244,7 +2199,7 @@ fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Director |
| 2244 | 2199 | return null; |
| 2245 | 2200 | } |
| 2246 | 2201 | |
| 2247 | pub fn flushModule( | |
| 2202 | pub fn flushZcu( | |
| 2248 | 2203 | coff: *Coff, |
| 2249 | 2204 | arena: Allocator, |
| 2250 | 2205 | tid: Zcu.PerThread.Id, |
| ... | ... | @@ -2256,22 +2211,17 @@ pub fn flushModule( |
| 2256 | 2211 | const comp = coff.base.comp; |
| 2257 | 2212 | const diags = &comp.link_diags; |
| 2258 | 2213 | |
| 2259 | if (coff.llvm_object) |llvm_object| { | |
| 2260 | try coff.base.emitLlvmObject(arena, llvm_object, prog_node); | |
| 2261 | return; | |
| 2262 | } | |
| 2263 | ||
| 2264 | 2214 | const sub_prog_node = prog_node.start("COFF Flush", 0); |
| 2265 | 2215 | defer sub_prog_node.end(); |
| 2266 | 2216 | |
| 2267 | return flushModuleInner(coff, arena, tid) catch |err| switch (err) { | |
| 2217 | return flushZcuInner(coff, arena, tid) catch |err| switch (err) { | |
| 2268 | 2218 | error.OutOfMemory => return error.OutOfMemory, |
| 2269 | 2219 | error.LinkFailure => return error.LinkFailure, |
| 2270 | 2220 | else => |e| return diags.fail("COFF flush failed: {s}", .{@errorName(e)}), |
| 2271 | 2221 | }; |
| 2272 | 2222 | } |
| 2273 | 2223 | |
| 2274 | fn flushModuleInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void { | |
| 2224 | fn flushZcuInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void { | |
| 2275 | 2225 | _ = arena; |
| 2276 | 2226 | |
| 2277 | 2227 | const comp = coff.base.comp; |
| ... | ... | @@ -2397,7 +2347,6 @@ pub fn getNavVAddr( |
| 2397 | 2347 | nav_index: InternPool.Nav.Index, |
| 2398 | 2348 | reloc_info: link.File.RelocInfo, |
| 2399 | 2349 | ) !u64 { |
| 2400 | assert(coff.llvm_object == null); | |
| 2401 | 2350 | const zcu = pt.zcu; |
| 2402 | 2351 | const ip = &zcu.intern_pool; |
| 2403 | 2352 | const nav = ip.getNav(nav_index); |
| ... | ... | @@ -2483,8 +2432,6 @@ pub fn getUavVAddr( |
| 2483 | 2432 | uav: InternPool.Index, |
| 2484 | 2433 | reloc_info: link.File.RelocInfo, |
| 2485 | 2434 | ) !u64 { |
| 2486 | assert(coff.llvm_object == null); | |
| 2487 | ||
| 2488 | 2435 | const this_atom_index = coff.uavs.get(uav).?.atom; |
| 2489 | 2436 | const sym_index = coff.getAtom(this_atom_index).getSymbolIndex().?; |
| 2490 | 2437 | const atom_index = coff.getAtomIndexForSymbol(.{ |
| ... | ... | @@ -3798,7 +3745,6 @@ const trace = @import("../tracy.zig").trace; |
| 3798 | 3745 | |
| 3799 | 3746 | const Air = @import("../Air.zig"); |
| 3800 | 3747 | const Compilation = @import("../Compilation.zig"); |
| 3801 | const LlvmObject = @import("../codegen/llvm.zig").Object; | |
| 3802 | 3748 | const Zcu = @import("../Zcu.zig"); |
| 3803 | 3749 | const InternPool = @import("../InternPool.zig"); |
| 3804 | 3750 | const TableSection = @import("table_section.zig").TableSection; |
src/link/Dwarf.zig+1-1| ... | ... | @@ -4391,7 +4391,7 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A |
| 4391 | 4391 | return @intFromEnum(abbrev_code); |
| 4392 | 4392 | } |
| 4393 | 4393 | |
| 4394 | pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | |
| 4394 | pub fn flushZcu(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | |
| 4395 | 4395 | const zcu = pt.zcu; |
| 4396 | 4396 | const ip = &zcu.intern_pool; |
| 4397 | 4397 |
src/link/Elf.zig+10-30| ... | ... | @@ -32,9 +32,6 @@ entry_name: ?[]const u8, |
| 32 | 32 | |
| 33 | 33 | ptr_width: PtrWidth, |
| 34 | 34 | |
| 35 | /// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path. | |
| 36 | llvm_object: ?LlvmObject.Ptr = null, | |
| 37 | ||
| 38 | 35 | /// A list of all input files. |
| 39 | 36 | /// First index is a special "null file". Order is otherwise not observed. |
| 40 | 37 | files: std.MultiArrayList(File.Entry) = .{}, |
| ... | ... | @@ -344,9 +341,6 @@ pub fn createEmpty( |
| 344 | 341 | .print_map = options.print_map, |
| 345 | 342 | .dump_argv_list = .empty, |
| 346 | 343 | }; |
| 347 | if (use_llvm and comp.config.have_zcu) { | |
| 348 | self.llvm_object = try LlvmObject.create(arena, comp); | |
| 349 | } | |
| 350 | 344 | errdefer self.base.destroy(); |
| 351 | 345 | |
| 352 | 346 | if (use_lld and (use_llvm or !comp.config.have_zcu)) { |
| ... | ... | @@ -457,8 +451,6 @@ pub fn open( |
| 457 | 451 | pub fn deinit(self: *Elf) void { |
| 458 | 452 | const gpa = self.base.comp.gpa; |
| 459 | 453 | |
| 460 | if (self.llvm_object) |llvm_object| llvm_object.deinit(); | |
| 461 | ||
| 462 | 454 | for (self.file_handles.items) |fh| { |
| 463 | 455 | fh.close(); |
| 464 | 456 | } |
| ... | ... | @@ -515,7 +507,6 @@ pub fn deinit(self: *Elf) void { |
| 515 | 507 | } |
| 516 | 508 | |
| 517 | 509 | pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 518 | assert(self.llvm_object == null); | |
| 519 | 510 | return self.zigObjectPtr().?.getNavVAddr(self, pt, nav_index, reloc_info); |
| 520 | 511 | } |
| 521 | 512 | |
| ... | ... | @@ -530,7 +521,6 @@ pub fn lowerUav( |
| 530 | 521 | } |
| 531 | 522 | |
| 532 | 523 | pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 533 | assert(self.llvm_object == null); | |
| 534 | 524 | return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info); |
| 535 | 525 | } |
| 536 | 526 | |
| ... | ... | @@ -805,35 +795,29 @@ pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std |
| 805 | 795 | else => |e| return diags.fail("failed to link with LLD: {s}", .{@errorName(e)}), |
| 806 | 796 | }; |
| 807 | 797 | } |
| 808 | try self.flushModule(arena, tid, prog_node); | |
| 798 | try self.flushZcu(arena, tid, prog_node); | |
| 809 | 799 | } |
| 810 | 800 | |
| 811 | pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 801 | pub fn flushZcu(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 812 | 802 | const tracy = trace(@src()); |
| 813 | 803 | defer tracy.end(); |
| 814 | 804 | |
| 815 | 805 | const comp = self.base.comp; |
| 816 | 806 | const diags = &comp.link_diags; |
| 817 | 807 | |
| 818 | if (self.llvm_object) |llvm_object| { | |
| 819 | try self.base.emitLlvmObject(arena, llvm_object, prog_node); | |
| 820 | const use_lld = build_options.have_llvm and comp.config.use_lld; | |
| 821 | if (use_lld) return; | |
| 822 | } | |
| 823 | ||
| 824 | 808 | if (comp.verbose_link) Compilation.dump_argv(self.dump_argv_list.items); |
| 825 | 809 | |
| 826 | 810 | const sub_prog_node = prog_node.start("ELF Flush", 0); |
| 827 | 811 | defer sub_prog_node.end(); |
| 828 | 812 | |
| 829 | return flushModuleInner(self, arena, tid) catch |err| switch (err) { | |
| 813 | return flushZcuInner(self, arena, tid) catch |err| switch (err) { | |
| 830 | 814 | error.OutOfMemory => return error.OutOfMemory, |
| 831 | 815 | error.LinkFailure => return error.LinkFailure, |
| 832 | 816 | else => |e| return diags.fail("ELF flush failed: {s}", .{@errorName(e)}), |
| 833 | 817 | }; |
| 834 | 818 | } |
| 835 | 819 | |
| 836 | fn flushModuleInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { | |
| 820 | fn flushZcuInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { | |
| 837 | 821 | const comp = self.base.comp; |
| 838 | 822 | const gpa = comp.gpa; |
| 839 | 823 | const diags = &comp.link_diags; |
| ... | ... | @@ -1523,8 +1507,12 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s |
| 1523 | 1507 | |
| 1524 | 1508 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 1525 | 1509 | // will not be part of the linker line anyway. |
| 1526 | const module_obj_path: ?[]const u8 = if (comp.zcu != null) blk: { | |
| 1527 | try self.flushModule(arena, tid, prog_node); | |
| 1510 | const module_obj_path: ?[]const u8 = if (comp.zcu) |zcu| blk: { | |
| 1511 | if (zcu.llvm_object == null) { | |
| 1512 | try self.flushZcu(arena, tid, prog_node); | |
| 1513 | } else { | |
| 1514 | // `Compilation.flush` has already made LLVM emit this object file for us. | |
| 1515 | } | |
| 1528 | 1516 | |
| 1529 | 1517 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 1530 | 1518 | break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? }); |
| ... | ... | @@ -2385,7 +2373,6 @@ pub fn writeElfHeader(self: *Elf) !void { |
| 2385 | 2373 | } |
| 2386 | 2374 | |
| 2387 | 2375 | pub fn freeNav(self: *Elf, nav: InternPool.Nav.Index) void { |
| 2388 | if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav); | |
| 2389 | 2376 | return self.zigObjectPtr().?.freeNav(self, nav); |
| 2390 | 2377 | } |
| 2391 | 2378 | |
| ... | ... | @@ -2399,7 +2386,6 @@ pub fn updateFunc( |
| 2399 | 2386 | if (build_options.skip_non_native and builtin.object_format != .elf) { |
| 2400 | 2387 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 2401 | 2388 | } |
| 2402 | if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness); | |
| 2403 | 2389 | return self.zigObjectPtr().?.updateFunc(self, pt, func_index, air, liveness); |
| 2404 | 2390 | } |
| 2405 | 2391 | |
| ... | ... | @@ -2411,7 +2397,6 @@ pub fn updateNav( |
| 2411 | 2397 | if (build_options.skip_non_native and builtin.object_format != .elf) { |
| 2412 | 2398 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 2413 | 2399 | } |
| 2414 | if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav); | |
| 2415 | 2400 | return self.zigObjectPtr().?.updateNav(self, pt, nav); |
| 2416 | 2401 | } |
| 2417 | 2402 | |
| ... | ... | @@ -2423,7 +2408,6 @@ pub fn updateContainerType( |
| 2423 | 2408 | if (build_options.skip_non_native and builtin.object_format != .elf) { |
| 2424 | 2409 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 2425 | 2410 | } |
| 2426 | if (self.llvm_object) |_| return; | |
| 2427 | 2411 | const zcu = pt.zcu; |
| 2428 | 2412 | const gpa = zcu.gpa; |
| 2429 | 2413 | return self.zigObjectPtr().?.updateContainerType(pt, ty) catch |err| switch (err) { |
| ... | ... | @@ -2449,12 +2433,10 @@ pub fn updateExports( |
| 2449 | 2433 | if (build_options.skip_non_native and builtin.object_format != .elf) { |
| 2450 | 2434 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 2451 | 2435 | } |
| 2452 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices); | |
| 2453 | 2436 | return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices); |
| 2454 | 2437 | } |
| 2455 | 2438 | |
| 2456 | 2439 | pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { |
| 2457 | if (self.llvm_object) |_| return; | |
| 2458 | 2440 | return self.zigObjectPtr().?.updateLineNumber(pt, ti_id); |
| 2459 | 2441 | } |
| 2460 | 2442 | |
| ... | ... | @@ -2463,7 +2445,6 @@ pub fn deleteExport( |
| 2463 | 2445 | exported: Zcu.Exported, |
| 2464 | 2446 | name: InternPool.NullTerminatedString, |
| 2465 | 2447 | ) void { |
| 2466 | if (self.llvm_object) |_| return; | |
| 2467 | 2448 | return self.zigObjectPtr().?.deleteExport(self, exported, name); |
| 2468 | 2449 | } |
| 2469 | 2450 | |
| ... | ... | @@ -5332,7 +5313,6 @@ const GotSection = synthetic_sections.GotSection; |
| 5332 | 5313 | const GotPltSection = synthetic_sections.GotPltSection; |
| 5333 | 5314 | const HashSection = synthetic_sections.HashSection; |
| 5334 | 5315 | const LinkerDefined = @import("Elf/LinkerDefined.zig"); |
| 5335 | const LlvmObject = @import("../codegen/llvm.zig").Object; | |
| 5336 | 5316 | const Zcu = @import("../Zcu.zig"); |
| 5337 | 5317 | const Object = @import("Elf/Object.zig"); |
| 5338 | 5318 | const InternPool = @import("../InternPool.zig"); |
src/link/Elf/ZigObject.zig+4-4| ... | ... | @@ -310,7 +310,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void { |
| 310 | 310 | if (self.dwarf) |*dwarf| { |
| 311 | 311 | const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid); |
| 312 | 312 | defer pt.deactivate(); |
| 313 | try dwarf.flushModule(pt); | |
| 313 | try dwarf.flushZcu(pt); | |
| 314 | 314 | |
| 315 | 315 | const gpa = elf_file.base.comp.gpa; |
| 316 | 316 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| ... | ... | @@ -481,7 +481,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void { |
| 481 | 481 | self.debug_str_section_dirty = false; |
| 482 | 482 | } |
| 483 | 483 | |
| 484 | // The point of flushModule() is to commit changes, so in theory, nothing should | |
| 484 | // The point of flushZcu() is to commit changes, so in theory, nothing should | |
| 485 | 485 | // be dirty after this. However, it is possible for some things to remain |
| 486 | 486 | // dirty because they fail to be written in the event of compile errors, |
| 487 | 487 | // such as debug_line_header_dirty and debug_info_header_dirty. |
| ... | ... | @@ -661,7 +661,7 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { |
| 661 | 661 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 662 | 662 | if (atom_ptr.scanRelocsRequiresCode(elf_file)) { |
| 663 | 663 | // TODO ideally we don't have to fetch the code here. |
| 664 | // Perhaps it would make sense to save the code until flushModule where we | |
| 664 | // Perhaps it would make sense to save the code until flushZcu where we | |
| 665 | 665 | // would free all of generated code? |
| 666 | 666 | const code = try self.codeAlloc(elf_file, atom_index); |
| 667 | 667 | defer gpa.free(code); |
| ... | ... | @@ -1075,7 +1075,7 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1075 | 1075 | } |
| 1076 | 1076 | state_ptr.* = .pending_flush; |
| 1077 | 1077 | const symbol_index = symbol_index_ptr.*; |
| 1078 | // anyerror needs to be deferred until flushModule | |
| 1078 | // anyerror needs to be deferred until flushZcu | |
| 1079 | 1079 | if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index); |
| 1080 | 1080 | return symbol_index; |
| 1081 | 1081 | } |
src/link/Goff.zig+22-24| ... | ... | @@ -17,10 +17,8 @@ const link = @import("../link.zig"); |
| 17 | 17 | const trace = @import("../tracy.zig").trace; |
| 18 | 18 | const build_options = @import("build_options"); |
| 19 | 19 | const Air = @import("../Air.zig"); |
| 20 | const LlvmObject = @import("../codegen/llvm.zig").Object; | |
| 21 | 20 | |
| 22 | 21 | base: link.File, |
| 23 | llvm_object: LlvmObject.Ptr, | |
| 24 | 22 | |
| 25 | 23 | pub fn createEmpty( |
| 26 | 24 | arena: Allocator, |
| ... | ... | @@ -36,7 +34,6 @@ pub fn createEmpty( |
| 36 | 34 | assert(!use_lld); // Caught by Compilation.Config.resolve. |
| 37 | 35 | assert(target.os.tag == .zos); // Caught by Compilation.Config.resolve. |
| 38 | 36 | |
| 39 | const llvm_object = try LlvmObject.create(arena, comp); | |
| 40 | 37 | const goff = try arena.create(Goff); |
| 41 | 38 | goff.* = .{ |
| 42 | 39 | .base = .{ |
| ... | ... | @@ -52,7 +49,6 @@ pub fn createEmpty( |
| 52 | 49 | .disable_lld_caching = options.disable_lld_caching, |
| 53 | 50 | .build_id = options.build_id, |
| 54 | 51 | }, |
| 55 | .llvm_object = llvm_object, | |
| 56 | 52 | }; |
| 57 | 53 | |
| 58 | 54 | return goff; |
| ... | ... | @@ -70,7 +66,7 @@ pub fn open( |
| 70 | 66 | } |
| 71 | 67 | |
| 72 | 68 | pub fn deinit(self: *Goff) void { |
| 73 | self.llvm_object.deinit(); | |
| 69 | _ = self; | |
| 74 | 70 | } |
| 75 | 71 | |
| 76 | 72 | pub fn updateFunc( |
| ... | ... | @@ -80,17 +76,19 @@ pub fn updateFunc( |
| 80 | 76 | air: Air, |
| 81 | 77 | liveness: Air.Liveness, |
| 82 | 78 | ) link.File.UpdateNavError!void { |
| 83 | if (build_options.skip_non_native and builtin.object_format != .goff) | |
| 84 | @panic("Attempted to compile for object format that was disabled by build configuration"); | |
| 85 | ||
| 86 | try self.llvm_object.updateFunc(pt, func_index, air, liveness); | |
| 79 | _ = self; | |
| 80 | _ = pt; | |
| 81 | _ = func_index; | |
| 82 | _ = air; | |
| 83 | _ = liveness; | |
| 84 | unreachable; // we always use llvm | |
| 87 | 85 | } |
| 88 | 86 | |
| 89 | 87 | pub fn updateNav(self: *Goff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void { |
| 90 | if (build_options.skip_non_native and builtin.object_format != .goff) | |
| 91 | @panic("Attempted to compile for object format that was disabled by build configuration"); | |
| 92 | ||
| 93 | return self.llvm_object.updateNav(pt, nav); | |
| 88 | _ = self; | |
| 89 | _ = pt; | |
| 90 | _ = nav; | |
| 91 | unreachable; // we always use llvm | |
| 94 | 92 | } |
| 95 | 93 | |
| 96 | 94 | pub fn updateExports( |
| ... | ... | @@ -99,21 +97,21 @@ pub fn updateExports( |
| 99 | 97 | exported: Zcu.Exported, |
| 100 | 98 | export_indices: []const Zcu.Export.Index, |
| 101 | 99 | ) !void { |
| 102 | if (build_options.skip_non_native and builtin.object_format != .goff) | |
| 103 | @panic("Attempted to compile for object format that was disabled by build configuration"); | |
| 104 | ||
| 105 | return self.llvm_object.updateExports(pt, exported, export_indices); | |
| 100 | _ = self; | |
| 101 | _ = pt; | |
| 102 | _ = exported; | |
| 103 | _ = export_indices; | |
| 104 | unreachable; // we always use llvm | |
| 106 | 105 | } |
| 107 | 106 | |
| 108 | 107 | pub fn flush(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 109 | return self.flushModule(arena, tid, prog_node); | |
| 108 | return self.flushZcu(arena, tid, prog_node); | |
| 110 | 109 | } |
| 111 | 110 | |
| 112 | pub fn flushModule(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 113 | if (build_options.skip_non_native and builtin.object_format != .goff) | |
| 114 | @panic("Attempted to compile for object format that was disabled by build configuration"); | |
| 115 | ||
| 111 | pub fn flushZcu(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 112 | _ = self; | |
| 113 | _ = arena; | |
| 116 | 114 | _ = tid; |
| 117 | ||
| 118 | try self.base.emitLlvmObject(arena, self.llvm_object, prog_node); | |
| 115 | _ = prog_node; | |
| 116 | unreachable; // we always use llvm | |
| 119 | 117 | } |
src/link/MachO.zig+4-25| ... | ... | @@ -6,9 +6,6 @@ base: link.File, |
| 6 | 6 | |
| 7 | 7 | rpath_list: []const []const u8, |
| 8 | 8 | |
| 9 | /// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path. | |
| 10 | llvm_object: ?LlvmObject.Ptr = null, | |
| 11 | ||
| 12 | 9 | /// Debug symbols bundle (or dSym). |
| 13 | 10 | d_sym: ?DebugSymbols = null, |
| 14 | 11 | |
| ... | ... | @@ -225,9 +222,6 @@ pub fn createEmpty( |
| 225 | 222 | .force_load_objc = options.force_load_objc, |
| 226 | 223 | .discard_local_symbols = options.discard_local_symbols, |
| 227 | 224 | }; |
| 228 | if (use_llvm and comp.config.have_zcu) { | |
| 229 | self.llvm_object = try LlvmObject.create(arena, comp); | |
| 230 | } | |
| 231 | 225 | errdefer self.base.destroy(); |
| 232 | 226 | |
| 233 | 227 | self.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{ |
| ... | ... | @@ -280,8 +274,6 @@ pub fn open( |
| 280 | 274 | pub fn deinit(self: *MachO) void { |
| 281 | 275 | const gpa = self.base.comp.gpa; |
| 282 | 276 | |
| 283 | if (self.llvm_object) |llvm_object| llvm_object.deinit(); | |
| 284 | ||
| 285 | 277 | if (self.d_sym) |*d_sym| { |
| 286 | 278 | d_sym.deinit(); |
| 287 | 279 | } |
| ... | ... | @@ -350,10 +342,10 @@ pub fn flush( |
| 350 | 342 | tid: Zcu.PerThread.Id, |
| 351 | 343 | prog_node: std.Progress.Node, |
| 352 | 344 | ) link.File.FlushError!void { |
| 353 | try self.flushModule(arena, tid, prog_node); | |
| 345 | try self.flushZcu(arena, tid, prog_node); | |
| 354 | 346 | } |
| 355 | 347 | |
| 356 | pub fn flushModule( | |
| 348 | pub fn flushZcu( | |
| 357 | 349 | self: *MachO, |
| 358 | 350 | arena: Allocator, |
| 359 | 351 | tid: Zcu.PerThread.Id, |
| ... | ... | @@ -366,10 +358,6 @@ pub fn flushModule( |
| 366 | 358 | const gpa = comp.gpa; |
| 367 | 359 | const diags = &self.base.comp.link_diags; |
| 368 | 360 | |
| 369 | if (self.llvm_object) |llvm_object| { | |
| 370 | try self.base.emitLlvmObject(arena, llvm_object, prog_node); | |
| 371 | } | |
| 372 | ||
| 373 | 361 | const sub_prog_node = prog_node.start("MachO Flush", 0); |
| 374 | 362 | defer sub_prog_node.end(); |
| 375 | 363 | |
| ... | ... | @@ -385,7 +373,7 @@ pub fn flushModule( |
| 385 | 373 | // --verbose-link |
| 386 | 374 | if (comp.verbose_link) try self.dumpArgv(comp); |
| 387 | 375 | |
| 388 | if (self.getZigObject()) |zo| try zo.flushModule(self, tid); | |
| 376 | if (self.getZigObject()) |zo| try zo.flushZcu(self, tid); | |
| 389 | 377 | if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); |
| 390 | 378 | if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); |
| 391 | 379 | |
| ... | ... | @@ -629,7 +617,7 @@ pub fn flushModule( |
| 629 | 617 | error.LinkFailure => return error.LinkFailure, |
| 630 | 618 | else => |e| return diags.fail("failed to calculate and write uuid: {s}", .{@errorName(e)}), |
| 631 | 619 | }; |
| 632 | if (self.getDebugSymbols()) |dsym| dsym.flushModule(self) catch |err| switch (err) { | |
| 620 | if (self.getDebugSymbols()) |dsym| dsym.flushZcu(self) catch |err| switch (err) { | |
| 633 | 621 | error.OutOfMemory => return error.OutOfMemory, |
| 634 | 622 | else => |e| return diags.fail("failed to get debug symbols: {s}", .{@errorName(e)}), |
| 635 | 623 | }; |
| ... | ... | @@ -3079,7 +3067,6 @@ pub fn updateFunc( |
| 3079 | 3067 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 3080 | 3068 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3081 | 3069 | } |
| 3082 | if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness); | |
| 3083 | 3070 | return self.getZigObject().?.updateFunc(self, pt, func_index, air, liveness); |
| 3084 | 3071 | } |
| 3085 | 3072 | |
| ... | ... | @@ -3087,12 +3074,10 @@ pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) lin |
| 3087 | 3074 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 3088 | 3075 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3089 | 3076 | } |
| 3090 | if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav); | |
| 3091 | 3077 | return self.getZigObject().?.updateNav(self, pt, nav); |
| 3092 | 3078 | } |
| 3093 | 3079 | |
| 3094 | 3080 | pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { |
| 3095 | if (self.llvm_object) |_| return; | |
| 3096 | 3081 | return self.getZigObject().?.updateLineNumber(pt, ti_id); |
| 3097 | 3082 | } |
| 3098 | 3083 | |
| ... | ... | @@ -3105,7 +3090,6 @@ pub fn updateExports( |
| 3105 | 3090 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 3106 | 3091 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3107 | 3092 | } |
| 3108 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices); | |
| 3109 | 3093 | return self.getZigObject().?.updateExports(self, pt, exported, export_indices); |
| 3110 | 3094 | } |
| 3111 | 3095 | |
| ... | ... | @@ -3114,17 +3098,14 @@ pub fn deleteExport( |
| 3114 | 3098 | exported: Zcu.Exported, |
| 3115 | 3099 | name: InternPool.NullTerminatedString, |
| 3116 | 3100 | ) void { |
| 3117 | if (self.llvm_object) |_| return; | |
| 3118 | 3101 | return self.getZigObject().?.deleteExport(self, exported, name); |
| 3119 | 3102 | } |
| 3120 | 3103 | |
| 3121 | 3104 | pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void { |
| 3122 | if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav); | |
| 3123 | 3105 | return self.getZigObject().?.freeNav(nav); |
| 3124 | 3106 | } |
| 3125 | 3107 | |
| 3126 | 3108 | pub fn getNavVAddr(self: *MachO, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 3127 | assert(self.llvm_object == null); | |
| 3128 | 3109 | return self.getZigObject().?.getNavVAddr(self, pt, nav_index, reloc_info); |
| 3129 | 3110 | } |
| 3130 | 3111 | |
| ... | ... | @@ -3139,7 +3120,6 @@ pub fn lowerUav( |
| 3139 | 3120 | } |
| 3140 | 3121 | |
| 3141 | 3122 | pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 3142 | assert(self.llvm_object == null); | |
| 3143 | 3123 | return self.getZigObject().?.getUavVAddr(self, uav, reloc_info); |
| 3144 | 3124 | } |
| 3145 | 3125 | |
| ... | ... | @@ -5496,7 +5476,6 @@ const ObjcStubsSection = synthetic.ObjcStubsSection; |
| 5496 | 5476 | const Object = @import("MachO/Object.zig"); |
| 5497 | 5477 | const LazyBind = bind.LazyBind; |
| 5498 | 5478 | const LaSymbolPtrSection = synthetic.LaSymbolPtrSection; |
| 5499 | const LlvmObject = @import("../codegen/llvm.zig").Object; | |
| 5500 | 5479 | const Md5 = std.crypto.hash.Md5; |
| 5501 | 5480 | const Zcu = @import("../Zcu.zig"); |
| 5502 | 5481 | const InternPool = @import("../InternPool.zig"); |
src/link/MachO/DebugSymbols.zig+1-1| ... | ... | @@ -178,7 +178,7 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) !u64 |
| 178 | 178 | return offset; |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { | |
| 181 | pub fn flushZcu(self: *DebugSymbols, macho_file: *MachO) !void { | |
| 182 | 182 | const zo = macho_file.getZigObject().?; |
| 183 | 183 | for (self.relocs.items) |*reloc| { |
| 184 | 184 | const sym = zo.symbols.items[reloc.target]; |
src/link/MachO/ZigObject.zig+4-4| ... | ... | @@ -550,7 +550,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se |
| 550 | 550 | return sect; |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.File.FlushError!void { | |
| 553 | pub fn flushZcu(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.File.FlushError!void { | |
| 554 | 554 | const diags = &macho_file.base.comp.link_diags; |
| 555 | 555 | |
| 556 | 556 | // Handle any lazy symbols that were emitted by incremental compilation. |
| ... | ... | @@ -589,7 +589,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) |
| 589 | 589 | if (self.dwarf) |*dwarf| { |
| 590 | 590 | const pt: Zcu.PerThread = .activate(macho_file.base.comp.zcu.?, tid); |
| 591 | 591 | defer pt.deactivate(); |
| 592 | dwarf.flushModule(pt) catch |err| switch (err) { | |
| 592 | dwarf.flushZcu(pt) catch |err| switch (err) { | |
| 593 | 593 | error.OutOfMemory => return error.OutOfMemory, |
| 594 | 594 | else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}), |
| 595 | 595 | }; |
| ... | ... | @@ -599,7 +599,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) |
| 599 | 599 | self.debug_strtab_dirty = false; |
| 600 | 600 | } |
| 601 | 601 | |
| 602 | // The point of flushModule() is to commit changes, so in theory, nothing should | |
| 602 | // The point of flushZcu() is to commit changes, so in theory, nothing should | |
| 603 | 603 | // be dirty after this. However, it is possible for some things to remain |
| 604 | 604 | // dirty because they fail to be written in the event of compile errors, |
| 605 | 605 | // such as debug_line_header_dirty and debug_info_header_dirty. |
| ... | ... | @@ -1537,7 +1537,7 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1537 | 1537 | } |
| 1538 | 1538 | state_ptr.* = .pending_flush; |
| 1539 | 1539 | const symbol_index = symbol_index_ptr.*; |
| 1540 | // anyerror needs to be deferred until flushModule | |
| 1540 | // anyerror needs to be deferred until flushZcu | |
| 1541 | 1541 | if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index); |
| 1542 | 1542 | return symbol_index; |
| 1543 | 1543 | } |
src/link/Plan9.zig+5-5| ... | ... | @@ -494,7 +494,7 @@ fn updateFinish(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 494 | 494 | // write the symbol |
| 495 | 495 | // we already have the got index |
| 496 | 496 | const sym: aout.Sym = .{ |
| 497 | .value = undefined, // the value of stuff gets filled in in flushModule | |
| 497 | .value = undefined, // the value of stuff gets filled in in flushZcu | |
| 498 | 498 | .type = atom.type, |
| 499 | 499 | .name = try gpa.dupe(u8, nav.name.toSlice(ip)), |
| 500 | 500 | }; |
| ... | ... | @@ -543,7 +543,7 @@ pub fn flush( |
| 543 | 543 | .Obj => return diags.fail("writing plan9 object files unimplemented", .{}), |
| 544 | 544 | .Lib => return diags.fail("writing plan9 lib files unimplemented", .{}), |
| 545 | 545 | } |
| 546 | return self.flushModule(arena, tid, prog_node); | |
| 546 | return self.flushZcu(arena, tid, prog_node); | |
| 547 | 547 | } |
| 548 | 548 | |
| 549 | 549 | pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { |
| ... | ... | @@ -586,7 +586,7 @@ fn atomCount(self: *Plan9) usize { |
| 586 | 586 | return data_nav_count + fn_nav_count + lazy_atom_count + extern_atom_count + uav_atom_count; |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | pub fn flushModule( | |
| 589 | pub fn flushZcu( | |
| 590 | 590 | self: *Plan9, |
| 591 | 591 | arena: Allocator, |
| 592 | 592 | /// TODO: stop using this |
| ... | ... | @@ -610,7 +610,7 @@ pub fn flushModule( |
| 610 | 610 | const sub_prog_node = prog_node.start("Flush Module", 0); |
| 611 | 611 | defer sub_prog_node.end(); |
| 612 | 612 | |
| 613 | log.debug("flushModule", .{}); | |
| 613 | log.debug("flushZcu", .{}); | |
| 614 | 614 | |
| 615 | 615 | defer assert(self.hdr.entry != 0x0); |
| 616 | 616 | |
| ... | ... | @@ -1039,7 +1039,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, lazy_sym: F |
| 1039 | 1039 | const atom = atom_ptr.*; |
| 1040 | 1040 | _ = try self.getAtomPtr(atom).getOrCreateSymbolTableEntry(self); |
| 1041 | 1041 | _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self); |
| 1042 | // anyerror needs to be deferred until flushModule | |
| 1042 | // anyerror needs to be deferred until flushZcu | |
| 1043 | 1043 | if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbolAtom(pt, lazy_sym, atom); |
| 1044 | 1044 | return atom; |
| 1045 | 1045 | } |
src/link/SpirV.zig+4-4| ... | ... | @@ -17,7 +17,7 @@ |
| 17 | 17 | //! All regular functions. |
| 18 | 18 | |
| 19 | 19 | // Because SPIR-V requires re-compilation anyway, and so hot swapping will not work |
| 20 | // anyway, we simply generate all the code in flushModule. This keeps | |
| 20 | // anyway, we simply generate all the code in flushZcu. This keeps | |
| 21 | 21 | // things considerably simpler. |
| 22 | 22 | |
| 23 | 23 | const SpirV = @This(); |
| ... | ... | @@ -194,17 +194,17 @@ pub fn updateExports( |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | 196 | pub fn flush(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 197 | return self.flushModule(arena, tid, prog_node); | |
| 197 | return self.flushZcu(arena, tid, prog_node); | |
| 198 | 198 | } |
| 199 | 199 | |
| 200 | pub fn flushModule( | |
| 200 | pub fn flushZcu( | |
| 201 | 201 | self: *SpirV, |
| 202 | 202 | arena: Allocator, |
| 203 | 203 | tid: Zcu.PerThread.Id, |
| 204 | 204 | prog_node: std.Progress.Node, |
| 205 | 205 | ) link.File.FlushError!void { |
| 206 | 206 | // The goal is to never use this because it's only needed if we need to |
| 207 | // write to InternPool, but flushModule is too late to be writing to the | |
| 207 | // write to InternPool, but flushZcu is too late to be writing to the | |
| 208 | 208 | // InternPool. |
| 209 | 209 | _ = tid; |
| 210 | 210 |
src/link/Wasm.zig+9-23| ... | ... | @@ -36,7 +36,6 @@ const abi = @import("../arch/wasm/abi.zig"); |
| 36 | 36 | const Compilation = @import("../Compilation.zig"); |
| 37 | 37 | const Dwarf = @import("Dwarf.zig"); |
| 38 | 38 | const InternPool = @import("../InternPool.zig"); |
| 39 | const LlvmObject = @import("../codegen/llvm.zig").Object; | |
| 40 | 39 | const Zcu = @import("../Zcu.zig"); |
| 41 | 40 | const codegen = @import("../codegen.zig"); |
| 42 | 41 | const dev = @import("../dev.zig"); |
| ... | ... | @@ -81,8 +80,6 @@ import_table: bool, |
| 81 | 80 | export_table: bool, |
| 82 | 81 | /// Output name of the file |
| 83 | 82 | name: []const u8, |
| 84 | /// If this is not null, an object file is created by LLVM and linked with LLD afterwards. | |
| 85 | llvm_object: ?LlvmObject.Ptr = null, | |
| 86 | 83 | /// List of relocatable files to be linked into the final binary. |
| 87 | 84 | objects: std.ArrayListUnmanaged(Object) = .{}, |
| 88 | 85 | |
| ... | ... | @@ -2992,9 +2989,6 @@ pub fn createEmpty( |
| 2992 | 2989 | .object_host_name = .none, |
| 2993 | 2990 | .preloaded_strings = undefined, |
| 2994 | 2991 | }; |
| 2995 | if (use_llvm and comp.config.have_zcu) { | |
| 2996 | wasm.llvm_object = try LlvmObject.create(arena, comp); | |
| 2997 | } | |
| 2998 | 2992 | errdefer wasm.base.destroy(); |
| 2999 | 2993 | |
| 3000 | 2994 | if (options.object_host_name) |name| wasm.object_host_name = (try wasm.internString(name)).toOptional(); |
| ... | ... | @@ -3116,7 +3110,6 @@ fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void { |
| 3116 | 3110 | |
| 3117 | 3111 | pub fn deinit(wasm: *Wasm) void { |
| 3118 | 3112 | const gpa = wasm.base.comp.gpa; |
| 3119 | if (wasm.llvm_object) |llvm_object| llvm_object.deinit(); | |
| 3120 | 3113 | |
| 3121 | 3114 | wasm.navs_exe.deinit(gpa); |
| 3122 | 3115 | wasm.navs_obj.deinit(gpa); |
| ... | ... | @@ -3196,7 +3189,6 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, |
| 3196 | 3189 | if (build_options.skip_non_native and builtin.object_format != .wasm) { |
| 3197 | 3190 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3198 | 3191 | } |
| 3199 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness); | |
| 3200 | 3192 | |
| 3201 | 3193 | dev.check(.wasm_backend); |
| 3202 | 3194 | |
| ... | ... | @@ -3228,7 +3220,6 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 3228 | 3220 | if (build_options.skip_non_native and builtin.object_format != .wasm) { |
| 3229 | 3221 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3230 | 3222 | } |
| 3231 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav_index); | |
| 3232 | 3223 | const zcu = pt.zcu; |
| 3233 | 3224 | const ip = &zcu.intern_pool; |
| 3234 | 3225 | const nav = ip.getNav(nav_index); |
| ... | ... | @@ -3308,8 +3299,6 @@ pub fn deleteExport( |
| 3308 | 3299 | exported: Zcu.Exported, |
| 3309 | 3300 | name: InternPool.NullTerminatedString, |
| 3310 | 3301 | ) void { |
| 3311 | if (wasm.llvm_object != null) return; | |
| 3312 | ||
| 3313 | 3302 | const zcu = wasm.base.comp.zcu.?; |
| 3314 | 3303 | const ip = &zcu.intern_pool; |
| 3315 | 3304 | const name_slice = name.toSlice(ip); |
| ... | ... | @@ -3332,7 +3321,6 @@ pub fn updateExports( |
| 3332 | 3321 | if (build_options.skip_non_native and builtin.object_format != .wasm) { |
| 3333 | 3322 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3334 | 3323 | } |
| 3335 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices); | |
| 3336 | 3324 | |
| 3337 | 3325 | const zcu = pt.zcu; |
| 3338 | 3326 | const gpa = zcu.gpa; |
| ... | ... | @@ -3391,7 +3379,7 @@ pub fn flush(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: st |
| 3391 | 3379 | else => |e| return diags.fail("failed to link with LLD: {s}", .{@errorName(e)}), |
| 3392 | 3380 | }; |
| 3393 | 3381 | } |
| 3394 | return wasm.flushModule(arena, tid, prog_node); | |
| 3382 | return wasm.flushZcu(arena, tid, prog_node); | |
| 3395 | 3383 | } |
| 3396 | 3384 | |
| 3397 | 3385 | pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!void { |
| ... | ... | @@ -3785,26 +3773,20 @@ fn markTable(wasm: *Wasm, i: ObjectTableIndex) link.File.FlushError!void { |
| 3785 | 3773 | try wasm.tables.put(wasm.base.comp.gpa, .fromObjectTable(i), {}); |
| 3786 | 3774 | } |
| 3787 | 3775 | |
| 3788 | pub fn flushModule( | |
| 3776 | pub fn flushZcu( | |
| 3789 | 3777 | wasm: *Wasm, |
| 3790 | 3778 | arena: Allocator, |
| 3791 | 3779 | tid: Zcu.PerThread.Id, |
| 3792 | 3780 | prog_node: std.Progress.Node, |
| 3793 | 3781 | ) link.File.FlushError!void { |
| 3794 | 3782 | // The goal is to never use this because it's only needed if we need to |
| 3795 | // write to InternPool, but flushModule is too late to be writing to the | |
| 3783 | // write to InternPool, but flushZcu is too late to be writing to the | |
| 3796 | 3784 | // InternPool. |
| 3797 | 3785 | _ = tid; |
| 3798 | 3786 | const comp = wasm.base.comp; |
| 3799 | const use_lld = build_options.have_llvm and comp.config.use_lld; | |
| 3800 | 3787 | const diags = &comp.link_diags; |
| 3801 | 3788 | const gpa = comp.gpa; |
| 3802 | 3789 | |
| 3803 | if (wasm.llvm_object) |llvm_object| { | |
| 3804 | try wasm.base.emitLlvmObject(arena, llvm_object, prog_node); | |
| 3805 | if (use_lld) return; | |
| 3806 | } | |
| 3807 | ||
| 3808 | 3790 | if (comp.verbose_link) Compilation.dump_argv(wasm.dump_argv_list.items); |
| 3809 | 3791 | |
| 3810 | 3792 | if (wasm.base.zcu_object_sub_path) |path| { |
| ... | ... | @@ -3870,8 +3852,12 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: |
| 3870 | 3852 | |
| 3871 | 3853 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 3872 | 3854 | // will not be part of the linker line anyway. |
| 3873 | const module_obj_path: ?[]const u8 = if (comp.zcu != null) blk: { | |
| 3874 | try wasm.flushModule(arena, tid, prog_node); | |
| 3855 | const module_obj_path: ?[]const u8 = if (comp.zcu) |zcu| blk: { | |
| 3856 | if (zcu.llvm_object == null) { | |
| 3857 | try wasm.flushZcu(arena, tid, prog_node); | |
| 3858 | } else { | |
| 3859 | // `Compilation.flush` has already made LLVM emit this object file for us. | |
| 3860 | } | |
| 3875 | 3861 | |
| 3876 | 3862 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 3877 | 3863 | break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? }); |
src/link/Xcoff.zig+22-24| ... | ... | @@ -17,10 +17,8 @@ const link = @import("../link.zig"); |
| 17 | 17 | const trace = @import("../tracy.zig").trace; |
| 18 | 18 | const build_options = @import("build_options"); |
| 19 | 19 | const Air = @import("../Air.zig"); |
| 20 | const LlvmObject = @import("../codegen/llvm.zig").Object; | |
| 21 | 20 | |
| 22 | 21 | base: link.File, |
| 23 | llvm_object: LlvmObject.Ptr, | |
| 24 | 22 | |
| 25 | 23 | pub fn createEmpty( |
| 26 | 24 | arena: Allocator, |
| ... | ... | @@ -36,7 +34,6 @@ pub fn createEmpty( |
| 36 | 34 | assert(!use_lld); // Caught by Compilation.Config.resolve. |
| 37 | 35 | assert(target.os.tag == .aix); // Caught by Compilation.Config.resolve. |
| 38 | 36 | |
| 39 | const llvm_object = try LlvmObject.create(arena, comp); | |
| 40 | 37 | const xcoff = try arena.create(Xcoff); |
| 41 | 38 | xcoff.* = .{ |
| 42 | 39 | .base = .{ |
| ... | ... | @@ -52,7 +49,6 @@ pub fn createEmpty( |
| 52 | 49 | .disable_lld_caching = options.disable_lld_caching, |
| 53 | 50 | .build_id = options.build_id, |
| 54 | 51 | }, |
| 55 | .llvm_object = llvm_object, | |
| 56 | 52 | }; |
| 57 | 53 | |
| 58 | 54 | return xcoff; |
| ... | ... | @@ -70,7 +66,7 @@ pub fn open( |
| 70 | 66 | } |
| 71 | 67 | |
| 72 | 68 | pub fn deinit(self: *Xcoff) void { |
| 73 | self.llvm_object.deinit(); | |
| 69 | _ = self; | |
| 74 | 70 | } |
| 75 | 71 | |
| 76 | 72 | pub fn updateFunc( |
| ... | ... | @@ -80,17 +76,19 @@ pub fn updateFunc( |
| 80 | 76 | air: Air, |
| 81 | 77 | liveness: Air.Liveness, |
| 82 | 78 | ) link.File.UpdateNavError!void { |
| 83 | if (build_options.skip_non_native and builtin.object_format != .xcoff) | |
| 84 | @panic("Attempted to compile for object format that was disabled by build configuration"); | |
| 85 | ||
| 86 | try self.llvm_object.updateFunc(pt, func_index, air, liveness); | |
| 79 | _ = self; | |
| 80 | _ = pt; | |
| 81 | _ = func_index; | |
| 82 | _ = air; | |
| 83 | _ = liveness; | |
| 84 | unreachable; // we always use llvm | |
| 87 | 85 | } |
| 88 | 86 | |
| 89 | 87 | pub fn updateNav(self: *Xcoff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void { |
| 90 | if (build_options.skip_non_native and builtin.object_format != .xcoff) | |
| 91 | @panic("Attempted to compile for object format that was disabled by build configuration"); | |
| 92 | ||
| 93 | return self.llvm_object.updateNav(pt, nav); | |
| 88 | _ = self; | |
| 89 | _ = pt; | |
| 90 | _ = nav; | |
| 91 | unreachable; // we always use llvm | |
| 94 | 92 | } |
| 95 | 93 | |
| 96 | 94 | pub fn updateExports( |
| ... | ... | @@ -99,21 +97,21 @@ pub fn updateExports( |
| 99 | 97 | exported: Zcu.Exported, |
| 100 | 98 | export_indices: []const Zcu.Export.Index, |
| 101 | 99 | ) !void { |
| 102 | if (build_options.skip_non_native and builtin.object_format != .xcoff) | |
| 103 | @panic("Attempted to compile for object format that was disabled by build configuration"); | |
| 104 | ||
| 105 | return self.llvm_object.updateExports(pt, exported, export_indices); | |
| 100 | _ = self; | |
| 101 | _ = pt; | |
| 102 | _ = exported; | |
| 103 | _ = export_indices; | |
| 104 | unreachable; // we always use llvm | |
| 106 | 105 | } |
| 107 | 106 | |
| 108 | 107 | pub fn flush(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 109 | return self.flushModule(arena, tid, prog_node); | |
| 108 | return self.flushZcu(arena, tid, prog_node); | |
| 110 | 109 | } |
| 111 | 110 | |
| 112 | pub fn flushModule(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 113 | if (build_options.skip_non_native and builtin.object_format != .xcoff) | |
| 114 | @panic("Attempted to compile for object format that was disabled by build configuration"); | |
| 115 | ||
| 111 | pub fn flushZcu(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 112 | _ = self; | |
| 113 | _ = arena; | |
| 116 | 114 | _ = tid; |
| 117 | ||
| 118 | try self.base.emitLlvmObject(arena, self.llvm_object, prog_node); | |
| 115 | _ = prog_node; | |
| 116 | unreachable; // we always use llvm | |
| 119 | 117 | } |
src/target.zig+1-1| ... | ... | @@ -739,7 +739,7 @@ pub fn functionPointerMask(target: std.Target) ?u64 { |
| 739 | 739 | |
| 740 | 740 | pub fn supportsTailCall(target: std.Target, backend: std.builtin.CompilerBackend) bool { |
| 741 | 741 | switch (backend) { |
| 742 | .stage1, .stage2_llvm => return @import("codegen/llvm.zig").supportsTailCall(target), | |
| 742 | .stage2_llvm => return @import("codegen/llvm.zig").supportsTailCall(target), | |
| 743 | 743 | .stage2_c => return true, |
| 744 | 744 | else => return false, |
| 745 | 745 | } |