authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-29 22:33:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:57-07:00
log66f83f27a2904180bae7797a7c87c6eddc7eebff
treebd3ef82451b2f04d720d84a9ed44c32d54c78455
parent27f1ad8afde86c8f734deeb05f5c8cad910275e4

InternPool: avoid indexToKey recursion for type_enum_auto

Recursion makes this hot function more difficult to profile and optimize. This commit adds the integer tag type to the type_enum_auto encoding even though the integer tag type can be inferred based on the number of fields of the enum. This avoids a call to getAssumeExists of the integer tag type inside indexToKey.

1 files changed, 15 insertions(+), 18 deletions(-)

src/InternPool.zig+15-18
...@@ -2169,6 +2169,9 @@ pub const EnumAuto = struct {...@@ -2169,6 +2169,9 @@ pub const EnumAuto = struct {
2169 decl: Module.Decl.Index,2169 decl: Module.Decl.Index,
2170 /// This may be `none` if there are no declarations.2170 /// This may be `none` if there are no declarations.
2171 namespace: Module.Namespace.OptionalIndex,2171 namespace: Module.Namespace.OptionalIndex,
2172 /// An integer type which is used for the numerical value of the enum, which
2173 /// was inferred by Zig based on the number of tags.
2174 int_tag_type: Index,
2172 fields_len: u32,2175 fields_len: u32,
2173 /// Maps field names to declaration index.2176 /// Maps field names to declaration index.
2174 names_map: MapIndex,2177 names_map: MapIndex,
...@@ -2553,7 +2556,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -2553,7 +2556,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
2553 return .{ .enum_type = .{2556 return .{ .enum_type = .{
2554 .decl = enum_auto.data.decl,2557 .decl = enum_auto.data.decl,
2555 .namespace = enum_auto.data.namespace,2558 .namespace = enum_auto.data.namespace,
2556 .tag_ty = ip.getEnumIntTagType(enum_auto.data.fields_len),2559 .tag_ty = enum_auto.data.int_tag_type,
2557 .names = names,2560 .names = names,
2558 .values = &.{},2561 .values = &.{},
2559 .tag_mode = .auto,2562 .tag_mode = .auto,
...@@ -2928,14 +2931,6 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType {...@@ -2928,14 +2931,6 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType {
2928 };2931 };
2929}2932}
29302933
2931/// Asserts the integer tag type is already present in the InternPool.
2932fn getEnumIntTagType(ip: InternPool, fields_len: u32) Index {
2933 return ip.getAssumeExists(.{ .int_type = .{
2934 .bits = if (fields_len == 0) 0 else std.math.log2_int_ceil(u32, fields_len),
2935 .signedness = .unsigned,
2936 } });
2937}
2938
2939fn indexToKeyEnum(ip: InternPool, data: u32, tag_mode: Key.EnumType.TagMode) Key {2934fn indexToKeyEnum(ip: InternPool, data: u32, tag_mode: Key.EnumType.TagMode) Key {
2940 const enum_explicit = ip.extraDataTrail(EnumExplicit, data);2935 const enum_explicit = ip.extraDataTrail(EnumExplicit, data);
2941 const names = @ptrCast(2936 const names = @ptrCast(
...@@ -3222,6 +3217,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -3222,6 +3217,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
3222 .data = ip.addExtraAssumeCapacity(EnumAuto{3217 .data = ip.addExtraAssumeCapacity(EnumAuto{
3223 .decl = enum_type.decl,3218 .decl = enum_type.decl,
3224 .namespace = enum_type.namespace,3219 .namespace = enum_type.namespace,
3220 .int_tag_type = enum_type.tag_ty,
3225 .names_map = names_map,3221 .names_map = names_map,
3226 .fields_len = fields_len,3222 .fields_len = fields_len,
3227 }),3223 }),
...@@ -4000,18 +3996,18 @@ pub fn getIncompleteEnum(...@@ -4000,18 +3996,18 @@ pub fn getIncompleteEnum(
4000 }3996 }
4001}3997}
40023998
4003pub fn getIncompleteEnumAuto(3999fn getIncompleteEnumAuto(
4004 ip: *InternPool,4000 ip: *InternPool,
4005 gpa: Allocator,4001 gpa: Allocator,
4006 enum_type: Key.IncompleteEnumType,4002 enum_type: Key.IncompleteEnumType,
4007) Allocator.Error!IncompleteEnumType {4003) Allocator.Error!IncompleteEnumType {
4008 // Although the integer tag type will not be stored in the `EnumAuto` struct,4004 const int_tag_type = if (enum_type.tag_ty != .none)
4009 // `InternPool` logic depends on it being present so that `typeOf` can be infallible.4005 enum_type.tag_ty
4010 // Ensure it is present here:4006 else
4011 _ = try ip.get(gpa, .{ .int_type = .{4007 try ip.get(gpa, .{ .int_type = .{
4012 .bits = if (enum_type.fields_len == 0) 0 else std.math.log2_int_ceil(u32, enum_type.fields_len),4008 .bits = if (enum_type.fields_len == 0) 0 else std.math.log2_int_ceil(u32, enum_type.fields_len),
4013 .signedness = .unsigned,4009 .signedness = .unsigned,
4014 } });4010 } });
40154011
4016 // We must keep the map in sync with `items`. The hash and equality functions4012 // We must keep the map in sync with `items`. The hash and equality functions
4017 // for enum types only look at the decl field, which is present even in4013 // for enum types only look at the decl field, which is present even in
...@@ -4029,6 +4025,7 @@ pub fn getIncompleteEnumAuto(...@@ -4029,6 +4025,7 @@ pub fn getIncompleteEnumAuto(
4029 const extra_index = ip.addExtraAssumeCapacity(EnumAuto{4025 const extra_index = ip.addExtraAssumeCapacity(EnumAuto{
4030 .decl = enum_type.decl,4026 .decl = enum_type.decl,
4031 .namespace = enum_type.namespace,4027 .namespace = enum_type.namespace,
4028 .int_tag_type = int_tag_type,
4032 .names_map = names_map,4029 .names_map = names_map,
4033 .fields_len = enum_type.fields_len,4030 .fields_len = enum_type.fields_len,
4034 });4031 });
...@@ -4040,7 +4037,7 @@ pub fn getIncompleteEnumAuto(...@@ -4040,7 +4037,7 @@ pub fn getIncompleteEnumAuto(
4040 ip.extra.appendNTimesAssumeCapacity(@enumToInt(Index.none), enum_type.fields_len);4037 ip.extra.appendNTimesAssumeCapacity(@enumToInt(Index.none), enum_type.fields_len);
4041 return .{4038 return .{
4042 .index = @intToEnum(Index, ip.items.len - 1),4039 .index = @intToEnum(Index, ip.items.len - 1),
4043 .tag_ty_index = undefined,4040 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
4044 .names_map = names_map,4041 .names_map = names_map,
4045 .names_start = extra_index + extra_fields_len,4042 .names_start = extra_index + extra_fields_len,
4046 .values_map = .none,4043 .values_map = .none,