| ... | @@ -7339,28 +7339,36 @@ pub const Constant = enum(u32) { | ... | @@ -7339,28 +7339,36 @@ pub const Constant = enum(u32) { |
| 7339 | .positive_integer, | 7339 | .positive_integer, |
| 7340 | .negative_integer, | 7340 | .negative_integer, |
| 7341 | => |tag| { | 7341 | => |tag| { |
| 7342 | const extra: *align(@alignOf(std.math.big.Limb)) Integer = | 7342 | const extra: *align(@alignOf(std.math.big.Limb)) const Integer = |
| 7343 | @ptrCast(data.builder.constant_limbs.items[item.data..][0..Integer.limbs]); | 7343 | @ptrCast(data.builder.constant_limbs.items[item.data..][0..Integer.limbs]); |
| 7344 | const limbs = data.builder.constant_limbs | 7344 | const limbs = data.builder.constant_limbs |
| 7345 | .items[item.data + Integer.limbs ..][0..extra.limbs_len]; | 7345 | .items[item.data + Integer.limbs ..][0..extra.limbs_len]; |
| 7346 | const bigint: std.math.big.int.Const = .{ | 7346 | const bigint: std.math.big.int.Const = .{ |
| 7347 | .limbs = limbs, | 7347 | .limbs = limbs, |
| 7348 | .positive = tag == .positive_integer, | 7348 | .positive = switch (tag) { |
| | 7349 | .positive_integer => true, |
| | 7350 | .negative_integer => false, |
| | 7351 | else => unreachable, |
| | 7352 | }, |
| 7349 | }; | 7353 | }; |
| 7350 | const ExpectedContents = extern struct { | 7354 | const ExpectedContents = extern struct { |
| 7351 | string: [(64 * 8 / std.math.log2(10)) + 2]u8, | 7355 | const expected_limbs = @divExact(512, @bitSizeOf(std.math.big.Limb)); |
| | 7356 | string: [ |
| | 7357 | (std.math.big.int.Const{ |
| | 7358 | .limbs = &([1]std.math.big.Limb{ |
| | 7359 | std.math.maxInt(std.math.big.Limb), |
| | 7360 | } ** expected_limbs), |
| | 7361 | .positive = false, |
| | 7362 | }).sizeInBaseUpperBound(10) |
| | 7363 | ]u8, |
| 7352 | limbs: [ | 7364 | limbs: [ |
| 7353 | std.math.big.int.calcToStringLimbsBufferLen( | 7365 | std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10) |
| 7354 | 64 / @sizeOf(std.math.big.Limb), | | |
| 7355 | 10, | | |
| 7356 | ) | | |
| 7357 | ]std.math.big.Limb, | 7366 | ]std.math.big.Limb, |
| 7358 | }; | 7367 | }; |
| 7359 | var stack align(@alignOf(ExpectedContents)) = | 7368 | var stack align(@alignOf(ExpectedContents)) = |
| 7360 | std.heap.stackFallback(@sizeOf(ExpectedContents), data.builder.gpa); | 7369 | std.heap.stackFallback(@sizeOf(ExpectedContents), data.builder.gpa); |
| 7361 | const allocator = stack.get(); | 7370 | const allocator = stack.get(); |
| 7362 | const str = bigint.toStringAlloc(allocator, 10, undefined) catch | 7371 | const str = try bigint.toStringAlloc(allocator, 10, undefined); |
| 7363 | return writer.writeAll("..."); | | |
| 7364 | defer allocator.free(str); | 7372 | defer allocator.free(str); |
| 7365 | try writer.writeAll(str); | 7373 | try writer.writeAll(str); |
| 7366 | }, | 7374 | }, |
| ... | @@ -9464,10 +9472,38 @@ pub fn print(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocato | ... | @@ -9464,10 +9472,38 @@ pub fn print(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocato |
| 9464 | try bw.flush(); | 9472 | try bw.flush(); |
| 9465 | } | 9473 | } |
| 9466 | | 9474 | |
| | 9475 | fn WriterWithErrors(comptime BackingWriter: type, comptime ExtraErrors: type) type { |
| | 9476 | return struct { |
| | 9477 | backing_writer: BackingWriter, |
| | 9478 | |
| | 9479 | pub const Error = BackingWriter.Error || ExtraErrors; |
| | 9480 | pub const Writer = std.io.Writer(*const Self, Error, write); |
| | 9481 | |
| | 9482 | const Self = @This(); |
| | 9483 | |
| | 9484 | pub fn writer(self: *const Self) Writer { |
| | 9485 | return .{ .context = self }; |
| | 9486 | } |
| | 9487 | |
| | 9488 | pub fn write(self: *const Self, bytes: []const u8) Error!usize { |
| | 9489 | return self.backing_writer.write(bytes); |
| | 9490 | } |
| | 9491 | }; |
| | 9492 | } |
| | 9493 | fn writerWithErrors( |
| | 9494 | backing_writer: anytype, |
| | 9495 | comptime ExtraErrors: type, |
| | 9496 | ) WriterWithErrors(@TypeOf(backing_writer), ExtraErrors) { |
| | 9497 | return .{ .backing_writer = backing_writer }; |
| | 9498 | } |
| | 9499 | |
| 9467 | pub fn printUnbuffered( | 9500 | pub fn printUnbuffered( |
| 9468 | self: *Builder, | 9501 | self: *Builder, |
| 9469 | writer: anytype, | 9502 | backing_writer: anytype, |
| 9470 | ) (@TypeOf(writer).Error || Allocator.Error)!void { | 9503 | ) (@TypeOf(backing_writer).Error || Allocator.Error)!void { |
| | 9504 | const writer_with_errors = writerWithErrors(backing_writer, Allocator.Error); |
| | 9505 | const writer = writer_with_errors.writer(); |
| | 9506 | |
| 9471 | var need_newline = false; | 9507 | var need_newline = false; |
| 9472 | var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; | 9508 | var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; |
| 9473 | defer metadata_formatter.map.deinit(self.gpa); | 9509 | defer metadata_formatter.map.deinit(self.gpa); |
| ... | @@ -10344,12 +10380,17 @@ pub fn printUnbuffered( | ... | @@ -10344,12 +10380,17 @@ pub fn printUnbuffered( |
| 10344 | const extra = self.metadataExtraData(Metadata.Enumerator, metadata_item.data); | 10380 | const extra = self.metadataExtraData(Metadata.Enumerator, metadata_item.data); |
| 10345 | | 10381 | |
| 10346 | const ExpectedContents = extern struct { | 10382 | const ExpectedContents = extern struct { |
| 10347 | string: [(64 * 8 / std.math.log2(10)) + 2]u8, | 10383 | const expected_limbs = @divExact(512, @bitSizeOf(std.math.big.Limb)); |
| | 10384 | string: [ |
| | 10385 | (std.math.big.int.Const{ |
| | 10386 | .limbs = &([1]std.math.big.Limb{ |
| | 10387 | std.math.maxInt(std.math.big.Limb), |
| | 10388 | } ** expected_limbs), |
| | 10389 | .positive = false, |
| | 10390 | }).sizeInBaseUpperBound(10) |
| | 10391 | ]u8, |
| 10348 | limbs: [ | 10392 | limbs: [ |
| 10349 | std.math.big.int.calcToStringLimbsBufferLen( | 10393 | std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10) |
| 10350 | 64 / @sizeOf(std.math.big.Limb), | | |
| 10351 | 10, | | |
| 10352 | ) | | |
| 10353 | ]std.math.big.Limb, | 10394 | ]std.math.big.Limb, |
| 10354 | }; | 10395 | }; |
| 10355 | var stack align(@alignOf(ExpectedContents)) = | 10396 | var stack align(@alignOf(ExpectedContents)) = |
| ... | @@ -10375,7 +10416,9 @@ pub fn printUnbuffered( | ... | @@ -10375,7 +10416,9 @@ pub fn printUnbuffered( |
| 10375 | .value = str, | 10416 | .value = str, |
| 10376 | .isUnsigned = switch (kind) { | 10417 | .isUnsigned = switch (kind) { |
| 10377 | .enumerator_unsigned => true, | 10418 | .enumerator_unsigned => true, |
| 10378 | .enumerator_signed_positive, .enumerator_signed_negative => false, | 10419 | .enumerator_signed_positive, |
| | 10420 | .enumerator_signed_negative, |
| | 10421 | => false, |
| 10379 | else => unreachable, | 10422 | else => unreachable, |
| 10380 | }, | 10423 | }, |
| 10381 | }, writer); | 10424 | }, writer); |
| ... | @@ -13787,37 +13830,42 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co | ... | @@ -13787,37 +13830,42 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 13787 | => |tag| { | 13830 | => |tag| { |
| 13788 | const extra: *align(@alignOf(std.math.big.Limb)) Constant.Integer = | 13831 | const extra: *align(@alignOf(std.math.big.Limb)) Constant.Integer = |
| 13789 | @ptrCast(self.constant_limbs.items[data..][0..Constant.Integer.limbs]); | 13832 | @ptrCast(self.constant_limbs.items[data..][0..Constant.Integer.limbs]); |
| 13790 | const limbs = self.constant_limbs | | |
| 13791 | .items[data + Constant.Integer.limbs ..][0..extra.limbs_len]; | | |
| 13792 | const bigint: std.math.big.int.Const = .{ | 13833 | const bigint: std.math.big.int.Const = .{ |
| 13793 | .limbs = limbs, | 13834 | .limbs = self.constant_limbs |
| 13794 | .positive = tag == .positive_integer, | 13835 | .items[data + Constant.Integer.limbs ..][0..extra.limbs_len], |
| | 13836 | .positive = switch (tag) { |
| | 13837 | .positive_integer => true, |
| | 13838 | .negative_integer => false, |
| | 13839 | else => unreachable, |
| | 13840 | }, |
| 13795 | }; | 13841 | }; |
| 13796 | | | |
| 13797 | const bit_count = extra.type.scalarBits(self); | 13842 | const bit_count = extra.type.scalarBits(self); |
| 13798 | if (bit_count <= 64) { | 13843 | const val: i64 = if (bit_count <= 64) |
| 13799 | const val = bigint.to(i64) catch unreachable; | 13844 | bigint.to(i64) catch unreachable |
| 13800 | const emit_val = if (tag == .positive_integer) | 13845 | else if (bigint.to(u64)) |val| |
| 13801 | @shlWithOverflow(val, 1)[0] | 13846 | @bitCast(val) |
| 13802 | else | 13847 | else |_| { |
| 13803 | (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1); | 13848 | const limbs = try record.addManyAsSlice( |
| 13804 | try constants_block.writeAbbrev(Constants.Integer{ .value = @bitCast(emit_val) }); | 13849 | self.gpa, |
| 13805 | } else { | 13850 | std.math.divCeil(u24, bit_count, 64) catch unreachable, |
| 13806 | const word_count = std.mem.alignForward(u24, bit_count, 64) / 64; | 13851 | ); |
| 13807 | try record.ensureUnusedCapacity(self.gpa, word_count); | 13852 | bigint.writeTwosComplement(std.mem.sliceAsBytes(limbs), .little); |
| 13808 | const buffer: [*]u8 = @ptrCast(record.items.ptr); | 13853 | for (limbs) |*limb| { |
| 13809 | bigint.writeTwosComplement(buffer[0..(word_count * 8)], .little); | 13854 | const val = std.mem.littleToNative(i64, @bitCast(limb.*)); |
| 13810 | | 13855 | limb.* = @bitCast(if (val >= 0) |
| 13811 | const signed_buffer: [*]i64 = @ptrCast(record.items.ptr); | 13856 | val << 1 | 0 |
| 13812 | for (signed_buffer[0..word_count], 0..) |val, i| { | | |
| 13813 | signed_buffer[i] = if (val >= 0) | | |
| 13814 | @shlWithOverflow(val, 1)[0] | | |
| 13815 | else | 13857 | else |
| 13816 | (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1); | 13858 | -%val << 1 | 1); |
| 13817 | } | 13859 | } |
| 13818 | | 13860 | try constants_block.writeUnabbrev(5, record.items); |
| 13819 | try constants_block.writeUnabbrev(5, record.items.ptr[0..word_count]); | 13861 | continue; |
| 13820 | } | 13862 | }; |
| | 13863 | try constants_block.writeAbbrev(Constants.Integer{ |
| | 13864 | .value = @bitCast(if (val >= 0) |
| | 13865 | val << 1 | 0 |
| | 13866 | else |
| | 13867 | -%val << 1 | 1), |
| | 13868 | }); |
| 13821 | }, | 13869 | }, |
| 13822 | .half, | 13870 | .half, |
| 13823 | .bfloat, | 13871 | .bfloat, |
| ... | @@ -14186,6 +14234,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co | ... | @@ -14186,6 +14234,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14186 | self.metadata_items.items(.tag)[1..], | 14234 | self.metadata_items.items(.tag)[1..], |
| 14187 | self.metadata_items.items(.data)[1..], | 14235 | self.metadata_items.items(.data)[1..], |
| 14188 | ) |tag, data| { | 14236 | ) |tag, data| { |
| | 14237 | record.clearRetainingCapacity(); |
| 14189 | switch (tag) { | 14238 | switch (tag) { |
| 14190 | .none => unreachable, | 14239 | .none => unreachable, |
| 14191 | .file => { | 14240 | .file => { |
| ... | @@ -14333,77 +14382,60 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co | ... | @@ -14333,77 +14382,60 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14333 | .enumerator_signed_positive, | 14382 | .enumerator_signed_positive, |
| 14334 | .enumerator_signed_negative, | 14383 | .enumerator_signed_negative, |
| 14335 | => |kind| { | 14384 | => |kind| { |
| 14336 | const positive = switch (kind) { | | |
| 14337 | .enumerator_unsigned, | | |
| 14338 | .enumerator_signed_positive, | | |
| 14339 | => true, | | |
| 14340 | .enumerator_signed_negative => false, | | |
| 14341 | else => unreachable, | | |
| 14342 | }; | | |
| 14343 | | | |
| 14344 | const unsigned = switch (kind) { | | |
| 14345 | .enumerator_unsigned => true, | | |
| 14346 | .enumerator_signed_positive, | | |
| 14347 | .enumerator_signed_negative, | | |
| 14348 | => false, | | |
| 14349 | else => unreachable, | | |
| 14350 | }; | | |
| 14351 | | | |
| 14352 | const extra = self.metadataExtraData(Metadata.Enumerator, data); | 14385 | const extra = self.metadataExtraData(Metadata.Enumerator, data); |
| 14353 | | | |
| 14354 | const limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len]; | | |
| 14355 | | | |
| 14356 | const bigint: std.math.big.int.Const = .{ | 14386 | const bigint: std.math.big.int.Const = .{ |
| 14357 | .limbs = limbs, | 14387 | .limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len], |
| 14358 | .positive = positive, | 14388 | .positive = switch (kind) { |
| | 14389 | .enumerator_unsigned, |
| | 14390 | .enumerator_signed_positive, |
| | 14391 | => true, |
| | 14392 | .enumerator_signed_negative => false, |
| | 14393 | else => unreachable, |
| | 14394 | }, |
| 14359 | }; | 14395 | }; |
| 14360 | | 14396 | const flags: MetadataBlock.Enumerator.Flags = .{ |
| 14361 | if (extra.bit_width <= 64) { | 14397 | .unsigned = switch (kind) { |
| 14362 | const val = bigint.to(i64) catch unreachable; | 14398 | .enumerator_unsigned => true, |
| 14363 | const emit_val = if (positive) | 14399 | .enumerator_signed_positive, |
| 14364 | @shlWithOverflow(val, 1)[0] | 14400 | .enumerator_signed_negative, |
| 14365 | else | 14401 | => false, |
| 14366 | (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1); | 14402 | else => unreachable, |
| 14367 | try metadata_block.writeAbbrevAdapted(MetadataBlock.Enumerator{ | 14403 | }, |
| 14368 | .flags = .{ | 14404 | }; |
| 14369 | .unsigned = unsigned, | 14405 | const val: i64 = if (bigint.to(i64)) |val| |
| 14370 | }, | 14406 | val |
| 14371 | .bit_width = extra.bit_width, | 14407 | else |_| if (bigint.to(u64)) |val| |
| 14372 | .name = extra.name, | 14408 | @bitCast(val) |
| 14373 | .value = @bitCast(emit_val), | 14409 | else |_| { |
| 14374 | }, metadata_adapter); | 14410 | const limbs_len = std.math.divCeil(u32, extra.bit_width, 64) catch unreachable; |
| 14375 | } else { | 14411 | try record.ensureTotalCapacity(self.gpa, 3 + limbs_len); |
| 14376 | const word_count = std.mem.alignForward(u32, extra.bit_width, 64) / 64; | 14412 | record.appendAssumeCapacity(@as( |
| 14377 | try record.ensureUnusedCapacity(self.gpa, 3 + word_count); | 14413 | @typeInfo(MetadataBlock.Enumerator.Flags).Struct.backing_integer.?, |
| 14378 | | 14414 | @bitCast(flags), |
| 14379 | const flags: MetadataBlock.Enumerator.Flags = .{ | 14415 | )); |
| 14380 | .unsigned = unsigned, | 14416 | record.appendAssumeCapacity(extra.bit_width); |
| 14381 | }; | | |
| 14382 | | | |
| 14383 | const FlagsInt = @typeInfo(MetadataBlock.Enumerator.Flags).Struct.backing_integer.?; | | |
| 14384 | | | |
| 14385 | const flags_int: FlagsInt = @bitCast(flags); | | |
| 14386 | | | |
| 14387 | record.appendAssumeCapacity(@intCast(flags_int)); | | |
| 14388 | record.appendAssumeCapacity(@intCast(extra.bit_width)); | | |
| 14389 | record.appendAssumeCapacity(metadata_adapter.getMetadataStringIndex(extra.name)); | 14417 | record.appendAssumeCapacity(metadata_adapter.getMetadataStringIndex(extra.name)); |
| 14390 | | 14418 | const limbs = record.addManyAsSliceAssumeCapacity(limbs_len); |
| 14391 | const buffer: [*]u8 = @ptrCast(record.items.ptr); | 14419 | bigint.writeTwosComplement(std.mem.sliceAsBytes(limbs), .little); |
| 14392 | bigint.writeTwosComplement(buffer[0..(word_count * 8)], .little); | 14420 | for (limbs) |*limb| { |
| 14393 | | 14421 | const val = std.mem.littleToNative(i64, @bitCast(limb.*)); |
| 14394 | const signed_buffer: [*]i64 = @ptrCast(record.items.ptr); | 14422 | limb.* = @bitCast(if (val >= 0) |
| 14395 | for (signed_buffer[0..word_count], 0..) |val, i| { | 14423 | val << 1 | 0 |
| 14396 | signed_buffer[i] = if (val >= 0) | | |
| 14397 | @shlWithOverflow(val, 1)[0] | | |
| 14398 | else | 14424 | else |
| 14399 | (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1); | 14425 | -%val << 1 | 1); |
| 14400 | } | 14426 | } |
| 14401 | | 14427 | try metadata_block.writeUnabbrev(MetadataBlock.Enumerator.id, record.items); |
| 14402 | try metadata_block.writeUnabbrev( | 14428 | continue; |
| 14403 | MetadataBlock.Enumerator.id, | 14429 | }; |
| 14404 | record.items.ptr[0..(3 + word_count)], | 14430 | try metadata_block.writeAbbrevAdapted(MetadataBlock.Enumerator{ |
| 14405 | ); | 14431 | .flags = flags, |
| 14406 | } | 14432 | .bit_width = extra.bit_width, |
| | 14433 | .name = extra.name, |
| | 14434 | .value = @bitCast(if (val >= 0) |
| | 14435 | val << 1 | 0 |
| | 14436 | else |
| | 14437 | -%val << 1 | 1), |
| | 14438 | }, metadata_adapter); |
| 14407 | }, | 14439 | }, |
| 14408 | .subrange => { | 14440 | .subrange => { |
| 14409 | const extra = self.metadataExtraData(Metadata.Subrange, data); | 14441 | const extra = self.metadataExtraData(Metadata.Subrange, data); |
| ... | @@ -14491,7 +14523,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co | ... | @@ -14491,7 +14523,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14491 | }, metadata_adapter); | 14523 | }, metadata_adapter); |
| 14492 | }, | 14524 | }, |
| 14493 | } | 14525 | } |
| 14494 | record.clearRetainingCapacity(); | | |
| 14495 | } | 14526 | } |
| 14496 | | 14527 | |
| 14497 | // Write named metadata | 14528 | // Write named metadata |
| ... | @@ -14615,7 +14646,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co | ... | @@ -14615,7 +14646,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14615 | } | 14646 | } |
| 14616 | | 14647 | |
| 14617 | pub fn getOffsetValueIndex(adapter: @This(), value: Value) u32 { | 14648 | pub fn getOffsetValueIndex(adapter: @This(), value: Value) u32 { |
| 14618 | return @subWithOverflow(adapter.offset(), adapter.getValueIndex(value))[0]; | 14649 | return adapter.offset() -% adapter.getValueIndex(value); |
| 14619 | } | 14650 | } |
| 14620 | | 14651 | |
| 14621 | pub fn getOffsetValueSignedIndex(adapter: @This(), value: Value) i32 { | 14652 | pub fn getOffsetValueSignedIndex(adapter: @This(), value: Value) i32 { |