aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-05-06 19:20:52 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-06-10 20:42:29 -0700
commit75900ec1b5a250935a6abe050a006738fba99e66 (patch)
tree9d3dd571b59648a585c3ce5bcdb2dbb50a574d58 /src/Module.zig
parent73720b6975e2650ece48cc5f38495c091360c6c9 (diff)
downloadzig-75900ec1b5a250935a6abe050a006738fba99e66.tar.gz
zig-75900ec1b5a250935a6abe050a006738fba99e66.zip
stage2: move integer values to InternPool
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig73
1 files changed, 50 insertions, 23 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 01e2403377..9315c9efa7 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -6597,7 +6597,7 @@ pub fn populateTestFunctions(
field_vals.* = .{
try Value.Tag.slice.create(arena, .{
.ptr = try Value.Tag.decl_ref.create(arena, test_name_decl_index),
- .len = try Value.Tag.int_u64.create(arena, test_name_slice.len),
+ .len = try mod.intValue(Type.usize, test_name_slice.len),
}), // name
try Value.Tag.decl_ref.create(arena, test_decl_index), // func
Value.null, // async_frame_size
@@ -6628,7 +6628,7 @@ pub fn populateTestFunctions(
new_var.* = decl.val.castTag(.variable).?.data.*;
new_var.init = try Value.Tag.slice.create(arena, .{
.ptr = try Value.Tag.decl_ref.create(arena, array_decl_index),
- .len = try Value.Tag.int_u64.create(arena, mod.test_functions.count()),
+ .len = try mod.intValue(Type.usize, mod.test_functions.count()),
});
const new_val = try Value.Tag.variable.create(arena, new_var);
@@ -6875,6 +6875,38 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true });
}
+pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
+ if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);
+ if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);
+ var limbs_buffer: [4]usize = undefined;
+ var big_int = BigIntMutable.init(&limbs_buffer, x);
+ return intValue_big(mod, ty, big_int.toConst());
+}
+
+pub fn intValue_big(mod: *Module, ty: Type, x: BigIntConst) Allocator.Error!Value {
+ const i = try intern(mod, .{ .int = .{
+ .ty = ty.ip_index,
+ .storage = .{ .big_int = x },
+ } });
+ return i.toValue();
+}
+
+pub fn intValue_u64(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {
+ const i = try intern(mod, .{ .int = .{
+ .ty = ty.ip_index,
+ .storage = .{ .u64 = x },
+ } });
+ return i.toValue();
+}
+
+pub fn intValue_i64(mod: *Module, ty: Type, x: i64) Allocator.Error!Value {
+ const i = try intern(mod, .{ .int = .{
+ .ty = ty.ip_index,
+ .storage = .{ .i64 = x },
+ } });
+ return i.toValue();
+}
+
pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {
return intType(mod, .unsigned, Type.smallestUnsignedBits(max));
}
@@ -6907,32 +6939,27 @@ pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {
/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 {
assert(!val.isUndef());
- switch (val.tag()) {
- .int_big_positive => {
- const limbs = val.castTag(.int_big_positive).?.data;
- const big: std.math.big.int.Const = .{ .limbs = limbs, .positive = true };
- return @intCast(u16, big.bitCountAbs() + @boolToInt(sign));
- },
- .int_big_negative => {
- const limbs = val.castTag(.int_big_negative).?.data;
- // Zero is still a possibility, in which case unsigned is fine
- for (limbs) |limb| {
- if (limb != 0) break;
- } else return 0; // val == 0
- assert(sign);
- const big: std.math.big.int.Const = .{ .limbs = limbs, .positive = false };
- return @intCast(u16, big.bitCountTwosComp());
- },
- .int_i64 => {
- const x = val.castTag(.int_i64).?.data;
- if (x >= 0) return Type.smallestUnsignedBits(@intCast(u64, x));
+
+ const key = mod.intern_pool.indexToKey(val.ip_index);
+ switch (key.int.storage) {
+ .i64 => |x| {
+ if (std.math.cast(u64, x)) |casted| return Type.smallestUnsignedBits(casted);
assert(sign);
+ // Protect against overflow in the following negation.
+ if (x == std.math.minInt(i64)) return 64;
return Type.smallestUnsignedBits(@intCast(u64, -x - 1)) + 1;
},
- else => {
- const x = val.toUnsignedInt(mod);
+ .u64 => |x| {
return Type.smallestUnsignedBits(x) + @boolToInt(sign);
},
+ .big_int => |big| {
+ if (big.positive) return @intCast(u16, big.bitCountAbs() + @boolToInt(sign));
+
+ // Zero is still a possibility, in which case unsigned is fine
+ if (big.eqZero()) return 0;
+
+ return @intCast(u16, big.bitCountTwosComp());
+ },
}
}