authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-23 19:10:36-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:54-07:00
log01ca841f1227cc3e17169c45318c8d4757a5c0d2
tree431768f9bac787fd2568de48fa1d178e98df51df
parent1b64eed107f54220f85a5158699225b59899a20a

Sema: improve the types_to_resolve mechanism

Store `InternPool.Index` as the key instead which means that an AIR instruction no longer needs to be burned to store the type, and also that we can use AutoArrayHashMap instead of an ArrayList, which avoids storing duplicates into the set, potentially saving CPU time.

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

src/Module.zig+2-3
...@@ -5773,9 +5773,8 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {...@@ -5773,9 +5773,8 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
57735773
5774 // Similarly, resolve any queued up types that were requested to be resolved for5774 // Similarly, resolve any queued up types that were requested to be resolved for
5775 // the backends.5775 // the backends.
5776 for (sema.types_to_resolve.items) |inst_ref| {5776 for (sema.types_to_resolve.keys()) |ty| {
5777 const ty = sema.getTmpAir().getRefType(inst_ref);5777 sema.resolveTypeFully(ty.toType()) catch |err| switch (err) {
5778 sema.resolveTypeFully(ty) catch |err| switch (err) {
5779 error.NeededSourceLocation => unreachable,5778 error.NeededSourceLocation => unreachable,
5780 error.GenericPoison => unreachable,5779 error.GenericPoison => unreachable,
5781 error.ComptimeReturn => unreachable,5780 error.ComptimeReturn => unreachable,
src/Sema.zig+9-7
...@@ -66,11 +66,14 @@ comptime_args_fn_inst: Zir.Inst.Index = 0,...@@ -66,11 +66,14 @@ comptime_args_fn_inst: Zir.Inst.Index = 0,
66/// extra hash table lookup in the `monomorphed_funcs` set.66/// extra hash table lookup in the `monomorphed_funcs` set.
67/// Sema will set this to null when it takes ownership.67/// Sema will set this to null when it takes ownership.
68preallocated_new_func: ?*Module.Fn = null,68preallocated_new_func: ?*Module.Fn = null,
69/// The key is `constant` AIR instructions to types that must be fully resolved69/// The key is types that must be fully resolved prior to machine code
70/// after the current function body analysis is done.70/// generation pass. Types are added to this set when resolving them
71/// TODO: after upgrading to use InternPool change the key here to be an71/// immediately could cause a dependency loop, but they do need to be resolved
72/// InternPool value index.72/// before machine code generation passes process the AIR.
73types_to_resolve: std.ArrayListUnmanaged(Air.Inst.Ref) = .{},73/// It would work fine if this were an array list instead of an array hash map.
74/// I chose array hash map with the intention to save time by omitting
75/// duplicates.
76types_to_resolve: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{},
74/// These are lazily created runtime blocks from block_inline instructions.77/// These are lazily created runtime blocks from block_inline instructions.
75/// They are created when an break_inline passes through a runtime condition, because78/// They are created when an break_inline passes through a runtime condition, because
76/// Sema must convert comptime control flow to runtime control flow, which means79/// Sema must convert comptime control flow to runtime control flow, which means
...@@ -34085,8 +34088,7 @@ fn anonStructFieldIndex(...@@ -34085,8 +34088,7 @@ fn anonStructFieldIndex(
34085}34088}
3408634089
34087fn queueFullTypeResolution(sema: *Sema, ty: Type) !void {34090fn queueFullTypeResolution(sema: *Sema, ty: Type) !void {
34088 const inst_ref = try sema.addType(ty);34091 try sema.types_to_resolve.put(sema.gpa, ty.toIntern(), {});
34089 try sema.types_to_resolve.append(sema.gpa, inst_ref);
34090}34092}
3409134093
34092fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {34094fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {