InternPool: pass by const pointer

The Zig language allows the compiler to make this optimization
automatically. We should definitely make the compiler do that, and
revert this commit. However, that will not happen in this branch, and I
want to continue to explore achieving performance parity with
merge-base. So, this commit changes all InternPool parameters to be
passed by const pointer rather than by value.

I measured a 1.03x ± 0.03 speedup vs the previous commit compiling the
(set of passing) behavior tests. Against merge-base, this commit is
1.17x ± 0.04 slower, which is an improvement from the previous
measurement of 1.22x ± 0.02.

Related issue: #13510
Related issue: #14129
Related issue: #15688
This commit is contained in:
Andrew Kelley 2023-05-30 13:54:22 -07:00
parent 6b81546454
commit 90a877f462
17 changed files with 94 additions and 94 deletions

View File

@ -1182,7 +1182,7 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {
return air.extra[extra.end..][0..extra.data.body_len];
}
pub fn typeOf(air: Air, inst: Air.Inst.Ref, ip: InternPool) Type {
pub fn typeOf(air: Air, inst: Air.Inst.Ref, ip: *const InternPool) Type {
const ref_int = @enumToInt(inst);
if (ref_int < InternPool.static_keys.len) {
return InternPool.static_keys[ref_int].typeOf().toType();
@ -1190,7 +1190,7 @@ pub fn typeOf(air: Air, inst: Air.Inst.Ref, ip: InternPool) Type {
return air.typeOfIndex(ref_int - ref_start_index, ip);
}
pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: *const InternPool) Type {
const datas = air.instructions.items(.data);
switch (air.instructions.items(.tag)[inst]) {
.add,
@ -1520,7 +1520,7 @@ pub fn value(air: Air, inst: Inst.Ref, mod: *Module) !?Value {
const air_datas = air.instructions.items(.data);
switch (air.instructions.items(.tag)[inst_index]) {
.interned => return air_datas[inst_index].interned.toValue(),
else => return air.typeOfIndex(inst_index, mod.intern_pool).onePossibleValue(mod),
else => return air.typeOfIndex(inst_index, &mod.intern_pool).onePossibleValue(mod),
}
}
@ -1537,7 +1537,7 @@ pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {
/// because it can cause side effects. If an instruction does not need to be
/// lowered, and Liveness determines its result is unused, backends should
/// avoid lowering it.
pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: InternPool) bool {
pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
const data = air.instructions.items(.data)[inst];
return switch (air.instructions.items(.tag)[inst]) {
.arg,

View File

@ -2992,7 +2992,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
};
}
fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType {
fn indexToKeyFuncType(ip: *const InternPool, data: u32) Key.FuncType {
const type_function = ip.extraDataTrail(TypeFunction, data);
const param_types = @ptrCast(
[]Index,
@ -3015,7 +3015,7 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType {
};
}
fn indexToKeyEnum(ip: InternPool, data: u32, tag_mode: Key.EnumType.TagMode) Key {
fn indexToKeyEnum(ip: *const InternPool, data: u32, tag_mode: Key.EnumType.TagMode) Key {
const enum_explicit = ip.extraDataTrail(EnumExplicit, data);
const names = @ptrCast(
[]const NullTerminatedString,
@ -3038,7 +3038,7 @@ fn indexToKeyEnum(ip: InternPool, data: u32, tag_mode: Key.EnumType.TagMode) Key
} };
}
fn indexToKeyBigInt(ip: InternPool, limb_index: u32, positive: bool) Key {
fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key {
const int_info = ip.limbData(Int, limb_index);
return .{ .int = .{
.ty = int_info.ty,
@ -4351,7 +4351,7 @@ fn addLimbsAssumeCapacity(ip: *InternPool, limbs: []const Limb) void {
}
}
fn extraDataTrail(ip: InternPool, comptime T: type, index: usize) struct { data: T, end: usize } {
fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct { data: T, end: usize } {
var result: T = undefined;
const fields = @typeInfo(T).Struct.fields;
inline for (fields, 0..) |field, i| {
@ -4384,12 +4384,12 @@ fn extraDataTrail(ip: InternPool, comptime T: type, index: usize) struct { data:
};
}
fn extraData(ip: InternPool, comptime T: type, index: usize) T {
fn extraData(ip: *const InternPool, comptime T: type, index: usize) T {
return extraDataTrail(ip, T, index).data;
}
/// Asserts the struct has 32-bit fields and the number of fields is evenly divisible by 2.
fn limbData(ip: InternPool, comptime T: type, index: usize) T {
fn limbData(ip: *const InternPool, comptime T: type, index: usize) T {
switch (@sizeOf(Limb)) {
@sizeOf(u32) => return extraData(ip, T, index),
@sizeOf(u64) => {},
@ -4413,7 +4413,7 @@ fn limbData(ip: InternPool, comptime T: type, index: usize) T {
}
/// This function returns the Limb slice that is trailing data after a payload.
fn limbSlice(ip: InternPool, comptime S: type, limb_index: u32, len: u32) []const Limb {
fn limbSlice(ip: *const InternPool, comptime S: type, limb_index: u32, len: u32) []const Limb {
const field_count = @typeInfo(S).Struct.fields.len;
switch (@sizeOf(Limb)) {
@sizeOf(u32) => {
@ -4433,7 +4433,7 @@ const LimbsAsIndexes = struct {
len: u32,
};
fn limbsSliceToIndex(ip: InternPool, limbs: []const Limb) LimbsAsIndexes {
fn limbsSliceToIndex(ip: *const InternPool, limbs: []const Limb) LimbsAsIndexes {
const host_slice = switch (@sizeOf(Limb)) {
@sizeOf(u32) => ip.extra.items,
@sizeOf(u64) => ip.limbs.items,
@ -4447,7 +4447,7 @@ fn limbsSliceToIndex(ip: InternPool, limbs: []const Limb) LimbsAsIndexes {
}
/// This function converts Limb array indexes to a primitive slice type.
fn limbsIndexToSlice(ip: InternPool, limbs: LimbsAsIndexes) []const Limb {
fn limbsIndexToSlice(ip: *const InternPool, limbs: LimbsAsIndexes) []const Limb {
return switch (@sizeOf(Limb)) {
@sizeOf(u32) => ip.extra.items[limbs.start..][0..limbs.len],
@sizeOf(u64) => ip.limbs.items[limbs.start..][0..limbs.len],
@ -4485,7 +4485,7 @@ test "basic usage" {
try std.testing.expect(another_array_i32 == array_i32);
}
pub fn childType(ip: InternPool, i: Index) Index {
pub fn childType(ip: *const InternPool, i: Index) Index {
return switch (ip.indexToKey(i)) {
.ptr_type => |ptr_type| ptr_type.elem_type,
.vector_type => |vector_type| vector_type.child,
@ -4496,7 +4496,7 @@ pub fn childType(ip: InternPool, i: Index) Index {
}
/// Given a slice type, returns the type of the ptr field.
pub fn slicePtrType(ip: InternPool, i: Index) Index {
pub fn slicePtrType(ip: *const InternPool, i: Index) Index {
switch (i) {
.slice_const_u8_type => return .manyptr_const_u8_type,
.slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
@ -4510,7 +4510,7 @@ pub fn slicePtrType(ip: InternPool, i: Index) Index {
}
/// Given a slice value, returns the value of the ptr field.
pub fn slicePtr(ip: InternPool, i: Index) Index {
pub fn slicePtr(ip: *const InternPool, i: Index) Index {
const item = ip.items.get(@enumToInt(i));
switch (item.tag) {
.ptr_slice => return ip.extraData(PtrSlice, item.data).ptr,
@ -4519,7 +4519,7 @@ pub fn slicePtr(ip: InternPool, i: Index) Index {
}
/// Given a slice value, returns the value of the len field.
pub fn sliceLen(ip: InternPool, i: Index) Index {
pub fn sliceLen(ip: *const InternPool, i: Index) Index {
const item = ip.items.get(@enumToInt(i));
switch (item.tag) {
.ptr_slice => return ip.extraData(PtrSlice, item.data).len,
@ -4702,7 +4702,7 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Ind
} });
}
pub fn indexToStructType(ip: InternPool, val: Index) Module.Struct.OptionalIndex {
pub fn indexToStructType(ip: *const InternPool, val: Index) Module.Struct.OptionalIndex {
assert(val != .none);
const tags = ip.items.items(.tag);
if (tags[@enumToInt(val)] != .type_struct) return .none;
@ -4710,7 +4710,7 @@ pub fn indexToStructType(ip: InternPool, val: Index) Module.Struct.OptionalIndex
return @intToEnum(Module.Struct.Index, datas[@enumToInt(val)]).toOptional();
}
pub fn indexToUnionType(ip: InternPool, val: Index) Module.Union.OptionalIndex {
pub fn indexToUnionType(ip: *const InternPool, val: Index) Module.Union.OptionalIndex {
assert(val != .none);
const tags = ip.items.items(.tag);
switch (tags[@enumToInt(val)]) {
@ -4721,7 +4721,7 @@ pub fn indexToUnionType(ip: InternPool, val: Index) Module.Union.OptionalIndex {
return @intToEnum(Module.Union.Index, datas[@enumToInt(val)]).toOptional();
}
pub fn indexToFuncType(ip: InternPool, val: Index) ?Key.FuncType {
pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {
assert(val != .none);
const tags = ip.items.items(.tag);
const datas = ip.items.items(.data);
@ -4731,7 +4731,7 @@ pub fn indexToFuncType(ip: InternPool, val: Index) ?Key.FuncType {
}
}
pub fn indexToFunc(ip: InternPool, val: Index) Module.Fn.OptionalIndex {
pub fn indexToFunc(ip: *const InternPool, val: Index) Module.Fn.OptionalIndex {
assert(val != .none);
const tags = ip.items.items(.tag);
if (tags[@enumToInt(val)] != .func) return .none;
@ -4739,7 +4739,7 @@ pub fn indexToFunc(ip: InternPool, val: Index) Module.Fn.OptionalIndex {
return ip.extraData(Key.Func, datas[@enumToInt(val)]).index.toOptional();
}
pub fn indexToInferredErrorSetType(ip: InternPool, val: Index) Module.Fn.InferredErrorSet.OptionalIndex {
pub fn indexToInferredErrorSetType(ip: *const InternPool, val: Index) Module.Fn.InferredErrorSet.OptionalIndex {
assert(val != .none);
const tags = ip.items.items(.tag);
if (tags[@enumToInt(val)] != .type_inferred_error_set) return .none;
@ -4748,7 +4748,7 @@ pub fn indexToInferredErrorSetType(ip: InternPool, val: Index) Module.Fn.Inferre
}
/// includes .comptime_int_type
pub fn isIntegerType(ip: InternPool, ty: Index) bool {
pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
return switch (ty) {
.usize_type,
.isize_type,
@ -4769,7 +4769,7 @@ pub fn isIntegerType(ip: InternPool, ty: Index) bool {
}
/// does not include .enum_literal_type
pub fn isEnumType(ip: InternPool, ty: Index) bool {
pub fn isEnumType(ip: *const InternPool, ty: Index) bool {
return switch (ty) {
.atomic_order_type,
.atomic_rmw_op_type,
@ -4783,35 +4783,35 @@ pub fn isEnumType(ip: InternPool, ty: Index) bool {
};
}
pub fn isFunctionType(ip: InternPool, ty: Index) bool {
pub fn isFunctionType(ip: *const InternPool, ty: Index) bool {
return ip.indexToKey(ty) == .func_type;
}
pub fn isPointerType(ip: InternPool, ty: Index) bool {
pub fn isPointerType(ip: *const InternPool, ty: Index) bool {
return ip.indexToKey(ty) == .ptr_type;
}
pub fn isOptionalType(ip: InternPool, ty: Index) bool {
pub fn isOptionalType(ip: *const InternPool, ty: Index) bool {
return ip.indexToKey(ty) == .opt_type;
}
/// includes .inferred_error_set_type
pub fn isErrorSetType(ip: InternPool, ty: Index) bool {
pub fn isErrorSetType(ip: *const InternPool, ty: Index) bool {
return ty == .anyerror_type or switch (ip.indexToKey(ty)) {
.error_set_type, .inferred_error_set_type => true,
else => false,
};
}
pub fn isInferredErrorSetType(ip: InternPool, ty: Index) bool {
pub fn isInferredErrorSetType(ip: *const InternPool, ty: Index) bool {
return ip.indexToKey(ty) == .inferred_error_set_type;
}
pub fn isErrorUnionType(ip: InternPool, ty: Index) bool {
pub fn isErrorUnionType(ip: *const InternPool, ty: Index) bool {
return ip.indexToKey(ty) == .error_union_type;
}
pub fn isAggregateType(ip: InternPool, ty: Index) bool {
pub fn isAggregateType(ip: *const InternPool, ty: Index) bool {
return switch (ip.indexToKey(ty)) {
.array_type, .vector_type, .anon_struct_type, .struct_type => true,
else => false,
@ -4827,11 +4827,11 @@ pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
ip.extra.items[ip.items.items(.data)[@enumToInt(index)] + field_index] = @enumToInt(init_index);
}
pub fn dump(ip: InternPool) void {
pub fn dump(ip: *const InternPool) void {
dumpFallible(ip, std.heap.page_allocator) catch return;
}
fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
fn dumpFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
const items_size = (1 + 4) * ip.items.len;
const extra_size = 4 * ip.extra.items.len;
const limbs_size = 8 * ip.limbs.items.len;
@ -5023,11 +5023,11 @@ pub fn structPtr(ip: *InternPool, index: Module.Struct.Index) *Module.Struct {
return ip.allocated_structs.at(@enumToInt(index));
}
pub fn structPtrConst(ip: InternPool, index: Module.Struct.Index) *const Module.Struct {
pub fn structPtrConst(ip: *const InternPool, index: Module.Struct.Index) *const Module.Struct {
return ip.allocated_structs.at(@enumToInt(index));
}
pub fn structPtrUnwrapConst(ip: InternPool, index: Module.Struct.OptionalIndex) ?*const Module.Struct {
pub fn structPtrUnwrapConst(ip: *const InternPool, index: Module.Struct.OptionalIndex) ?*const Module.Struct {
return structPtrConst(ip, index.unwrap() orelse return null);
}
@ -5035,7 +5035,7 @@ pub fn unionPtr(ip: *InternPool, index: Module.Union.Index) *Module.Union {
return ip.allocated_unions.at(@enumToInt(index));
}
pub fn unionPtrConst(ip: InternPool, index: Module.Union.Index) *const Module.Union {
pub fn unionPtrConst(ip: *const InternPool, index: Module.Union.Index) *const Module.Union {
return ip.allocated_unions.at(@enumToInt(index));
}
@ -5043,7 +5043,7 @@ pub fn funcPtr(ip: *InternPool, index: Module.Fn.Index) *Module.Fn {
return ip.allocated_funcs.at(@enumToInt(index));
}
pub fn funcPtrConst(ip: InternPool, index: Module.Fn.Index) *const Module.Fn {
pub fn funcPtrConst(ip: *const InternPool, index: Module.Fn.Index) *const Module.Fn {
return ip.allocated_funcs.at(@enumToInt(index));
}
@ -5051,7 +5051,7 @@ pub fn inferredErrorSetPtr(ip: *InternPool, index: Module.Fn.InferredErrorSet.In
return ip.allocated_inferred_error_sets.at(@enumToInt(index));
}
pub fn inferredErrorSetPtrConst(ip: InternPool, index: Module.Fn.InferredErrorSet.Index) *const Module.Fn.InferredErrorSet {
pub fn inferredErrorSetPtrConst(ip: *const InternPool, index: Module.Fn.InferredErrorSet.Index) *const Module.Fn.InferredErrorSet {
return ip.allocated_inferred_error_sets.at(@enumToInt(index));
}
@ -5182,7 +5182,7 @@ pub fn getString(ip: *InternPool, s: []const u8) OptionalNullTerminatedString {
}
}
pub fn stringToSlice(ip: InternPool, s: NullTerminatedString) [:0]const u8 {
pub fn stringToSlice(ip: *const InternPool, s: NullTerminatedString) [:0]const u8 {
const string_bytes = ip.string_bytes.items;
const start = @enumToInt(s);
var end: usize = start;
@ -5190,11 +5190,11 @@ pub fn stringToSlice(ip: InternPool, s: NullTerminatedString) [:0]const u8 {
return string_bytes[start..end :0];
}
pub fn stringToSliceUnwrap(ip: InternPool, s: OptionalNullTerminatedString) ?[:0]const u8 {
pub fn stringToSliceUnwrap(ip: *const InternPool, s: OptionalNullTerminatedString) ?[:0]const u8 {
return ip.stringToSlice(s.unwrap() orelse return null);
}
pub fn typeOf(ip: InternPool, index: Index) Index {
pub fn typeOf(ip: *const InternPool, index: Index) Index {
// This optimization of static keys is required so that typeOf can be called
// on static keys that haven't been added yet during static key initialization.
// An alternative would be to topological sort the static keys, but this would
@ -5382,12 +5382,12 @@ pub fn typeOf(ip: InternPool, index: Index) Index {
}
/// Assumes that the enum's field indexes equal its value tags.
pub fn toEnum(ip: InternPool, comptime E: type, i: Index) E {
pub fn toEnum(ip: *const InternPool, comptime E: type, i: Index) E {
const int = ip.indexToKey(i).enum_tag.int;
return @intToEnum(E, ip.indexToKey(int).int.storage.u64);
}
pub fn aggregateTypeLen(ip: InternPool, ty: Index) u64 {
pub fn aggregateTypeLen(ip: *const InternPool, ty: Index) u64 {
return switch (ip.indexToKey(ty)) {
.struct_type => |struct_type| ip.structPtrConst(struct_type.index.unwrap() orelse return 0).fields.count(),
.anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
@ -5397,7 +5397,7 @@ pub fn aggregateTypeLen(ip: InternPool, ty: Index) u64 {
};
}
pub fn aggregateTypeLenIncludingSentinel(ip: InternPool, ty: Index) u64 {
pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
return switch (ip.indexToKey(ty)) {
.struct_type => |struct_type| ip.structPtrConst(struct_type.index.unwrap() orelse return 0).fields.count(),
.anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
@ -5407,7 +5407,7 @@ pub fn aggregateTypeLenIncludingSentinel(ip: InternPool, ty: Index) u64 {
};
}
pub fn isNoReturn(ip: InternPool, ty: Index) bool {
pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
return switch (ty) {
.noreturn_type => true,
else => switch (ip.indexToKey(ty)) {
@ -5420,7 +5420,7 @@ pub fn isNoReturn(ip: InternPool, ty: Index) bool {
/// This is a particularly hot function, so we operate directly on encodings
/// rather than the more straightforward implementation of calling `indexToKey`.
pub fn zigTypeTagOrPoison(ip: InternPool, index: Index) error{GenericPoison}!std.builtin.TypeId {
pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPoison}!std.builtin.TypeId {
return switch (index) {
.u1_type,
.u8_type,

View File

@ -225,7 +225,7 @@ pub fn categorizeOperand(
air: Air,
inst: Air.Inst.Index,
operand: Air.Inst.Index,
ip: InternPool,
ip: *const InternPool,
) OperandCategory {
const air_tags = air.instructions.items(.tag);
const air_datas = air.instructions.items(.data);
@ -1139,7 +1139,7 @@ fn analyzeInst(
.aggregate_init => {
const ty_pl = inst_datas[inst].ty_pl;
const aggregate_ty = a.air.getRefType(ty_pl.ty);
const len = @intCast(usize, aggregate_ty.arrayLenIp(ip.*));
const len = @intCast(usize, aggregate_ty.arrayLenIp(ip));
const elements = @ptrCast([]const Air.Inst.Ref, a.air.extra[ty_pl.payload..][0..len]);
if (elements.len <= bpi - 1) {
@ -1291,7 +1291,7 @@ fn analyzeOperands(
// If our result is unused and the instruction doesn't need to be lowered, backends will
// skip the lowering of this instruction, so we don't want to record uses of operands.
// That way, we can mark as many instructions as possible unused.
if (!immediate_death or a.air.mustLower(inst, ip.*)) {
if (!immediate_death or a.air.mustLower(inst, ip)) {
// Note that it's important we iterate over the operands backwards, so that if a dying
// operand is used multiple times we mark its last use as its death.
var i = operands.len;
@ -1837,7 +1837,7 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {
// If our result is unused and the instruction doesn't need to be lowered, backends will
// skip the lowering of this instruction, so we don't want to record uses of operands.
// That way, we can mark as many instructions as possible unused.
if (big.will_die_immediately and !big.a.air.mustLower(big.inst, ip.*)) return;
if (big.will_die_immediately and !big.a.air.mustLower(big.inst, ip)) return;
const extra_byte = (big.operands_remaining - (bpi - 1)) / 31;
const extra_bit = @intCast(u5, big.operands_remaining - (bpi - 1) - extra_byte * 31);

View File

@ -32,7 +32,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
const tag = self.air.instructions.items(.tag);
const data = self.air.instructions.items(.data);
for (body) |inst| {
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*)) {
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) {
// This instruction will not be lowered and should be ignored.
continue;
}
@ -325,7 +325,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.aggregate_init => {
const ty_pl = data[inst].ty_pl;
const aggregate_ty = self.air.getRefType(ty_pl.ty);
const len = @intCast(usize, aggregate_ty.arrayLenIp(ip.*));
const len = @intCast(usize, aggregate_ty.arrayLenIp(ip));
const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
var bt = self.liveness.iterateBigTomb(inst);

View File

@ -6726,7 +6726,7 @@ pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
}
pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
const info = Type.ptrInfoIp(mod.intern_pool, ptr_ty.toIntern());
const info = Type.ptrInfoIp(&mod.intern_pool, ptr_ty.toIntern());
return mod.ptrType(.{
.elem_type = new_child.toIntern(),

View File

@ -33624,7 +33624,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
/// Returns the type of the AIR instruction.
fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {
return sema.getTmpAir().typeOf(inst, sema.mod.intern_pool);
return sema.getTmpAir().typeOf(inst, &sema.mod.intern_pool);
}
pub fn getTmpAir(sema: Sema) Air {

View File

@ -660,7 +660,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
for (body) |inst| {
// TODO: remove now-redundant isUnused calls from AIR handler functions
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
continue;
const old_air_bookkeeping = self.air_bookkeeping;
@ -6412,10 +6412,10 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register {
fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOf(inst, mod.intern_pool);
return self.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOfIndex(inst, mod.intern_pool);
return self.air.typeOfIndex(inst, &mod.intern_pool);
}

View File

@ -644,7 +644,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
for (body) |inst| {
// TODO: remove now-redundant isUnused calls from AIR handler functions
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
continue;
const old_air_bookkeeping = self.air_bookkeeping;
@ -6317,10 +6317,10 @@ fn parseRegName(name: []const u8) ?Register {
fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOf(inst, mod.intern_pool);
return self.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOfIndex(inst, mod.intern_pool);
return self.air.typeOfIndex(inst, &mod.intern_pool);
}

View File

@ -478,7 +478,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
for (body) |inst| {
// TODO: remove now-redundant isUnused calls from AIR handler functions
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
continue;
const old_air_bookkeeping = self.air_bookkeeping;
@ -2737,10 +2737,10 @@ fn parseRegName(name: []const u8) ?Register {
fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOf(inst, mod.intern_pool);
return self.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOfIndex(inst, mod.intern_pool);
return self.air.typeOfIndex(inst, &mod.intern_pool);
}

View File

@ -498,7 +498,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
for (body) |inst| {
// TODO: remove now-redundant isUnused calls from AIR handler functions
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
continue;
const old_air_bookkeeping = self.air_bookkeeping;
@ -4883,10 +4883,10 @@ fn wantSafety(self: *Self) bool {
fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOf(inst, mod.intern_pool);
return self.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOfIndex(inst, mod.intern_pool);
return self.air.typeOfIndex(inst, &mod.intern_pool);
}

View File

@ -2076,7 +2076,7 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
const ip = &mod.intern_pool;
for (body) |inst| {
if (func.liveness.isUnused(inst) and !func.air.mustLower(inst, ip.*)) {
if (func.liveness.isUnused(inst) and !func.air.mustLower(inst, ip)) {
continue;
}
const old_bookkeeping_value = func.air_bookkeeping;
@ -7436,10 +7436,10 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type {
const mod = func.bin_file.base.options.module.?;
return func.air.typeOf(inst, mod.intern_pool);
return func.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(func: *CodeGen, inst: Air.Inst.Index) Type {
const mod = func.bin_file.base.options.module.?;
return func.air.typeOfIndex(inst, mod.intern_pool);
return func.air.typeOfIndex(inst, &mod.intern_pool);
}

View File

@ -1738,7 +1738,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
try self.mir_to_air_map.put(self.gpa, mir_inst, inst);
}
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*)) continue;
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;
wip_mir_log.debug("{}", .{self.fmtAir(inst)});
verbose_tracking_log.debug("{}", .{self.fmtTracking()});
@ -11992,10 +11992,10 @@ fn hasAllFeatures(self: *Self, features: anytype) bool {
fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOf(inst, mod.intern_pool);
return self.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
const mod = self.bin_file.options.module.?;
return self.air.typeOfIndex(inst, mod.intern_pool);
return self.air.typeOfIndex(inst, &mod.intern_pool);
}

View File

@ -489,12 +489,12 @@ pub const Function = struct {
fn typeOf(f: *Function, inst: Air.Inst.Ref) Type {
const mod = f.object.dg.module;
return f.air.typeOf(inst, mod.intern_pool);
return f.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type {
const mod = f.object.dg.module;
return f.air.typeOfIndex(inst, mod.intern_pool);
return f.air.typeOfIndex(inst, &mod.intern_pool);
}
};
@ -2808,7 +2808,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
const air_tags = f.air.instructions.items(.tag);
for (body) |inst| {
if (f.liveness.isUnused(inst) and !f.air.mustLower(inst, ip.*))
if (f.liveness.isUnused(inst) and !f.air.mustLower(inst, ip))
continue;
const result_value = switch (air_tags[inst]) {

View File

@ -1574,7 +1574,7 @@ pub const Object = struct {
},
.Pointer => {
// Normalize everything that the debug info does not represent.
const ptr_info = Type.ptrInfoIp(mod.intern_pool, ty.toIntern());
const ptr_info = Type.ptrInfoIp(&mod.intern_pool, ty.toIntern());
if (ptr_info.sentinel != .none or
ptr_info.address_space != .generic or
@ -4330,7 +4330,7 @@ pub const FuncGen = struct {
const ip = &mod.intern_pool;
const air_tags = self.air.instructions.items(.tag);
for (body, 0..) |inst, i| {
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
continue;
const opt_value: ?*llvm.Value = switch (air_tags[inst]) {
@ -8055,7 +8055,7 @@ pub const FuncGen = struct {
const mod = fg.dg.module;
const ip = &mod.intern_pool;
for (body_tail[1..]) |body_inst| {
switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip.*)) {
switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) {
.none => continue,
.write, .noret, .complex => return false,
.tomb => return true,
@ -9920,12 +9920,12 @@ pub const FuncGen = struct {
fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
const mod = fg.dg.module;
return fg.air.typeOf(inst, mod.intern_pool);
return fg.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {
const mod = fg.dg.module;
return fg.air.typeOfIndex(inst, mod.intern_pool);
return fg.air.typeOfIndex(inst, &mod.intern_pool);
}
};

View File

@ -1688,7 +1688,7 @@ pub const DeclGen = struct {
const mod = self.module;
const ip = &mod.intern_pool;
// TODO: remove now-redundant isUnused calls from AIR handler functions
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
return;
const air_tags = self.air.instructions.items(.tag);
@ -3339,11 +3339,11 @@ pub const DeclGen = struct {
fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type {
const mod = self.module;
return self.air.typeOf(inst, mod.intern_pool);
return self.air.typeOf(inst, &mod.intern_pool);
}
fn typeOfIndex(self: *DeclGen, inst: Air.Inst.Index) Type {
const mod = self.module;
return self.air.typeOfIndex(inst, mod.intern_pool);
return self.air.typeOfIndex(inst, &mod.intern_pool);
}
};

View File

@ -978,6 +978,6 @@ const Writer = struct {
fn typeOfIndex(w: *Writer, inst: Air.Inst.Index) Type {
const mod = w.module;
return w.air.typeOfIndex(inst, mod.intern_pool);
return w.air.typeOfIndex(inst, &mod.intern_pool);
}
};

View File

@ -102,7 +102,7 @@ pub const Type = struct {
};
}
pub fn ptrInfoIp(ip: InternPool, ty: InternPool.Index) InternPool.Key.PtrType {
pub fn ptrInfoIp(ip: *const InternPool, ty: InternPool.Index) InternPool.Key.PtrType {
return switch (ip.indexToKey(ty)) {
.ptr_type => |p| p,
.opt_type => |child| switch (ip.indexToKey(child)) {
@ -114,7 +114,7 @@ pub const Type = struct {
}
pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data {
return Payload.Pointer.Data.fromKey(ptrInfoIp(mod.intern_pool, ty.toIntern()));
return Payload.Pointer.Data.fromKey(ptrInfoIp(&mod.intern_pool, ty.toIntern()));
}
pub fn eql(a: Type, b: Type, mod: *const Module) bool {
@ -1832,10 +1832,10 @@ pub const Type = struct {
}
pub fn isVolatilePtr(ty: Type, mod: *const Module) bool {
return isVolatilePtrIp(ty, mod.intern_pool);
return isVolatilePtrIp(ty, &mod.intern_pool);
}
pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool {
pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool {
return switch (ip.indexToKey(ty.toIntern())) {
.ptr_type => |ptr_type| ptr_type.is_volatile,
else => false,
@ -1920,10 +1920,10 @@ pub const Type = struct {
/// For *T, returns T.
/// For [*]T, returns T.
pub fn childType(ty: Type, mod: *const Module) Type {
return childTypeIp(ty, mod.intern_pool);
return childTypeIp(ty, &mod.intern_pool);
}
pub fn childTypeIp(ty: Type, ip: InternPool) Type {
pub fn childTypeIp(ty: Type, ip: *const InternPool) Type {
return ip.childType(ty.toIntern()).toType();
}
@ -2164,10 +2164,10 @@ pub const Type = struct {
/// Asserts the type is an array or vector or struct.
pub fn arrayLen(ty: Type, mod: *const Module) u64 {
return arrayLenIp(ty, mod.intern_pool);
return arrayLenIp(ty, &mod.intern_pool);
}
pub fn arrayLenIp(ty: Type, ip: InternPool) u64 {
pub fn arrayLenIp(ty: Type, ip: *const InternPool) u64 {
return switch (ip.indexToKey(ty.toIntern())) {
.vector_type => |vector_type| vector_type.len,
.array_type => |array_type| array_type.len,
@ -2385,10 +2385,10 @@ pub const Type = struct {
/// Asserts the type is a function or a function pointer.
pub fn fnReturnType(ty: Type, mod: *Module) Type {
return fnReturnTypeIp(ty, mod.intern_pool);
return fnReturnTypeIp(ty, &mod.intern_pool);
}
pub fn fnReturnTypeIp(ty: Type, ip: InternPool) Type {
pub fn fnReturnTypeIp(ty: Type, ip: *const InternPool) Type {
return switch (ip.indexToKey(ty.toIntern())) {
.ptr_type => |ptr_type| ip.indexToKey(ptr_type.elem_type).func_type.return_type,
.func_type => |func_type| func_type.return_type,