| author | |
| committer | |
| log | 424e6ac54b0f8bbfb43f24e28c71ac72169f3719 |
| tree | f979f0e580e4ebff81eac779da8cb4889d57f1b1 |
| parent | 4a02e080d127cc577d40f8ea5d68122ba8ac4243 |
| signature |
* The `codegen_nav`, `codegen_func`, `codegen_type` tasks are renamed to
`link_nav`, `link_func`, and `link_type`, to more accurately reflect
their purpose of sending data to the *linker*. Currently, `link_func`
remains responsible for codegen; this will change in an upcoming
commit.
* Don't go on a pointless detour through `PerThread` when linking ZCU
functions/`Nav`s; so, the `linkerUpdateNav` etc logic now lives in
`link.zig`. Currently, `linkerUpdateFunc` is an exception, because it
has broader responsibilities including codegen, but this will be
solved in an upcoming commit.5 files changed, 109 insertions(+), 129 deletions(-)
src/Compilation.zig+15-14| ... | ... | @@ -848,17 +848,18 @@ pub const RcIncludes = enum { |
| 848 | 848 | const Job = union(enum) { |
| 849 | 849 | /// Corresponds to the task in `link.Task`. |
| 850 | 850 | /// Only needed for backends that haven't yet been updated to not race against Sema. |
| 851 | codegen_nav: InternPool.Nav.Index, | |
| 851 | link_nav: InternPool.Nav.Index, | |
| 852 | 852 | /// Corresponds to the task in `link.Task`. |
| 853 | /// TODO: this is currently also responsible for performing codegen. | |
| 853 | 854 | /// Only needed for backends that haven't yet been updated to not race against Sema. |
| 854 | codegen_func: link.Task.CodegenFunc, | |
| 855 | link_func: link.Task.CodegenFunc, | |
| 855 | 856 | /// Corresponds to the task in `link.Task`. |
| 856 | 857 | /// Only needed for backends that haven't yet been updated to not race against Sema. |
| 857 | codegen_type: InternPool.Index, | |
| 858 | link_type: InternPool.Index, | |
| 858 | 859 | update_line_number: InternPool.TrackedInst.Index, |
| 859 | 860 | /// The `AnalUnit`, which is *not* a `func`, must be semantically analyzed. |
| 860 | 861 | /// This may be its first time being analyzed, or it may be outdated. |
| 861 | /// If the unit is a function, a `codegen_func` job will then be queued. | |
| 862 | /// If the unit is a test function, an `analyze_func` job will then be queued. | |
| 862 | 863 | analyze_comptime_unit: InternPool.AnalUnit, |
| 863 | 864 | /// This function must be semantically analyzed. |
| 864 | 865 | /// This may be its first time being analyzed, or it may be outdated. |
| ... | ... | @@ -879,13 +880,13 @@ const Job = union(enum) { |
| 879 | 880 | return switch (tag) { |
| 880 | 881 | // Prioritize functions so that codegen can get to work on them on a |
| 881 | 882 | // separate thread, while Sema goes back to its own work. |
| 882 | .resolve_type_fully, .analyze_func, .codegen_func => 0, | |
| 883 | .resolve_type_fully, .analyze_func, .link_func => 0, | |
| 883 | 884 | else => 1, |
| 884 | 885 | }; |
| 885 | 886 | } |
| 886 | 887 | comptime { |
| 887 | 888 | // Job dependencies |
| 888 | assert(stage(.resolve_type_fully) <= stage(.codegen_func)); | |
| 889 | assert(stage(.resolve_type_fully) <= stage(.link_func)); | |
| 889 | 890 | } |
| 890 | 891 | }; |
| 891 | 892 | |
| ... | ... | @@ -4552,7 +4553,7 @@ pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void { |
| 4552 | 4553 | |
| 4553 | 4554 | fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { |
| 4554 | 4555 | switch (job) { |
| 4555 | .codegen_nav => |nav_index| { | |
| 4556 | .link_nav => |nav_index| { | |
| 4556 | 4557 | const zcu = comp.zcu.?; |
| 4557 | 4558 | const nav = zcu.intern_pool.getNav(nav_index); |
| 4558 | 4559 | if (nav.analysis != null) { |
| ... | ... | @@ -4562,16 +4563,16 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { |
| 4562 | 4563 | } |
| 4563 | 4564 | } |
| 4564 | 4565 | assert(nav.status == .fully_resolved); |
| 4565 | comp.dispatchCodegenTask(tid, .{ .codegen_nav = nav_index }); | |
| 4566 | comp.dispatchLinkTask(tid, .{ .link_nav = nav_index }); | |
| 4566 | 4567 | }, |
| 4567 | .codegen_func => |func| { | |
| 4568 | comp.dispatchCodegenTask(tid, .{ .codegen_func = func }); | |
| 4568 | .link_func => |func| { | |
| 4569 | comp.dispatchLinkTask(tid, .{ .link_func = func }); | |
| 4569 | 4570 | }, |
| 4570 | .codegen_type => |ty| { | |
| 4571 | comp.dispatchCodegenTask(tid, .{ .codegen_type = ty }); | |
| 4571 | .link_type => |ty| { | |
| 4572 | comp.dispatchLinkTask(tid, .{ .link_type = ty }); | |
| 4572 | 4573 | }, |
| 4573 | 4574 | .update_line_number => |ti| { |
| 4574 | comp.dispatchCodegenTask(tid, .{ .update_line_number = ti }); | |
| 4575 | comp.dispatchLinkTask(tid, .{ .update_line_number = ti }); | |
| 4575 | 4576 | }, |
| 4576 | 4577 | .analyze_func => |func| { |
| 4577 | 4578 | const named_frame = tracy.namedFrame("analyze_func"); |
| ... | ... | @@ -4665,7 +4666,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { |
| 4665 | 4666 | |
| 4666 | 4667 | /// The reason for the double-queue here is that the first queue ensures any |
| 4667 | 4668 | /// resolve_type_fully tasks are complete before this dispatch function is called. |
| 4668 | fn dispatchCodegenTask(comp: *Compilation, tid: usize, link_task: link.Task) void { | |
| 4669 | fn dispatchLinkTask(comp: *Compilation, tid: usize, link_task: link.Task) void { | |
| 4669 | 4670 | if (comp.separateCodegenThreadOk()) { |
| 4670 | 4671 | comp.queueLinkTasks(&.{link_task}); |
| 4671 | 4672 | } else { |
src/Sema.zig+8-8| ... | ... | @@ -2991,7 +2991,7 @@ fn zirStructDecl( |
| 2991 | 2991 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 2992 | 2992 | if (block.ownerModule().strip) break :codegen_type; |
| 2993 | 2993 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 2994 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 2994 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 2995 | 2995 | } |
| 2996 | 2996 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 2997 | 2997 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| ... | ... | @@ -3250,7 +3250,7 @@ fn zirEnumDecl( |
| 3250 | 3250 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 3251 | 3251 | if (block.ownerModule().strip) break :codegen_type; |
| 3252 | 3252 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 3253 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3253 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 3254 | 3254 | } |
| 3255 | 3255 | return Air.internedToRef(wip_ty.index); |
| 3256 | 3256 | } |
| ... | ... | @@ -3368,7 +3368,7 @@ fn zirUnionDecl( |
| 3368 | 3368 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 3369 | 3369 | if (block.ownerModule().strip) break :codegen_type; |
| 3370 | 3370 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 3371 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3371 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 3372 | 3372 | } |
| 3373 | 3373 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 3374 | 3374 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| ... | ... | @@ -3455,7 +3455,7 @@ fn zirOpaqueDecl( |
| 3455 | 3455 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 3456 | 3456 | if (block.ownerModule().strip) break :codegen_type; |
| 3457 | 3457 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 3458 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3458 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 3459 | 3459 | } |
| 3460 | 3460 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| 3461 | 3461 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index); |
| ... | ... | @@ -20086,7 +20086,7 @@ fn structInitAnon( |
| 20086 | 20086 | codegen_type: { |
| 20087 | 20087 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 20088 | 20088 | if (block.ownerModule().strip) break :codegen_type; |
| 20089 | try zcu.comp.queueJob(.{ .codegen_type = wip.index }); | |
| 20089 | try zcu.comp.queueJob(.{ .link_type = wip.index }); | |
| 20090 | 20090 | } |
| 20091 | 20091 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index); |
| 20092 | 20092 | break :ty wip.finish(ip, new_namespace_index); |
| ... | ... | @@ -21396,7 +21396,7 @@ fn reifyEnum( |
| 21396 | 21396 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 21397 | 21397 | if (block.ownerModule().strip) break :codegen_type; |
| 21398 | 21398 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 21399 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 21399 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 21400 | 21400 | } |
| 21401 | 21401 | return Air.internedToRef(wip_ty.index); |
| 21402 | 21402 | } |
| ... | ... | @@ -21650,7 +21650,7 @@ fn reifyUnion( |
| 21650 | 21650 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 21651 | 21651 | if (block.ownerModule().strip) break :codegen_type; |
| 21652 | 21652 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 21653 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 21653 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 21654 | 21654 | } |
| 21655 | 21655 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 21656 | 21656 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| ... | ... | @@ -22004,7 +22004,7 @@ fn reifyStruct( |
| 22004 | 22004 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 22005 | 22005 | if (block.ownerModule().strip) break :codegen_type; |
| 22006 | 22006 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 22007 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 22007 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 22008 | 22008 | } |
| 22009 | 22009 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 22010 | 22010 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
src/Sema/LowerZon.zig+1-1| ... | ... | @@ -194,7 +194,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter |
| 194 | 194 | codegen_type: { |
| 195 | 195 | if (pt.zcu.comp.config.use_llvm) break :codegen_type; |
| 196 | 196 | if (self.block.ownerModule().strip) break :codegen_type; |
| 197 | try pt.zcu.comp.queueJob(.{ .codegen_type = wip.index }); | |
| 197 | try pt.zcu.comp.queueJob(.{ .link_type = wip.index }); | |
| 198 | 198 | } |
| 199 | 199 | break :ty wip.finish(ip, new_namespace_index); |
| 200 | 200 | }, |
src/Zcu/PerThread.zig+8-73| ... | ... | @@ -1320,7 +1320,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1320 | 1320 | } |
| 1321 | 1321 | |
| 1322 | 1322 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 1323 | try zcu.comp.queueJob(.{ .codegen_nav = nav_id }); | |
| 1323 | try zcu.comp.queueJob(.{ .link_nav = nav_id }); | |
| 1324 | 1324 | } |
| 1325 | 1325 | |
| 1326 | 1326 | switch (old_nav.status) { |
| ... | ... | @@ -1716,7 +1716,7 @@ fn analyzeFuncBody( |
| 1716 | 1716 | } |
| 1717 | 1717 | |
| 1718 | 1718 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 1719 | try comp.queueJob(.{ .codegen_func = .{ | |
| 1719 | try comp.queueJob(.{ .link_func = .{ | |
| 1720 | 1720 | .func = func_index, |
| 1721 | 1721 | .air = air, |
| 1722 | 1722 | } }); |
| ... | ... | @@ -1880,7 +1880,7 @@ fn createFileRootStruct( |
| 1880 | 1880 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 1881 | 1881 | if (file.mod.?.strip) break :codegen_type; |
| 1882 | 1882 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 1883 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 1883 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 1884 | 1884 | } |
| 1885 | 1885 | zcu.setFileRootType(file_index, wip_ty.index); |
| 1886 | 1886 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index); |
| ... | ... | @@ -3457,73 +3457,8 @@ pub fn populateTestFunctions( |
| 3457 | 3457 | zcu.codegen_prog_node = std.Progress.Node.none; |
| 3458 | 3458 | } |
| 3459 | 3459 | |
| 3460 | try pt.linkerUpdateNav(nav_index); | |
| 3461 | } | |
| 3462 | } | |
| 3463 | ||
| 3464 | pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{OutOfMemory}!void { | |
| 3465 | const zcu = pt.zcu; | |
| 3466 | const comp = zcu.comp; | |
| 3467 | const gpa = zcu.gpa; | |
| 3468 | const ip = &zcu.intern_pool; | |
| 3469 | ||
| 3470 | const nav = zcu.intern_pool.getNav(nav_index); | |
| 3471 | const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(ip), 0); | |
| 3472 | defer codegen_prog_node.end(); | |
| 3473 | ||
| 3474 | if (!Air.valFullyResolved(zcu.navValue(nav_index), zcu)) { | |
| 3475 | // The value of this nav failed to resolve. This is a transitive failure. | |
| 3476 | // TODO: do we need to mark this failure anywhere? I don't think so, since compilation | |
| 3477 | // will fail due to the type error anyway. | |
| 3478 | } else if (comp.bin_file) |lf| { | |
| 3479 | lf.updateNav(pt, nav_index) catch |err| switch (err) { | |
| 3480 | error.OutOfMemory => return error.OutOfMemory, | |
| 3481 | error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)), | |
| 3482 | error.Overflow, error.RelocationNotByteAligned => { | |
| 3483 | try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create( | |
| 3484 | gpa, | |
| 3485 | zcu.navSrcLoc(nav_index), | |
| 3486 | "unable to codegen: {s}", | |
| 3487 | .{@errorName(err)}, | |
| 3488 | )); | |
| 3489 | // Not a retryable failure. | |
| 3490 | }, | |
| 3491 | }; | |
| 3492 | } else if (zcu.llvm_object) |llvm_object| { | |
| 3493 | llvm_object.updateNav(pt, nav_index) catch |err| switch (err) { | |
| 3494 | error.OutOfMemory => return error.OutOfMemory, | |
| 3495 | }; | |
| 3496 | } | |
| 3497 | } | |
| 3498 | ||
| 3499 | pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{OutOfMemory}!void { | |
| 3500 | const zcu = pt.zcu; | |
| 3501 | const gpa = zcu.gpa; | |
| 3502 | const comp = zcu.comp; | |
| 3503 | const ip = &zcu.intern_pool; | |
| 3504 | ||
| 3505 | const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0); | |
| 3506 | defer codegen_prog_node.end(); | |
| 3507 | ||
| 3508 | if (zcu.failed_types.fetchSwapRemove(ty)) |*entry| entry.value.deinit(gpa); | |
| 3509 | ||
| 3510 | if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) { | |
| 3511 | // This type failed to resolve. This is a transitive failure. | |
| 3512 | return; | |
| 3513 | } | |
| 3514 | ||
| 3515 | if (comp.bin_file) |lf| lf.updateContainerType(pt, ty) catch |err| switch (err) { | |
| 3516 | error.OutOfMemory => return error.OutOfMemory, | |
| 3517 | error.TypeFailureReported => assert(zcu.failed_types.contains(ty)), | |
| 3518 | }; | |
| 3519 | } | |
| 3520 | ||
| 3521 | pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Index) !void { | |
| 3522 | if (pt.zcu.comp.bin_file) |lf| { | |
| 3523 | lf.updateLineNumber(pt, ti) catch |err| switch (err) { | |
| 3524 | error.OutOfMemory => return error.OutOfMemory, | |
| 3525 | else => |e| log.err("update line number failed: {s}", .{@errorName(e)}), | |
| 3526 | }; | |
| 3460 | // The linker thread is not running, so we actually need to dispatch this task directly. | |
| 3461 | @import("../link.zig").doTask(zcu.comp, @intFromEnum(pt.tid), .{ .link_nav = nav_index }); | |
| 3527 | 3462 | } |
| 3528 | 3463 | } |
| 3529 | 3464 | |
| ... | ... | @@ -3984,7 +3919,7 @@ pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error! |
| 3984 | 3919 | const result = try pt.zcu.intern_pool.getExtern(pt.zcu.gpa, pt.tid, key); |
| 3985 | 3920 | if (result.new_nav.unwrap()) |nav| { |
| 3986 | 3921 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 3987 | try pt.zcu.comp.queueJob(.{ .codegen_nav = nav }); | |
| 3922 | try pt.zcu.comp.queueJob(.{ .link_nav = nav }); | |
| 3988 | 3923 | if (pt.zcu.comp.debugIncremental()) try pt.zcu.incremental_debug_state.newNav(pt.zcu, nav); |
| 3989 | 3924 | } |
| 3990 | 3925 | return result.index; |
| ... | ... | @@ -4132,7 +4067,7 @@ fn recreateStructType( |
| 4132 | 4067 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 4133 | 4068 | if (file.mod.?.strip) break :codegen_type; |
| 4134 | 4069 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 4135 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 4070 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 4136 | 4071 | } |
| 4137 | 4072 | |
| 4138 | 4073 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index); |
| ... | ... | @@ -4225,7 +4160,7 @@ fn recreateUnionType( |
| 4225 | 4160 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 4226 | 4161 | if (file.mod.?.strip) break :codegen_type; |
| 4227 | 4162 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 4228 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 4163 | try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); | |
| 4229 | 4164 | } |
| 4230 | 4165 | |
| 4231 | 4166 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index); |
src/link.zig+77-33| ... | ... | @@ -704,7 +704,7 @@ pub const File = struct { |
| 704 | 704 | } |
| 705 | 705 | |
| 706 | 706 | /// May be called before or after updateExports for any given Nav. |
| 707 | pub fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void { | |
| 707 | fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void { | |
| 708 | 708 | const nav = pt.zcu.intern_pool.getNav(nav_index); |
| 709 | 709 | assert(nav.status == .fully_resolved); |
| 710 | 710 | switch (base.tag) { |
| ... | ... | @@ -721,7 +721,7 @@ pub const File = struct { |
| 721 | 721 | TypeFailureReported, |
| 722 | 722 | }; |
| 723 | 723 | |
| 724 | pub fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void { | |
| 724 | fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void { | |
| 725 | 725 | switch (base.tag) { |
| 726 | 726 | else => {}, |
| 727 | 727 | inline .elf => |tag| { |
| ... | ... | @@ -732,6 +732,7 @@ pub const File = struct { |
| 732 | 732 | } |
| 733 | 733 | |
| 734 | 734 | /// May be called before or after updateExports for any given Decl. |
| 735 | /// TODO: currently `pub` because `Zcu.PerThread` is calling this. | |
| 735 | 736 | pub fn updateFunc( |
| 736 | 737 | base: *File, |
| 737 | 738 | pt: Zcu.PerThread, |
| ... | ... | @@ -755,7 +756,7 @@ pub const File = struct { |
| 755 | 756 | |
| 756 | 757 | /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because |
| 757 | 758 | /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`. |
| 758 | pub fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) UpdateLineNumberError!void { | |
| 759 | fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) UpdateLineNumberError!void { | |
| 759 | 760 | { |
| 760 | 761 | const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?; |
| 761 | 762 | const file = pt.zcu.fileByIndex(ti.file); |
| ... | ... | @@ -1435,10 +1436,10 @@ pub const Task = union(enum) { |
| 1435 | 1436 | load_input: Input, |
| 1436 | 1437 | |
| 1437 | 1438 | /// Write the constant value for a Decl to the output file. |
| 1438 | codegen_nav: InternPool.Nav.Index, | |
| 1439 | link_nav: InternPool.Nav.Index, | |
| 1439 | 1440 | /// Write the machine code for a function to the output file. |
| 1440 | codegen_func: CodegenFunc, | |
| 1441 | codegen_type: InternPool.Index, | |
| 1441 | link_func: CodegenFunc, | |
| 1442 | link_type: InternPool.Index, | |
| 1442 | 1443 | |
| 1443 | 1444 | update_line_number: InternPool.TrackedInst.Index, |
| 1444 | 1445 | |
| ... | ... | @@ -1585,47 +1586,90 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void { |
| 1585 | 1586 | }, |
| 1586 | 1587 | }; |
| 1587 | 1588 | }, |
| 1588 | .codegen_nav => |nav_index| { | |
| 1589 | if (comp.remaining_prelink_tasks == 0) { | |
| 1590 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); | |
| 1591 | defer pt.deactivate(); | |
| 1592 | pt.linkerUpdateNav(nav_index) catch |err| switch (err) { | |
| 1593 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1594 | }; | |
| 1595 | } else { | |
| 1589 | .link_nav => |nav_index| { | |
| 1590 | if (comp.remaining_prelink_tasks != 0) { | |
| 1596 | 1591 | comp.link_task_queue_postponed.appendAssumeCapacity(task); |
| 1592 | return; | |
| 1597 | 1593 | } |
| 1598 | }, | |
| 1599 | .codegen_func => |func| { | |
| 1600 | if (comp.remaining_prelink_tasks == 0) { | |
| 1601 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); | |
| 1602 | defer pt.deactivate(); | |
| 1603 | var air = func.air; | |
| 1604 | defer air.deinit(comp.gpa); | |
| 1605 | pt.linkerUpdateFunc(func.func, &air) catch |err| switch (err) { | |
| 1594 | const zcu = comp.zcu.?; | |
| 1595 | const pt: Zcu.PerThread = .activate(zcu, @enumFromInt(tid)); | |
| 1596 | defer pt.deactivate(); | |
| 1597 | if (!Air.valFullyResolved(zcu.navValue(nav_index), zcu)) { | |
| 1598 | // Type resolution failed in a way which affects this `Nav`. This is a transitive | |
| 1599 | // failure, but it doesn't need recording, because this `Nav` semantically depends | |
| 1600 | // on the failed type, so when it is changed the `Nav` will be updated. | |
| 1601 | return; | |
| 1602 | } | |
| 1603 | if (comp.bin_file) |lf| { | |
| 1604 | lf.updateNav(pt, nav_index) catch |err| switch (err) { | |
| 1605 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1606 | error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)), | |
| 1607 | error.Overflow, error.RelocationNotByteAligned => { | |
| 1608 | zcu.failed_codegen.ensureUnusedCapacity(zcu.gpa, 1) catch return diags.setAllocFailure(); | |
| 1609 | const msg = Zcu.ErrorMsg.create( | |
| 1610 | zcu.gpa, | |
| 1611 | zcu.navSrcLoc(nav_index), | |
| 1612 | "unable to codegen: {s}", | |
| 1613 | .{@errorName(err)}, | |
| 1614 | ) catch return diags.setAllocFailure(); | |
| 1615 | zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, msg); | |
| 1616 | // Not a retryable failure. | |
| 1617 | }, | |
| 1618 | }; | |
| 1619 | } else if (zcu.llvm_object) |llvm_object| { | |
| 1620 | llvm_object.updateNav(pt, nav_index) catch |err| switch (err) { | |
| 1606 | 1621 | error.OutOfMemory => diags.setAllocFailure(), |
| 1607 | 1622 | }; |
| 1608 | } else { | |
| 1623 | } | |
| 1624 | }, | |
| 1625 | .link_func => |func| { | |
| 1626 | if (comp.remaining_prelink_tasks != 0) { | |
| 1609 | 1627 | comp.link_task_queue_postponed.appendAssumeCapacity(task); |
| 1628 | return; | |
| 1610 | 1629 | } |
| 1630 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); | |
| 1631 | defer pt.deactivate(); | |
| 1632 | var air = func.air; | |
| 1633 | defer air.deinit(comp.gpa); | |
| 1634 | pt.linkerUpdateFunc(func.func, &air) catch |err| switch (err) { | |
| 1635 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1636 | }; | |
| 1611 | 1637 | }, |
| 1612 | .codegen_type => |ty| { | |
| 1613 | if (comp.remaining_prelink_tasks == 0) { | |
| 1614 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); | |
| 1615 | defer pt.deactivate(); | |
| 1616 | pt.linkerUpdateContainerType(ty) catch |err| switch (err) { | |
| 1638 | .link_type => |ty| { | |
| 1639 | if (comp.remaining_prelink_tasks != 0) { | |
| 1640 | comp.link_task_queue_postponed.appendAssumeCapacity(task); | |
| 1641 | return; | |
| 1642 | } | |
| 1643 | const zcu = comp.zcu.?; | |
| 1644 | const pt: Zcu.PerThread = .activate(zcu, @enumFromInt(tid)); | |
| 1645 | defer pt.deactivate(); | |
| 1646 | if (zcu.failed_types.fetchSwapRemove(ty)) |*entry| entry.value.deinit(zcu.gpa); | |
| 1647 | if (!Air.typeFullyResolved(.fromInterned(ty), zcu)) { | |
| 1648 | // Type resolution failed in a way which affects this type. This is a transitive | |
| 1649 | // failure, but it doesn't need recording, because this type semantically depends | |
| 1650 | // on the failed type, so when that is changed, this type will be updated. | |
| 1651 | return; | |
| 1652 | } | |
| 1653 | if (comp.bin_file) |lf| { | |
| 1654 | lf.updateContainerType(pt, ty) catch |err| switch (err) { | |
| 1617 | 1655 | error.OutOfMemory => diags.setAllocFailure(), |
| 1656 | error.TypeFailureReported => assert(zcu.failed_types.contains(ty)), | |
| 1618 | 1657 | }; |
| 1619 | } else { | |
| 1620 | comp.link_task_queue_postponed.appendAssumeCapacity(task); | |
| 1621 | 1658 | } |
| 1622 | 1659 | }, |
| 1623 | 1660 | .update_line_number => |ti| { |
| 1661 | if (comp.remaining_prelink_tasks != 0) { | |
| 1662 | comp.link_task_queue_postponed.appendAssumeCapacity(task); | |
| 1663 | return; | |
| 1664 | } | |
| 1624 | 1665 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); |
| 1625 | 1666 | defer pt.deactivate(); |
| 1626 | pt.linkerUpdateLineNumber(ti) catch |err| switch (err) { | |
| 1627 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1628 | }; | |
| 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 | }; | |
| 1672 | } | |
| 1629 | 1673 | }, |
| 1630 | 1674 | } |
| 1631 | 1675 | } |