stage2: more InternPool-related fixes

This commit is contained in:
Andrew Kelley 2023-05-07 16:14:08 -07:00
parent 4d88f825bc
commit 4fe0c583be
4 changed files with 57 additions and 24 deletions

View file

@ -6716,6 +6716,7 @@ fn reportRetryableFileError(
}
pub fn markReferencedDeclsAlive(mod: *Module, val: Value) void {
if (val.ip_index != .none) return;
switch (val.tag()) {
.decl_ref_mut => return mod.markDeclIndexAlive(val.castTag(.decl_ref_mut).?.data.decl_index),
.extern_fn => return mod.markDeclIndexAlive(val.castTag(.extern_fn).?.data.owner_decl),

View file

@ -12307,8 +12307,7 @@ fn zirShl(
if (block.wantSafety()) {
const bit_count = scalar_ty.intInfo(mod).bits;
if (!std.math.isPowerOfTwo(bit_count)) {
const bit_count_val = try mod.intValue(scalar_ty, bit_count);
const bit_count_val = try mod.intValue(scalar_rhs_ty, bit_count);
const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
@ -27391,10 +27390,19 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
const prev_ptr = while (air_tags[ptr_inst] == .bitcast) {
const prev_ptr = air_datas[ptr_inst].ty_op.operand;
const prev_ptr_ty = sema.typeOf(prev_ptr);
const prev_ptr_child_ty = switch (prev_ptr_ty.tag()) {
.pointer => prev_ptr_ty.castTag(.pointer).?.data.pointee_type,
else => return null,
};
if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null;
// TODO: I noticed that the behavior tests do not pass if these two
// checks are missing. I don't understand why the presence of inferred
// allocations is relevant to this function, or why it would have
// different behavior depending on whether the types were inferred.
// Something seems wrong here.
if (prev_ptr_ty.ip_index == .none) {
if (prev_ptr_ty.tag() == .inferred_alloc_mut) return null;
if (prev_ptr_ty.tag() == .inferred_alloc_const) return null;
}
const prev_ptr_child_ty = prev_ptr_ty.childType(mod);
if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;
ptr_inst = Air.refToIndex(prev_ptr) orelse return null;
} else return null;

View file

@ -2058,16 +2058,23 @@ pub const Type = struct {
}
}
pub fn ptrAddressSpace(self: Type, mod: *const Module) std.builtin.AddressSpace {
return switch (self.tag()) {
.pointer => self.castTag(.pointer).?.data.@"addrspace",
pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => ty.castTag(.pointer).?.data.@"addrspace",
.optional => {
const child_type = self.optionalChild(mod);
return child_type.ptrAddressSpace(mod);
.optional => {
const child_type = ty.optionalChild(mod);
return child_type.ptrAddressSpace(mod);
},
else => unreachable,
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.address_space,
.opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space,
else => unreachable,
},
else => unreachable,
};
}

View file

@ -644,15 +644,32 @@ pub const Value = struct {
/// Asserts the type is an enum type.
pub fn toEnum(val: Value, comptime E: type) E {
switch (val.tag()) {
.enum_field_index => {
const field_index = val.castTag(.enum_field_index).?.data;
return @intToEnum(E, field_index);
switch (val.ip_index) {
.calling_convention_c => {
if (E == std.builtin.CallingConvention) {
return .C;
} else {
unreachable;
}
},
.the_only_possible_value => {
const fields = std.meta.fields(E);
assert(fields.len == 1);
return @intToEnum(E, fields[0].value);
.calling_convention_inline => {
if (E == std.builtin.CallingConvention) {
return .Inline;
} else {
unreachable;
}
},
.none => switch (val.tag()) {
.enum_field_index => {
const field_index = val.castTag(.enum_field_index).?.data;
return @intToEnum(E, field_index);
},
.the_only_possible_value => {
const fields = std.meta.fields(E);
assert(fields.len == 1);
return @intToEnum(E, fields[0].value);
},
else => unreachable,
},
else => unreachable,
}
@ -2177,7 +2194,7 @@ pub const Value = struct {
std.hash.autoHash(hasher, zig_ty_tag);
if (val.isUndef()) return;
// The value is runtime-known and shouldn't affect the hash.
if (val.tag() == .runtime_value) return;
if (val.isRuntimeValue()) return;
switch (zig_ty_tag) {
.Opaque => unreachable, // Cannot hash opaque types
@ -2323,7 +2340,7 @@ pub const Value = struct {
pub fn hashUncoerced(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
if (val.isUndef()) return;
// The value is runtime-known and shouldn't affect the hash.
if (val.tag() == .runtime_value) return;
if (val.isRuntimeValue()) return;
switch (ty.zigTypeTag(mod)) {
.Opaque => unreachable, // Cannot hash opaque types