authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-26 04:06:39+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-26 13:48:06+00:00
log26a94e8481385619ae049143dd67e551f333fa3f
tree2106272eed6fb7b15a8309c6fc5137e6fec93234
parent152a2ceaf738301cd59165a4f17d915391321bdc
signaturelock-open Commit is signed but in an unrecognized format.

Zcu: eliminate `Decl.alive` field

Legacy anon decls now have three uses: * Type owner decls * Function owner decls * `@export` and `@extern` Therefore, there are no longer any cases where we wish to explicitly omit legacy anon decls from the binary. This means we can remove the concept of an "alive" vs "dead" `Decl`, which also allows us to remove the separate `anon_work_queue` in `Compilation`.

10 files changed, 2 insertions(+), 101 deletions(-)

src/Compilation.zig+1-18
...@@ -102,7 +102,6 @@ link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{},...@@ -102,7 +102,6 @@ link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{},
102lld_errors: std.ArrayListUnmanaged(LldError) = .{},102lld_errors: std.ArrayListUnmanaged(LldError) = .{},
103103
104work_queue: std.fifo.LinearFifo(Job, .Dynamic),104work_queue: std.fifo.LinearFifo(Job, .Dynamic),
105anon_work_queue: std.fifo.LinearFifo(Job, .Dynamic),
106105
107/// These jobs are to invoke the Clang compiler to create an object file, which106/// These jobs are to invoke the Clang compiler to create an object file, which
108/// gets linked with the Compilation.107/// gets linked with the Compilation.
...@@ -1417,7 +1416,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1417,7 +1416,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1417 .emit_llvm_ir = options.emit_llvm_ir,1416 .emit_llvm_ir = options.emit_llvm_ir,
1418 .emit_llvm_bc = options.emit_llvm_bc,1417 .emit_llvm_bc = options.emit_llvm_bc,
1419 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),1418 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
1420 .anon_work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
1421 .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),1419 .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),
1422 .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa),1420 .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa),
1423 .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),1421 .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),
...@@ -1840,7 +1838,6 @@ pub fn destroy(comp: *Compilation) void {...@@ -1840,7 +1838,6 @@ pub fn destroy(comp: *Compilation) void {
1840 if (comp.module) |zcu| zcu.deinit();1838 if (comp.module) |zcu| zcu.deinit();
1841 comp.cache_use.deinit();1839 comp.cache_use.deinit();
1842 comp.work_queue.deinit();1840 comp.work_queue.deinit();
1843 comp.anon_work_queue.deinit();
1844 comp.c_object_work_queue.deinit();1841 comp.c_object_work_queue.deinit();
1845 if (!build_options.only_core_functionality) {1842 if (!build_options.only_core_functionality) {
1846 comp.win32_resource_work_queue.deinit();1843 comp.win32_resource_work_queue.deinit();
...@@ -3354,18 +3351,11 @@ pub fn performAllTheWork(...@@ -3354,18 +3351,11 @@ pub fn performAllTheWork(
3354 mod.sema_prog_node = undefined;3351 mod.sema_prog_node = undefined;
3355 };3352 };
33563353
3357 // In this main loop we give priority to non-anonymous Decls in the work queue, so
3358 // that they can establish references to anonymous Decls, setting alive=true in the
3359 // backend, preventing anonymous Decls from being prematurely destroyed.
3360 while (true) {3354 while (true) {
3361 if (comp.work_queue.readItem()) |work_item| {3355 if (comp.work_queue.readItem()) |work_item| {
3362 try processOneJob(comp, work_item, main_progress_node);3356 try processOneJob(comp, work_item, main_progress_node);
3363 continue;3357 continue;
3364 }3358 }
3365 if (comp.anon_work_queue.readItem()) |work_item| {
3366 try processOneJob(comp, work_item, main_progress_node);
3367 continue;
3368 }
3369 if (comp.module) |zcu| {3359 if (comp.module) |zcu| {
3370 // If there's no work queued, check if there's anything outdated3360 // If there's no work queued, check if there's anything outdated
3371 // which we need to work on, and queue it if so.3361 // which we need to work on, and queue it if so.
...@@ -3413,14 +3403,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v...@@ -3413,14 +3403,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
34133403
3414 assert(decl.has_tv);3404 assert(decl.has_tv);
34153405
3416 if (decl.alive) {3406 try module.linkerUpdateDecl(decl_index);
3417 try module.linkerUpdateDecl(decl_index);
3418 return;
3419 }
3420
3421 // Instead of sending this decl to the linker, we actually will delete it
3422 // because we found out that it in fact was never referenced.
3423 module.deleteUnusedDecl(decl_index);
3424 return;3407 return;
3425 },3408 },
3426 }3409 }
src/InternPool.zig-1
...@@ -6740,7 +6740,6 @@ fn finishFuncInstance(...@@ -6740,7 +6740,6 @@ fn finishFuncInstance(
6740 .zir_decl_index = fn_owner_decl.zir_decl_index,6740 .zir_decl_index = fn_owner_decl.zir_decl_index,
6741 .is_pub = fn_owner_decl.is_pub,6741 .is_pub = fn_owner_decl.is_pub,
6742 .is_exported = fn_owner_decl.is_exported,6742 .is_exported = fn_owner_decl.is_exported,
6743 .alive = true,
6744 .kind = .anon,6743 .kind = .anon,
6745 });6744 });
6746 errdefer ip.destroyDecl(gpa, decl_index);6745 errdefer ip.destroyDecl(gpa, decl_index);
src/Module.zig+1-63
...@@ -394,15 +394,6 @@ pub const Decl = struct {...@@ -394,15 +394,6 @@ pub const Decl = struct {
394 is_pub: bool,394 is_pub: bool,
395 /// Whether the corresponding AST decl has a `export` keyword.395 /// Whether the corresponding AST decl has a `export` keyword.
396 is_exported: bool,396 is_exported: bool,
397 /// Flag used by garbage collection to mark and sweep.
398 /// Decls which correspond to an AST node always have this field set to `true`.
399 /// Anonymous Decls are initialized with this field set to `false` and then it
400 /// is the responsibility of machine code backends to mark it `true` whenever
401 /// a `decl_ref` Value is encountered that points to this Decl.
402 /// When the `codegen_decl` job is encountered in the main work queue, if the
403 /// Decl is marked alive, then it sends the Decl to the linker. Otherwise it
404 /// deletes the Decl on the spot.
405 alive: bool,
406 /// If true `name` is already fully qualified.397 /// If true `name` is already fully qualified.
407 name_fully_qualified: bool = false,398 name_fully_qualified: bool = false,
408 /// What kind of a declaration is this.399 /// What kind of a declaration is this.
...@@ -3525,7 +3516,6 @@ fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3525,7 +3516,6 @@ fn semaFile(mod: *Module, file: *File) SemaError!void {
3525 new_decl.is_exported = false;3516 new_decl.is_exported = false;
3526 new_decl.alignment = .none;3517 new_decl.alignment = .none;
3527 new_decl.@"linksection" = .none;3518 new_decl.@"linksection" = .none;
3528 new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive.
3529 new_decl.analysis = .in_progress;3519 new_decl.analysis = .in_progress;
35303520
3531 if (file.status != .success_zir) {3521 if (file.status != .success_zir) {
...@@ -4375,7 +4365,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void...@@ -4375,7 +4365,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
4375 const decl = zcu.declPtr(decl_index);4365 const decl = zcu.declPtr(decl_index);
4376 const was_exported = decl.is_exported;4366 const was_exported = decl.is_exported;
4377 assert(decl.kind == kind); // ZIR tracking should preserve this4367 assert(decl.kind == kind); // ZIR tracking should preserve this
4378 assert(decl.alive);
4379 decl.name = decl_name;4368 decl.name = decl_name;
4380 decl.src_node = decl_node;4369 decl.src_node = decl_node;
4381 decl.src_line = line;4370 decl.src_line = line;
...@@ -4392,7 +4381,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void...@@ -4392,7 +4381,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
4392 new_decl.is_pub = declaration.flags.is_pub;4381 new_decl.is_pub = declaration.flags.is_pub;
4393 new_decl.is_exported = declaration.flags.is_export;4382 new_decl.is_exported = declaration.flags.is_export;
4394 new_decl.zir_decl_index = tracked_inst.toOptional();4383 new_decl.zir_decl_index = tracked_inst.toOptional();
4395 new_decl.alive = true; // This Decl corresponds to an AST node and is therefore always alive.
4396 break :decl_index .{ false, new_decl_index };4384 break :decl_index .{ false, new_decl_index };
4397 };4385 };
43984386
...@@ -4470,12 +4458,8 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {...@@ -4470,12 +4458,8 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
44704458
4471/// Finalize the creation of an anon decl.4459/// Finalize the creation of an anon decl.
4472pub fn finalizeAnonDecl(mod: *Module, decl_index: Decl.Index) Allocator.Error!void {4460pub fn finalizeAnonDecl(mod: *Module, decl_index: Decl.Index) Allocator.Error!void {
4473 // The Decl starts off with alive=false and the codegen backend will set alive=true
4474 // if the Decl is referenced by an instruction or another constant. Otherwise,
4475 // the Decl will be garbage collected by the `codegen_decl` task instead of sent
4476 // to the linker.
4477 if (mod.declPtr(decl_index).typeOf(mod).isFnOrHasRuntimeBits(mod)) {4461 if (mod.declPtr(decl_index).typeOf(mod).isFnOrHasRuntimeBits(mod)) {
4478 try mod.comp.anon_work_queue.writeItem(.{ .codegen_decl = decl_index });4462 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
4479 }4463 }
4480}4464}
44814465
...@@ -4815,7 +4799,6 @@ pub fn allocateNewDecl(...@@ -4815,7 +4799,6 @@ pub fn allocateNewDecl(
4815 .zir_decl_index = .none,4799 .zir_decl_index = .none,
4816 .is_pub = false,4800 .is_pub = false,
4817 .is_exported = false,4801 .is_exported = false,
4818 .alive = false,
4819 .kind = .anon,4802 .kind = .anon,
4820 });4803 });
48214804
...@@ -5582,51 +5565,6 @@ fn reportRetryableFileError(...@@ -5582,51 +5565,6 @@ fn reportRetryableFileError(
5582 gop.value_ptr.* = err_msg;5565 gop.value_ptr.* = err_msg;
5583}5566}
55845567
5585pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void {
5586 switch (mod.intern_pool.indexToKey(val.toIntern())) {
5587 .variable => |variable| try mod.markDeclIndexAlive(variable.decl),
5588 .extern_func => |extern_func| try mod.markDeclIndexAlive(extern_func.decl),
5589 .func => |func| try mod.markDeclIndexAlive(func.owner_decl),
5590 .error_union => |error_union| switch (error_union.val) {
5591 .err_name => {},
5592 .payload => |payload| try mod.markReferencedDeclsAlive(Value.fromInterned(payload)),
5593 },
5594 .slice => |slice| {
5595 try mod.markReferencedDeclsAlive(Value.fromInterned(slice.ptr));
5596 try mod.markReferencedDeclsAlive(Value.fromInterned(slice.len));
5597 },
5598 .ptr => |ptr| switch (ptr.addr) {
5599 .decl => |decl| try mod.markDeclIndexAlive(decl),
5600 .anon_decl => {},
5601 .int, .comptime_field, .comptime_alloc => {},
5602 .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(Value.fromInterned(parent)),
5603 .elem, .field => |base_index| try mod.markReferencedDeclsAlive(Value.fromInterned(base_index.base)),
5604 },
5605 .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(opt.val)),
5606 .aggregate => |aggregate| for (aggregate.storage.values()) |elem|
5607 try mod.markReferencedDeclsAlive(Value.fromInterned(elem)),
5608 .un => |un| {
5609 if (un.tag != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(un.tag));
5610 try mod.markReferencedDeclsAlive(Value.fromInterned(un.val));
5611 },
5612 else => {},
5613 }
5614}
5615
5616pub fn markDeclAlive(mod: *Module, decl: *Decl) Allocator.Error!void {
5617 if (decl.alive) return;
5618 decl.alive = true;
5619
5620 // This is the first time we are marking this Decl alive. We must
5621 // therefore recurse into its value and mark any Decl it references
5622 // as also alive, so that any Decl referenced does not get garbage collected.
5623 try mod.markReferencedDeclsAlive(decl.val);
5624}
5625
5626fn markDeclIndexAlive(mod: *Module, decl_index: Decl.Index) Allocator.Error!void {
5627 return mod.markDeclAlive(mod.declPtr(decl_index));
5628}
5629
5630pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void {5568pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void {
5631 const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);5569 const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);
5632 if (gop.found_existing) {5570 if (gop.found_existing) {
src/Sema.zig-2
...@@ -6445,8 +6445,6 @@ pub fn analyzeExport(...@@ -6445,8 +6445,6 @@ pub fn analyzeExport(
6445 return sema.fail(block, src, "export target cannot be extern", .{});6445 return sema.fail(block, src, "export target cannot be extern", .{});
6446 }6446 }
64476447
6448 // This decl is alive no matter what, since it's being exported
6449 try mod.markDeclAlive(exported_decl);
6450 try sema.maybeQueueFuncBodyAnalysis(exported_decl_index);6448 try sema.maybeQueueFuncBodyAnalysis(exported_decl_index);
64516449
6452 try addExport(mod, .{6450 try addExport(mod, .{
src/arch/wasm/CodeGen.zig-2
...@@ -3121,7 +3121,6 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue...@@ -3121,7 +3121,6 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
3121fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {3121fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
3122 const mod = func.bin_file.base.comp.module.?;3122 const mod = func.bin_file.base.comp.module.?;
3123 const decl = mod.declPtr(decl_index);3123 const decl = mod.declPtr(decl_index);
3124 try mod.markDeclAlive(decl);
3125 const ptr_ty = try mod.singleMutPtrType(decl.typeOf(mod));3124 const ptr_ty = try mod.singleMutPtrType(decl.typeOf(mod));
3126 return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset);3125 return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset);
3127}3126}
...@@ -3178,7 +3177,6 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.Decl...@@ -3178,7 +3177,6 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.Decl
3178 return WValue{ .imm32 = 0xaaaaaaaa };3177 return WValue{ .imm32 = 0xaaaaaaaa };
3179 }3178 }
31803179
3181 try mod.markDeclAlive(decl);
3182 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);3180 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);
3183 const atom = func.bin_file.getAtom(atom_index);3181 const atom = func.bin_file.getAtom(atom_index);
31843182
src/arch/x86_64/CodeGen.zig-2
...@@ -12263,7 +12263,6 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12263,7 +12263,6 @@ fn genCall(self: *Self, info: union(enum) {
12263 },12263 },
12264 }) {12264 }) {
12265 .func => |func| {12265 .func => |func| {
12266 try mod.markDeclAlive(mod.declPtr(func.owner_decl));
12267 if (self.bin_file.cast(link.File.Elf)) |elf_file| {12266 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
12268 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);12267 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
12269 const sym = elf_file.symbol(sym_index);12268 const sym = elf_file.symbol(sym_index);
...@@ -12323,7 +12322,6 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12323,7 +12322,6 @@ fn genCall(self: *Self, info: union(enum) {
12323 },12322 },
12324 .extern_func => |extern_func| {12323 .extern_func => |extern_func| {
12325 const owner_decl = mod.declPtr(extern_func.decl);12324 const owner_decl = mod.declPtr(extern_func.decl);
12326 try mod.markDeclAlive(owner_decl);
12327 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);12325 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
12328 const decl_name = mod.intern_pool.stringToSlice(owner_decl.name);12326 const decl_name = mod.intern_pool.stringToSlice(owner_decl.name);
12329 try self.genExternSymbolRef(.call, lib_name, decl_name);12327 try self.genExternSymbolRef(.call, lib_name, decl_name);
src/codegen.zig-4
...@@ -835,8 +835,6 @@ fn lowerDeclRef(...@@ -835,8 +835,6 @@ fn lowerDeclRef(
835 return Result.ok;835 return Result.ok;
836 }836 }
837837
838 try zcu.markDeclAlive(decl);
839
840 const vaddr = try lf.getDeclVAddr(decl_index, .{838 const vaddr = try lf.getDeclVAddr(decl_index, .{
841 .parent_atom_index = reloc_info.parent_atom_index,839 .parent_atom_index = reloc_info.parent_atom_index,
842 .offset = code.items.len,840 .offset = code.items.len,
...@@ -958,8 +956,6 @@ fn genDeclRef(...@@ -958,8 +956,6 @@ fn genDeclRef(
958 }956 }
959 }957 }
960958
961 try zcu.markDeclAlive(decl);
962
963 const decl_namespace = zcu.namespacePtr(decl.src_namespace);959 const decl_namespace = zcu.namespacePtr(decl.src_namespace);
964 const single_threaded = decl_namespace.file_scope.mod.single_threaded;960 const single_threaded = decl_namespace.file_scope.mod.single_threaded;
965 const is_threadlocal = tv.val.isPtrToThreadLocal(zcu) and !single_threaded;961 const is_threadlocal = tv.val.isPtrToThreadLocal(zcu) and !single_threaded;
src/codegen/c.zig-1
...@@ -2010,7 +2010,6 @@ pub const DeclGen = struct {...@@ -2010,7 +2010,6 @@ pub const DeclGen = struct {
2010 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex, export_index: u32) !void {2010 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex, export_index: u32) !void {
2011 const mod = dg.module;2011 const mod = dg.module;
2012 const decl = mod.declPtr(decl_index);2012 const decl = mod.declPtr(decl_index);
2013 try mod.markDeclAlive(decl);
20142013
2015 if (mod.decl_exports.get(decl_index)) |exports| {2014 if (mod.decl_exports.get(decl_index)) |exports| {
2016 try writer.print("{ }", .{2015 try writer.print("{ }", .{
src/codegen/llvm.zig-7
...@@ -3722,15 +3722,11 @@ pub const Object = struct {...@@ -3722,15 +3722,11 @@ pub const Object = struct {
3722 => unreachable, // non-runtime values3722 => unreachable, // non-runtime values
3723 .extern_func => |extern_func| {3723 .extern_func => |extern_func| {
3724 const fn_decl_index = extern_func.decl;3724 const fn_decl_index = extern_func.decl;
3725 const fn_decl = mod.declPtr(fn_decl_index);
3726 try mod.markDeclAlive(fn_decl);
3727 const function_index = try o.resolveLlvmFunction(fn_decl_index);3725 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3728 return function_index.ptrConst(&o.builder).global.toConst();3726 return function_index.ptrConst(&o.builder).global.toConst();
3729 },3727 },
3730 .func => |func| {3728 .func => |func| {
3731 const fn_decl_index = func.owner_decl;3729 const fn_decl_index = func.owner_decl;
3732 const fn_decl = mod.declPtr(fn_decl_index);
3733 try mod.markDeclAlive(fn_decl);
3734 const function_index = try o.resolveLlvmFunction(fn_decl_index);3730 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3735 return function_index.ptrConst(&o.builder).global.toConst();3731 return function_index.ptrConst(&o.builder).global.toConst();
3736 },3732 },
...@@ -4262,7 +4258,6 @@ pub const Object = struct {...@@ -4262,7 +4258,6 @@ pub const Object = struct {
4262 fn lowerParentPtrDecl(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {4258 fn lowerParentPtrDecl(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {
4263 const mod = o.module;4259 const mod = o.module;
4264 const decl = mod.declPtr(decl_index);4260 const decl = mod.declPtr(decl_index);
4265 try mod.markDeclAlive(decl);
4266 const ptr_ty = try mod.singleMutPtrType(decl.typeOf(mod));4261 const ptr_ty = try mod.singleMutPtrType(decl.typeOf(mod));
4267 return o.lowerDeclRefValue(ptr_ty, decl_index);4262 return o.lowerDeclRefValue(ptr_ty, decl_index);
4268 }4263 }
...@@ -4455,8 +4450,6 @@ pub const Object = struct {...@@ -4455,8 +4450,6 @@ pub const Object = struct {
4455 if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or4450 if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or
4456 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ty);4451 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ty);
44574452
4458 try mod.markDeclAlive(decl);
4459
4460 const llvm_global = if (is_fn_body)4453 const llvm_global = if (is_fn_body)
4461 (try o.resolveLlvmFunction(decl_index)).ptrConst(&o.builder).global4454 (try o.resolveLlvmFunction(decl_index)).ptrConst(&o.builder).global
4462 else4455 else
src/codegen/spirv.zig-1
...@@ -255,7 +255,6 @@ pub const Object = struct {...@@ -255,7 +255,6 @@ pub const Object = struct {
255 pub fn resolveDecl(self: *Object, mod: *Module, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index {255 pub fn resolveDecl(self: *Object, mod: *Module, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index {
256 const decl = mod.declPtr(decl_index);256 const decl = mod.declPtr(decl_index);
257 assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false?257 assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false?
258 try mod.markDeclAlive(decl);
259258
260 const entry = try self.decl_link.getOrPut(self.gpa, decl_index);259 const entry = try self.decl_link.getOrPut(self.gpa, decl_index);
261 if (!entry.found_existing) {260 if (!entry.found_existing) {