From 28dd9d478d24190ab5c8c4b892d7dfc16c380ae0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 12 Jul 2021 12:40:32 -0700 Subject: C backend: TypedefMap is now ArrayHashMap The C backend depends on insertion order into this map so that type definitions will be declared before they are used. --- src/codegen/c.zig | 6 +++--- src/codegen/spirv.zig | 2 +- src/link.zig | 2 +- src/link/C.zig | 13 +++++-------- src/type.zig | 13 ++++++++++++- 5 files changed, 22 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 31c7fa76d3..391375c709 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -39,11 +39,11 @@ const BlockData = struct { }; pub const CValueMap = std.AutoHashMap(*Inst, CValue); -pub const TypedefMap = std.HashMap( +pub const TypedefMap = std.ArrayHashMap( Type, struct { name: []const u8, rendered: []u8 }, - Type.HashContext, - std.hash_map.default_max_load_percentage, + Type.HashContext32, + true, ); fn formatTypeAsCIdentifier( diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 9e0cd19f6f..7fa813e565 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -18,7 +18,7 @@ const Inst = ir.Inst; pub const Word = u32; pub const ResultId = u32; -pub const TypeMap = std.HashMap(Type, u32, Type.HashContext, std.hash_map.default_max_load_percentage); +pub const TypeMap = std.HashMap(Type, u32, Type.HashContext64, std.hash_map.default_max_load_percentage); pub const InstMap = std.AutoHashMap(*Inst, ResultId); const IncomingBlock = struct { diff --git a/src/link.zig b/src/link.zig index 61a46e8b06..02d9afaf07 100644 --- a/src/link.zig +++ b/src/link.zig @@ -168,7 +168,7 @@ pub const File = struct { }; /// For DWARF .debug_info. - pub const DbgInfoTypeRelocsTable = std.HashMapUnmanaged(Type, DbgInfoTypeReloc, Type.HashContext, std.hash_map.default_max_load_percentage); + pub const DbgInfoTypeRelocsTable = std.HashMapUnmanaged(Type, DbgInfoTypeReloc, Type.HashContext64, std.hash_map.default_max_load_percentage); /// For DWARF .debug_info. pub const DbgInfoTypeReloc = struct { diff --git a/src/link/C.zig b/src/link/C.zig index 875fd2e964..53561d16cd 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -89,8 +89,7 @@ pub fn freeDecl(self: *C, decl: *Module.Decl) void { fn deinitDecl(gpa: *Allocator, decl: *Module.Decl) void { decl.link.c.code.deinit(gpa); decl.fn_link.c.fwd_decl.deinit(gpa); - var it = decl.fn_link.c.typedefs.valueIterator(); - while (it.next()) |value| { + for (decl.fn_link.c.typedefs.values()) |value| { gpa.free(value.rendered); } decl.fn_link.c.typedefs.deinit(gpa); @@ -108,8 +107,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { const code = &decl.link.c.code; fwd_decl.shrinkRetainingCapacity(0); { - var it = typedefs.valueIterator(); - while (it.next()) |value| { + for (typedefs.values()) |value| { module.gpa.free(value.rendered); } } @@ -135,8 +133,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { object.blocks.deinit(module.gpa); object.code.deinit(); object.dg.fwd_decl.deinit(); - var it = object.dg.typedefs.valueIterator(); - while (it.next()) |value| { + for (object.dg.typedefs.values()) |value| { module.gpa.free(value.rendered); } object.dg.typedefs.deinit(); @@ -207,7 +204,7 @@ pub fn flushModule(self: *C, comp: *Compilation) !void { } var fn_count: usize = 0; - var typedefs = std.HashMap(Type, void, Type.HashContext, std.hash_map.default_max_load_percentage).init(comp.gpa); + var typedefs = std.HashMap(Type, void, Type.HashContext64, std.hash_map.default_max_load_percentage).init(comp.gpa); defer typedefs.deinit(); // Typedefs, forward decls and non-functions first. @@ -217,7 +214,7 @@ pub fn flushModule(self: *C, comp: *Compilation) !void { if (!decl.has_tv) continue; const buf = buf: { if (decl.val.castTag(.function)) |_| { - try typedefs.ensureUnusedCapacity(decl.fn_link.c.typedefs.count()); + try typedefs.ensureUnusedCapacity(@intCast(u32, decl.fn_link.c.typedefs.count())); var it = decl.fn_link.c.typedefs.iterator(); while (it.next()) |new| { const gop = typedefs.getOrPutAssumeCapacity(new.key_ptr.*); diff --git a/src/type.zig b/src/type.zig index 8ded2ee906..52a82c0b93 100644 --- a/src/type.zig +++ b/src/type.zig @@ -602,7 +602,7 @@ pub const Type = extern union { return hasher.final(); } - pub const HashContext = struct { + pub const HashContext64 = struct { pub fn hash(self: @This(), t: Type) u64 { _ = self; return t.hash(); @@ -613,6 +613,17 @@ pub const Type = extern union { } }; + pub const HashContext32 = struct { + pub fn hash(self: @This(), t: Type) u32 { + _ = self; + return @truncate(u32, t.hash()); + } + pub fn eql(self: @This(), a: Type, b: Type) bool { + _ = self; + return a.eql(b); + } + }; + pub fn copy(self: Type, allocator: *Allocator) error{OutOfMemory}!Type { if (self.tag_if_small_enough < Tag.no_payload_count) { return Type{ .tag_if_small_enough = self.tag_if_small_enough }; -- cgit v1.2.3