authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-29 11:32:12-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:56-07:00
log5580a69d714af92883e2031a131c30917162dc15
tree0670bfea111f650038a883b29588be61a1f31101
parenta702af062bb65673ba554dba330b4c5ca8d50f3e

cbe: fix InternPool regressions


2 files changed, 164 insertions(+), 275 deletions(-)

src/Module.zig+5-2
...@@ -707,8 +707,11 @@ pub const Decl = struct {...@@ -707,8 +707,11 @@ pub const Decl = struct {
707 return TypedValue{ .ty = decl.ty, .val = decl.val };707 return TypedValue{ .ty = decl.ty, .val = decl.val };
708 }708 }
709709
710 pub fn internValue(decl: Decl, mod: *Module) Allocator.Error!InternPool.Index {710 pub fn internValue(decl: *Decl, mod: *Module) Allocator.Error!InternPool.Index {
711 return decl.val.intern(decl.ty, mod);711 assert(decl.has_tv);
712 const ip_index = try decl.val.intern(decl.ty, mod);
713 decl.val = ip_index.toValue();
714 return ip_index;
712 }715 }
713716
714 pub fn isFunction(decl: Decl, mod: *const Module) !bool {717 pub fn isFunction(decl: Decl, mod: *const Module) !bool {
src/codegen/c.zig+159-273
...@@ -560,7 +560,7 @@ pub const DeclGen = struct {...@@ -560,7 +560,7 @@ pub const DeclGen = struct {
560 // them). The analysis until now should ensure that the C function560 // them). The analysis until now should ensure that the C function
561 // pointers are compatible. If they are not, then there is a bug561 // pointers are compatible. If they are not, then there is a bug
562 // somewhere and we should let the C compiler tell us about it.562 // somewhere and we should let the C compiler tell us about it.
563 const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.eql(decl.ty, mod);563 const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.childType(mod).eql(decl.ty, mod);
564 if (need_typecast) {564 if (need_typecast) {
565 try writer.writeAll("((");565 try writer.writeAll("((");
566 try dg.renderType(writer, ty);566 try dg.renderType(writer, ty);
...@@ -581,6 +581,7 @@ pub const DeclGen = struct {...@@ -581,6 +581,7 @@ pub const DeclGen = struct {
581 ) error{ OutOfMemory, AnalysisFail }!void {581 ) error{ OutOfMemory, AnalysisFail }!void {
582 const mod = dg.module;582 const mod = dg.module;
583 const ptr_ty = mod.intern_pool.typeOf(ptr_val).toType();583 const ptr_ty = mod.intern_pool.typeOf(ptr_val).toType();
584 const ptr_cty = try dg.typeToIndex(ptr_ty, .complete);
584 const ptr = mod.intern_pool.indexToKey(ptr_val).ptr;585 const ptr = mod.intern_pool.indexToKey(ptr_val).ptr;
585 switch (ptr.addr) {586 switch (ptr.addr) {
586 .decl, .mut_decl => try dg.renderDeclValue(587 .decl, .mut_decl => try dg.renderDeclValue(
...@@ -598,22 +599,66 @@ pub const DeclGen = struct {...@@ -598,22 +599,66 @@ pub const DeclGen = struct {
598 try dg.fmtIntLiteral(Type.usize, int.toValue(), .Other),599 try dg.fmtIntLiteral(Type.usize, int.toValue(), .Other),
599 }),600 }),
600 .eu_payload, .opt_payload => |base| {601 .eu_payload, .opt_payload => |base| {
601 const base_ty = mod.intern_pool.typeOf(base).toType().childType(mod);602 const ptr_base_ty = mod.intern_pool.typeOf(base).toType();
603 const base_ty = ptr_base_ty.childType(mod);
602 // Ensure complete type definition is visible before accessing fields.604 // Ensure complete type definition is visible before accessing fields.
603 _ = try dg.typeToIndex(base_ty, .complete);605 _ = try dg.typeToIndex(base_ty, .complete);
606 const payload_ty = switch (ptr.addr) {
607 .eu_payload => base_ty.errorUnionPayload(mod),
608 .opt_payload => base_ty.optionalChild(mod),
609 else => unreachable,
610 };
611 const ptr_payload_ty = try mod.adjustPtrTypeChild(ptr_base_ty, payload_ty);
612 const ptr_payload_cty = try dg.typeToIndex(ptr_payload_ty, .complete);
613 if (ptr_cty != ptr_payload_cty) {
614 try writer.writeByte('(');
615 try dg.renderCType(writer, ptr_cty);
616 try writer.writeByte(')');
617 }
604 try writer.writeAll("&(");618 try writer.writeAll("&(");
605 try dg.renderParentPtr(writer, base, location);619 try dg.renderParentPtr(writer, base, location);
606 try writer.writeAll(")->payload");620 try writer.writeAll(")->payload");
607 },621 },
608 .elem => |elem| {622 .elem => |elem| {
623 const ptr_base_ty = mod.intern_pool.typeOf(elem.base).toType();
624 const elem_ty = ptr_base_ty.elemType2(mod);
625 const ptr_elem_ty = try mod.adjustPtrTypeChild(ptr_base_ty, elem_ty);
626 const ptr_elem_cty = try dg.typeToIndex(ptr_elem_ty, .complete);
627 if (ptr_cty != ptr_elem_cty) {
628 try writer.writeByte('(');
629 try dg.renderCType(writer, ptr_cty);
630 try writer.writeByte(')');
631 }
609 try writer.writeAll("&(");632 try writer.writeAll("&(");
633 if (mod.intern_pool.indexToKey(ptr_base_ty.toIntern()).ptr_type.size == .One)
634 try writer.writeByte('*');
610 try dg.renderParentPtr(writer, elem.base, location);635 try dg.renderParentPtr(writer, elem.base, location);
611 try writer.print(")[{d}]", .{elem.index});636 try writer.print(")[{d}]", .{elem.index});
612 },637 },
613 .field => |field| {638 .field => |field| {
614 const base_ty = mod.intern_pool.typeOf(field.base).toType().childType(mod);639 const ptr_base_ty = mod.intern_pool.typeOf(field.base).toType();
640 const base_ty = ptr_base_ty.childType(mod);
615 // Ensure complete type definition is visible before accessing fields.641 // Ensure complete type definition is visible before accessing fields.
616 _ = try dg.typeToIndex(base_ty, .complete);642 _ = try dg.typeToIndex(base_ty, .complete);
643 const field_ty = switch (mod.intern_pool.indexToKey(base_ty.toIntern())) {
644 .anon_struct_type, .struct_type, .union_type => base_ty.structFieldType(field.index, mod),
645 .ptr_type => |ptr_type| switch (ptr_type.size) {
646 .One, .Many, .C => unreachable,
647 .Slice => switch (field.index) {
648 Value.slice_ptr_index => base_ty.slicePtrFieldType(mod),
649 Value.slice_len_index => Type.usize,
650 else => unreachable,
651 },
652 },
653 else => unreachable,
654 };
655 const ptr_field_ty = try mod.adjustPtrTypeChild(ptr_base_ty, field_ty);
656 const ptr_field_cty = try dg.typeToIndex(ptr_field_ty, .complete);
657 if (ptr_cty != ptr_field_cty) {
658 try writer.writeByte('(');
659 try dg.renderCType(writer, ptr_cty);
660 try writer.writeByte(')');
661 }
617 switch (fieldLocation(base_ty, ptr_ty, @intCast(u32, field.index), mod)) {662 switch (fieldLocation(base_ty, ptr_ty, @intCast(u32, field.index), mod)) {
618 .begin => try dg.renderParentPtr(writer, field.base, location),663 .begin => try dg.renderParentPtr(writer, field.base, location),
619 .field => |name| {664 .field => |name| {
...@@ -861,234 +906,6 @@ pub const DeclGen = struct {...@@ -861,234 +906,6 @@ pub const DeclGen = struct {
861 unreachable;906 unreachable;
862 }907 }
863908
864 if (val.ip_index == .none) switch (ty.zigTypeTag(mod)) {
865 .Array, .Vector => {
866 if (location == .FunctionArgument) {
867 try writer.writeByte('(');
868 try dg.renderType(writer, ty);
869 try writer.writeByte(')');
870 }
871
872 // First try specific tag representations for more efficiency.
873 switch (val.toIntern()) {
874 .undef => {
875 const ai = ty.arrayInfo(mod);
876 try writer.writeByte('{');
877 if (ai.sentinel) |s| {
878 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
879 } else {
880 try writer.writeByte('0');
881 }
882 try writer.writeByte('}');
883 return;
884 },
885 .empty_struct => {
886 const ai = ty.arrayInfo(mod);
887 try writer.writeByte('{');
888 if (ai.sentinel) |s| {
889 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
890 } else {
891 try writer.writeByte('0');
892 }
893 try writer.writeByte('}');
894 return;
895 },
896 else => {},
897 }
898 // Fall back to generic implementation.
899
900 // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal
901 const max_string_initializer_len = 65535;
902
903 const ai = ty.arrayInfo(mod);
904 if (ai.elem_type.eql(Type.u8, mod)) {
905 if (ai.len <= max_string_initializer_len) {
906 var literal = stringLiteral(writer);
907 try literal.start();
908 var index: usize = 0;
909 while (index < ai.len) : (index += 1) {
910 const elem_val = try val.elemValue(mod, index);
911 const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
912 try literal.writeChar(elem_val_u8);
913 }
914 if (ai.sentinel) |s| {
915 const s_u8 = @intCast(u8, s.toUnsignedInt(mod));
916 if (s_u8 != 0) try literal.writeChar(s_u8);
917 }
918 try literal.end();
919 } else {
920 try writer.writeByte('{');
921 var index: usize = 0;
922 while (index < ai.len) : (index += 1) {
923 if (index != 0) try writer.writeByte(',');
924 const elem_val = try val.elemValue(mod, index);
925 const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
926 try writer.print("'\\x{x}'", .{elem_val_u8});
927 }
928 if (ai.sentinel) |s| {
929 if (index != 0) try writer.writeByte(',');
930 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
931 }
932 try writer.writeByte('}');
933 }
934 } else {
935 try writer.writeByte('{');
936 var index: usize = 0;
937 while (index < ai.len) : (index += 1) {
938 if (index != 0) try writer.writeByte(',');
939 const elem_val = try val.elemValue(mod, index);
940 try dg.renderValue(writer, ai.elem_type, elem_val, initializer_type);
941 }
942 if (ai.sentinel) |s| {
943 if (index != 0) try writer.writeByte(',');
944 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
945 }
946 try writer.writeByte('}');
947 }
948 },
949 .Struct => switch (ty.containerLayout(mod)) {
950 .Auto, .Extern => {
951 const field_vals = val.castTag(.aggregate).?.data;
952
953 if (!location.isInitializer()) {
954 try writer.writeByte('(');
955 try dg.renderType(writer, ty);
956 try writer.writeByte(')');
957 }
958
959 try writer.writeByte('{');
960 var empty = true;
961 for (field_vals, 0..) |field_val, field_i| {
962 if (ty.structFieldIsComptime(field_i, mod)) continue;
963 const field_ty = ty.structFieldType(field_i, mod);
964 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
965
966 if (!empty) try writer.writeByte(',');
967 try dg.renderValue(writer, field_ty, field_val, initializer_type);
968
969 empty = false;
970 }
971 try writer.writeByte('}');
972 },
973 .Packed => {
974 const field_vals = val.castTag(.aggregate).?.data;
975 const int_info = ty.intInfo(mod);
976
977 const bits = Type.smallestUnsignedBits(int_info.bits - 1);
978 const bit_offset_ty = try mod.intType(.unsigned, bits);
979
980 var bit_offset: u64 = 0;
981
982 var eff_num_fields: usize = 0;
983 for (0..field_vals.len) |field_i| {
984 if (ty.structFieldIsComptime(field_i, mod)) continue;
985 const field_ty = ty.structFieldType(field_i, mod);
986 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
987
988 eff_num_fields += 1;
989 }
990
991 if (eff_num_fields == 0) {
992 try writer.writeByte('(');
993 try dg.renderValue(writer, ty, Value.undef, initializer_type);
994 try writer.writeByte(')');
995 } else if (ty.bitSize(mod) > 64) {
996 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
997 var num_or = eff_num_fields - 1;
998 while (num_or > 0) : (num_or -= 1) {
999 try writer.writeAll("zig_or_");
1000 try dg.renderTypeForBuiltinFnName(writer, ty);
1001 try writer.writeByte('(');
1002 }
1003
1004 var eff_index: usize = 0;
1005 var needs_closing_paren = false;
1006 for (field_vals, 0..) |field_val, field_i| {
1007 if (ty.structFieldIsComptime(field_i, mod)) continue;
1008 const field_ty = ty.structFieldType(field_i, mod);
1009 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
1010
1011 const cast_context = IntCastContext{ .value = .{ .value = field_val } };
1012 if (bit_offset != 0) {
1013 try writer.writeAll("zig_shl_");
1014 try dg.renderTypeForBuiltinFnName(writer, ty);
1015 try writer.writeByte('(');
1016 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
1017 try writer.writeAll(", ");
1018 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
1019 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
1020 try writer.writeByte(')');
1021 } else {
1022 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
1023 }
1024
1025 if (needs_closing_paren) try writer.writeByte(')');
1026 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");
1027
1028 bit_offset += field_ty.bitSize(mod);
1029 needs_closing_paren = true;
1030 eff_index += 1;
1031 }
1032 } else {
1033 try writer.writeByte('(');
1034 // a << a_off | b << b_off | c << c_off
1035 var empty = true;
1036 for (field_vals, 0..) |field_val, field_i| {
1037 if (ty.structFieldIsComptime(field_i, mod)) continue;
1038 const field_ty = ty.structFieldType(field_i, mod);
1039 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
1040
1041 if (!empty) try writer.writeAll(" | ");
1042 try writer.writeByte('(');
1043 try dg.renderType(writer, ty);
1044 try writer.writeByte(')');
1045
1046 if (bit_offset != 0) {
1047 try dg.renderValue(writer, field_ty, field_val, .Other);
1048 try writer.writeAll(" << ");
1049 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
1050 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
1051 } else {
1052 try dg.renderValue(writer, field_ty, field_val, .Other);
1053 }
1054
1055 bit_offset += field_ty.bitSize(mod);
1056 empty = false;
1057 }
1058 try writer.writeByte(')');
1059 }
1060 },
1061 },
1062
1063 .Frame,
1064 .AnyFrame,
1065 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
1066 @tagName(tag),
1067 }),
1068
1069 .Float,
1070 .Union,
1071 .Optional,
1072 .ErrorUnion,
1073 .ErrorSet,
1074 .Int,
1075 .Enum,
1076 .Bool,
1077 .Pointer,
1078 => unreachable, // handled below
1079 .Type,
1080 .Void,
1081 .NoReturn,
1082 .ComptimeFloat,
1083 .ComptimeInt,
1084 .Undefined,
1085 .Null,
1086 .Opaque,
1087 .EnumLiteral,
1088 .Fn,
1089 => unreachable, // comptime-only types
1090 };
1091
1092 switch (mod.intern_pool.indexToKey(val.ip_index)) {909 switch (mod.intern_pool.indexToKey(val.ip_index)) {
1093 // types, not values910 // types, not values
1094 .int_type,911 .int_type,
...@@ -1144,10 +961,24 @@ pub const DeclGen = struct {...@@ -1144,10 +961,24 @@ pub const DeclGen = struct {
1144 .error_union => |error_union| {961 .error_union => |error_union| {
1145 const payload_ty = ty.errorUnionPayload(mod);962 const payload_ty = ty.errorUnionPayload(mod);
1146 const error_ty = ty.errorUnionSet(mod);963 const error_ty = ty.errorUnionSet(mod);
1147 const error_val = if (val.errorUnionIsPayload(mod)) try mod.intValue(Type.err_int, 0) else val;
1148
1149 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {964 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1150 return dg.renderValue(writer, Type.err_int, error_val, location);965 switch (error_union.val) {
966 .err_name => |err_name| return dg.renderValue(
967 writer,
968 error_ty,
969 (try mod.intern(.{ .err = .{
970 .ty = error_ty.toIntern(),
971 .name = err_name,
972 } })).toValue(),
973 location,
974 ),
975 .payload => return dg.renderValue(
976 writer,
977 Type.err_int,
978 try mod.intValue(Type.err_int, 0),
979 location,
980 ),
981 }
1151 }982 }
1152983
1153 if (!location.isInitializer()) {984 if (!location.isInitializer()) {
...@@ -1156,15 +987,34 @@ pub const DeclGen = struct {...@@ -1156,15 +987,34 @@ pub const DeclGen = struct {
1156 try writer.writeByte(')');987 try writer.writeByte(')');
1157 }988 }
1158989
1159 const payload_val = switch (error_union.val) {
1160 .err_name => try mod.intern(.{ .undef = payload_ty.ip_index }),
1161 .payload => |payload| payload,
1162 }.toValue();
1163
1164 try writer.writeAll("{ .payload = ");990 try writer.writeAll("{ .payload = ");
1165 try dg.renderValue(writer, payload_ty, payload_val, initializer_type);991 try dg.renderValue(
992 writer,
993 payload_ty,
994 switch (error_union.val) {
995 .err_name => try mod.intern(.{ .undef = payload_ty.ip_index }),
996 .payload => |payload| payload,
997 }.toValue(),
998 initializer_type,
999 );
1166 try writer.writeAll(", .error = ");1000 try writer.writeAll(", .error = ");
1167 try dg.renderValue(writer, error_ty, error_val, initializer_type);1001 switch (error_union.val) {
1002 .err_name => |err_name| try dg.renderValue(
1003 writer,
1004 error_ty,
1005 (try mod.intern(.{ .err = .{
1006 .ty = error_ty.toIntern(),
1007 .name = err_name,
1008 } })).toValue(),
1009 location,
1010 ),
1011 .payload => try dg.renderValue(
1012 writer,
1013 Type.err_int,
1014 try mod.intValue(Type.err_int, 0),
1015 location,
1016 ),
1017 }
1168 try writer.writeAll(" }");1018 try writer.writeAll(" }");
1169 },1019 },
1170 .enum_tag => {1020 .enum_tag => {
...@@ -1272,30 +1122,42 @@ pub const DeclGen = struct {...@@ -1272,30 +1122,42 @@ pub const DeclGen = struct {
1272 }1122 }
1273 try writer.writeByte('{');1123 try writer.writeByte('{');
1274 }1124 }
1125 const ptr_location = switch (ptr.len) {
1126 .none => location,
1127 else => initializer_type,
1128 };
1129 const ptr_ty = switch (ptr.len) {
1130 .none => ty,
1131 else => ty.slicePtrFieldType(mod),
1132 };
1133 const ptr_val = switch (ptr.len) {
1134 .none => val,
1135 else => val.slicePtr(mod),
1136 };
1275 switch (ptr.addr) {1137 switch (ptr.addr) {
1276 .decl, .mut_decl => try dg.renderDeclValue(1138 .decl, .mut_decl => try dg.renderDeclValue(
1277 writer,1139 writer,
1278 ty,1140 ptr_ty,
1279 val,1141 ptr_val,
1280 switch (ptr.addr) {1142 switch (ptr.addr) {
1281 .decl => |decl| decl,1143 .decl => |decl| decl,
1282 .mut_decl => |mut_decl| mut_decl.decl,1144 .mut_decl => |mut_decl| mut_decl.decl,
1283 else => unreachable,1145 else => unreachable,
1284 },1146 },
1285 location,1147 ptr_location,
1286 ),1148 ),
1287 .int => |int| {1149 .int => |int| {
1288 try writer.writeAll("((");1150 try writer.writeAll("((");
1289 try dg.renderType(writer, ty);1151 try dg.renderType(writer, ptr_ty);
1290 try writer.print("){x})", .{1152 try writer.print("){x})", .{
1291 try dg.fmtIntLiteral(Type.usize, int.toValue(), .Other),1153 try dg.fmtIntLiteral(Type.usize, int.toValue(), ptr_location),
1292 });1154 });
1293 },1155 },
1294 .eu_payload,1156 .eu_payload,
1295 .opt_payload,1157 .opt_payload,
1296 .elem,1158 .elem,
1297 .field,1159 .field,
1298 => try dg.renderParentPtr(writer, val.ip_index, location),1160 => try dg.renderParentPtr(writer, ptr_val.ip_index, ptr_location),
1299 .comptime_field => unreachable,1161 .comptime_field => unreachable,
1300 }1162 }
1301 if (ptr.len != .none) {1163 if (ptr.len != .none) {
...@@ -1311,10 +1173,19 @@ pub const DeclGen = struct {...@@ -1311,10 +1173,19 @@ pub const DeclGen = struct {
1311 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))1173 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
1312 return dg.renderValue(writer, Type.bool, is_null_val, location);1174 return dg.renderValue(writer, Type.bool, is_null_val, location);
13131175
1314 if (ty.optionalReprIsPayload(mod)) switch (opt.val) {1176 if (ty.optionalReprIsPayload(mod)) return dg.renderValue(
1315 .none => return writer.writeByte('0'),1177 writer,
1316 else => |payload| return dg.renderValue(writer, payload_ty, payload.toValue(), location),1178 payload_ty,
1317 };1179 switch (opt.val) {
1180 .none => switch (payload_ty.zigTypeTag(mod)) {
1181 .ErrorSet => try mod.intValue(Type.err_int, 0),
1182 .Pointer => try mod.getCoerced(val, payload_ty),
1183 else => unreachable,
1184 },
1185 else => |payload| payload.toValue(),
1186 },
1187 location,
1188 );
13181189
1319 if (!location.isInitializer()) {1190 if (!location.isInitializer()) {
1320 try writer.writeByte('(');1191 try writer.writeByte('(');
...@@ -2535,7 +2406,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2535,7 +2406,7 @@ pub fn genErrDecls(o: *Object) !void {
2535 try writer.writeAll("enum {\n");2406 try writer.writeAll("enum {\n");
2536 o.indent_writer.pushIndent();2407 o.indent_writer.pushIndent();
2537 var max_name_len: usize = 0;2408 var max_name_len: usize = 0;
2538 for (mod.error_name_list.items, 0..) |name, value| {2409 for (mod.error_name_list.items[1..], 1..) |name, value| {
2539 max_name_len = std.math.max(name.len, max_name_len);2410 max_name_len = std.math.max(name.len, max_name_len);
2540 const err_val = try mod.intern(.{ .err = .{2411 const err_val = try mod.intern(.{ .err = .{
2541 .ty = .anyerror_type,2412 .ty = .anyerror_type,
...@@ -2562,21 +2433,21 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2562,21 +2433,21 @@ pub fn genErrDecls(o: *Object) !void {
2562 .child = .u8_type,2433 .child = .u8_type,
2563 .sentinel = .zero_u8,2434 .sentinel = .zero_u8,
2564 });2435 });
25652436 const name_val = try mod.intern(.{ .aggregate = .{
2566 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name };2437 .ty = name_ty.toIntern(),
2567 const name_val = Value.initPayload(&name_pl.base);2438 .storage = .{ .bytes = name },
2439 } });
25682440
2569 try writer.writeAll("static ");2441 try writer.writeAll("static ");
2570 try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, Const, 0, .complete);2442 try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, Const, 0, .complete);
2571 try writer.writeAll(" = ");2443 try writer.writeAll(" = ");
2572 try o.dg.renderValue(writer, name_ty, name_val, .StaticInitializer);2444 try o.dg.renderValue(writer, name_ty, name_val.toValue(), .StaticInitializer);
2573 try writer.writeAll(";\n");2445 try writer.writeAll(";\n");
2574 }2446 }
25752447
2576 const name_array_ty = try mod.arrayType(.{2448 const name_array_ty = try mod.arrayType(.{
2577 .len = mod.error_name_list.items.len,2449 .len = mod.error_name_list.items.len,
2578 .child = .slice_const_u8_sentinel_0_type,2450 .child = .slice_const_u8_sentinel_0_type,
2579 .sentinel = .zero_u8,
2580 });2451 });
25812452
2582 try writer.writeAll("static ");2453 try writer.writeAll("static ");
...@@ -2588,7 +2459,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2588,7 +2459,7 @@ pub fn genErrDecls(o: *Object) !void {
2588 const len_val = try mod.intValue(Type.usize, name.len);2459 const len_val = try mod.intValue(Type.usize, name.len);
25892460
2590 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{2461 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
2591 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val, .Other),2462 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val, .StaticInitializer),
2592 });2463 });
2593 }2464 }
2594 try writer.writeAll("};\n");2465 try writer.writeAll("};\n");
...@@ -2642,10 +2513,10 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {...@@ -2642,10 +2513,10 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
2642 .child = .u8_type,2513 .child = .u8_type,
2643 .sentinel = .zero_u8,2514 .sentinel = .zero_u8,
2644 });2515 });
26452516 const name_val = try mod.intern(.{ .aggregate = .{
2646 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name };2517 .ty = name_ty.toIntern(),
2647 const name_val = Value.initPayload(&name_pl.base);2518 .storage = .{ .bytes = name },
26482519 } });
2649 const len_val = try mod.intValue(Type.usize, name.len);2520 const len_val = try mod.intValue(Type.usize, name.len);
26502521
2651 try w.print(" case {}: {{\n static ", .{2522 try w.print(" case {}: {{\n static ", .{
...@@ -2653,7 +2524,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {...@@ -2653,7 +2524,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
2653 });2524 });
2654 try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, 0, .complete);2525 try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, 0, .complete);
2655 try w.writeAll(" = ");2526 try w.writeAll(" = ");
2656 try o.dg.renderValue(w, name_ty, name_val, .Initializer);2527 try o.dg.renderValue(w, name_ty, name_val.toValue(), .Initializer);
2657 try w.writeAll(";\n return (");2528 try w.writeAll(";\n return (");
2658 try o.dg.renderType(w, name_slice_ty);2529 try o.dg.renderType(w, name_slice_ty);
2659 try w.print("){{{}, {}}};\n", .{2530 try w.print("){{{}, {}}};\n", .{
...@@ -2789,7 +2660,7 @@ pub fn genDecl(o: *Object) !void {...@@ -2789,7 +2660,7 @@ pub fn genDecl(o: *Object) !void {
2789 const mod = o.dg.module;2660 const mod = o.dg.module;
2790 const decl = o.dg.decl.?;2661 const decl = o.dg.decl.?;
2791 const decl_c_value = .{ .decl = o.dg.decl_index.unwrap().? };2662 const decl_c_value = .{ .decl = o.dg.decl_index.unwrap().? };
2792 const tv: TypedValue = .{ .ty = decl.ty, .val = decl.val };2663 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
27932664
2794 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;2665 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;
2795 if (tv.val.getExternFunc(mod)) |_| {2666 if (tv.val.getExternFunc(mod)) |_| {
...@@ -4771,6 +4642,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4771,6 +4642,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
4771 try writer.writeAll(") ");4642 try writer.writeAll(") ");
47724643
4773 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);4644 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);
4645 try writer.writeByte('\n');
47744646
4775 // We don't need to use `genBodyResolveState` for the else block, because this instruction is4647 // We don't need to use `genBodyResolveState` for the else block, because this instruction is
4776 // noreturn so must terminate a body, therefore we don't need to leave `value_map` or4648 // noreturn so must terminate a body, therefore we don't need to leave `value_map` or
...@@ -5165,7 +5037,7 @@ fn airIsNull(...@@ -5165,7 +5037,7 @@ fn airIsNull(
5165 TypedValue{ .ty = Type.bool, .val = Value.true }5037 TypedValue{ .ty = Type.bool, .val = Value.true }
5166 else if (optional_ty.isPtrLikeOptional(mod))5038 else if (optional_ty.isPtrLikeOptional(mod))
5167 // operand is a regular pointer, test `operand !=/== NULL`5039 // operand is a regular pointer, test `operand !=/== NULL`
5168 TypedValue{ .ty = optional_ty, .val = try mod.nullValue(optional_ty) }5040 TypedValue{ .ty = optional_ty, .val = try mod.getCoerced(Value.null, optional_ty) }
5169 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)5041 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
5170 TypedValue{ .ty = Type.err_int, .val = try mod.intValue(Type.err_int, 0) }5042 TypedValue{ .ty = Type.err_int, .val = try mod.intValue(Type.err_int, 0) }
5171 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {5043 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
...@@ -5778,7 +5650,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5778,7 +5650,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5778 try reap(f, inst, &.{ty_op.operand});5650 try reap(f, inst, &.{ty_op.operand});
5779 try f.writeCValueDeref(writer, operand);5651 try f.writeCValueDeref(writer, operand);
5780 try writer.writeAll(".error = ");5652 try writer.writeAll(".error = ");
5781 try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other);5653 try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);
5782 try writer.writeAll(";\n");5654 try writer.writeAll(";\n");
57835655
5784 // Then return the payload pointer (only if it is used)5656 // Then return the payload pointer (only if it is used)
...@@ -6760,27 +6632,41 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6760,27 +6632,41 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6760 try writer.writeAll(" = ");6632 try writer.writeAll(" = ");
67616633
6762 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {6634 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {
6763 .Or, .Xor, .Add => try mod.intValue(scalar_ty, 0),6635 .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {
6636 .Bool => Value.false,
6637 .Int => try mod.intValue(scalar_ty, 0),
6638 else => unreachable,
6639 },
6764 .And => switch (scalar_ty.zigTypeTag(mod)) {6640 .And => switch (scalar_ty.zigTypeTag(mod)) {
6765 .Bool => try mod.intValue(Type.comptime_int, 1),6641 .Bool => Value.true,
6766 else => switch (scalar_ty.intInfo(mod).signedness) {6642 .Int => switch (scalar_ty.intInfo(mod).signedness) {
6767 .unsigned => try scalar_ty.maxIntScalar(mod, scalar_ty),6643 .unsigned => try scalar_ty.maxIntScalar(mod, scalar_ty),
6768 .signed => try mod.intValue(scalar_ty, -1),6644 .signed => try mod.intValue(scalar_ty, -1),
6769 },6645 },
6646 else => unreachable,
6647 },
6648 .Add => switch (scalar_ty.zigTypeTag(mod)) {
6649 .Int => try mod.intValue(scalar_ty, 0),
6650 .Float => try mod.floatValue(scalar_ty, 0.0),
6651 else => unreachable,
6652 },
6653 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
6654 .Int => try mod.intValue(scalar_ty, 1),
6655 .Float => try mod.floatValue(scalar_ty, 1.0),
6656 else => unreachable,
6770 },6657 },
6771 .Min => switch (scalar_ty.zigTypeTag(mod)) {6658 .Min => switch (scalar_ty.zigTypeTag(mod)) {
6772 .Bool => Value.one_comptime_int,6659 .Bool => Value.true,
6773 .Int => try scalar_ty.maxIntScalar(mod, scalar_ty),6660 .Int => try scalar_ty.maxIntScalar(mod, scalar_ty),
6774 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),6661 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),
6775 else => unreachable,6662 else => unreachable,
6776 },6663 },
6777 .Max => switch (scalar_ty.zigTypeTag(mod)) {6664 .Max => switch (scalar_ty.zigTypeTag(mod)) {
6778 .Bool => try mod.intValue(scalar_ty, 0),6665 .Bool => Value.false,
6779 .Int => try scalar_ty.minInt(mod, scalar_ty),6666 .Int => try scalar_ty.minIntScalar(mod, scalar_ty),
6780 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),6667 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),
6781 else => unreachable,6668 else => unreachable,
6782 },6669 },
6783 .Mul => try mod.intValue(Type.comptime_int, 1),
6784 }, .Initializer);6670 }, .Initializer);
6785 try writer.writeAll(";\n");6671 try writer.writeAll(";\n");
67866672