Commit c9b957c937

Luuk de Gram <luuk@degram.dev>
2023-02-03 16:46:55
link: remove `FnData` and make it self-owned
This finishes the work started in #14502 where atoms are owned by the linker themselves. This now makes debug atoms fully owned by dwarf, and no information is left stored on the decl.
1 parent 60935de
Changed files (3)
src/arch/wasm/CodeGen.zig
@@ -1194,7 +1194,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
     const fn_info = func.decl.ty.fnInfo();
     var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type, func.target);
     defer func_type.deinit(func.gpa);
-    func.decl.fn_link.?.type_index = try func.bin_file.putOrGetFuncType(func_type);
+    _ = try func.bin_file.storeDeclType(func.decl_index, func_type);
 
     var cc_result = try func.resolveCallingConventionValues(func.decl.ty);
     defer cc_result.deinit(func.gpa);
@@ -2131,12 +2131,12 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
             defer func_type.deinit(func.gpa);
             const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_fn.data.owner_decl);
             const atom = func.bin_file.getAtomPtr(atom_index);
-            ext_decl.fn_link.?.type_index = try func.bin_file.putOrGetFuncType(func_type);
+            const type_index = try func.bin_file.storeDeclType(extern_fn.data.owner_decl, func_type);
             try func.bin_file.addOrUpdateImport(
                 mem.sliceTo(ext_decl.name, 0),
                 atom.getSymbolIndex().?,
                 ext_decl.getExternFn().?.lib_name,
-                ext_decl.fn_link.?.type_index,
+                type_index,
             );
             break :blk extern_fn.data.owner_decl;
         } else if (func_val.castTag(.decl_ref)) |decl_ref| {
src/link/Wasm.zig
@@ -46,6 +46,9 @@ host_name: []const u8 = "env",
 /// List of all `Decl` that are currently alive.
 /// Each index maps to the corresponding `Atom.Index`.
 decls: std.AutoHashMapUnmanaged(Module.Decl.Index, Atom.Index) = .{},
+/// Mapping between an `Atom` and its type index representing the Wasm
+/// type of the function signature.
+atom_types: std.AutoHashMapUnmanaged(Atom.Index, u32) = .{},
 /// List of all symbols generated by Zig code.
 symbols: std.ArrayListUnmanaged(Symbol) = .{},
 /// List of symbol indexes which are free to be used.
@@ -175,15 +178,6 @@ pub const Segment = struct {
     offset: u32,
 };
 
-pub const FnData = struct {
-    /// Reference to the wasm type that represents this function.
-    type_index: u32,
-
-    pub const empty: FnData = .{
-        .type_index = undefined,
-    };
-};
-
 pub const Export = struct {
     sym_index: ?u32 = null,
 };
@@ -961,6 +955,7 @@ pub fn deinit(wasm: *Wasm) void {
     }
 
     wasm.decls.deinit(gpa);
+    wasm.atom_types.deinit(gpa);
     wasm.symbols.deinit(gpa);
     wasm.symbols_free_list.deinit(gpa);
     wasm.globals.deinit(gpa);
@@ -1607,7 +1602,7 @@ const Kind = union(enum) {
         initialized,
         synthetic,
     },
-    function: FnData,
+    function: void,
 
     /// Returns the segment name the data kind represents.
     /// Asserts `kind` has its active tag set to `data`.
@@ -1626,12 +1621,13 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
     const atom = wasm.getAtomPtr(atom_index);
     const symbol = (SymbolLoc{ .file = null, .index = atom.sym_index }).getSymbol(wasm);
     const final_index: u32 = switch (kind) {
-        .function => |fn_data| result: {
+        .function => result: {
             const index = @intCast(u32, wasm.functions.count() + wasm.imported_functions_count);
+            const type_index = wasm.atom_types.get(atom_index).?;
             try wasm.functions.putNoClobber(
                 wasm.base.allocator,
                 .{ .file = null, .index = index },
-                .{ .type_index = fn_data.type_index },
+                .{ .type_index = type_index },
             );
             symbol.tag = .function;
             symbol.index = index;
@@ -2829,7 +2825,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
             if (decl.isExtern()) continue;
             const atom_index = entry.value_ptr.*;
             if (decl.ty.zigTypeTag() == .Fn) {
-                try wasm.parseAtom(atom_index, .{ .function = decl.fn_link.? });
+                try wasm.parseAtom(atom_index, .function);
             } else if (decl.getVariable()) |variable| {
                 if (!variable.is_mutable) {
                     try wasm.parseAtom(atom_index, .{ .data = .read_only });
@@ -4172,3 +4168,13 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
     });
     return index;
 }
+
+/// For the given `decl_index`, stores the corresponding type representing the function signature.
+/// Asserts declaration has an associated `Atom`.
+/// Returns the index into the list of types.
+pub fn storeDeclType(wasm: *Wasm, decl_index: Module.Decl.Index, func_type: std.wasm.Type) !u32 {
+    const atom_index = wasm.decls.get(decl_index).?;
+    const index = try wasm.putOrGetFuncType(func_type);
+    try wasm.atom_types.put(wasm.base.allocator, atom_index, index);
+    return index;
+}
src/Module.zig
@@ -531,9 +531,6 @@ pub const Decl = struct {
     /// What kind of a declaration is this.
     kind: Kind,
 
-    /// TODO remove this once Wasm backend catches up
-    fn_link: ?link.File.Wasm.FnData = null,
-
     /// The shallow set of other decls whose typed_value could possibly change if this Decl's
     /// typed_value is modified.
     dependants: DepsTable = .{},
@@ -5247,11 +5244,6 @@ pub fn clearDecl(
     if (decl.has_tv) {
         if (decl.ty.isFnOrHasRuntimeBits()) {
             mod.comp.bin_file.freeDecl(decl_index);
-
-            decl.fn_link = switch (mod.comp.bin_file.tag) {
-                .wasm => link.File.Wasm.FnData.empty,
-                else => null,
-            };
         }
         if (decl.getInnerNamespace()) |namespace| {
             try namespace.deleteAllDecls(mod, outdated_decls);
@@ -5652,10 +5644,6 @@ pub fn allocateNewDecl(
         .deletion_flag = false,
         .zir_decl_index = 0,
         .src_scope = src_scope,
-        .fn_link = switch (mod.comp.bin_file.tag) {
-            .wasm => link.File.Wasm.FnData.empty,
-            else => null,
-        },
         .generation = 0,
         .is_pub = false,
         .is_exported = false,